Registrati

What is MCP (Model Context Protocol)

This article is not available in Italian yet. It is shown in English.

The Model Context Protocol (MCP) is an open protocol that standardizes how AI applications connect to external tools, data sources and services. An application that supports MCP can work with any MCP server, whether it gives access to a file system, a database, a bug tracker or a payment API, without a separate integration for each pair of application and service.

MCP was introduced by Anthropic in November 2024. Since December 2025 the protocol has been developed under the Agentic AI Foundation, part of the Linux Foundation. The current version of the specification is 2026-07-28.

Overview

Property Value
Type Open application-level protocol, client-server
Message format JSON-RPC 2.0
Transports stdio for local servers, Streamable HTTP for remote servers
Server primitives Tools, resources, prompts
Current specification 2026-07-28
Governance Agentic AI Foundation (Linux Foundation) since December 2025
Official SDKs TypeScript, Python, Go, C# (Tier 1); also Java, Kotlin, Rust, Swift, PHP and others

The problem MCP solves

A language model only works with the text it receives. To read a file, query a database or create a ticket, the model needs an application that calls external systems on its behalf and puts the results back into the model's context. Model providers support this through function calling (also called tool use): the application describes functions with JSON Schema, the model returns a request to call one of them, and the application executes the call.

Function calling defines how the model asks for a call. It does not define where the tools come from. Before MCP, every AI application had its own plugin or integration format, so the integration with a given service was written separately for each application. With N applications and M services this means up to N × M integrations, each with its own code, authentication and maintenance.

MCP replaces this with a single contract. A service implements an MCP server once, an application implements an MCP client once, and any compatible pair works together: N + M implementations instead of N × M.

The idea comes from the Language Server Protocol (LSP), which solved the same problem for code editors and programming languages: one language server works in every editor that supports LSP. MCP reuses the LSP approach to message flow and the same message format, JSON-RPC 2.0.

History

Date Event
25 November 2024 Anthropic publishes MCP as an open standard, with SDKs for Python and TypeScript and a set of reference servers. The authors are David Soria Parra and Justin Spahr-Summers
March 2025 Specification 2025-03-26: the Streamable HTTP transport and authorization based on OAuth 2.1. OpenAI adopts MCP, starting with its Agents SDK
April 2025 Google announces MCP support for Gemini models and the Gemini SDK
May 2025 Microsoft announces MCP support across its platforms at Build 2025
June 2025 Specification 2025-06-18: structured tool output and elicitation
September 2025 Preview of the official MCP Registry
November 2025 Specification 2025-11-25: experimental tasks, OAuth Client ID Metadata Documents
December 2025 Anthropic transfers MCP to the Agentic AI Foundation (AAIF), a directed fund of the Linux Foundation co-founded by Anthropic, Block and OpenAI
January 2026 MCP Apps, the first official extension: interactive interfaces delivered by MCP servers
28 July 2026 Specification 2026-07-28: the protocol core becomes stateless

Architecture

Participants

MCP has three roles:

  • Host is the AI application the user works with: a chat assistant, an IDE, an agent. The host runs the conversation with the model and decides what the model is allowed to do. Examples are Claude Desktop, Claude Code, Visual Studio Code and ChatGPT.
  • Client is a component inside the host that maintains the connection to one MCP server. The host creates a separate client for every server it connects to.
  • Server is a program that provides context and actions: tools, data, prompt templates. A server can wrap a file system, a database, a SaaS API or an internal company service.
Host (AI application)
 |
 +-- MCP client 1 --- stdio ------------- MCP server: file system (local)
 +-- MCP client 2 --- stdio ------------- MCP server: database (local)
 +-- MCP client 3 --- Streamable HTTP --- MCP server: bug tracker (remote)

The model does not connect to servers. It sees the descriptions of the available tools in its context and returns a request to call one of them. The host decides whether to execute the request, sends it through the right client and returns the result to the model. Control over what the model can do stays with the host and the user.

A server that runs as a process on the user's machine is called local. A server that runs as a network service is called remote. A local server usually serves one client; a remote server serves many.

Layers

The protocol has two layers:

  • The data layer defines JSON-RPC 2.0 messages and their meaning: discovery, primitives, notifications, errors.
  • The transport layer defines how messages are delivered: connection, message framing, authorization.

The same JSON-RPC messages travel over any transport, so the logic of a server does not depend on how it is deployed.

Primitives

Primitives are what the two sides offer each other. The specification defines three server primitives:

Primitive What it is Who decides to use it Methods
Tools Functions that perform actions: query a database, create a ticket, call an external API The model, with the permission of the host tools/list, tools/call
Resources Data that adds context: file contents, database records, documents. Each resource is identified by a URI The application resources/list, resources/read
Prompts Reusable instruction templates for the model, often with parameters The user, for example through a slash command prompts/list, prompts/get

A tool is described by a name, a human-readable title, a description and a JSON Schema of its input parameters (inputSchema). A tool can also declare the schema of its result (outputSchema). The model chooses a tool and fills in its arguments based on the name, the description and the schema. The text of descriptions is therefore part of the interface: an inaccurate description leads to wrong or missed calls even when the code of the tool is correct.

The client side offers primitives that let a server ask the host for something:

  • Elicitation: the server asks the user for additional input or for confirmation, for example a missing parameter or approval of an action (elicitation/create).
  • Sampling (deprecated in 2026-07-28): the server asks the client's model to generate a completion (sampling/createMessage). New implementations call model provider APIs directly.
  • Roots (deprecated): the client tells the server which directories it may work with. Paths are now passed as tool parameters or in the server configuration.
  • Logging (deprecated): log messages from the server to the client. Replaced by standard error output for stdio servers and by OpenTelemetry.

A deprecated feature keeps working for at least twelve months. This minimum period is part of the formal deprecation policy introduced in 2026-07-28.

The protocol also defines utilities: notifications, progress reporting for long operations, cancellation, pagination of lists and caching hints for list results. Each server primitive is described in a separate article: tools, resources and resource templates, prompts.

How a request works

Discovery

Since 2026-07-28 MCP is stateless: every request contains everything the server needs to process it. The protocol version, the identity of the client and its capabilities travel in the _meta field of each request.

To learn what a server supports, the client can send server/discover. Every server must implement this method; the client may skip it and send other requests directly.

JSON
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "server/discover",
  "params": {
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientInfo": { "name": "example-client", "version": "1.0.0" },
      "io.modelcontextprotocol/clientCapabilities": { "elicitation": {} }
    }
  }
}

The response lists the supported protocol versions and the capabilities of the server, and it can be cached:

JSON
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "resultType": "complete",
    "supportedVersions": ["2026-07-28"],
    "capabilities": { "tools": { "listChanged": true }, "resources": {} },
    "_meta": {
      "io.modelcontextprotocol/serverInfo": { "name": "example-server", "version": "1.0.0" }
    },
    "ttlMs": 3600000,
    "cacheScope": "public"
  }
}

If the server does not support the requested version, it rejects the request with UnsupportedProtocolVersionError and the list of versions it supports. The client then repeats the request with a version both sides support.

Calling a tool

A typical cycle looks like this:

  1. The host requests the list of tools from each connected server (tools/list) and adds their descriptions to the model's context.
  2. The user asks a question. The model decides that a tool is needed and returns a call with arguments.
  3. The host checks permissions, asks the user for confirmation if needed, and sends tools/call through the client of the corresponding server.
  4. The server performs the action and returns the result as a content array: text, images, links to resources, structured data.
  5. The host passes the result to the model, and the model continues its answer.

The request and the response of step 3 and 4:

JSON
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "weather_current",
    "arguments": { "location": "San Francisco", "units": "imperial" },
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientInfo": { "name": "example-client", "version": "1.0.0" },
      "io.modelcontextprotocol/clientCapabilities": { "elicitation": {} }
    }
  }
}
JSON
{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "resultType": "complete",
    "content": [
      { "type": "text", "text": "Current weather in San Francisco: 68°F, partly cloudy" }
    ]
  }
}

An error that occurs while a tool runs is returned inside the result with isError: true, so the model sees it and can correct the call. Protocol errors, such as an unknown method or invalid parameters, are returned as JSON-RPC errors.

When the server needs more input

In earlier versions a server could send a request to the client in the middle of processing, for example to ask the user a question. This required a long-lived connection to the same server instance.

The 2026-07-28 specification replaces this with Multi Round-Trip Requests (MRTR). The server answers tools/call, resources/read or prompts/get with a result of type input_required. The result lists what the server needs in inputRequests and can carry an opaque requestState:

JSON
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "resultType": "input_required",
    "inputRequests": {
      "github_login": {
        "method": "elicitation/create",
        "params": {
          "mode": "form",
          "message": "Please provide your GitHub username",
          "requestedSchema": {
            "type": "object",
            "properties": { "name": { "type": "string" } },
            "required": ["name"]
          }
        }
      }
    },
    "requestState": "AEAD-protected blob"
  }
}

The client collects the answers, for example by asking the user, and repeats the original request with a new id, the answers in inputResponses and the unchanged requestState. Any server instance can process the repeated request. Because requestState passes through the client, the server must treat it as untrusted input and protect its integrity when it affects authorization or business logic.

Notifications

A server can notify the client about changes, for example that its list of tools has changed (notifications/tools/list_changed). Notifications are opt-in: the client opens a long-lived subscriptions/listen stream and names the notification types it wants to receive. Delivery is best effort, so clients also request lists again from time to time.

The results of tools/list, prompts/list, resources/list and resources/read carry caching hints: ttlMs (how long the result stays fresh) and cacheScope (who may reuse it). The specification recommends returning tools in a deterministic order, which keeps the model's prompt cache stable.

Transports

stdio

The host starts the server as a child process. Messages go through standard input and output as JSON-RPC, one message per line; standard error is used for logs. This transport is used for local servers: there is no network, and credentials come from the environment of the process, for example from environment variables.

Streamable HTTP

The server is an HTTP endpoint. The client sends each message with an HTTP POST request. The server answers with JSON or opens a Server-Sent Events stream when it needs to send several messages, for example progress updates.

Since 2026-07-28 requests carry headers with the method and the name of the tool, resource or prompt. Gateways, rate limiters and web application firewalls can route and meter traffic without parsing the JSON body:

HTTP
POST /mcp HTTP/1.1
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search_issues

There is no protocol session and no Mcp-Session-Id header, so a remote server can run behind a standard round-robin load balancer, without sticky sessions or shared session storage, including on serverless platforms.

The older HTTP+SSE transport from the first version of the specification is deprecated in favour of Streamable HTTP. Both transports, their headers and requirements are described in the article MCP transports.

The 2026-07-28 specification

The maintainers describe 2026-07-28 as the largest revision of the protocol since its launch. The main changes compared with 2025-11-25:

Area Up to 2025-11-25 2026-07-28
Start of work initialize / initialized handshake that opens a session No handshake, every request is self-contained
Session Mcp-Session-Id header Removed
Capabilities Exchanged once during initialize Sent in _meta of every request; server/discover
Requests from server to client Sent by the server during processing Multi Round-Trip Requests
Long-running operations Experimental tasks in the core Tasks extension io.modelcontextprotocol/tasks
HTTP routing Method only inside the JSON body Mcp-Method and Mcp-Name headers
Lists No caching hints ttlMs, cacheScope, deterministic order of tools
Deprecation No formal policy At least twelve months; roots, sampling and logging deprecated

The release also formalized extensions: optional features that both client and server must support explicitly and that evolve outside the core protocol. Official extensions include:

  • Tasks: asynchronous execution of long operations. A tool returns a task handle; the client polls its status (tasks/get) and retrieves the result later.
  • MCP Apps: interactive interfaces. A server links a tool to a ui:// resource, and the host renders it in a sandboxed iframe. Hosts without support fall back to text or structured data.
  • Enterprise-Managed Authorization: access to servers is provisioned by administrators through the company identity provider, and users are connected automatically when they sign in.

The cost of migration falls mostly on servers that relied on session identifiers. State that an application needs between calls is passed explicitly: for example, a tool returns a handle, and the model passes it back as an argument of the next call. The changes and the migration from 2025-11-25 are described in the article Stateless MCP, the extension mechanism and the official extensions in the article MCP extensions.

Security and authorization

Authorization in MCP is optional. For servers that use HTTP and require it, the specification defines authorization based on OAuth 2.1. The MCP server acts as an OAuth resource server: the client obtains an access token from the authorization server and sends it in the Authorization header of every request. The server accepts only tokens issued for it. The 2026-07-28 specification adds requirements that close known attack paths:

  • the client must validate the issuer of the authorization response (iss, RFC 9207) before redeeming an authorization code;
  • client credentials are bound to the issuer that created them and cannot be reused with another authorization server;
  • Dynamic Client Registration is deprecated in favour of Client ID Metadata Documents.

A server must not pass the token it received from the client on to other services (token passthrough is forbidden): for calls to other APIs it obtains its own tokens. Servers that use stdio do not follow the OAuth flow and take credentials from the environment. The full flow is described in the article Authorization in MCP.

The specification requires hosts to obtain explicit user consent before invoking a tool and treats tool descriptions from untrusted servers as untrusted. Known classes of risks:

  • Tool poisoning: instructions hidden in tool descriptions, which the model reads and the user usually does not see. This is a form of prompt injection, described publicly in April 2025.
  • Prompt injection through data: text returned by a tool or a resource, such as a web page, an email or a ticket, can contain instructions addressed to the model.
  • Confused deputy: a proxy server with broad permissions performs an action for a user who should not have access to it.
  • Vulnerabilities in implementations: for example, CVE-2025-6514 in the mcp-remote package (CVSS 9.6) allowed a malicious server to execute commands on the user's machine, and CVE-2025-49596 in MCP Inspector came from the lack of authentication by default.

The risks and the measures against them are described in the article MCP security.

Ecosystem

  • SDKs. The Tier 1 SDKs (TypeScript, Python, Go and C#) supported 2026-07-28 at release. Official SDKs also exist for Java, Kotlin, Rust, Swift, PHP and other languages.
  • MCP Inspector is a developer tool that connects to a server, lists its primitives, calls tools and shows the messages. Its use in testing is described in the article Testing MCP servers.
  • MCP Registry (registry.modelcontextprotocol.io(opens in a new tab)) is the official catalog of publicly available servers, launched in preview in September 2025. It stores metadata, not code: each entry is a server.json file with a unique name in reverse-DNS form (such as io.github.user/server-name) and the location of the package in npm, PyPI, Docker Hub or the address of a remote server. The registry API is open, so companies can run their own private registries in the same format. Publishing a server is described in the article Publishing an MCP server to the MCP Registry.
  • Hosts. MCP is supported by Claude, ChatGPT, Visual Studio Code, Cursor and many other AI applications and agent frameworks.
Function calling MCP REST or GraphQL API
Level Feature of a model API Protocol between an AI application and external systems Interface of a service for programs
Who describes the tools The application developer, in every request to the model The server author, once The service developer
Discovery at runtime No Yes: tools/list, notifications about changes Usually through documentation or OpenAPI
Reuse across AI applications No Yes Each AI application integrates separately

MCP does not replace function calling: the host still uses the function calling of its model so that the model can choose a tool. MCP defines where the tools come from and how they are called.

MCP does not replace APIs either. A typical MCP server is a layer over an existing API that adapts it for a model: it selects the operations worth exposing, describes them in plain language, simplifies parameters and shapes results to fit the model's context. How such a layer is designed is described in the article MCP server over an existing API.

The Agent2Agent (A2A) protocol solves a different task: it connects agents with each other, while MCP connects an agent to tools and data. The two protocols are used together.

Terms

Term Meaning
MCP host AI application that runs the model and connects to MCP servers
MCP client Component of the host that keeps the connection to one server
MCP server Program that provides tools, resources and prompts
Tool Function that the model can call through the host
Resource Data identified by a URI that the application can add to the context
Prompt Instruction template that the user can invoke
Elicitation Request from the server for additional input from the user
Capability Feature that a client or server declares as supported
_meta Field of a request that carries the protocol version, client identity and capabilities
MRTR Multi Round-Trip Requests: the server answers input_required, the client repeats the request with the answers
Extension Optional feature outside the core protocol, such as Tasks or MCP Apps

Sources

Series

Model Context Protocol (MCP)
  1. What is MCP (Model Context Protocol)Current
  2. Tools in MCP
  3. Resources and resource templates in MCP
  4. Prompts in MCP
  5. MCP transports: stdio and Streamable HTTP
  6. Stateless MCP: changes in 2026-07-28
  7. Authorization in MCP
  8. MCP security
  9. MCP extensions
  10. MCP server over an existing API
  11. Testing MCP servers: the basics
  12. Evaluating an MCP server with models
  13. Regression testing of an MCP server
  14. Publishing an MCP server to the MCP Registry

Wiki articles are written and maintained by the ComplexQA team.