AIARTICLE

MCP 2025-06-18 brings elicitation and structured output to production servers

The 2025-06-18 revision of the Model Context Protocol, published in June 2025, formalized elicitation, structured output, and resource links, but it also removed JSON-RPC batching. Anyone already running an MCP server needs to review transport and authentication before updating the SDK.

The official Model Context Protocol specification received a revision on June 18, 2025, replacing the previous version from March 26 of that year. The changelog published at modelcontextprotocol.io lists changes that are not cosmetic: they affect how server and client communicate, how tools return data, and how authentication is negotiated. More than a year later, it's worth taking a careful look at what this means for anyone already running an MCP server in production, because part of these changes are backward compatible and part are not.

What the 2025-06-18 revision changed in the specification

The source organizes the changes into two categories: major changes and schema changes. The major ones include the removal of JSON-RPC batching support (PR #416), the addition of structured output in tools (PR #371), the classification of MCP servers as OAuth Resource Servers with discovery metadata (PR #338), the requirement for Resource Indicators per RFC 8707 in clients (PR #734), support for elicitation (PR #382), and resource links in tool call results (PR #603).

Two smaller changes carry significant practical weight. Protocol version negotiation now requires the MCP-Protocol-Version header on every subsequent HTTP request (PR #548), and a SHOULD in the lifecycle operation became a MUST. Among the schema changes, the _meta field added to more interface types (PR #710) stands out, as does the new title field, which separates the display name from the programmatic identifier (PR #663).

Elicitation: the server can pause the flow and ask for more information

Before the revision, an MCP server only had the data the client sent in the tool call. With elicitation, the server can interrupt execution and ask the client to collect more information from the user, mid-interaction, before continuing. This solves a common problem in agents: tools that need confirmation or a piece of data that wasn't in the original prompt.

The flow follows the request pattern already used in other parts of the protocol. The server sends an elicitation/create message describing what it needs, with a JSON schema of the expected format:

json
{
 "method": "elicitation/create",
 "params": {
 "message": "I need to confirm the destination directory before continuing",
 "requestedSchema": {
 "type": "object",
 "properties": {
 "directory": { "type": "string" }
 },
 "required": ["directory"]
 }
 }
}

The client decides how to present this to the user (a form, a chat prompt, whatever makes sense in the interface) and responds with an action: accept and return the data, decline, or cancel. For those building agents that currently make risky assumptions about file paths, credentials, or operation scope, elicitation removes that guesswork from the equation.

Structured output: tools stop returning just loose text

Up to version 2025-03-26, an MCP tool returned results as generic content blocks, usually text, and the client had to parse that string to extract structured data. PR #371 allows the tool definition to declare an outputSchema, in the same spirit as the inputSchema that already existed, and for the result to carry a structuredContent field validated against that schema.

ts
// Before: the client needs to parse free text
return {
 content: [{ type: "text", text: JSON.stringify(weather) }]
};

// After: outputSchema declared and typed structuredContent
server.registerTool("get_weather", {
 description: "Returns the weather forecast",
 inputSchema: { city: z.string() },
 outputSchema: {
 temperature: z.number(),
 condition: z.string(),
 },
}, async ({ city }) => {
 const weather = await fetchWeather(city);
 return {
 content: [{ type: "text", text: `Weather in ${city}: ${weather.condition}` }],
 structuredContent: weather,
 };
});

In practice, this eliminates an entire class of silent bugs: text parsers that break when the model formats the response slightly differently. With outputSchema declared, the client validates the return against a contract, not against regex heuristics.

PR #603 allows a tool call result to include links to resources instead of embedding the entire content inline. A tool that generates a large report, for example, can return a URI reference to that resource instead of pasting the whole file into the result. This avoids blowing up the model's context with a payload it doesn't even need to read in full, and leaves the decision to fetch the complete content for when it's actually necessary.

What breaks: batching gone, mandatory header, stricter authentication

Not every change in the revision is additive. Three points require work from anyone who already has an MCP server or client in production, because they are not just new optional features.

ChangePractical effectRequired action
Removal of JSON-RPC batchingArray requests are no longer acceptedUpdate client/server to send individual calls
Mandatory MCP-Protocol-Version header in HTTPA request without the header may be rejected after initial negotiationEnsure the HTTP transport sends the header on every subsequent call
Server classified as OAuth Resource Server + Resource Indicators (RFC 8707)Clients need to declare the token's target resourceReview the authorization flow to prevent token leakage between servers

The authentication change isn't just schema bureaucracy: it exists to prevent a malicious server from obtaining an access token issued for another resource. Anyone who doesn't implement Resource Indicators on the client is exposed to exactly the problem the change is trying to close.

The roadmap for validating a server against 2025-06-18

For anyone who wants to check whether an existing MCP server is aligned with the revision, the logical path goes through a few checkpoints, in the order problems typically show up:

  1. Check the version of the SDK used (TypeScript, Python, or other) and confirm it already supports the 2025-06-18 revision, not just 2025-03-26.
  2. Test protocol version negotiation via the MCP-Protocol-Version header in an HTTP call and verify the server responds correctly when the header is missing.
  3. Look through the server code for any place that still assembles batched JSON-RPC requests; this needs to become individual calls.
  4. Review the tool definitions: which already have outputSchema and which still return only free text that the client has to parse.
  5. If the server exposes OAuth authentication, check whether it publishes the protected resource metadata and whether the client sends Resource Indicators.

This roadmap doesn't replace running the protocol's conformance test suite, but it covers the points where the 2025-06-18 revision has historically broken integrations written against 2025-03-26.

When it's not yet worth migrating

Elicitation and structured output solve real problems, but they bring engineering costs that not every tool justifies. A simple MCP server that exposes a single deterministic function with no need for user confirmation doesn't gain much from implementing the elicitation flow: it's extra complexity with no visible benefit. Likewise, declaring outputSchema only pays off when the client actually consumes the structuredContent field; if the surrounding ecosystem still only reads text, the schema stays decorative.

The most sensitive point remains the client ecosystem. The specification allows version negotiation, so server and client can, in theory, coexist on different revisions. In practice, anyone relying on third-party integrations still stuck on 2025-03-26 will feel the removal of batching and the header requirement before being able to take advantage of elicitation or structured output.

Translated from the Brazilian Portuguese original · Read the original

View profile →