What official SDKs exist for building MCP servers, and how do they structure a minimal server?

4 minbeginnermcpsdkpythontypescript

Quick Answer

Anthropic and the MCP community maintain official SDKs in several languages, including Python (mcp, with a high-level FastMCP API), TypeScript/JavaScript (@modelcontextprotocol/sdk), Java, Kotlin, and C#, all published under the modelcontextprotocol GitHub organization. Each SDK handles the JSON-RPC framing, lifecycle handshake, and transport plumbing for you, so building a server mostly means registering tools/resources/prompts through decorators or builder methods and writing their handler logic — you rarely touch raw JSON-RPC messages directly unless you need something the high-level API doesn't expose.

Detailed Answer

The SDKs exist precisely so implementers don't have to hand-roll JSON-RPC framing, the initialize handshake, or pagination cursors themselves.

Python (FastMCP-style high-level API)

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("demo-server")

@mcp.tool()
def add(a: int, b: int) -> int:
    """Add two numbers."""
    return a + b

if __name__ == "__main__":
    mcp.run(transport="stdio")

TypeScript

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({ name: "demo-server", version: "1.0.0" });

server.tool("add", "Add two numbers", { a: z.number(), b: z.number() },
  async ({ a, b }) => ({ content: [{ type: "text", text: String(a + b) }] })
);

await server.connect(new StdioServerTransport());

What the SDK handles for you

Hand-implementing the protocol is a reasonable learning exercise, but for a real server it means re-solving problems the SDK already handles correctly and keeps updated as the spec evolves:

  • Deriving inputSchema from typed function signatures (Python type hints, Zod schemas in TypeScript) instead of hand-writing JSON Schema.
  • The full initialize/initialized handshake and capability negotiation.
  • Transport wiring — swapping stdio for streamable-http is usually a one-line change, as covered in the transports section.
  • Pagination cursor handling for */list methods, if your catalog is large enough to need it.

Related Resources