Introduction to MCP v0.3

The Model Context Protocol (MCP) is an open standard that enables AI applications (LLMs and agents) to securely connect with external data sources, tools, and services in a uniform way. At its core, MCP defines a client-server architecture reminiscent of the Language Server Protocol (LSP) - but for AI models’ context and tooling. An MCP client (e.g. Claude Desktop, an IDE plugin, etc.) can discover and invoke capabilities exposed by an MCP server (e.g. a connector to a database, Git repo, Slack, etc.) over a well-defined protocol. This bridges the isolation gap of LLMs by giving them controlled access to the “outside world” of resources and actions.

MCP v0.3, released June 18, 2025, refines and extends the protocol significantly. It builds on the foundations of earlier versions (v0.1 in late 2024 and v0.2 in early 2025) with new features, security enhancements, and a more streamlined HTTP-based communication model. Notably, v0.3 introduces interactive elicitation (allowing servers to ask users for additional info mid-interaction), filesystem roots (letting clients expose limited file directories to servers), and structured outputs for tools (so tools can return machine-readable results). It also tightens security by fully embracing OAuth 2.1 for authentication and requiring explicit protocol version negotiation in HTTP connections. Below is a comparison of how MCP has evolved from v0.1 through v0.3:

AspectMCP v0.1 (2024-11-05)MCP v0.2 (2025-03-26)MCP v0.3 (2025-06-18)
Transport ProtocolLocal STDIO or HTTP + SSE (“legacy” separate endpoints for events).Introduced Streamable HTTP - single HTTP endpoint for requests & server-sent events (while maintaining backward compat with v0.1).Streamable HTTP (default). Single /mcp endpoint for POST (requests) and GET (SSE for pushes). HTTP+SSE legacy deprecated (still supported for older clients).
Message FormatJSON-RPC 2.0 (requests, responses, notifications). Allowed batching of multiple calls.JSON-RPC 2.0 (same format). Streamed responses via SSE allowed. Batching still supported.JSON-RPC 2.0 over HTTP. Batching removed (no JSON-RPC batch arrays). Supports streaming responses/events via SSE.
Server CapabilitiesTools, Resources, Prompts - servers could expose functions, data, and prompt templates.Tools, Resources, Prompts (as in v0.1) with improvements (e.g. remote servers and OAuth introduced).Tools, Resources, Prompts plus output schemas & resource links in tool results. More robust notifications (listChanged, etc.).
Client CapabilitiesBasic client features. (Initial version focused on server-driven context; client-initiated features were minimal.)Added Sampling - servers could request the client/LLM to perform model inferences (agentic loops).Sampling plus new Roots and Elicitation features for richer interaction. (Clients declare these in handshake if supported.)
AuthenticationNone standardized. (Assumed local use or out-of-band auth; no OAuth yet.)OAuth 2.1 framework introduced - MCP servers defined as OAuth Resource Servers; clients obtain access tokens via Authorization Server. Still optional, but laid groundwork for secure remote use.OAuth 2.1 required for protected resources - MCP servers advertise auth metadata (per RFC 9728); clients must use OAuth with Resource Indicators (RFC 8707) to scope tokens. Native OAuth flows (e.g. OAuth2 PKCE) recommended for remote servers.
Notable Additions- (Initial release)Streamable HTTP transport; Comprehensive OAuth 2.1 auth spec; Logging utility; Improved error codes.Interactive elicitation (server->user queries); Filesystem roots exposure; Structured tool outputs with JSON schemas; Resource links in results; Mandatory version headers; Various schema tweaks (e.g. _meta fields, title vs name separation).
Deprecated/Removed-Deprecated HTTP+SSE transport (legacy) in favor of Streamable HTTP.Removed JSON-RPC batch calls; Strengthened certain normative requirements (e.g. lifecycle “SHOULD” -> “MUST”).

What’s new in v0.3? In summary, MCP v0.3 solidifies the protocol for internet-scale use. It adds new layers of interactivity (roots and elicitation), richer output formats for tools, and full-fledged HTTP support with standardized authentication. Importantly, it maintains backwards compatibility so existing v0.2 implementations can interoperate - e.g. by supporting both the unified HTTP endpoint and the older SSE endpoint if needed. Now, let’s dive deeper into the structure of MCP v0.3 and how developers can implement it over HTTP.

MCP Architecture and Core Components

MCP architecture overview - a host application with an MCP client can connect to multiple MCP servers (local or remote) to integrate various data sources.

MCP follows a host / client / server architecture that cleanly separates concerns between AI applications and external integrations:

  • Host: The host is the AI application or environment that contains one or more MCP clients. For example, Claude Desktop, an IDE, or a chat platform can act as a host. The host is responsible for orchestrating connections and enforcing policies. It creates and manages MCP client instances, handles user permissions and consent, and aggregates context from multiple servers for the AI model. The host ensures security boundaries between servers and typically holds the conversation state that isn’t shared in full with any server (preventing servers from seeing each other’s data or the whole chat).

  • Client: An MCP client is a component (often a library or SDK in the host) that manages a single connection to an MCP server. The client speaks the MCP protocol, acting on behalf of the host to send requests and receive responses. Each client instance establishes one stateful session per server, negotiating capabilities and routing messages between the server and the host/LLM. Clients also maintain isolation - e.g. one client connected to a GitHub server and another to a Database server won’t leak data between each other because the host keeps them separate. In essence, the MCP client is the “protocol driver” that handles JSON-RPC messaging, reconnection, subscriptions, etc., so the host and server can focus on higher-level logic.

  • Server: An MCP server is a service or process that provides a specific set of data or tools to the client. Servers expose capabilities in the form of features (more on these below) - for example, a server might expose a set of Tools (functions) to query a database, or a set of Resources representing documents in a repository. Servers are focused and modular by design: each server handles one domain or data source (like “a GitHub server”, “a Slack server”), enabling composition. They operate independently, and can run locally (spawned as subprocesses by a host in STDIO mode) or remotely (as a web service that clients connect to via HTTP). A key principle is that a server never sees the entire model conversation, only the pieces of context or requests relevant to its function - this prevents unwanted data leakage across servers.

This architecture draws inspiration from the Language Server Protocol in that it decouples the “frontend” (AI app) from “backends” (data/tool providers) via a standard protocol. The benefit is scalability: instead of building M×N custom integrations for M AI apps and N data sources, you build M clients and N servers, all speaking MCP (reducing integration complexity to M+N).

MCP transforms the integration problem from M×N custom connectors (top) to M+N standardized connectors (bottom), by acting as a common layer between AI applications and data sources.

Layers of the Specification

MCP v0.3 is organized into layered components, which together define the full protocol:

  • Base Protocol: The core JSON-RPC 2.0 message format and basic connection semantics. MCP uses JSON-RPC for all messaging (requests from client to server and server to client, responses, and notifications). This base defines how messages are structured (fields like jsonrpc, id, method, params, etc.) and the fact that connections are stateful (maintaining an ongoing session). It also covers general utilities like heartbeats (ping), error codes, and cancellation. JSON-RPC in MCP is slightly restricted - for instance, batched requests are no longer supported in v0.3 to simplify processing (each request must be a single JSON object, not an array of them). All implementations must support the base protocol as it is the foundation for everything else.

  • Lifecycle Management: The protocol defines a standard connection lifecycle with distinct phases: Initialization, Operation, and Shutdown. In Initialization, the client and server perform a handshake: they negotiate which MCP version to use and which features each side supports (capabilities exchange), and they share identifying info (like client name/version and server name/version). After agreeing, the session enters the Operation phase, where normal requests (tool calls, resource access, etc.) occur under the agreed capabilities. Finally, a Shutdown phase handles graceful termination (allowing either side to cleanly close the session). We will detail initialization and version negotiation in the HTTP context shortly.

  • Server Features: These are the capabilities that servers can provide. MCP v0.3 defines three primary feature categories on servers:

    • Resources - pieces of data or context that can be fetched or subscribed to. For example, a file’s content, a database record, an image, etc. Servers can offer resource listings and allow clients to retrieve or stream updates to resources.
    • Prompts - predefined prompt templates or workflow scripts that guide the AI on how to interact with the server’s data/tools. (Prompts essentially allow servers to supply “advice” or templates for user instructions, making integration smoother).
    • Tools - functions or operations that the AI can invoke. Each tool has a name, description, and input schema (and in v0.3, possibly an output schema) and represents an action the model can ask the server to perform. For example, searchDocuments or sendEmail could be tools.

    A server advertises which of these it implements during initialization (via capability flags). In v0.3, tool outputs have been enhanced: a tool can now return structured data in a structuredContent field (e.g. a JSON object result) in addition to or instead of plain text. If a tool provides an outputSchema, the server must return results conforming to it and clients should validate against it. For backward compatibility, servers are recommended to also include a text rendition of the result for LLMs to consume. Another new addition is that tools can return resource links - essentially references (URIs) to resources that the client can then fetch via the resource APIs. This is useful if a tool call result is a large data blob or file; rather than returning it inline, the server can return a link that the client may resolve with a separate resource request.

  • Client Features: These are optional capabilities that clients (hosts) can offer to servers, typically enabling servers to request things from the client side. MCP v0.3 expands this considerably. The client can advertise support for:

    • Sampling: Allows the server to request the host to perform an LLM generation (e.g. to continue a thought or answer a sub-question). This feature essentially lets a server say, “I need the AI to draft or expand on X now,” enabling agentic loops where the server can defer to the model. The client would then call the model and return the result back to the server. This was present in v0.2 and remains in v0.3.
    • Roots: New in v0.3, this feature allows the client to expose a set of allowed filesystem locations to the server. If a client declares roots, a server can query roots/list to get a list of directories/files that it is permitted to operate on. This is especially useful for IDE scenarios - e.g. an MCP server providing coding assistance can know the boundaries of the project’s folder, but nothing outside. The client may also send notifications if the root set changes (e.g. user opened a new workspace). In short, Roots establish a sandbox of the filesystem for server operations, bolstering security.
    • Elicitation: Also new in v0.3, elicitation allows a server to ask the end-user a question via the client. This is a way to implement interactive workflows. For example, if a tool needs additional user input (like an API key or a disambiguation), the server can send an elicitation/create request with a prompt message and a JSON schema for the expected answer. The client (host UI) will then prompt the user and ultimately respond to the server with the user’s input, or a rejection/cancellation action. Elicitation ensures the user stays in control - the server can’t directly query the model for potentially sensitive info, it must go through a user prompt. MCP v0.3’s spec emphasizes that elicitation should not be abused to ask for sensitive data and that UIs should clearly identify which server is asking and allow the user to approve/deny.
  • Utilities: Cross-cutting features that aren’t core to context exchange but are important for robust operation. MCP defines things like Configuration, Logging, Progress updates, Cancellation, and error handling conventions. For example, a server with the logging capability can send structured log messages to the client (perhaps to be shown in a debug console). Progress tracking would allow a server to notify how a long-running operation is proceeding. These utilities are optional and negotiated similarly via capabilities (e.g. a server might declare a logging capability to indicate it will emit logs).

Thanks to this layered design, MCP can be extended over time without breaking older clients/servers - new features are only used if both sides declare support (capability negotiation ensures that). MCP v0.3 indeed takes advantage of this: features like elicitation and roots simply won’t be invoked unless the client said “I support this” during initialization.

Ecosystem Role and Use Cases

Why is MCP important? In a word: interoperability. It aims to be the “USB-C of AI integrations” - a universal connector so that any AI application can plug into any data source or tool, without custom glue code for each pairing. Before MCP, integrating an AI assistant with multiple systems required one-off adapters for each combination, which scaled poorly as those numbers grew (the M×N problem). MCP flips this into a hub-and-spoke model (M+N): AI apps implement a client once, data/tool providers implement a server once, and everything speaks the same protocol. This is analogous to how standard REST APIs transformed web integrations, or how LSP transformed dev tool integrations.

Concretely, MCP fosters an ecosystem of reusable connectors. Already, there are open-source MCP server implementations for Google Drive, Slack, GitHub, Git (repositories), PostgreSQL databases, Sentry, Linear, and many more systems. For example, an enterprise could run an “MCP Slack server” that exposes Slack conversations as searchable resources and Slack actions as tools - then any MCP-compatible AI client (Claude, ChatGPT with plugins, a custom agent, etc.) could connect to it and allow the AI to pull context from Slack or post messages, without bespoke API handling in the AI app. Developers are actively contributing to a library of MCP servers covering popular services, accelerating adoption.

Early adopters of MCP include companies and tools across the industry. Anthropic integrated MCP into Claude (Claude Desktop supports local MCP servers, and as of June 2025 Claude can also attach to remote MCP servers). Other collaborators range from fintech (Block) to dev platforms (Zed, Replit, Sourcegraph, Codeium) who see MCP as a way to empower AI coding assistants with project-specific context. Amazon has embraced MCP in the context of its Bedrock platform - viewing MCP as a way to connect Bedrock-hosted models with AWS services securely. In fact, the AWS Machine Learning Blog demonstrates how MCP servers on AWS can expose S3, DynamoDB, or CloudWatch data to an AI agent in a standardized way, all secured by IAM and the OAuth flows behind MCP. This broad interest suggests MCP is on a path to becoming a de facto standard for “bringing your own data” to AI.

Typical use cases being explored with MCP include:

  • Enterprise search and analytics: An AI assistant that can query internal knowledge bases, ticket systems, or databases. For example, a “Confluence MCP server” providing company wiki pages as resources, or a “Jira MCP server” exposing project issues as both resources (issue data) and tools (create or update an issue). With MCP, an analyst could ask a question in natural language and the AI client can retrieve precise data via these servers.
  • Code assistants and IDEs: Developers integrating MCP servers for code repositories and dev tools. E.g., connecting an IDE’s AI assistant to a Git MCP server (for repository content), a CI/CD MCP server (for build statuses as resources), and so on. The AI can then fetch relevant code files or test results on demand, enabling deeper coding assistance. The “roots” feature in v0.3 is especially relevant here - the IDE (client) can limit the server to just the project directory, ensuring the AI only accesses intended files.
  • RPA and Operations: Using MCP as a bridge for AI agents to perform tasks like reading emails, controlling cloud resources, or monitoring logs. For instance, an MCP server for an email inbox might list recent emails as resources and provide a tool to send an email. An agent can then autonomously decide to summarize an email or send a response via those interfaces.
  • Interactive workflows: Through elicitation, MCP v0.3 allows multi-turn interactions where an AI can defer to the user. One scenario: an AI agent wants to execute a high-risk tool (say, delete a file on a server). Instead of doing it blindly, the MCP server could use elicitation to explicitly ask the user “Do you really want to delete file X?” and only proceed if the user confirms. This pattern, combined with OAuth’s user consent flows, means MCP can facilitate safe AI actions with a human-in-the-loop at critical junctures.

Overall, MCP’s role is to standardize and sandbox AI integrations. It provides the structure (JSON-RPC schema, handshake, auth) and leaves the actual domain logic to pluggable servers. This is powerful: organizations can develop connectors internally or share them openly, and any advanced AI agent that speaks MCP can leverage them. As the protocol matures, we can expect a growing “market” of MCP servers (much like APIs or Slack apps today) and broad compatibility across AI platforms. Anthropic, for example, has hinted at an upcoming MCP registry to help discover available servers and share schemas, further fueling the ecosystem.

MCP v0.3 over HTTP: Transport, Messages, and Version Negotiation

One of the biggest focuses of MCP v0.3 is robust HTTP-based implementation. While MCP can be used in a local setting (running servers as subprocesses via STDIO pipes), the protocol is designed to work equally well over networked HTTP - enabling remote connectors and cloud services. Let’s break down how MCP works in an HTTP environment, including message formats, connection handling, versioning, and authentication in v0.3.

Unified HTTP Endpoint and Streaming

MCP v0.3 defines a “Streamable HTTP” transport that uses a single HTTP endpoint for all client-server communication. This unified endpoint (e.g. https://api.example.com/mcp) accepts both POST and GET requests:

  • HTTP POST is used by the client to send any JSON-RPC message to the server. This includes requests (like initialize, tools/call, etc.), notifications (which have no response), and even responses (for handling server-initiated calls). Each POST carries exactly one JSON-RPC message in the body (no batching). The client must set an Accept header indicating it can handle application/json and text/event-stream responses. If the message is a notification or a response from the client’s side, the server will just return 202 Accepted (or an error code) with no body, since no reply is needed. If the message is a request, the server’s behavior is twofold:

    • For simple, immediate responses, the server can return a traditional JSON response (Content-Type: application/json) containing the JSON-RPC result or error. This is a standard HTTP reply with the JSON body corresponding to the response message (with matching id).
    • For longer or multi-part responses, the server can upgrade the response to an SSE (Server-Sent Events) stream (Content-Type: text/event-stream). In this mode, the HTTP POST’s response is kept open and the server sends one or more SSE events over time. Each event’s data is a JSON-RPC message (encoded as a JSON text chunk). This allows the server to stream results or send interleaved messages (like progress updates, partial results, or even server->client requests) before the final answer. Notably, the SSE stream will include the final JSON-RPC response for the original request at some point (which signals completion). After that, the server generally closes the stream.

    The streaming mechanism is crucial for supporting things like tool output streaming (e.g. a tool that streams chunks of data or a long answer) and server-initiated prompts (the server can ask something via elicitation in the middle of handling a request). The client must be prepared to handle both cases: a quick one-off JSON response or an SSE that yields multiple messages.

  • HTTP GET on the endpoint is used by the client to open a standalone SSE channel to listen for server-initiated messages. This is optional - a client can decide to maintain a persistent receive channel. If the client does a GET with Accept: text/event-stream, the server may respond with an SSE stream (or reject with 405 if it doesn’t support separate pulls). Once open, the server can push notifications or requests down this channel at any time, without waiting for a client request. For example, if the server has new data (resource changed) or wants to initiate an elicitation, it can send that on the SSE. The spec ensures that a server will not send the final response for a client’s earlier request on this out-of-band stream unless it’s a resumption scenario (more on resumption later). Essentially, the out-of-band SSE is for async server events unrelated to a specific client call.

Having multiple concurrent SSE connections is allowed (a client could do more than one GET if needed), and servers will distribute messages to only one of them (no duplicate broadcasts). This can help with load balancing or segregating different kinds of events. If a connection drops, the client can open a new GET and use the Last-Event-ID header to resume from where it left off. MCP v0.3 specifies that servers may assign SSE event IDs and support resuming missed events using the standard Last-Event-ID mechanism of SSE. This is a nod to reliability: networks aren’t perfect, so this helps avoid losing messages if a stream disconnects.

Session Management: Because HTTP is stateless by nature, MCP adds an explicit concept of a session when using the streamable HTTP transport. On initialization, a server may generate a session ID (e.g. a UUID or token) and include it in an Mcp-Session-Id header in its HTTP response to the initialize call. The client will then include that Mcp-Session-Id header in all subsequent HTTP requests for that session. This way, the server can correlate all requests (and SSE streams) to the same logical session, enabling it to maintain state. If a request comes without the correct session header (or an unknown session), the server can reject with 400 or 404, prompting the client to re-initiate a fresh session. The client can also explicitly terminate a session by sending an HTTP DELETE to the endpoint with the session header, if the server allows (servers may respond 405 if they don’t support client-initiated termination). This session mechanism is important for cleanup (server can free resources when a session ends) and for scenarios where servers want to enforce single-session per client or tie sessions to auth scopes.

Example - Initialize over HTTP: To illustrate the message format, here’s what an initialization handshake might look like in HTTP:

POST /mcp HTTP/1.1
Host: myserver.example
Accept: application/json, text/event-stream
Content-Type: application/json

{ 
  "jsonrpc": "2.0", "id": 1, "method": "initialize", 
  "params": {
      "protocolVersion": "2025-06-18",
      "capabilities": { 
          "roots": { "listChanged": true }, 
          "sampling": {}, "elicitation": {} 
      },
      "clientInfo": { "name": "MyClient", "version": "1.2.3" }
  }
}

The server might respond:

HTTP/1.1 200 OK
Content-Type: application/json
MCP-Session-Id: 48b43b3e-...-session-token

{
  "jsonrpc": "2.0", "id": 1, "result": {
      "protocolVersion": "2025-06-18",
      "capabilities": {
          "tools": { "listChanged": true },
          "resources": { "subscribe": true, "listChanged": true },
          "prompts": { "listChanged": true }
      },
      "serverInfo": { "name": "MyServer", "version": "2.4.0" }
  }
}

Now the client and server agreed on version 2025-06-18 and exchanged capabilities. The server issued a session ID (e.g. a UUID) - the client will include MCP-Session-Id: 48b43b3e... in the header of every subsequent POST or GET. Finally, the client would send:

POST /mcp HTTP/1.1
MCP-Session-Id: 48b43b3e-... 
Content-Type: application/json

{ "jsonrpc": "2.0", "method": "notifications/initialized" }

to indicate it’s ready, then proceed with normal operations.

A few important notes on HTTP endpoint behavior and best practices in MCP v0.3:

  • Servers must validate the Origin header of incoming requests, especially if running on localhost, to prevent malicious web pages from making requests (a DNS rebinding attack). Additionally, local servers should bind to localhost only, not all interfaces, to avoid exposure. These precautions are called out in the spec’s security guidelines since MCP servers could potentially execute dangerous operations if an attacker could drive them.

  • If a client sends a request that the server doesn’t understand or that violates protocol (e.g. missing required header or invalid JSON), the server will respond with an HTTP error status (4xx/5xx). It may include a JSON-RPC error object in the body for details (with no id since the request wasn’t processed fully).

  • MCP v0.3 expects clients to include an MCP-Protocol-Version HTTP header on all requests after initialization, specifying the agreed version (e.g. MCP-Protocol-Version: 2025-06-18). This serves as an explicit indicator to the server of which spec it should adhere to for this request. If the header is missing, a v0.3 server will assume the latest version, but servers are allowed to require it (and give 400 otherwise). This was added to prevent any ambiguity if, say, a client reconnects without a full re-init - the server can immediately know what spec it’s speaking. The header is especially useful in proxies or multi-tenant setups where version negotiation might have happened elsewhere.

  • Version Negotiation: During initialization, the client proposes a protocol version (usually the latest it supports), and the server responds with the version it will use (which could be the same or a lower one it supports). If there’s no overlap (client can’t support server’s choice), the client should gracefully disconnect. In practice, since MCP is young, most will just use the latest. The negotiated version then governs the rest of the session - and as noted, is communicated via the header on each HTTP request going forward. This mechanism allows newer clients and older servers (or vice versa) to still work together by falling back to an older spec revision if needed.

  • Backward compatibility: MCP v0.3 servers/clients can interoperate with v0.2 or v0.1 implementations by implementing a few conditional behaviors (the spec provides a guide). For example, a v0.3 client connecting to a v0.1 server might attempt the new unified POST and get a 404/405, in which case it knows to switch to the legacy behavior: open an SSE first to get an endpoint event (the old handshake style). Conversely, a v0.3 server that wants to support old clients might actually host two endpoints: the new one and the old /events SSE endpoint, etc.. Over time these older patterns will fade, but v0.3 is explicitly designed to not break the ecosystem during the transition.

Authentication and Security (OAuth2 in MCP v0.3)

Security is paramount in MCP’s design - after all, it lets AI agents invoke tools that might modify data or access sensitive information. MCP v0.3 doubles down on authentication and authorization via OAuth 2.1 to ensure that when clients talk to remote servers, they do so on behalf of a user with proper consent and scoping.

In MCP’s terms, an MCP server that requires auth is treated as an OAuth 2 Resource Server, and there will be a corresponding OAuth 2 Authorization Server that issues tokens for it. MCP’s auth flow is optional (servers can choose to not require auth), but if used, the spec lays out how it works:

  • An MCP server that requires authorization will advertise a special metadata URL as per OAuth 2.0 Protected Resource Metadata (RFC 8728). Essentially, when a client connects and does not supply a valid token, the server can respond with 401 Unauthorized and a WWW-Authenticate header that points to its metadata (including the auth server’s URL). This tells the client “you need to get a token to talk to me, here’s where.” The metadata will list one or more authorization servers (authorization_servers field) that can issue tokens for this resource.

  • The MCP client then goes to the Authorization Server (which could be a separate service, or the same server in another role) and performs an OAuth flow to obtain an access token. The exact OAuth grant could be anything supported (authorization code with PKCE for user login, device code, client credentials for headless, etc.), as the spec leans on standard OAuth 2.1. Importantly, MCP suggests that servers and clients support OAuth 2 Dynamic Client Registration (RFC 7591) - meaning the MCP client can programmatically register itself with the auth server to get client credentials if needed, improving interoperability. It also suggests use of PKCE and other modern security measures (since OAuth 2.1 is essentially OAuth 2.0 with those best practices baked in).

  • MCP v0.3 introduces a requirement that clients use Resource Indicators (RFC 8707) when requesting tokens. In simpler terms, the client must specify the intended resource server’s identifier (URI) while obtaining the token, so that the token is audience-restricted. This prevents a malicious MCP server from tricking a client into using a token meant for another service. It’s a direct response to security concerns - binding tokens to the specific MCP server ensures least privilege (a token for “Server A” can’t be used at “Server B”).

  • Once the client has an OAuth access token, it includes it in Authorization: Bearer headers for all MCP HTTP requests to the server (just like calling a protected REST API). The server will validate the token on each call. Notably, Claude’s implementation (Claude Code) in June 2025 added native OAuth support - meaning it can pop up the OAuth authorization page to the user, etc., to handle this flow. This is far better than API keys floating around, because the user can grant and revoke access per server.

  • Scopes and consent: The protocol itself doesn’t define scopes (that’s up to the server’s OAuth configuration), but you can imagine an MCP server for, say, Google Drive might request a scope like drive.readonly. The user, during the OAuth consent screen, would see what access is being granted (e.g. “Allow ChatGPT to read your Google Drive files?”). This way, users stay in control of what an AI agent can do. MCP’s security principles explicitly state that user consent and control are paramount: “Users must explicitly consent to and understand all data access and operations” and should be able to revoke or limit as needed.

  • The MCP spec’s Authorization section goes into deep detail on aligning with OAuth 2.1 and related standards. It references using Authorization Server Metadata (RFC 8414) for discovery (the client can fetch the auth server’s .well-known/openid-configuration or similar to get token endpoints), and emphasizes supporting both confidential and public clients securely. The bottom line: MCP v0.3 formalizes a secure token-based auth model. This was a big step from earlier versions - v0.2’s introduction of OAuth was significant, and v0.3 refines it by plugging the resource indicator gap and adding more guidance.

Beyond authentication, MCP has other safety measures:

  • Permissions and Sandboxing: Even aside from OAuth, the host (client side) should enforce that servers cannot access data the user didn’t okay. For example, an MCP client should not automatically share all user documents with a server - it should only share what the user explicitly selects or what falls under a root directory given. The spec calls out that hosts must obtain explicit consent before exposing user data via resources, and that servers should respect boundaries (like file system roots or URI domains).
  • Tool invocation control: An AI might decide to invoke a dangerous tool (delete something, send an email). MCP best practices suggest having a human in the loop for such actions. Clients are required to get user confirmation before actually executing any tool, unless it’s a scenario where the user explicitly disabled confirmations. This ensures that the user can veto any action they didn’t intend the AI to do.
  • LLM prompt controls: The protocol limits server visibility into the LLM’s prompt to avoid leaking conversation content inadvertently. For instance, if a server requests a sampling (LLM call), the client might provide only a snippet of relevant context, not the entire chat history, if not needed. Users should always have transparency on what the model actually saw and what the server saw.

In summary, HTTP-based MCP in v0.3 brings enterprise-grade practices (OAuth 2.1, secure headers, session IDs) into the loop, so that AI integrations can be done safely and at scale. A developer implementing an MCP server should follow the spec’s security best practices - e.g. validating input thoroughly (you’re receiving JSON from possibly an AI - treat it with caution), implementing authorization if the data is sensitive, and not trusting any annotations or user-provided schema blindly. On the client side, developers should ensure they handle tokens carefully, provide a good UI for auth (token storage, refresh, etc.), and always let the user override or approve critical steps (like enabling sampling or executing tools). MCP v0.3’s motto could well be “power with responsibility” - it unlocks powerful AI workflows but continually emphasizes guardrails and user agency.

Future Directions

MCP is still in rapid development (v0.3 is version “2025-06-18” and it’s not yet at a 1.0 semantic version). The community and maintainers have outlined several key areas of expansion for the next iterations:

  • Validation and Compliance: There’s a drive to provide reference implementations of MCP clients/servers and automated test suites. These would help ensure that different MCP implementations all behave consistently. As more vendors adopt MCP, having a compliance suite (like LSP has) will be important to avoid fragmentation.

  • MCP Registry and Discovery: Finding and sharing MCP connectors should be easier. A planned MCP registry service will allow servers to publish their presence and metadata. Third-party marketplaces or UIs could then query this registry to let users quickly find, say, “an MCP server for Salesforce” or “MCP connector for MySQL” and plug it into their AI app. This would function akin to an app store or extension marketplace, but for AI tool/data connectors, accelerating integration development.

  • Agents and Orchestration: MCP is becoming a backbone for multi-agent systems. Future proposals include Agent Graphs - a concept of multiple AI agents coordinating via MCP, possibly with hierarchical or peer-to-peer messaging using MCP as the medium. Namespacing and graph-aware patterns could allow an agent to spawn sub-agents, each with their own MCP connections, all in a controlled structure. Additionally, improving human-in-the-loop workflows is on the agenda (v0.3’s elicitation is a first step). Expect further standardization around how an AI agent can request user guidance or how a user can intervene, beyond just a simple Q&A prompt.

  • Multimodality and Streaming Enhancements: Current MCP supports text, and with v0.3 it added basic image/audio content support (tools can return base64 images or audio). But looking forward, there’s interest in handling video, large files, and more interactive streaming. Ideas like chunked binary messages or multipart responses are being explored. Also, the spec might evolve to handle bidirectional streaming more gracefully (perhaps via WebSocket transport as an alternative to SSE+POST). Real-time use cases (like an AI assistant that continuously listens to a microphone and sends audio to a server, etc.) could drive these changes.

  • Governance and Standardization: MCP started as an open-source project (driven by Anthropic and partners) and is evolving with community input. The maintainers plan to formalize the governance, potentially involving standards bodies, to ensure MCP’s longevity and openness. They want a transparent, community-led evolution so that MCP truly becomes a universal standard not controlled by any single company. This likely means more public discussions, proposals (the GitHub “standards track” is mentioned for following proposals), and maybe a path to an RFC or consortium adoption in the future.

In conclusion, MCP v0.3 represents a maturing protocol that’s tackling the hard problems of AI integration - interoperability, security, and user control - head on. For developers, it offers a clear framework to connect AI to the world: you focus on your domain logic (what tools or data you expose) and let MCP handle the how (the messaging, auth, negotiation). As we look to the future, MCP might very well do for AI what USB did for peripherals or what HTTP did for information - provide a common language for connectivity, so that innovation in AI capabilities can be seamlessly plugged into innovation in data and tools. The roadmap is exciting, and if you’re building AI applications, it’s a great time to get involved with MCP’s community and shape the next version of this emerging standard.

Sources: The details above were drawn from the official Model Context Protocol v0.3 specification and related documentation, as well as commentary from industry blogs and early use cases on AWS. All code examples and technical specifics (message formats, headers, etc.) are based on the MCP 2025-06-18 spec. As MCP continues to evolve, keeping an eye on the official spec site and the project’s GitHub discussions is recommended for the latest updates.