The MCP binding

Version 0.2.0 of the specification.

7. The MCP binding

A provider is an MCP server. The two operations are MCP resources. Everything in this section follows MCP revision 2026-07-28; the details relied on are listed with their sources in section 14.

7.1 — The server

  • Address. The provider listens on 127.0.0.1 only. It may open a listener for this protocol on a port the system assigns at launch, or use a listener the app already has. A listener bound to any other address, including all interfaces, must not carry the endpoint.
  • Path. The endpoint is a single path, chosen by the provider and published in the descriptor: /mcp on a listener of its own, or a path such as /ambient on a shared one. It begins with / and has no query or fragment. A host uses it as given.
  • Transport. MCP's Streamable HTTP transport: each JSON-RPC request is one HTTP POST to that path. The provider may answer every request with a single JSON object (Content-Type: application/json); it does not need to stream.
  • Authentication. Every request must carry Authorization: Bearer <token>. The token is random, made at launch, and published only in the descriptor file. It is used for this endpoint only, and must not be a credential the app's server accepts anywhere else.
  • Browser protection. The provider refuses any request that carries an Origin header. Browsers attach one to requests made by web pages, and no web page should be calling this server. This is stricter than MCP requires, and a host must not send the header.
  • Required MCP methods. server/discover, resources/list, resources/templates/list and resources/read. A provider should also answer ping with an empty result, for clients that test a connection. Nothing else is required.

On a shared listener. An app that already runs a local HTTP or MCP server may serve the endpoint from it. The rules above then apply to the endpoint's path, with three additions:

  1. The token and Origin checks are enforced on that path before any other handling the server applies to requests, including middleware that adds headers or answers preflights.
  2. The provider does not answer a cross-origin preflight (OPTIONS) on that path with permission, and no response from that path carries an Access-Control-Allow-* header.
  3. Neither the token nor anything from an answer is written to the server's logs.

A provider answered by a different process than the app, and a provider without a token, are not defined by this version.

7.2 — Declaring the extension

The provider lists the extension in its capabilities, which a client gets from server/discover:

{
  "resultType": "complete",
  "supportedVersions": ["2026-07-28"],
  "capabilities": {
    "resources": {},
    "extensions": {
      "io.github.ambientcontextprotocol/context": { "version": "0.2.0" }
    }
  },
  "_meta": {
    "io.modelcontextprotocol/serverInfo": { "name": "Editor", "version": "2.3.0" }
  }
}

The settings object has one field, version, the version of this protocol the provider speaks. A client that does not know the extension ignores it and sees an ordinary server with two resources.

7.3 — The two resources

OperationResourceListed by
currentambient://currentresources/list
locateambient://location/{id}resources/templates/list

A host performs an operation with resources/read on the address. For locate, the host puts the element's id in place of {id}.

The result's contents array holds exactly one entry: the uri that was read, mimeType application/json, and text holding the operation's result (4.1 or a location) as a JSON document.

resources/list returns:

{
  "resultType": "complete",
  "resources": [
    {
      "uri": "ambient://current",
      "name": "current",
      "title": "Current context",
      "description": "What the user has open and selected in this app, right now.",
      "mimeType": "application/json"
    }
  ]
}

resources/templates/list returns:

{
  "resultType": "complete",
  "resourceTemplates": [
    {
      "uriTemplate": "ambient://location/{id}",
      "name": "location",
      "title": "Location of an element",
      "description": "Where an element from the current context is on screen.",
      "mimeType": "application/json"
    }
  ]
}

A provider that cannot report positions leaves the template out. Its context still reaches the agent; the host places its own interface by default.

7.4 — Errors and refusals

CaseResponse
An Origin header is present, on any HTTP method including OPTIONSHTTP 403, with no body. Checked first, so a web page learns nothing else
No Authorization header, or the wrong tokenHTTP 401
An HTTP method other than POSTHTTP 405
A request body larger than the provider acceptsHTTP 413. The limit is the provider's choice
A body that is not JSON, or not a JSON-RPC requestHTTP 400 with JSON-RPC error -32700 or -32600
locate for an id whose element is goneA normal result with state: "gone"
locate for an id the provider never issued, or an element it cannot placeJSON-RPC error -32602, as MCP requires for a resource that does not exist
A request that names MCP 2026-07-28 and lacks a _meta field MCP requires (protocolVersion, clientCapabilities)HTTP 400 with JSON-RPC error -32602
A header MCP requires (MCP-Protocol-Version, Mcp-Method, Mcp-Name) that is missing or disagrees with the bodyHTTP 400 with MCP's header-mismatch error (-32020)
A method the provider does not implementHTTP 404 with JSON-RPC error -32601
A protocol version the provider does not supportHTTP 400 with MCP's UnsupportedProtocolVersionError (-32022)

A request that names no MCP version. A request with no version in its body, and either no MCP-Protocol-Version header or one naming an older revision, is treated as coming from an older client (7.6), not refused. Refusing it would turn away the clients 7.6 asks a provider to serve, which never put a version in the body. The refusal in the table applies to a request whose header names 2026-07-28 or a revision the provider does not know.

7.5 — An optional tool

An agent connected straight to a provider, with no host between them, cannot read a resource on its own initiative in every MCP client. A provider may therefore also offer one tool, context_current, which takes no arguments and returns the current result (4.1) as structured content, with the same JSON as a text block. It is a convenience for that case. A host never uses it, and a provider is complete without it.

7.6 — Older MCP clients

MCP revisions up to 2025-11-25 open with an initialize handshake, which 2026-07-28 removed. A provider should also answer that handshake, so that clients which have not moved yet can connect. MCP allows a server to support both. Doing so is more than one extra method: requests, results and errors differ between the two revisions, and a provider that supports both follows each revision's rules for the clients that use it. Two differences matter here. The provider declares this protocol to those clients under capabilities.experimental in its initialize result, with the same identifier and settings object. And a resource that does not exist, or a method the provider does not implement, is answered to those clients with HTTP 200 carrying the JSON-RPC error (-32002 and -32601), as those revisions define.

11. Implementing a provider

A provider has four jobs:

  1. Listen on the loopback interface and answer the four MCP methods in 7.1, checking the token and refusing Origin.
  2. Write the descriptor when the listener is up, and remove it at quit.
  3. Answer current: build the tree of what is open, mint an id for each element, and mark what is selected, focused and, if the app tracks it, hovered.
  4. Answer locate: look up an id and return the screen rectangles of what it refers to.

An app already has the information for the third in its window and selection state. It has the information for the fourth in the code that draws and hit-tests its content. The work is exposing it.

There are two ways to do the first job:

  • A listener of its own. The provider opens a port the system assigns and serves only this endpoint on it. This is the simplest to get right, because nothing else shares the listener.
  • A route on a server the app already has. The app adds one path and hands every request on it to code that checks Origin and the token and answers the four methods: one request in, one response out. The extra rules for a shared listener in 7.1 apply. The descriptor is written the same way, with endpoint naming that path.

14. MCP details this draft relies on

Read from the MCP specification's source pages for revision 2026-07-28 (repository modelcontextprotocol/modelcontextprotocol, folder docs/specification/2026-07-28/, copied 2026.11.09).

DetailWhat the specification saysPage
Resources are for the application, tools for the modelResources are "application-driven"; tools are "model-controlled"server/index.mdx, server/resources.mdx, server/tools.mdx
Reading a resourceresources/read with params.uri; the result has resultType and contents, each entry with uri, mimeType and text or blobserver/resources.mdx
Parameterized resourcesresources/templates/list returns resourceTemplates, each with a uriTemplateserver/resources.mdx
A resource that does not existJSON-RPC error -32602; never an empty contentsserver/resources.mdx
Custom address schemesAllowed, and must follow RFC 3986server/resources.mdx
Resource capabilityA server offering resources declares "resources": {}; subscribe and listChanged are optionalserver/resources.mdx
No handshakeEvery request carries its protocol version in _meta under io.modelcontextprotocol/protocolVersion; a server must implement server/discoverbasic/versioning.mdx, server/discover.mdx
Required request metadataprotocolVersion and clientCapabilities are required in _meta on every request; a request missing either is refused with 400 and -32602basic/index.mdx
AuthorizationOptional for MCP implementationsbasic/authorization/index.mdx
ExtensionsAdvertised under capabilities.extensions, a map from identifier to settings object; identifiers take a vendor prefix in reverse DNS form; prefixes whose second label is modelcontextprotocol or mcp are reservedbasic/versioning.mdx, basic/index.mdx
HTTP transportOne endpoint accepting POST; a request is answered with one JSON object or an event stream; the client's Accept lists bothbasic/transports/streamable-http.mdx
Required headersMCP-Protocol-Version and Mcp-Method on every request; Mcp-Name carrying the address on resources/read; a mismatch with the body is refused with 400 and error -32020basic/transports/streamable-http.mdx
Local serversMust validate Origin and answer 403 when it is invalid; should bind to 127.0.0.1; should authenticatebasic/transports/streamable-http.mdx
Unknown method and version404 with -32601; 400 with -32022basic/transports/streamable-http.mdx, basic/versioning.mdx
Tool namesLetters, digits, underscore, hyphen and dot; 1 to 128 charactersserver/tools.mdx
Older clientsA server may support both the initialize handshake and per-request metadatabasic/versioning.mdx

On this page