The Model Context Protocol, despite its aggressive adoption (or perhaps because of it), continues to evolve. Anthropic recently updated the MCP specification, and below, we’ll look at the main changes.

Security Enhancements

An MCP server is now always classified as an OAuth Resource Server, and clients are required to implement Resource Indicators (RFC 8707). This is necessary to protect against attacks like the Confused Deputy. Previously, tokens requested by a client from an authorization server were “impersonal,” meaning they could be used by anyone. This allowed an attacker to create a phishing MCP server, deceive a client, steal the token, and use that token to gain access to the real MCP server.

  sequenceDiagram
    participant Client
    participant Authorization Server (AS)
    participant Malicious MCP Server
    participant Legit as Legitimate MCP Server

    Client->>Authorization Server (AS): Authorization request for calendar access
    note right of Client: Client thinks it will talk to calendar-mcp.com

    Authorization Server (AS)-->>Client: Issues access token (recipient unspecified)
    note left of Malicious MCP Server: Token grants `calendar:read` permission

    Client->>Malicious MCP Server: Connects (phished) and sends the token
    note right of Client: Error! The client is a "confused deputy"
    
    Malicious MCP Server->>Legit: Uses the stolen, non-specific token
    Legit-->>Malicious MCP Server: Returns data (since the token is valid)
    note over Malicious MCP Server, Legit: **ATTACK SUCCESSFUL**

In the new implementation, this loophole has been closed. When requesting a token, the client must now specify the exact resource (the MCP server’s address). In response, the Authorization Server embeds this address into the aud (audience) field of the token itself. This allows the MCP server to verify that the token was intended specifically for it, rendering a token obtained for another resource useless.

  sequenceDiagram
    participant Client
    participant Authorization Server (AS)
    participant Zlo as Malicious MCP Server
    participant Legit as Legitimate MCP Server

    Client->>Authorization Server (AS): Token request with parameter:<br/>`resource=https://evil-mcp.com`
    note right of Client: The client has been phished and thinks<br/>evil-mcp.com is a legitimate service.

    Authorization Server (AS)-->>Client: Issues a token with the field:<br/>`"aud": "https://evil-mcp.com"`
    note left of Legit: The token is now audience-specific, but for the attacker.

    Client->>Zlo: Sends the token to evil-mcp.com

    Zlo->>Legit: Attempts to use this token to access the real calendar.

    Legit-->>Legit: Token validation: check the `aud` field.<br>It contains `"https://evil-mcp.com"`.<br>But my address is `"https://calendar-mcp.com"`.<br>The audience doesn't match!
    
    Legit-->>Zlo: **ACCESS DENIED (401/403)**
    note over Legit, Zlo: **ATTACK THWARTED**

Additionally, a page with security best practices has been added. It covers practices applicable at the protocol level, but not at the level of attacks on LLMs that the protocol’s use might enable. These vulnerabilities are described on the main page of the specification, but the responsibility for mitigating them lies with the party implementing the host (the application using MCP).

Removal of JSON-RPC Batching

JSON-RPC batching, which previously allowed a client to perform multiple actions by sending them to the server in a single batch, has been removed. This simplifies the protocol but leads to potentially less efficient communication with the server. Now, if developers need similar functionality, they can implement it by modifying the MCP server itself, providing a batch tool that takes a set of calls to other tools as parameters.

As an alternative for improving communication efficiency, engineers can use HTTP/2 Multiplexing and parallel asynchronous requests to the server.

Structured Output Support

Support for structured output has been added. The server can now return not only text but also data in JSON format according to a specified schema in the structuredContent field. This not only simplifies client development but also makes communication more reliable and predictable. Nevertheless, the client is still advised to validate the result.

To maintain backward compatibility, the protocol’s creators recommend that the server also return the same data in plain text.

The Elicitation Mechanism

A mechanism for Elicitation has been added, which allows the server to ask the user for more information needed to complete a task. This enables the server to collect necessary data dynamically.

I see several applications for this, for example:

  1. Simplifying user interaction. Previously, to call a tool that needed to gather a large amount of information, you had to request it from the user all at once in a huge form. This could hardly be called a good UI. With Elicitation, you can query the user step-by-step with intermediate validation.
  2. Implementing “branching” processing flows, where different branches require different data.
  3. Resolving ambiguity. For instance, if a user asks to write a letter to John, the server can clarify which John.
  4. Confirming dangerous actions. Although tool invocations require confirmation, many hosts allow the user to just click an Allow all button. In any case, applications using MCP are often susceptible to Confirmation Fatigue, where the operator receives so many confirmation requests that they approve them without a second thought. Implementing Elicitation through a separate interface can signal to the user that this confirmation really deserves their attention.

Other Changes and New Features

  1. The server can now return links to resources. While it was possible to return a link within text or JSON before, the implementation of format and semantics could differ across MCP servers, making the development of MCP clients and hosts significantly more complex. Now, such links can be returned and processed uniformly.
  2. HTTP requests must now include the protocol version, and both parties (client and server) must check the protocol version and only use available features. This is especially relevant in light of the technology’s aggressive adoption and the resulting zoo of servers, clients, and hosts.

Conclusion

It’s nice to see that the specification continues to evolve and that its authors aren’t afraid to change it actively. Pressing problems faced by users and developers are being resolved, and excessive complexity is being burned out with a red-hot iron. This gives hope that after a few more iterations, we will arrive at a sleek and bulletproof standard.

But beyond improving the specification, a long and bumpy road awaits us in developing best practices for building applications with MCP, as it opens up new opportunities as well as new problems. And considering that it’s currently being snapped up by all AI applications like hot cakes, sometimes without proper consideration, these problems could be truly global in scale.

That said, time will tell.