← Blog

July 30, 2026 · 8 min read

MCP 2026-07-28 Migration Guide: What Breaks and How to Fix It

The MCP 2026-07-28 specification published on July 28. It's the fifth spec version and the largest revision since MCP's launch — stateless core, new discovery endpoint, header routing, EMA auth, and a formal extensions framework. It contains breaking changes. Here's a concrete migration guide: what breaks, what to add, and the order to do it in.

Quick summary of what changed

  • initialize → server/discover: The initialize handshake is deprecated (18-month notice). New clients use server/discover instead.
  • Stateless by default: Servers must not return Mcp-Session-Id on stateless responses.
  • New required headers: Mcp-Method and Mcp-Name must be in CORS allowed headers.
  • SSE transport deprecated: Streamable HTTP is now the recommended transport (18-month notice for SSE removal).
  • EMA auth stabilized: Enterprise-Managed Authorization is now a stable extension.
  • Tool caching: ttlMs and cacheScope fields on tools/list responses.
  • protocolVersion fallback: Servers should now default to 2026-07-28 when no version is negotiated.

Step 1: Add server/discover (required for new clients)

The server/discover method replaces initialize for capability negotiation. It returns everything in one call: protocol version, capabilities, server info, and the full tool list. New clients (Claude Desktop post-July 28, updated Cursor/Windsurf) will call this first.

// Handle server/discover
case 'server/discover': {
  return Response.json({
    jsonrpc: '2.0',
    id,
    result: {
      protocolVersion: '2026-07-28',
      capabilities: { tools: { listChanged: false } },
      serverInfo: { name: 'your-server', version: '1.0.0' },
      tools: TOOLS  // inline the full tools array
    }
  })
}

Keep your existing initialize handler — it's deprecated but still required for the 18-month transition window. Old clients will keep using it.

Step 2: Remove Mcp-Session-Id from stateless responses

If your server is stateless — no per-user session context, no sticky connections required — remove any Mcp-Session-Id header from responses. Returning this header on a stateless server is now a protocol violation (12-month deprecation, but flag this immediately).

// Before (incorrect for stateless servers):
const headers = {
  'Content-Type': 'application/json',
  'Mcp-Session-Id': crypto.randomUUID(),  // ❌ remove this
}

// After:
const headers = {
  'Content-Type': 'application/json',
}

If your server genuinely maintains session state (e.g., multi-turn context, authentication sessions), you may keep the session ID — but stateless RAG servers, documentation servers, and read-only data servers should not return it.

Step 3: Update CORS headers

Add Mcp-Method and Mcp-Name to your CORS Access-Control-Allow-Headers. New clients send these headers on every tool call request. If your CORS preflight doesn't allow them, browser-based agent clients will fail with a CORS error before the tool call even reaches your server.

const CORS_HEADERS = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Methods': 'POST, OPTIONS',
  'Access-Control-Allow-Headers': [
    'Content-Type',
    'Authorization',
    'Mcp-Method',   // ← add
    'Mcp-Name',     // ← add
  ].join(', '),
}

Step 4: Update protocolVersion negotiation

Your version negotiation logic needs to recognize 2026-07-28 as a supported version and use it as the default fallback for clients that don't specify a version. Before the spec published, it was safe to default to 2025-06-18 to avoid sending clients a draft version. Now that 2026-07-28 is stable, it should be the default.

const SUPPORTED_VERSIONS = ['2026-07-28', '2025-06-18', '2025-03-26', '2024-11-05']

function negotiateVersion(requested?: string): string {
  if (requested && SUPPORTED_VERSIONS.includes(requested)) return requested
  return '2026-07-28'  // default to stable spec
}

Step 5: Add tool caching hints (optional but recommended)

The new spec allows ttlMs and cacheScope on tools/list responses. If your tool list rarely changes, tell clients they can cache it:

{
  "result": {
    "tools": [...],
    "ttlMs": 3600000,      // cache for 1 hour
    "cacheScope": "global" // same tools for all callers
  }
}

This reduces the number of tools/list calls your server receives, which matters at scale. Use cacheScope: "user" if your tool list is personalized per authenticated user.

Step 6: Plan for SSE migration (not urgent, 18-month window)

If you're using Server-Sent Events as your transport, you have until approximately January 2028 before SSE is removed from the spec. Streamable HTTP is the replacement — it's the same JSON-RPC over HTTP you may already be using for non-streaming responses, with optional streaming via chunked transfer encoding for responses that return partial results.

Most serverless MCP servers are already on Streamable HTTP and don't need to change. If you specifically built SSE endpoints for the older transport, plan the migration but don't rush it — the window is generous.

Testing the migration

After deploying, verify with the MCP Inspector CLI:

# Test server/discover
npx @modelcontextprotocol/inspector \
  --url https://your-server.com/mcp \
  --method server/discover

# Verify protocolVersion in response is 2026-07-28
# Verify no Mcp-Session-Id in response headers
# Verify tools array is included inline

Also test with an older client that still uses initialize — your backward compatibility path should still work.

How AgentReady migrated

AgentReady's MCP endpoint was updated in stages as the spec moved from RC to stable: server/discover and routing headers were added in early July; Mcp-Session-Id was removed from stateless responses; ttlMs/cacheScope were added to tools/list. The protocolVersion default was updated to 2026-07-28 on July 30, the first working day after the spec published. The endpoint is backward compatible — clients on any spec version from 2024-11-05 onward work without changes.

AgentReady's MCP endpoint is fully updated for the 2026-07-28 spec. Connect to Claude, Cursor, or Windsurf and query any indexed site.

Connect AgentReady →