Website | Source | Specification | Docs
SDKs:
MCP servers can provide three main types of capabilities:
Connection lifecycle:
Model Context Protocol (MCP) is an open protocol that
enables seamless integration between LLM applications and external data sources and
tools. Whether you're building an AI-powered IDE, enhancing a chat interface, or creating
custom AI workflows, MCP provides a standardized way to connect LLMs with the context
they need.
This specification defines the authoritative protocol requirements, based on the
TypeScript schema in
schema.ts.
For implementation guides and examples, visit
modelcontextprotocol.io.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD
NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
interpreted as described in BCP 14
[RFC2119]
[RFC8174] when, and only when, they
appear in all capitals, as shown here.
MCP provides a standardized way for applications to:
The protocol uses JSON-RPC 2.0 messages to establish
communication between:
MCP takes some inspiration from the Language Server Protocol, which standardizes how to add support for programming languages across a whole ecosystem of development tools. In a similar way, MCP standardizes how to integrate additional context and tools into the ecosystem of AI applications.
Servers offer any of the following features to clients:
Clients may offer the following features to servers:
Beyond the core protocol, MCP defines optional extensions
that add modular, specialized, or experimental functionality. Extensions
are always opt-in and require explicit support from both client and server, negotiated
during initialization. Notable extensions include:
The Model Context Protocol enables powerful capabilities through arbitrary data access
and code execution paths. With this power comes important security and trust
considerations that all implementors must carefully address.
While MCP itself cannot enforce these security principles at the protocol level,
implementors SHOULD:
Remove protocol-level sessions and the Mcp-Session-Id header from the Streamable HTTP transport. List endpoints (tools/list, resources/list, prompts/list) no longer vary per-connection. Servers that need cross-call state use explicit, server-minted handles passed as ordinary tool arguments (SEP-2567).
Make MCP stateless: remove the initialize/notifications/initialized handshake. Every request now carries its protocol version and client capabilities in _meta (io.modelcontextprotocol/protocolVersion, io.modelcontextprotocol/clientCapabilities). Clients SHOULD identify themselves on each request (io.modelcontextprotocol/clientInfo), and servers SHOULD identify themselves in each result's _meta (io.modelcontextprotocol/serverInfo). Version mismatches return UnsupportedProtocolVersionError (SEP-2575).
Add server/discover: servers MUST implement this RPC to advertise their supported protocol versions, capabilities, and identity. Clients MAY call it before any other request for up-front version selection, or use it as a backward-compatibility probe on STDIO (SEP-2575).
Replace the HTTP GET endpoint and resources/subscribe/resources/unsubscribe with subscriptions/listen: a single long-lived POST-response stream for opted-in server-to-client change notifications. Clients opt in to specific types (toolsListChanged, promptsListChanged, resourcesListChanged, resourceSubscriptions); the server acknowledges and tags notifications with io.modelcontextprotocol/subscriptionId. Request-scoped notifications such as notifications/progress and notifications/message continue to flow on the response stream of the request they relate to, not the subscriptions/listen stream (SEP-2575).
Remove ping, logging/setLevel, and notifications/roots/list_changed. Log level is now set per-request via io.modelcontextprotocol/logLevel in _meta; servers MUST NOT emit notifications/message for requests that did not include this field (SEP-2575).
Move experimental tasks out of the core protocol and into an official extension (io.modelcontextprotocol/tasks). The redesigned extension replaces the blocking tasks/result method with polling via tasks/get and a new tasks/update for client-to-server input, removes tasks/list, and allows servers to return task handles unsolicited without per-request opt-in (SEP-2663).
Multi Round-Trip Requests (MRTR) pattern introduced which replaces the previous approach of sending server-initiated requests, such as roots/list, sampling/createMessage, or elicitation/create. Servers return an InputRequiredResult (resultType: "input_required") whose inputRequests field carries the requests for the additional information needed to process the request. Clients respond with inputResponses on a retry of the original request providing the requested information. (SEP-2322).
All results now carry a required resultType field: "complete" for ordinary results and "input_required" for multi round-trip request interim results. Clients MUST treat results from earlier-protocol servers that omit the field as "complete" (SEP-2322).
Remove SSE stream resumability and message redelivery (the Last-Event-ID header and SSE event IDs) from the Streamable HTTP transport. A broken response stream loses the in-flight request; clients MUST re-issue it as a new request with a new request ID (SEP-2575).
extensions field to ClientCapabilities and ServerCapabilities to support optional extensions beyond the core protocol._meta keys (traceparent, tracestate, baggage) (SEP-414).tools/list in a deterministic order to enable client-side caching and improve LLM prompt cache hit rates.Mcp-Method, Mcp-Name) on Streamable HTTP POST requests, and add support for custom headers from tool parameters via x-mcp-header (SEP-2243).ttlMs and cacheScope fields on results returned by tools/list, prompts/list, resources/list, resources/read, and resources/templates/list via a new CacheableResult interface. ttlMs is a freshness hint (in milliseconds) allowing clients to cache responses and reduce polling; cacheScope ("public" or "private") controls whether shared intermediaries may cache the response. Both fields complement existing listChanged notifications (SEP-2549).-32002 to -32602 (Invalid Params) to align with JSON-RPC specification.iss parameter in authorization responses periss against the recorded issuer before redeeming the authorization codeapplication_type during Dynamic ClientinputSchema and outputSchema to allow any JSON Schema 2020-12 keywords, andstructuredContent to allow any JSON value. Add $ref resolution requirements andnotifications/elicitation/complete notification and theelicitationId field of URL mode elicitation requests, both introduced in2025-11-25. Under therequestState.-32000 to -32019 remains-32020 to -32099 isHeaderMismatch -32001 → -32020, MissingRequiredClientCapability-32003 → -32021, UnsupportedProtocolVersion -32004 → -32022 — and addHeaderMismatchError to the schema, which previously existed only in transport prose.Features listed here remain part of the specification but are scheduled for removal under the feature lifecycle and deprecation policy. New implementations should not adopt them. The deprecated features registry tracks every feature currently in the Deprecated state.
Deprecate the Roots, Sampling, and Logging features
(SEP-2577).
These features remain fully functional during the deprecation window but new
implementations should not add support for them. Suggested migrations: pass
directories or files via tool parameters, resource URIs, or server
configuration instead of Roots; integrate directly with LLM provider APIs
instead of Sampling; log to stderr (stdio) or use OpenTelemetry instead of
Logging.
Reclassify the HTTP+SSE transport (deprecated since protocol version
2025-03-26) as Deprecated under the feature lifecycle policy
(SEP-2596).
Migrate to Streamable HTTP.
Reclassify the includeContext values "thisServer" and "allServers"
(soft-deprecated since protocol version 2025-11-25) as Deprecated
(SEP-2596).
Omit the field or use "none"; these values will be removed no later than
the Sampling feature itself.
Deprecate the OAuth 2.0 Dynamic Client Registration Protocol
(RFC7591) as a client registration
mechanism in favor of
Client ID Metadata Documents
(PR #2858).
It remains available for backwards compatibility with authorization servers that do
not support Client ID Metadata Documents.
schema.json now correctly reflects that the Typescript definition of minimum/maximum/default are number's and not just integers. This was caused by running the generator using --defaultNumberType integer (PR#2710).seps/ directory, PR-derived numbering, sponsor responsibilities, and status management via PR labels (SEP-1850).Edit your configuration file:
- macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
- Windows: %APPDATA%\Claude\claude_desktop_config.json
Example Configuration:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/username/Desktop"
]
}
}
}
Explore the detailed specification for each protocol component:
get-alerts and get-forecast. Then we’ll connect the server to an MCP host (in this case, Claude for Desktop):"import asyncio
import mcp.types as types
from mcp.server import Server
from mcp.server.stdio import stdio_server
app = Server("example-server")
@app.list_resources()
async def list_resources() -> list[types.Resource]:
return [
types.Resource(
uri="example://resource",
name="Example Resource"
)
]
async def main():
async with stdio_server() as streams:
await app.run(
streams[0],
streams[1],
app.create_initialization_options()
)
if __name__ == "__main__":
asyncio.run(main())
Setup
npm init -y
npm install @modelcontextprotocol/sdk
Code
import { createServer } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
// Create the MCP server
const server = createServer({
name: 'ollama-mcp-server',
version: '1.0.0',
});
// 1. Define the tool (What it does)
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "add_numbers",
description: "Adds two numbers together and returns the result",
inputSchema: {
type: "object",
properties: {
a: { type: "number", description: "The first number" },
b: { type: "number", description: "The second number" }
},
required: ["a", "b"]
}
}
]
};
});
// 2. Handle the tool call (How it works)
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
if (name === "add_numbers") {
const result = args.a + args.b;
return {
content: [
{
type: "text",
text: `The sum of ${args.a} and ${args.b} is ${result}.`
}
]
};
}
throw new Error(`Unknown tool: ${name}`);
});
// 3. Start the server
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
}
main().catch((err) => {
console.error("Server error:", err);
process.exit(1);
});
Configuring it for use with Ollama: Find your config file. Mac/Linux: ~/.ollama/config.json; Windows: %APPDATA%\Ollama\config.json. Add the tool to the config: Open the config file (create it if it doesn't exist) and add a tools section. The value of handler must be the absolute path to your server.js file.
```json
{
"tools": [
{
"name": "add_numbers",
"description": "Adds two numbers together",
"handler": "/full/path/to/your/project/server.js"
}
]
}
```
Once you have saved the configuration file, you must restart Ollama for the changes to take effect.
Start a conversation with a model (e.g., ollama run llama3) and ask it to use your tool.
>>> Can you add 50 and 25 for me?
If successful, the model should invoke your MCP tool, and you should see output indicating the tool ran and the result (75).
These official reference servers demonstrate core MCP features and SDK usage:
⚠️ Note: The following servers have been moved to the servers-archived repository and are no longer actively maintained. They are provided for historical reference only.
TypeScript-based servers can be used directly with npx:
npx -y @modelcontextprotocol/server-memory
Python-based servers can be used with uvx (recommended) or pip:
# Using uvx
uvx mcp-server-git
# Using pip
pip install mcp-server-git
python -m mcp_server_git
To use an MCP server with Claude, add it to your configuration:
{
"mcpServers": {
"memory": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-memory"]
},
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/path/to/allowed/files"
]
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "<YOUR_TOKEN>"
}
}
}
}
Last modified 03 November 2026