MCP: Concepts
The Model Context Protocol (MCP) is an open standard for connecting AI applications to tools and data. Build a server once, and it works in Cursor, Claude Code, Claude Desktop, Claude.ai, the SDKs, and many other clients.
Architecture
Section titled “Architecture”┌──────────── Host (Cursor / Claude Desktop / Claude Code) ────────────┐│ Model ◀──▶ MCP client A ◀──▶ ┐ ││ MCP client B ◀──▶ ┼───────────┐ │└──────────────────────────────────┼───────────┼───────────────────────┘ stdio (local) Streamable HTTP (remote) ▼ ▼ MCP server A MCP server B ──▶ API / DB / files- Host: the app the user interacts with.
- Client: one connection per server, managed by the host.
- Server: your program. It exposes capabilities and does the actual work.
- Messages are JSON-RPC 2.0.
What a server can expose
Section titled “What a server can expose”| Primitive | Controlled by | What it is | Example |
|---|---|---|---|
| Tools | The model decides to call them | Functions with a JSON Schema input that can take actions | create_ticket, query_orders |
| Resources | The app/user attaches them | Read-only data addressed by URI | db://schema, file:///notes/today.md |
| Prompts | The user picks them (often as / commands) |
Reusable message templates with arguments | /summarise-incident <id> |
Tools are by far the most widely supported and most used. Build tools first, and add resources or prompts only if your target clients support them and they help.
A server can also ask the client for things, if the client supports it:
| Client feature | What the server asks for |
|---|---|
| Sampling | “Please run this completion on your model for me” |
| Elicitation | “Please ask the user for this input” (for example a confirmation or a missing field) |
| Roots | “Which directories / URIs am I allowed to work in?” |
Transports
Section titled “Transports”| Transport | How | Use for |
|---|---|---|
| stdio | The host launches your server as a child process and talks over stdin/stdout | Local tools, personal use, anything touching local files. Simplest. |
| Streamable HTTP | Your server is an HTTP endpoint (for example https://api.example.com/mcp) with optional SSE streaming |
Remote/shared servers, SaaS integrations, Claude.ai connectors, multi-user |
| SSE (legacy) | The older HTTP + Server-Sent Events transport | Only for compatibility with old clients |
The number-one stdio bug: in a stdio server, stdout is the protocol channel. Any
console.logorprint()to stdout corrupts the stream, and the server “mysteriously” fails to connect. Log to stderr instead (console.error,print(..., file=sys.stderr), or the logging module).
Lifecycle
Section titled “Lifecycle”1. initialize client → server (protocol version, client capabilities)2. initialize result server → client (server info, capabilities: tools/resources/prompts)3. initialized client → server (notification)4. tools/list client → server (discover tools)5. tools/call client → server (model invokes a tool) ... repeat6. shutdown close transport / kill processThe official SDKs handle all of this for you. You write the tool handlers.
Anatomy of a tool
Section titled “Anatomy of a tool”{ "name": "search_orders", "title": "Search orders", "description": "Search customer orders by email, order number, or date range. Returns at most 20 orders, newest first.", "inputSchema": { "type": "object", "properties": { "email": { "type": "string", "description": "Customer email (exact match)" }, "since": { "type": "string", "format": "date", "description": "ISO date, inclusive" }, "limit": { "type": "integer", "minimum": 1, "maximum": 20, "default": 10 } } }, "annotations": { "readOnlyHint": true, "openWorldHint": true }}A tool result contains content (text, images, resource links) and, optionally, structuredContent that matches an outputSchema. Failures are returned as results with isError: true, so the model can see what went wrong and recover.
Build vs install
Section titled “Build vs install”Before you build a server, check for an existing one:
- the official reference servers and registry at https://github.com/modelcontextprotocol
- the vendor’s own official server (GitHub, Linear, Sentry, Stripe, and others publish them)
- Cursor’s MCP directory and Claude’s connectors directory
Build your own when no trusted server exists, when you need your internal systems, or when existing servers expose far too many tools for your use case.
Official SDKs
Section titled “Official SDKs”| Language | Package | Guide |
|---|---|---|
| TypeScript | @modelcontextprotocol/server (v2; @modelcontextprotocol/sdk was v1) |
Build in TypeScript |
| Python | mcp v2 (MCPServer; it was FastMCP in v1) |
Build in Python |
| Others | C#, Java, Kotlin, Go, Rust, Ruby, Swift, PHP | https://modelcontextprotocol.io |
Next: Build in TypeScript or Build in Python