https://modelcontextprotocol.io/introduction
MCP - A standard protocol (like LSP for IDEs) to connect LLMs with context and tools. Uses JSON-RPC - An RPC standard that uses JSON - pass a method name and some params, get a result back.
- Hosts - LLM applications (i.e. your IDE or Claude Desktop). Takes all the output from the clients and manages it. Acts as the UI.
- Clients - Connects to one server instance. Does handshaking (capability exchange), manages talking back and forth between host and server.
- Servers - Implement tools, contexts
- Resources - Context, data
- Prompts - Templates for querying an LLM
- Tools - Functions the LLM can execute
- Sampling - Server-initiated agentic behaviors and recursive LLM interactions
- Requests - Messages sent to initiate an operation. Expect a response. Must include ID and method name. (e.g. tool usage)
- Responses - Messages sent that fulfill a request. Must include same ID as request.
- Success
- Error - Includes an error code and message at minimum
- Notifications - Messages that do not require a response (e.g. status updates)
- SSE - Server sent events (like websockets, but only push from server to client)
Text(Resources + Prompt) -> LLM -> Text(Output/Tools)
- Client
- roots - provide filesystem roots
- sampling
- experimental
- Server
- prompts - prompt templates
- resources - readable resources
- tools - callable tools
- logging
- experimental
- Sub-capabilities
- list changed - change notifications
- subscribed - subscribing to individual items' changes
There is a host. A host has many clients. Each client has one server connection. Servers are connected to resources.
- Host
- Client
- Server
- Servers are easy to build
- Servers are extremely composable
- Servers should not be able to read the whole conversation, nor "see into" other servers
- Features can be added to servers and clients progressively through negotiation
- Requests - Messages sent to initiate an operation. Expect a response. Must include ID and method name. (e.g. tool usage)
- Responses - Messages sent that fulfill a request. Must include same ID as request.
- Notifications - Messages that do not require a response (e.g. status updates)
- Servers and clients declare capabilities during initial handshaking
- Additional capabilities can be negotiated through extensions to the protocol
All nouns are implemented in a typescript schema
- Base Protocol - Core JSON-RPC message types
- Lifecycle Management - Connection initialization, capability negotiation, and session control
- Server Features - Resources, prompts, and tools exposed by servers
- Client Features - Sampling and root directory lists provided by clients
- Utilities - Cross-cutting concerns like logging and argument completion
- Request
- id
- method
- params (hash, nullable)
- Response (must include either result or error)
- id
- result (hash, nullable)
- error (hash, nullable)
- code
- message
- data (nullable)
- Notification
- method
- params (hash, nullable)
- Initialization - capability negotiation and protocol version agreement
- Operation - Normal protocol communication
- Shutdown - Graceful termination
- Client - initialize request
- Server - initialize response
- Client - initialized notification
- stdio
- HTTP with SSE
- servers provide
- SSE endpoint
- HTTP POST endpoint
- servers provide
Versions are specified with a date string e.g. 2024-11-05
- ping - "are you still there?" to the server or client
- cancellation - "cancel that last" to the server or client (useful for long running operations)
- progress - "i'm almost done" to server or client (useful for long running operations)
- prompts - canned prompt templates for particular task (think "slash commands" in slack). E.g. your company has a particular workflow for looking up data on the server - you can encapsulate that into a slash command and make it portable to any LLM UI
- resources - context, input text that can be given to the LLM (e.g. "read")
- tools - functions the LLM can call to take actions (e.g. "write")
- capabilities
listChanged
- declares whether or not the server will send a notification when the list of prompts changes
- messages
prompts/list
(client to server)prompts/get
(client to server)- text
- images
- embedded resources (i.e. URIs)
notifications/prompts/list_changed
(server to client)
See message definitions in schema.
Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "prompts/list",
"params": {
"cursor": "optional-cursor-value"
}
}
Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"prompts": [
{
"name": "code_review",
"description": "Asks the LLM to analyze code quality and suggest improvements",
"arguments": [
{
"name": "code",
"description": "The code to review",
"required": true
}
]
}
],
"nextCursor": "next-page-cursor"
}
}
Request
{
"jsonrpc": "2.0",
"id": 2,
"method": "prompts/get",
"params": {
"name": "code_review",
"arguments": {
"code": "def hello():\n print('world')"
}
}
}
Response
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"description": "Code review prompt",
"messages": [
{
"role": "user",
"content": {
"type": "text",
"text": "Please review this Python code:\ndef hello():\n print('world')"
}
}
]
}
}
- capabilities
subscribe
- whether the client can subscribe to be notified of changes to individual resourceslistChanged
- whether the server will emit notifications when the list of available resources changes
- messages
resources/list
resources/read
resources/templates/list
notifications/resources/list_changed
resources/subscribe
Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "resources/list",
"params": {
"cursor": "optional-cursor-value"
}
}
Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"resources": [
{
"uri": "file:///project/src/main.rs",
"name": "main.rs",
"description": "Primary application entry point",
"mimeType": "text/x-rust"
}
],
"nextCursor": "next-page-cursor"
}
}
Request
{
"jsonrpc": "2.0",
"id": 2,
"method": "resources/read",
"params": {
"uri": "file:///project/src/main.rs"
}
}
Response
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"contents": [
{
"uri": "file:///project/src/main.rs",
"mimeType": "text/x-rust",
"text": "fn main() {\n println!(\"Hello world!\");\n}"
}
]
}
}
Request
{
"jsonrpc": "2.0",
"id": 3,
"method": "resources/templates/list"
}
Response
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"resourceTemplates": [
{
"uriTemplate": "file:///{path}",
"name": "Project Files",
"description": "Access files in the project directory",
"mimeType": "application/octet-stream"
}
]
}
}
- capabilities
listChanged
tools/list
tools/call
notifications/tools/list_changed
Request
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {
"cursor": "optional-cursor-value"
}
}
Response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "get_weather",
"description": "Get current weather information for a location",
"inputSchema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name or zip code"
}
},
"required": ["location"]
}
}
],
"nextCursor": "next-page-cursor"
}
}
Request
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": {
"location": "New York"
}
}
}
Response
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [
{
"type": "text",
"text": "Current weather in New York:\nTemperature: 72°F\nConditions: Partly cloudy"
}
],
"isError": false
}
}
Provide a client autocomplete capabilities. E.g. There's a dog breed MCP with a tool to list dogs that takes an option breed filter. As you are calling the tool and entering a filter, say you start to type "b" - the MCP will return the list of breeds starting with "b" that you can filter on.
Exposes the ability for a server to send a client log messages.
MCP supports pagination using cursors.
Exposes an ability for servers to ask about what files exist and subscribe to changes to those files. e.g. "what's the working directory for this project?"
roots/list
notifications/roots/list_changed
Allows servers to ask clients to use their LLM connection so that the server doesn't need to e.g. have its own API key.
- capabilities
- sampling
sampling/createMessage