Skip to content

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.

┌──────────── 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.
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?”
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.log or print() 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).

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) ... repeat
6. shutdown close transport / kill process

The official SDKs handle all of this for you. You write the tool handlers.

{
"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.

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.

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