Skip to content

    What is MCP? The Model Context Protocol, explained

    MCPModel Context Protocol — is an open standard for connecting AI applications to external systems. (If you were searching for the MCP joint, the metacarpophalangeal joint of the hand, this page is about a software protocol, not orthopaedics.) In one line: instead of every model relearning every system, a server declares what it can do, a client discovers that at run time, and the model asks for it — all over JSON-RPC 2.0.

    Specification revision marked current: 2025-11-25. We checked: 2026-07-27.

    official versioning page

    The precise definition, and why each word in it matters

    MCP is an application-layer protocol. It does not define a model, a prompt, or how an agent decides anything. It defines exactly one thing: how one side declares capabilities, how the other discovers them, and how they are invoked. The messages are JSON-RPC 2.0 — the same request/response format behind Language Server Protocol. The resemblance is not accidental: LSP solved an identical problem between editors and languages, and MCP applies the same solution to models and systems.

    Three roles, and most confusion about MCP comes from conflating them. The host is the application you open: Claude Desktop, ChatGPT, VS Code. The client is a component inside the host, and each client holds exactly one connection to one server. The server is the process exposing capabilities. When someone says "I installed three MCPs", what happened is that three clients opened inside one host, each against a different server. The distinction sounds pedantic until the first time you debug, and then it is the difference between "the AI can't see my files" and "the client failed initialize".

    Two transports. Over stdio the server runs as a subprocess on your machine and messages travel through a pipe. Over streaming HTTP the server runs remotely — and that, not before, is where authorization begins. Note that authorization is OPTIONAL in the specification overall, and about stdio the spec says plainly:

    Implementations using an STDIO transport SHOULD NOT follow this specification, and instead retrieve credentials from the environment.
    MCP authorization specification

    Versioning has one rule worth knowing before you plan a project. The revision identifier is a YYYY-MM-DD date and increments only on a backwards-incompatible change; a revision marked Current can still receive backwards-compatible changes without the identifier moving. So "we are on 2025-11-25" is a weaker statement than it sounds, which is why we link the versioning page instead of freezing a number into prose.

    The anatomy: who talks to whom, and where the trust boundary runs

    Anatomy of an MCP connectionThe application you open contains two clients. Each client holds exactly one connection to one MCP server over JSON-RPC 2.0. The servers and the systems of record behind them sit past the trust boundary, where the credentials and permissions live.Host — the app you openMCP clientMCP clientJSON-RPC 2.0 · 1:1trust boundary — credentials and scopesMCP serverMCP servermcp.monday.coma server you builtsystem of recordsystem of recordmonday.comPriority ERP

    The drawing carries what prose struggles with: the one-to-one rule. Two clients inside one host, two separate servers, two separate connections. A client does not multiplex, and no client reaches another client's server. The accented line traces a single request, from the moment the model asked for a tool to the moment the business system answered.

    The dashed boundary is where declaration ends and authorization begins. Above it sits a model's context, into which text can be injected from anywhere. Below it sit keys, tokens and write authority. Every serious question about MCP security is a question about what crosses that line, in which direction, and who approved it.

    Three capabilities for a server, three for a client

    The specification is carefully worded and the wording is worth preserving: a server offers any of three capabilities, and a client may offer three others. "Any of" and "may" are the load-bearing words. A server exposing only Tools is a perfectly valid MCP server — which is exactly how the official server we run further down this page behaves: it declares Tools and nothing else.

    What a server may offer

    Resources
    Readable data identified by a URI: a file, a record, the result of a query. The application, not the model, decides whether a resource enters context. In practice that means a server can expose resources and, if your host never built a picker for them, nobody will ever use them.
    Prompts
    Pre-built interaction templates the user selects explicitly — the slash menu, or "add context". It is the only one of the three under direct user control rather than the model's or the application's — and therefore the only one that disappears entirely if the host never built a picker for it.
    Tools
    Actions the model can decide to call. This is what everyone means when they say "MCP", and the only capability where the decision belongs to the model. A tool that writes, deletes or moves money lives here — which is why human approval belongs here and nowhere else.

    What a client may offer

    Sampling
    The server asks the client for a model completion. The commercial consequence: a server can use an LLM without holding its own API key and without billing you separately for tokens — the tokens are spent on the client's account.
    Roots
    The client tells the server which directories or URIs it may operate on. You can watch this happen in the transcript below: our client declared no Roots, so the server fell back to the directory list it was handed on the command line. It is a client capability that sets a real permission boundary, which is why its absence is immediately visible: the server itself wrote to stderr that the client does not support Roots.
    Elicitation
    The server asks the user for more input mid-operation. The rules around it are sharply normative: servers MUST NOT use form mode to request passwords, API keys, access tokens or payment credentials, and MUST use URL mode instead. Clients MUST NOT pre-fetch the URL, MUST NOT open it without explicit consent, and MUST display it in full for examination.

    SEP-2577

    One note that will save you an architecture. In revision 2026-07-28, Roots, Sampling and Logging are marked deprecated under SEP-2577. In the specification's own words they remain fully functional during the deprecation window, and the earliest removal is worded as First revision released on or after 2027-07-28.

    The published migration paths, verbatim: RootsPass directories or files via tool parameters, resource URIs, or server configuration; SamplingIntegrate directly with LLM provider APIs; LoggingLog to stderr for stdio transports; use OpenTelemetry for observability. If someone is proposing an architecture that leans on Sampling today, attach this paragraph to the budget request.

    What MCP replaces — and what it does not

    Before MCP, every pairing of an AI application with a business system was its own project. m applications against n systems produced m times n integrations, each with its own tool definitions, release cycle and owner. A shared standard turns the product into a sum: m plus n.

    But be precise, because this is where most of the marketing in this space stops being precise. MCP does not replace the API. An MCP server for Priority still calls Priority's REST API; somebody still writes that code, handles its errors and maintains it. What the standard replaces is the description layer: instead of every AI application relearning the shape of the API, the server describes itself once in a format every client can read.

    The second replacement is more practical and less discussed: hand-written function calling. Until MCP, tool definitions lived in application code — to add a tool, you shipped a release. Now they live on the server and are discovered at run time. That is exactly what makes MCP convenient, and exactly what makes it dangerous: the tool list and its descriptions can change between one connection and the next, with nobody on your side shipping anything and nobody approving it.

    And what MCP does not replace in your organisation: the workflow engine. The protocol has no scheduler, no triggers, no retry policy and no long-running state. "When a lead arrives, run seven steps and log them" is still orchestration work — MCP is how that orchestration talks to the systems, not the orchestration itself.

    The full comparison: MCP versus API integration

    A worked example: we ran a server and read what it said

    The fastest way to understand MCP is to run one server and read the answer. We used the official filesystem server from the MCP project's own repository, pinned to an exact version. First the declaration a host reads at startup, then the three messages we exchanged.

    STDIO CONFIGA stdio server declaration, pinned to an exact version
    {
      "mcpServers": {
        "filesystem": {
          "command": "npx",
          "args": [
            "-y",
            "@modelcontextprotocol/[email protected]",
            "/Users/you/Documents"
          ]
        }
      }
    }
    TOOLS/LIST · VERBATIMWhat we sent and what came back — verbatim, our line wrapping
    $ npx -y @modelcontextprotocol/[email protected] ./probe
    
    -> {"jsonrpc":"2.0","id":1,"method":"initialize","params":
         {"protocolVersion":"2025-11-25","capabilities":{},
          "clientInfo":{"name":"mcpisrael-probe","version":"1.0.0"}}}
    
    -> {"jsonrpc":"2.0","method":"notifications/initialized"}
    
    -> {"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}
    
    <- {"result":{"protocolVersion":"2025-11-25",
         "capabilities":{"tools":{"listChanged":true}},
         "serverInfo":{"name":"secure-filesystem-server",
                       "version":"0.2.0"}},"jsonrpc":"2.0","id":1}
    
    <- 14 tools. One entry, verbatim (schemas elided):
         {"name":"write_file","title":"Write File",
          "description":"Create a new file or completely overwrite an
            existing file with new content. Use with caution as it will
            overwrite existing files without warning. Handles text
            content with proper encoding. Only works within allowed
            directories.",
          "annotations":{"readOnlyHint":false,"idempotentHint":true,
                         "destructiveHint":true,"openWorldHint":false},
          "execution":{"taskSupport":"forbidden"}, ...}
    
    # stderr
    Secure MCP Filesystem Server running on stdio
    Client does not support MCP Roots, using allowed directories set
    from server args: [ './probe' ]

    Source: the npm package · official repository · Run: 2026-07-29

    Three messages and the whole protocol is already visible. initialize is a version negotiation: we asked for 2025-11-25 and the server returned 2025-11-25. Had it supported only an older revision it would have said so, and the client would have had to decide whether to continue. That handshake belongs to the revision marked current: revision 2026-07-28 removes it entirely in favour of a stateless core, in which every request carries its own protocol version.

    capabilities is a declaration, not a questionnaire. This server declared tools only, with listChanged. No Resources, no Prompts — and it is an official server of the project. That is the best available answer to whether a server must expose all three capabilities: it need not, and the specification writes "any of" precisely so that it does not have to.

    tools/list returned fourteen tools. write_file arrived with annotations: readOnlyHint false, destructiveHint true, idempotentHint true, openWorldHint false. Those values look like access control. They are not. The schema says so itself:

    NOTE: all properties in ToolAnnotations are hints. They are not guaranteed to provide a faithful description of tool behavior (including descriptive properties like `title`). Clients should never make tool use decisions based on ToolAnnotations received from untrusted servers.
    schema/2025-11-25/schema.ts, ToolAnnotations

    And the tools specification adds, in wording unchanged across revisions: For trust & safety and security, clients MUST consider tool annotations to be untrusted unless they come from trusted servers. The defaults are deliberately inconvenient too — readOnlyHint defaults to false and destructiveHint defaults to true. A silent server is treated as dangerous, not safe. This is why write approval, in our builds, is enforced at a gateway we maintain against an allow-list — never by a flag a server sets about itself.

    Now look at the last stderr line. Our client declared no Roots, so the server fell back to the directory list it received on the command line. In other words the effective permission boundary here was set by a command-line argument, not by a client declaration. That is what happens when a client capability exists in the spec but not in the client.

    One note that completes the picture, because without it the example misleads: this exact server had two known vulnerabilities. CVE-2025-53109 (CVSS 8.4) — a symlink validation flaw checking the link's parent directory instead of its target, letting a link reach files such as /etc/sudoers; and CVE-2025-53110 (CVSS 7.3) — naive prefix matching that let a path named allowed_dir_sensitive_credentials pass an allowed_dir allow-list. Reported 2025-03-30, patched 2025-07-01. We ran a later, pinned release. "Official" is not a synonym for "safe", and pinning is what lets you know exactly what is running.

    What MCP is not

    Not a model and not an agent
    MCP does not think, plan or decide. It carries declarations and calls. An agent built on it is exactly as good as the model and the instructions driving it.
    Not an automation engine
    No scheduler, no triggers, no retries, no state. Comparing it to Zapier, Make or n8n compares different layers — they run a process; MCP defines how you talk to the system at the end of it.
    Not a security layer
    Authorization is OPTIONAL in the protocol, and for stdio the spec explicitly says not to implement it but to pull credentials from the environment. An MCP connection is not secure by virtue of being MCP; it is secure because of what you built around it.
    Not a replacement for the API
    Behind every server there is still an API, with permissions, rate limits and errors. The server is translation and scoping, not abolition.
    Not a quality mark
    A listing in the official registry is namespace verification, not a security audit. The registry describes itself as preview and states that it delegates security scanning to the package registries beneath it.
    Not frozen
    Revision 2026-07-28 removes the Mcp-Session-Id session, makes the core stateless, and deprecates several capabilities. Anyone building today should plan for migration rather than assume stability.

    Governance: not a fad, and not a committee

    The question in every first meeting is whether MCP is another passing trend. The answer is a checkable fact rather than a promise. On 2025-12-09 MCP became a founding project of the Agentic AI Foundation — a directed fund under the Linux Foundation, co-founded by Anthropic, Block and OpenAI, with support from Google, Microsoft, AWS, Cloudflare and Bloomberg.

    The detail that matters more than the roster is the Foundation's own wording: it will not dictate the technical direction of MCP. The donation moved legal ownership and institutional neutrality without moving technical decisions into a committee. That is precisely the difference between an open standard and a single-vendor project that calls itself open.

    What governance did change is versioning discipline. Revisions are marked Draft, Current, Final and Deprecated. The lifecycle policy defines a minimum twelve-month deprecation window — and, explicitly, an expedited-removal exception that shortens it to ninety days. The exception is not theoretical: HTTP+SSE transport is already classified Deprecated, and its clock is worded as "three months after SEP-2596 reaches Final" — not a year.

    For perspective, from the release notes themselves: SDKs will adopt this version at their own pace, and the prior version of the spec may remain in use for an undetermined amount of time. A standard with real governance is not a standard that stands still, and your planning should assume that.

    How to tell a real MCP server from a thin wrapper

    Every check below can be run before you sign anything, and most take minutes. They are ordered by what filters fastest.

    1. 01

      Run initialize and read capabilities

      If the server does not answer, you are done. If it does, you now know what it actually offers instead of what the README claims. A server offering only tools is legitimate; a server that cannot complete initialize is not a product.

    2. 02

      Read the tool descriptions, not just the names

      A description containing instructions to the model — always call this first, ignore previous instructions — is not documentation, it is a prompt. Trail of Bits described exactly this on 2025-04-21: descriptions returned by tools/list enter the model's context at connection time, before any tool is invoked or approved. An approval gate on tool execution closes the door after the payload is already inside.

    3. 03

      On a remote server, confirm it returns 401

      An endpoint returning 401 with a WWW-Authenticate challenge and resource_metadata is a live endpoint enforcing authorization before any tool is reachable. An endpoint returning 200 with no credentials is the problem, not the proof.

    4. 04

      Check the credential model

      Does the server want one shared credential, or per-user OAuth? A thin wrapper almost always wants one key — and once it runs under a single broadly-scoped key, everyone talking to it effectively inherits that key's permissions regardless of their own.

    5. 05

      Ask whether it forwards your token upstream

      The specification forbids it: The MCP server MUST NOT pass through the token it received from the MCP client. The consequences the spec itself names: circumvention of rate limiting, request validation and traffic monitoring; broken audit trails; and an attacker holding a stolen token being able to use the server as a proxy for data exfiltration.

    6. 06

      Check who publishes the package

      postmark-mcp was published on npm by a third party impersonating the legitimate project. Versions 1.0.0 through 1.0.15 were clean copies of the real code; version 1.0.16, uploaded 2025-09-17, added a single line that BCC'd every outgoing email to the attacker. Pinning with a lockfile is not bureaucracy.

    7. 07

      Do not trust readOnlyHint

      Or destructiveHint. These are hints a server reports about itself, and the specification explicitly tells clients to treat them as untrusted. Write enforcement belongs in an allow-list you maintain.

    Where to go next

    This page explains the standard. The next three answer what follows from it: what actually connects today, what it takes to make that safe, and how it differs in practice from a normal integration.

    Want to know which of this applies to you?

    The MCP Readiness Review is a ninety-minute working session and a written document sent to you within three business days.

    Last checked: 2026-07-29

    /* deployed 2026-04-08T12:08 */