@tank/mcp-server-dev
1.0.0Description
Build MCP servers in TypeScript and Python. Covers tools/resources/prompts, TypeScript SDK v2, FastMCP, tool design, OAuth 2.1 auth, security, transports, inspector testing, and deployment.
Triggered by
MCP servermodel context protocolFastMCPMCP toolsMCP resourcesMCP security
Download
Verified
tank install @tank/mcp-server-devMCP Server Development
Core Philosophy
- Tools are the primary interface — Most LLM interactions go through tools. Design tools first, add resources for context and prompts for canned workflows.
- Validate everything, trust nothing — Tool inputs originate from LLM output shaped by potentially adversarial context. Validate with Zod/Pydantic, sanitize against injection, constrain with
additionalProperties: false. - Return errors, don't throw them — Set
isError: trueso the LLM can self-correct. Thrown exceptions become opaque protocol errors the model cannot reason about. - Choose transport by deployment — stdio for local CLI integrations (Claude Desktop, OpenCode). Streamable HTTP for remote servers accessible over the network. Never mix them.
- Scope permissions to the minimum — Each server gets its own credentials with narrow OAuth scopes. Broad tokens across servers create aggregation risk and confused deputy attacks.
Quick-Start: Common Problems
"How do I create a basic MCP server?"
| Language | Command |
|---|---|
| TypeScript | npm init -y && npm i @modelcontextprotocol/server zod |
| Python | pip install fastmcp or uv add fastmcp |
- Register tools with typed schemas (Zod for TS, type hints for Python)
- Choose transport:
StdioServerTransportfor local,NodeStreamableHTTPServerTransportfor remote - Connect:
server.connect(transport) - Test with MCP Inspector:
npx @modelcontextprotocol/inspector-> Seereferences/typescript-sdk.mdandreferences/python-fastmcp.md
"My tool returns data but the LLM ignores it"
- Check
description— it drives LLM tool selection. Be specific about when and why to use the tool - Return
content: [{ type: 'text', text: '...' }]— not raw objects - Add
outputSchemafor structured responses the LLM can parse reliably - Use
isError: truefor failures instead of empty responses -> Seereferences/tool-design.md
"How do I add authentication to my remote server?"
- Remote servers (Streamable HTTP) need OAuth 2.1 or bearer tokens
- Use
@modelcontextprotocol/expressor FastMCP's auth providers for built-in OAuth - Validate tokens on every request — bind sessions to user identity
- Never store tokens in config files; use OS secure credential storage
-> See
references/auth-transport.md
"How do I test my MCP server?"
- MCP Inspector:
npx @modelcontextprotocol/inspector— visual tool testing - Programmatic: create a client, call
tools/listandtools/call, assert results - FastMCP:
InMemoryTransportfor unit tests without network - Integration: test against real data sources in CI
-> See
references/testing-deployment.md
Decision Trees
SDK Selection
| Signal | SDK |
|---|---|
| TypeScript/Node.js project | @modelcontextprotocol/server (v2) + Zod |
| Python project | FastMCP 3 (fastmcp) |
| Go project | mcp-go |
| Wrapping an OpenAPI spec | FastMCP from_openapi() |
| Need both languages | Build two servers; compose at the host level |
Transport Selection
| Deployment | Transport | Session |
|---|---|---|
| Claude Desktop / local CLI | stdio | Single client |
| Remote API server | Streamable HTTP | Multi-client, stateful |
| Legacy SSE requirement | SSE (deprecated) | Multi-client |
| Serverless (Vercel/CF Workers) | Streamable HTTP (stateless) | Per-request |
Primitive Selection
| Need | Primitive | Who Controls |
|---|---|---|
| LLM executes an action | Tool | Model decides |
| Read-only context data | Resource | Application decides |
| Canned interaction pattern | Prompt | User invokes |
| Structured LLM output | Tool with outputSchema | Model decides |
Reference Index
| File | Contents |
|---|---|
references/typescript-sdk.md | TypeScript SDK v2: McpServer, registerTool, registerResource, registerPrompt, Zod schemas, Express/Hono middleware, server instructions, completions |
references/python-fastmcp.md | FastMCP 3: decorators, Pydantic, Context, lifespan, composition, OpenAPI import, dependency injection, middleware |
references/tool-design.md | Tool definition patterns: inputSchema, outputSchema, annotations, error handling, progress reporting, ResourceLink outputs, multi-tool servers, naming conventions |
references/resources-prompts.md | Resource patterns (static, dynamic templates, subscriptions), prompt templates, argument completions, URI design, MIME types |
references/auth-transport.md | Transport mechanics (stdio, Streamable HTTP, SSE), OAuth 2.1 for remote servers, bearer tokens, session management, DNS rebinding protection |
references/security.md | OWASP MCP security: tool poisoning defense, input/output validation, sandboxing, supply chain, cross-server isolation, prompt injection via return values |
references/testing-deployment.md | MCP Inspector, programmatic testing, InMemoryTransport, deployment (Vercel, Cloudflare Workers, Docker, npm/PyPI publishing), CI/CD patterns |