An MCP server is a program that exposes capabilities -- tools, resources, and prompts -- to AI applications over the Model Context Protocol. Servers are the supply side of the protocol: they advertise what they can do during the initialization handshake and then respond to requests from clients. The official SDKs for TypeScript (@modelcontextprotocol/sdk) and Python (mcp) provide high-level abstractions that handle the protocol plumbing so you can focus on your domain logic. In TypeScript you use the McpServer class with registerTool and registerResource methods; in Python you use the FastMCP class with @mcp.tool() and @mcp.resource() decorators. Both SDKs support stdio, SSE, and Streamable HTTP transports out of the box.
This is the minimal structure for a TypeScript MCP server. The McpServer instance manages capability declaration and request routing. registerTool takes a name, metadata with a Zod input schema, and an async handler. StdioServerTransport connects via stdin/stdout, which is ideal for local process-spawned servers. Note that logs go to stderr because stdout is reserved for protocol messages.
The Python SDK uses decorators for a concise, Pythonic API. The @mcp.tool() decorator registers a function as a tool, using the function name as the tool name and the docstring as the description. Type hints on the function parameters are automatically converted to the JSON Schema input definition. mcp.run() starts the server on stdio by default.
For production deployments, Streamable HTTP supports session management and concurrent clients. Each initialize request creates a new session with a unique ID. Subsequent requests include the session ID in headers to route to the correct transport. This approach integrates naturally with Express middleware for authentication, rate limiting, and logging. For a shipped example of this pattern, Web Anatomy runs a token-authenticated MCP server over Streamable HTTP, exposing its landing-page benchmark library (search_sections, search_pages, get_section, get_page, plus list_filters and health) to any MCP-compatible client.
Switching transports in the Python SDK is a one-line change. Setting transport to streamable-http starts an HTTP server that handles session management automatically. The json_response=True option tells FastMCP to serialize return values as JSON, which is useful when tools return structured data like dictionaries or lists.
MCP servers can be distributed as npm or PyPI packages and run without permanent installation using npx or uvx. AI hosts like Claude Desktop use a JSON configuration file to specify which servers to launch. Each server entry defines the command to run and the arguments to pass, and the host manages the server lifecycle automatically.
Logging output to stdout in a stdio-transport server, which corrupts the JSON-RPC message stream and causes protocol errors.
Always log to stderr (console.error in Node.js, print to sys.stderr in Python) when using stdio transport. Stdout is exclusively reserved for protocol messages.
Creating a single server instance that handles multiple concurrent HTTP sessions, leading to shared state and race conditions.
Create a new McpServer instance per session when using Streamable HTTP transport. The factory pattern (a createServer function called for each new session) ensures complete isolation between clients.
Not handling server shutdown gracefully, leaving orphaned connections or resources open when the process exits.
Listen for process signals (SIGINT, SIGTERM) and call server.close() or transport.close() to cleanly shut down. In HTTP mode, also clean up session state on connection close.
Forgetting to set the name and version in the McpServer constructor, causing clients to receive empty server info during initialization.
Always provide a descriptive name and semantic version when creating the server. Clients use this information for logging, debugging, and compatibility checks.
Returning raw strings from Python tool handlers instead of structured content, causing the client to receive improperly formatted responses.
For simple text responses, return a plain string -- FastMCP wraps it in the correct content format. For structured data, use json_response=True on the FastMCP instance or return a dict/list, and FastMCP will serialize it as JSON text content.
MCP servers are programs that expose tools, resources, and prompts to AI applications over the Model Context Protocol. The TypeScript SDK provides McpServer with registerTool and registerResource methods, while the Python SDK provides FastMCP with decorator-based registration. Servers follow a strict lifecycle: initialize handshake, capability negotiation, then request-response communication. Use stdio transport for local development and Streamable HTTP for production. Both SDKs handle JSON-RPC serialization, error formatting, and transport management, letting you focus on your domain logic.
Interactive lessons and challenges on Stanza, practice in VS Code, Cursor, or the web.
Interactive lessons and challenges, right in your code editor.
Check the free courses. No credit card.