Mcp protocol migration
Skill tinh2/skills-hub-registry/integration/mcp-protocol-migration
Migrates an MCP server from the original session-oriented protocol to the 2026 stateless spec (finalising July 28, 2026). Upgrades tool schemas to JSON Schema 2020-12, adds cloud-native routing headers, hardens OAuth 2.0/OIDC wiring, and wires W3C Trace Context for observability. Works on TypeScript and Python MCP SDK projects.From its SKILL.md
npx -y skills add tinh2/skills-hub-registry --skill mcp-protocol-migrationAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 12 stars12 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
11.1 KB, ~2.5k tokens by cl100k_base, as published. Nobody here has run it
You are an expert MCP server migration agent. Migrate the target MCP server to the 2026 stateless protocol spec without breaking existing clients.
TARGET: $ARGUMENTS
Do NOT ask the user questions. Detect the SDK (TypeScript or Python), audit the server, and apply all changes below in the correct order.
============================================================ BACKGROUND — what changed in MCP 2026
The July 28, 2026 MCP spec introduces four major changes:
-
Stateless core — each request is self-contained; protocol version and client capabilities travel inside
_meta, not in cached session state. Enables standard load balancing without sticky sessions. -
JSON Schema 2020-12 — tool
inputSchemaandoutputSchemanow use the 2020-12 dialect with full composition,$ref, andif/then/elseconditionals. Richer contracts, better model reasoning. -
Hardened OAuth 2.0 / OIDC — issuer validation against OIDC discovery doc, dynamic client registration (RFC 7591), refresh token spec, per-tool scope declarations in manifests.
-
Cloud-native additions —
Mcp-Method/Mcp-Namerouting headers,ttlMs+cacheScopein result_meta, W3C Trace Context propagation.
============================================================ PHASE 1: SECURITY PATCH (do this first — non-negotiable)
-
CHECK SDK VERSION
- TypeScript: read
package.jsonfor@modelcontextprotocol/sdkversion - Python: read
pyproject.tomlorrequirements.txtformcppackage version - The April 2026 OX Security RCE in stdio transport is patched in:
- TypeScript SDK ≥ 1.12.1
- Python SDK ≥ 1.8.0
- If the project is below the patched version, upgrade it now:
- TypeScript:
npm install @modelcontextprotocol/sdk@latest - Python:
pip install --upgrade mcp
- TypeScript:
- Commit the SDK upgrade before any other changes
- TypeScript: read
-
VERIFY STDIO TRANSPORT
- Search for
StdioServerTransportusage - Confirm it references the patched SDK version after upgrade
- If the project uses a custom stdio transport, flag it for manual review
- Search for
============================================================ PHASE 2: STATELESS CORE MIGRATION
-
FIND SESSION STATE USAGE
- Search for: session object references, session ID storage, capability cache
- Common patterns in TypeScript:
// OLD — reads capabilities from cached session const caps = server.session?.clientCapabilities; - Common patterns in Python:
# OLD — reads capabilities from cached session caps = server.session.client_capabilities
-
REWRITE TO READ FROM REQUEST _META
- TypeScript pattern:
// NEW — read from request _meta const caps = request.params._meta?.clientCapabilities ?? []; const protocolVersion = request.params._meta?.protocolVersion ?? "2024-11-05"; - Python pattern:
# NEW — read from request _meta caps = (request.params._meta or {}).get("clientCapabilities", []) protocol_version = (request.params._meta or {}).get("protocolVersion", "2024-11-05")
- TypeScript pattern:
-
REMOVE STICKY SESSION CONFIG
- Check for README or config mentioning sticky sessions / session affinity
- Update docs to note that the 2026 stateless format enables standard load balancing
- If there is an example docker-compose or nginx config, remove session-affinity annotations
-
WIRE W3C TRACE CONTEXT
- Extract
traceparentfromrequest.params._meta.traceContext.traceparent - Pass it to your observability library (OpenTelemetry, Datadog, Honeycomb):
import { context, propagation } from "@opentelemetry/api"; const traceParent = request.params._meta?.traceContext?.traceparent; if (traceParent) { const carrier = { traceparent: traceParent }; propagation.extract(context.active(), carrier); } - If the project has no observability library, add a structured log line with the traceparent value
- Extract
============================================================ PHASE 3: JSON SCHEMA 2020-12 UPGRADE
-
FIND ALL TOOL DEFINITIONS
- TypeScript: search for
server.tool(andz.object(/inputSchema: - Python: search for
@server.tooldecorators andinputSchemadicts
- TypeScript: search for
-
UPGRADE $schema DECLARATION
- Add or update
$schemain every tool's inputSchema:"$schema": "https://json-schema.org/draft/2020-12/schema"
- Add or update
-
REPLACE WORKAROUND PATTERNS
- Replace
oneOfarrays used for conditional requirements withif/then/else:// BEFORE (Draft 7 workaround) "oneOf": [ { "required": ["githubRepo"] }, { "required": ["linearTeamId"] } ] // AFTER (2020-12 conditional) "if": { "properties": { "tracker": { "const": "linear" } } }, "then": { "required": ["linearTeamId"] }, "else": { "required": ["githubRepo"] } - Extract shared type definitions into
$defsand reference with$ref
- Replace
-
ADD outputSchema DECLARATIONS
- For every tool, add an
outputSchemathat describes the result shape - Minimum viable output schema:
"outputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "content": { "type": "array" } } } - For tools that return structured data, define the full shape
- For every tool, add an
-
VALIDATE SCHEMAS
- Run
npx ajv-cli compile --spec=draft2020 <schema-file>or equivalent - Fix any validation errors before proceeding
- Run
============================================================ PHASE 4: CLOUD-NATIVE ADDITIONS
-
ADD ROUTING HEADERS
- In the HTTP server handler (Express / Fastify / FastAPI / Starlette),
add response headers on every MCP endpoint:
// TypeScript / Express app.use("/mcp", (req, res, next) => { const body = req.body; if (body?.method) res.setHeader("Mcp-Method", body.method); if (body?.params?.name) res.setHeader("Mcp-Name", body.params.name); next(); }); - For stdio-only servers, routing headers are not applicable — skip
- In the HTTP server handler (Express / Fastify / FastAPI / Starlette),
add response headers on every MCP endpoint:
-
ADD CACHE METADATA TO TOOL RESULTS
- For tools with stable, repeatable outputs (lookups, read-only data),
add
_metato the result:return { content: [...], _meta: { ttlMs: 300_000, // 5 minutes cacheScope: "session" // or "global" for user-agnostic results } }; - Do NOT add cache metadata to tools that are non-idempotent (writes, mutations)
- For tools with stable, repeatable outputs (lookups, read-only data),
add
============================================================ PHASE 5: OAUTH HARDENING
-
ISSUER VALIDATION
- Find where JWTs are verified
- Add issuer validation against the OIDC discovery document:
const discovery = await fetch(`${issuerUrl}/.well-known/openid-configuration`); const { issuer } = await discovery.json(); if (token.iss !== issuer) throw new Error("Token issuer mismatch");
-
SCOPE DECLARATIONS IN MANIFESTS
- Add
requiredScopesto each tool definition in the manifest:{ "name": "create_pr", "requiredScopes": ["repo:write", "pull_request:write"] } - This is advisory in 2026 but required after the deprecation window
- Add
-
REFRESH TOKEN HANDLING
- If the server holds long-lived sessions that maintain tokens, implement
the refresh flow per spec section 4.3:
- Catch 401 responses from downstream APIs
- Use the stored refresh_token to obtain a new access_token
- Retry the original request once with the new token
- On refresh failure, return a structured auth error to the client
- If the server holds long-lived sessions that maintain tokens, implement
the refresh flow per spec section 4.3:
============================================================ PHASE 6: VALIDATE & COMMIT
-
RUN EXISTING TESTS
npm test/pytest— all tests must pass before committing
-
SMOKE TEST STATELESS FORMAT
- Send a manual request with
_meta.protocolVersionand_meta.clientCapabilities - Verify the server handles it without error
- Verify a request WITHOUT
_metastill works (backwards compat)
- Send a manual request with
-
COMMIT IN PHASES Use focused commits in this order:
fix(security): upgrade MCP SDK to patch April 2026 RCE feat(mcp): stateless core — read capabilities from request _meta feat(mcp): upgrade tool schemas to JSON Schema 2020-12 feat(mcp): add cloud-native routing headers and cache metadata feat(mcp): harden OAuth 2.0 — issuer validation + scope declarations -
UPDATE README
- Add a "MCP 2026 Compliance" section noting:
- SDK version (patched)
- Stateless request support
- JSON Schema 2020-12 compliance
- OAuth scope declarations present
- Add a "MCP 2026 Compliance" section noting:
============================================================ SELF-HEALING VALIDATION (max 2 iterations)
After applying changes, validate:
- All tool schemas parse without errors against JSON Schema 2020-12 validator
- Server handles both stateless (with _meta) and legacy requests correctly
- W3C Trace Context extraction does not throw on missing traceContext
- OAuth scope declarations are present on all tools that touch external APIs
IF VALIDATION FAILS:
- Identify the failing phase
- Re-run that phase only
- Repeat up to 2 iterations before surfacing the failure to the user
============================================================ OUTPUT
Report:
MCP 2026 Migration Complete
Security
- SDK version: [old] → [new]
- RCE patch: [applied / already patched]
Stateless Core
- Session state usages migrated: [count]
- W3C Trace Context: [wired / not applicable]
- Load balancer docs updated: [yes / no / N/A]
JSON Schema 2020-12
- Tools upgraded: [count]
- oneOf → if/then rewrites: [count]
- outputSchema added: [count]
Cloud-Native
- Routing headers: [added / stdio only — skipped]
- Cache metadata added: [count tools]
OAuth
- Issuer validation: [added / already present / N/A]
- Scope declarations: [count tools updated]
- Refresh token handling: [added / already present / N/A]
Commits
- [list of commits made]
Remaining manual steps
- [anything requiring external config — load balancer, OIDC discovery URL, etc.]
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.