MCP

Model Context Protocol (MCP)👨‍💻

The Model Context Protocol (MCP) is an open standard that defines how AI applications communicate with external tools and data sources. Before MCP, every AI integration required a bespoke adapter -- if you wanted Claude to query a database, you wrote one connector, and if you wanted it to search files, you wrote another. MCP eliminates this fragmentation by providing a single, well-defined protocol that any AI host can speak and any tool provider can implement. Think of it as USB-C for AI: one standard plug that connects any model to any capability. The protocol is built on JSON-RPC 2.0, supports multiple transport layers, and defines three core primitives -- tools, resources, and prompts -- that cover the vast majority of AI-to-world interactions.

Key Takeaways

  • 1MCP is an open specification maintained by Anthropic that standardizes how AI applications discover, connect to, and interact with external data sources and tools. It removes the need for one-off integrations.
  • 2The protocol defines three core primitives: Tools (actions the model can invoke), Resources (read-only data the model can access), and Prompts (reusable templates for model interactions). Each primitive has a well-defined schema and lifecycle.
  • 3MCP uses JSON-RPC 2.0 as its message format, which means every request has an id, a method name, and params -- and every response includes a result or error. This makes the protocol language-agnostic and easy to debug.
  • 4The protocol supports capability negotiation during initialization. Clients and servers declare what they support (tools, resources, prompts, logging, etc.) so both sides know what is available before any work begins.
  • 5MCP is transport-agnostic. The spec works over stdio (for local processes), HTTP with Server-Sent Events (for remote servers), and the newer Streamable HTTP transport. This flexibility means the same server can run locally or in the cloud.
  • 6The specification is versioned and backward-compatible. Clients and servers negotiate the protocol version during the initialize handshake, ensuring older clients can work with newer servers gracefully.

Examples

MCP initialize handshake (JSON-RPC request and response)

json

The initialize handshake is the first exchange in every MCP session. The client declares its protocol version and capabilities, and the server responds with its own. This lets both sides know exactly what features are available -- for example, here the server supports tools with change notifications and resource subscriptions.

Listing available tools via JSON-RPC

json

After initialization, the client can discover what tools are available by calling tools/list. Each tool includes a name, description, and a JSON Schema defining its inputs. This allows the AI model to understand what each tool does and what arguments it expects, enabling accurate tool selection.

Calling a tool and receiving the result

json

Tool invocation follows a simple request-response pattern. The client sends the tool name and arguments, and the server returns a content array. Content can be text, images, or embedded resources. The content array structure allows tools to return rich, multi-part responses.

Reading a resource via the protocol

json

Resources are read-only data endpoints identified by URIs. The client requests a resource by its URI, and the server returns the contents with a MIME type. Unlike tools, resources do not perform side effects -- they simply expose data for the model to read and reason about.

MCP notification (no response expected)

json

MCP uses JSON-RPC notifications for one-way messages that do not require a response. The client sends notifications/initialized to signal it is ready, and the server can send notifications like tools/list_changed to inform the client that available tools have changed. Notifications are distinguished from requests by the absence of an id field.

Common Mistakes

Mistake:

Confusing MCP with function calling. Developers assume MCP is just another name for the tool-use or function-calling feature built into LLM APIs.

Fix:

MCP is a transport and discovery protocol, not a model feature. Function calling tells the model how to structure a tool request; MCP defines how that request reaches the tool server, how the server is discovered, and how capabilities are negotiated. They are complementary layers.

Mistake:

Skipping the initialize handshake and sending tool calls immediately, resulting in errors or undefined behavior.

Fix:

Always complete the full initialize / initialized sequence before sending any other requests. The handshake establishes the protocol version and declares capabilities that both sides depend on.

Mistake:

Assuming all MCP servers support all three primitives (tools, resources, and prompts) without checking the capabilities response.

Fix:

Check the server's capabilities in the initialize response. A server may only support tools and not resources, or vice versa. Attempting to call an unsupported method will result in an error.

Mistake:

Hardcoding a specific transport mechanism (e.g., only stdio) instead of designing the server to be transport-agnostic.

Fix:

Keep your server logic separate from the transport layer. The MCP SDKs make it easy to switch between stdio, SSE, and Streamable HTTP. A well-structured server can run in any mode without code changes.

Mistake:

Ignoring the JSON-RPC error responses and not implementing proper error handling for tool calls and resource reads.

Fix:

Always handle the error field in JSON-RPC responses. MCP defines standard error codes (invalid params, method not found, internal error). Surface these errors to the model so it can retry or adjust its approach.

Best Practices

  • Always implement the full initialization handshake (initialize request, initialize response, notifications/initialized) before sending any other MCP messages. This ensures version and capability agreement.
  • Design your MCP integrations to be transport-agnostic. Use stdio for local development and testing, and Streamable HTTP for production deployments. The protocol is the same regardless of transport.
  • Use capability negotiation to gracefully handle feature differences. If the server does not declare resources support, do not attempt to read resources. Check capabilities programmatically rather than assuming.
  • Return descriptive tool and resource descriptions. The AI model uses these descriptions to decide which tools to invoke, so clear and specific descriptions directly improve tool selection accuracy.
  • Version your MCP servers and track the protocol version they support. This makes it easy to debug compatibility issues and plan upgrades when new protocol versions are released.
  • Log all MCP messages during development. Since the protocol uses JSON-RPC 2.0, every message is human-readable JSON, making it straightforward to trace issues in the request-response flow.

Summary

The Model Context Protocol (MCP) is the open standard for connecting AI applications to external tools and data. It uses JSON-RPC 2.0 over flexible transports (stdio, SSE, Streamable HTTP) and defines three primitives: tools for actions, resources for read-only data, and prompts for reusable templates. The initialization handshake negotiates capabilities so both client and server know exactly what is supported. By adopting MCP, developers write one integration that works with any compliant AI host, eliminating the fragmented adapter approach that preceded it.

Practice MCP with hands-on challenges

Learn model context protocol (mcp) hands-on in your IDE

Interactive lessons and challenges on Stanza, practice in VS Code, Cursor, or the web.

Related Concepts

Related Cheatsheets

Master MCP with Stanza

Interactive lessons and challenges, right in your code editor.

Check the free courses. No credit card.