One read of Model Context Protocolmcp-20260928T220720Z
173 pages moved out of 349 read.
Pages moved
173
significant first
Pages read
349
in this capture
Captured
22:07 UTC
Corpus hash
719057065235
corpus-hash
What this read moved
101-125 of 173, page 5 of 7This capture is too large to show at once. Changes 101-125 of 173 are below, significant first; the rest are on the following screens.
seps/2106-json-schema-2020-12 Changed · +19 / -19 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
25| **SEP** | 2106 |
26| **Title** | Tools `inputSchema` & `outputSchema` Conform to JSON Schema 2020-12 |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-01-06 |
23| Field | Value |
24| - | - |
25| **SEP** | 2106 |
26| **Title** | Tools `inputSchema` & `outputSchema` Conform to JSON Schema 2020-12 |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-01-06 |
3030| **Author(s)** | John McBride ([@jpmcb](https://github.com/jpmcb)) — original proposal; Ola Hungerford ([@olaservo](https://github.com/olaservo)) — current shepherd, post-SEP-1850 conversion |
31| **Sponsor** | Ola Hungerford ([@olaservo](https://github.com/olaservo)) |
32| **PR** | [#2106](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2106) |
31| **Sponsor** | Ola Hungerford ([@olaservo](https://github.com/olaservo)) |
32| **PR** | [#2106](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2106) |
3333
3434***
3535
from line 310
310310
311311OpenAPI 3.1 made the strategic decision to fully align with JSON Schema 2020-12, accepting breaking changes to eliminate the friction. The result: better tooling compatibility and less ecosystem confusion.
312312
313| OpenAPI's Problem | MCP's Parallel |
314| ----------------------------------- | ----------------------------------------- |
315| `type` must be string, not array | `inputSchema` only allows specific fields |
316| Couldn't use standard null handling | Can't use `oneOf`/`anyOf` in schemas |
317| Custom `nullable` keyword | Object-only `structuredContent` |
318| Caused tooling confusion | Causes SDK workarounds |
313| OpenAPI's Problem | MCP's Parallel |
314| - | - |
315| `type` must be string, not array | `inputSchema` only allows specific fields |
316| Couldn't use standard null handling | Can't use `oneOf`/`anyOf` in schemas |
317| Custom `nullable` keyword | Object-only `structuredContent` |
318| Caused tooling confusion | Causes SDK workarounds |
319319
320320MCP can learn from OpenAPI's experience rather than repeating the same evolution over several years.
321321
from line 325
325325
326326### Compatibility Matrix
327327
328| | New client (post-SEP) | Old client (pre-SEP) |
329| ------------------------- | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
330| **New server (post-SEP)** | Fully compatible. | Compatible **only when the server returns object-typed `structuredContent`**. Arrays/primitives in `structuredContent` may break. |
331| **Old server (pre-SEP)** | Fully compatible. Existing object-only schemas remain valid. | Unchanged. |
328| | New client (post-SEP) | Old client (pre-SEP) |
329| - | - | - |
330| **New server (post-SEP)** | Fully compatible. | Compatible **only when the server returns object-typed `structuredContent`**. Arrays/primitives in `structuredContent` may break. |
331| **Old server (pre-SEP)** | Fully compatible. Existing object-only schemas remain valid. | Unchanged. |
332332
333333The asymmetry: a new server that takes advantage of array or primitive `structuredContent` (or composition keywords in `inputSchema`) cannot assume an old client will accept the response. Old clients written against the previous wire format may reject `structuredContent` that is not a JSON object, or fail to validate `inputSchema` containing keywords beyond `type`/`properties`/`required`.
334334
seps/2133-extensions Changed · +10 / -10 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ------------------------------------------------------------------------------- |
25| **SEP** | 2133 |
26| **Title** | Extensions |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2025-01-21 |
30| **Author(s)** | Peter Alexander ([@pja-ant](https://github.com/pja-ant)) |
31| **Sponsor** | None (seeking sponsor) |
32| **PR** | [#2133](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2133) |
23| Field | Value |
24| - | - |
25| **SEP** | 2133 |
26| **Title** | Extensions |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2025-01-21 |
30| **Author(s)** | Peter Alexander ([@pja-ant](https://github.com/pja-ant)) |
31| **Sponsor** | None (seeking sponsor) |
32| **PR** | [#2133](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2133) |
3333
3434***
3535
seps/2148-contributor-ladder Changed · +33 / -33 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ---------------------------------------------------------------------------------------------------------------------------- |
25| **SEP** | 2148 |
26| **Title** | MCP Contributor Ladder |
27| **Status** | Final |
28| **Type** | Process |
29| **Created** | 2026-01-15 |
23| Field | Value |
24| - | - |
25| **SEP** | 2148 |
26| **Title** | MCP Contributor Ladder |
27| **Status** | Final |
28| **Type** | Process |
29| **Created** | 2026-01-15 |
3030| **Author(s)** | David Soria Parra ([@dsp-ant](https://github.com/dsp-ant)), Sarah Novotny ([@sarahnovotny](https://github.com/sarahnovotny)) |
31| **Sponsor** | David Soria Parra ([@dsp-ant](https://github.com/dsp-ant)) |
32| **PR** | [#2148](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2148) |
31| **Sponsor** | David Soria Parra ([@dsp-ant](https://github.com/dsp-ant)) |
32| **PR** | [#2148](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2148) |
3333
3434***
3535
from line 68
6868
6969### Role Definitions
7070
71| Role | Summary | Key Privileges | Minimum Timeline |
72| ------------------------------------------------ | --------------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------------- |
73| [**Contributor**](#contributor) | Anyone who contributes to MCP | Submit issues, PRs, participate in discussions | Immediate |
74| [**Member**](#member) | Established, active contributor | GitHub org membership, triage rights, eligible for WG/IG leadership | 2-3 months of meaningful contributions |
75| [**Maintainer**](#maintainer) | Area steward with operational responsibility | Merge rights, release participation | 6+ months as Member |
76| [**Core Maintainer**](#core-maintainer) | Technical leadership and protocol stewardship | Final decision authority, governance participation | By invitation after sustained Maintainer contribution |
77| [**Lead Maintainer**](#lead-maintainer) | Ultimate project authority (founders) | All Core Maintainer privileges, veto authority, appoints Core Maintainers | Reserved for project founders — succession only |
78| [**Community Moderator**](#community-moderators) | CoC enforcement and community health | Moderation rights on community platforms, incident handling | Parallel track — Member status + appointment |
71| Role | Summary | Key Privileges | Minimum Timeline |
72| - | - | - | - |
73| [**Contributor**](#contributor) | Anyone who contributes to MCP | Submit issues, PRs, participate in discussions | Immediate |
74| [**Member**](#member) | Established, active contributor | GitHub org membership, triage rights, eligible for WG/IG leadership | 2-3 months of meaningful contributions |
75| [**Maintainer**](#maintainer) | Area steward with operational responsibility | Merge rights, release participation | 6+ months as Member |
76| [**Core Maintainer**](#core-maintainer) | Technical leadership and protocol stewardship | Final decision authority, governance participation | By invitation after sustained Maintainer contribution |
77| [**Lead Maintainer**](#lead-maintainer) | Ultimate project authority (founders) | All Core Maintainer privileges, veto authority, appoints Core Maintainers | Reserved for project founders — succession only |
78| [**Community Moderator**](#community-moderators) | CoC enforcement and community health | Moderation rights on community platforms, incident handling | Parallel track — Member status + appointment |
7979
8080*Timelines listed are minimum contribution periods, not guarantees of advancement. They exist to protect the project from rapid privilege escalation and to ensure a high bar of demonstrated commitment. Actual advancement is discretionary and may take longer in practice; the only guarantee is that advancement will not happen on a shorter timescale than documented. Exceptions require explicit Core Maintainer approval with documented rationale.*
8181
from line 261
2612613. **Decision**: Approving authority reviews and decides
2622624. **Onboarding**: New role-holder receives appropriate access and onboarding
263263
264| Advancement To | Approved By |
265| ------------------- | ------------------------------------------------------------------------------- |
266| Member | 2 existing Members+ from different organizations, **or** 1 Core/Lead Maintainer |
267| Maintainer | 1 Maintainer or Core Maintainer sponsor + Core Maintainer approval |
268| Core Maintainer | Lead Maintainers |
269| Community Moderator | 1 Core Maintainer or Lead Maintainer |
264| Advancement To | Approved By |
265| - | - |
266| Member | 2 existing Members+ from different organizations, **or** 1 Core/Lead Maintainer |
267| Maintainer | 1 Maintainer or Core Maintainer sponsor + Core Maintainer approval |
268| Core Maintainer | Lead Maintainers |
269| Community Moderator | 1 Core Maintainer or Lead Maintainer |
270270
271271Self-nomination is encouraged, but nominees must still secure the required sponsorship. Sponsors confirm support in the nomination issue.
272272
from line 286
286286
287287#### Escalation Matrix
288288
289| Issue Type | First Escalation | Second Escalation | Timeline |
290| ------------------------------------------ | ------------------- | ----------------- | ---------------- |
291| Technical disagreement in PR | Maintainer in scope | Core Maintainer | 5 business days |
292| Technical disagreement in WG | WG Lead | Core Maintainer | 5 business days |
293| Technical disagreement in IG | IG Facilitator | Core Maintainer | 5 business days |
294| Disagreement with WG Lead / IG Facilitator | Core Maintainer | Lead Maintainer | 7 business days |
295| Disagreement with Maintainer decision | Core Maintainer | Lead Maintainer | 7 business days |
296| Core Maintainer disagreement | Lead Maintainer | N/A | 10 business days |
297| Code of Conduct violation | Community Moderator | Core Maintainer | Immediate |
298| Security issue | Core Maintainer | Lead Maintainer | Immediate |
289| Issue Type | First Escalation | Second Escalation | Timeline |
290| - | - | - | - |
291| Technical disagreement in PR | Maintainer in scope | Core Maintainer | 5 business days |
292| Technical disagreement in WG | WG Lead | Core Maintainer | 5 business days |
293| Technical disagreement in IG | IG Facilitator | Core Maintainer | 5 business days |
294| Disagreement with WG Lead / IG Facilitator | Core Maintainer | Lead Maintainer | 7 business days |
295| Disagreement with Maintainer decision | Core Maintainer | Lead Maintainer | 7 business days |
296| Core Maintainer disagreement | Lead Maintainer | N/A | 10 business days |
297| Code of Conduct violation | Community Moderator | Core Maintainer | Immediate |
298| Security issue | Core Maintainer | Lead Maintainer | Immediate |
299299
300300**Escalation process:**
301301
seps/2149-working-group-charter-template Changed · +35 / -35 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ---------------------------------------------------------------------------------------------------------------------------- |
25| **SEP** | 2149 |
26| **Title** | MCP Group Governance and Charter Template |
27| **Status** | Final |
28| **Type** | Process |
29| **Created** | 2025-01-15 |
23| Field | Value |
24| - | - |
25| **SEP** | 2149 |
26| **Title** | MCP Group Governance and Charter Template |
27| **Status** | Final |
28| **Type** | Process |
29| **Created** | 2025-01-15 |
3030| **Author(s)** | David Soria Parra ([@dsp-ant](https://github.com/dsp-ant)), Sarah Novotny ([@sarahnovotny](https://github.com/sarahnovotny)) |
31| **Sponsor** | David Soria Parra ([@dsp-ant](https://github.com/dsp-ant)) |
32| **PR** | [#2149](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2149) |
31| **Sponsor** | David Soria Parra ([@dsp-ant](https://github.com/dsp-ant)) |
32| **PR** | [#2149](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2149) |
3333
3434***
3535
from line 115
115115
116116All groups use the following participation tiers. Note that **WG Member** is a group-specific participation level distinct from the org-wide **Member** role defined in the [Contributor Ladder](./2148-contributor-ladder.md) — an individual may be a WG Member in a specific group without holding org-wide Member status, and vice versa.
117117
118| Level | Description | Privileges |
119| -------------------- | ------------------------------------------------- | ------------------------------------------------------------------ |
120| **Observer** | Anyone interested in following the group's work | Read access, may attend meetings, limited discussion participation |
121| **Participant** | Active contributor to group discussions | Can propose agenda items, participate in async votes |
122| **WG Member** | Sustained contributor with demonstrated expertise | Counted for quorum (WGs only) |
123| **Lead/Facilitator** | Operational leadership of the group | Sets agenda, facilitates, escalates |
118| Level | Description | Privileges |
119| - | - | - |
120| **Observer** | Anyone interested in following the group's work | Read access, may attend meetings, limited discussion participation |
121| **Participant** | Active contributor to group discussions | Can propose agenda items, participate in async votes |
122| **WG Member** | Sustained contributor with demonstrated expertise | Counted for quorum (WGs only) |
123| **Lead/Facilitator** | Operational leadership of the group | Sets agenda, facilitates, escalates |
124124
125125Interest Groups primarily operate with Observers, Participants, and Facilitators. IGs may adopt the WG Member tier if their work warrants formal decision-making, but are not required to.
126126
from line 207
207207
208208All groups use the following channels:
209209
210| Channel | Purpose | Response Expectation |
211| ------------------------------------ | ------------------------------ | -------------------- |
212| Discord `#{name}-wg` or `#{name}-ig` | Quick questions, coordination | Best effort |
213| GitHub Discussions | Long-form technical discussion | Weekly triage |
210| Channel | Purpose | Response Expectation |
211| - | - | - |
212| Discord `#{name}-wg` or `#{name}-ig` | Quick questions, coordination | Best effort |
213| GitHub Discussions | Long-form technical discussion | Weekly triage |
214214
215215In addition to Discord, groups can establish a discussion category in the [GitHub Discussions](https://github.com/modelcontextprotocol/modelcontextprotocol/discussions/). Leads will be granted the appropriate roles to manage and moderate discussions.
216216
from line 320
320320
321321*Example:*
322322
323| Decision Type | Authority Level |
324| ----------------------------------- | ------------------------------------------------------ |
325| Meeting logistics & scheduling | WG Leads (autonomous) |
326| Proposal prioritization within WG | WG Leads (autonomous) |
327| SEP triage & closure (in scope) | WG Leads (autonomous, with documented rationale) |
328| Technical design within scope | WG consensus |
329| Spec changes (additive) | WG consensus → Core Maintainer approval |
323| Decision Type | Authority Level |
324| - | - |
325| Meeting logistics & scheduling | WG Leads (autonomous) |
326| Proposal prioritization within WG | WG Leads (autonomous) |
327| SEP triage & closure (in scope) | WG Leads (autonomous, with documented rationale) |
328| Technical design within scope | WG consensus |
329| Spec changes (additive) | WG consensus → Core Maintainer approval |
330330| Spec changes (breaking/fundamental) | WG consensus → Core Maintainer approval + wider review |
331| Scope expansion | Core Maintainer approval required |
332| WG Member approval | WG Member sponsors |
331| Scope expansion | Core Maintainer approval required |
332| WG Member approval | WG Member sponsors |
333333
334334IGs do not make binding decisions and do not need this section.
335335
from line 344
344344
345345*Example:*
346346
347| Meeting | Frequency | Duration | Purpose |
348| --------------- | --------------- | -------- | ------------------------------------- |
349| Working Session | Weekly/Biweekly | 60 min | Technical discussion, proposal review |
350| Office Hours | Monthly | 30 min | Open Q\&A for newcomers and observers |
347| Meeting | Frequency | Duration | Purpose |
348| - | - | - | - |
349| Working Session | Weekly/Biweekly | 60 min | Technical discussion, proposal review |
350| Office Hours | Monthly | 30 min | Open Q\&A for newcomers and observers |
351351
352352#### 8. Deliverables & Success Metrics (WG only)
353353
354354**Active Work Items:**
355355
356| Item | Status | Target Date | Champion |
357| ------------- | --------------------- | ----------- | -------- |
358| SEP-XXX: Name | Draft/Review/Approved | Date | Name |
356| Item | Status | Target Date | Champion |
357| - | - | - | - |
358| SEP-XXX: Name | Draft/Review/Approved | Date | Name |
359359
360360**Success Criteria:** Measurable outcomes for WG success.
361361
seps/2164-resource-not-found-error Changed · +22 / -22 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ------------------------------------------------------------------------------- |
25| **SEP** | 2164 |
26| **Title** | Standardize Resource Not Found Error Code |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-01-28 |
30| **Author(s)** | Peter Alexander ([@pja-ant](https://github.com/pja-ant)) |
31| **Sponsor** | None (seeking sponsor) |
32| **PR** | [#2164](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2164) |
23| Field | Value |
24| - | - |
25| **SEP** | 2164 |
26| **Title** | Standardize Resource Not Found Error Code |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-01-28 |
30| **Author(s)** | Peter Alexander ([@pja-ant](https://github.com/pja-ant)) |
31| **Sponsor** | None (seeking sponsor) |
32| **PR** | [#2164](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2164) |
3333
3434***
3535
from line 43
4343
4444Current SDK implementations vary in their error handling for resource not found:
4545
46| SDK | Current Error Code | Source |
47| ---------- | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
48| TypeScript | `-32602` (InvalidParams) | [mcp.ts#L561](https://github.com/modelcontextprotocol/typescript-sdk/blob/main/packages/server/src/server/mcp.ts#L561) |
49| Python | `0` (generic) | [server.py#L790](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/lowlevel/server.py#L790) |
50| C# | `-32002` (custom RESOURCE\_NOT\_FOUND) | [McpServerImpl.cs#L289](https://github.com/modelcontextprotocol/csharp-sdk/blob/main/src/ModelContextProtocol.Core/Server/McpServerImpl.cs#L289) |
51| Rust | `-32002` (custom RESOURCE\_NOT\_FOUND) | [model.rs#L450](https://github.com/modelcontextprotocol/rust-sdk/blob/main/crates/rmcp/src/model.rs#L450) |
52| Java | `-32002` (custom RESOURCE\_NOT\_FOUND) | [McpAsyncServer.java#L732](https://github.com/modelcontextprotocol/java-sdk/blob/main/mcp-core/src/main/java/io/modelcontextprotocol/server/McpAsyncServer.java#L732) |
53| Go | `-32002` (custom RESOURCE\_NOT\_FOUND) | [server.go#L786](https://github.com/modelcontextprotocol/go-sdk/blob/main/mcp/server.go#L786) |
54| Kotlin | `-32603` (INTERNAL\_ERROR) | [Server.kt#L618-L621](https://github.com/modelcontextprotocol/kotlin-sdk/blob/main/kotlin-sdk-server/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/server/Server.kt#L618-L621) |
55| PHP | `-32002` (custom RESOURCE\_NOT\_FOUND) | [Error.php#L37](https://github.com/modelcontextprotocol/php-sdk/blob/main/src/Schema/JsonRpc/Error.php#L37) |
56| Ruby | N/A (left to implementor) | [server.rb#L375-L379](https://github.com/modelcontextprotocol/ruby-sdk/blob/main/lib/mcp/server.rb#L375-L379) |
57| Swift | N/A (no built-in handler) | N/A |
46| SDK | Current Error Code | Source |
47| - | - | - |
48| TypeScript | `-32602` (InvalidParams) | [mcp.ts#L561](https://github.com/modelcontextprotocol/typescript-sdk/blob/main/packages/server/src/server/mcp.ts#L561) |
49| Python | `0` (generic) | [server.py#L790](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/lowlevel/server.py#L790) |
50| C# | `-32002` (custom RESOURCE\_NOT\_FOUND) | [McpServerImpl.cs#L289](https://github.com/modelcontextprotocol/csharp-sdk/blob/main/src/ModelContextProtocol.Core/Server/McpServerImpl.cs#L289) |
51| Rust | `-32002` (custom RESOURCE\_NOT\_FOUND) | [model.rs#L450](https://github.com/modelcontextprotocol/rust-sdk/blob/main/crates/rmcp/src/model.rs#L450) |
52| Java | `-32002` (custom RESOURCE\_NOT\_FOUND) | [McpAsyncServer.java#L732](https://github.com/modelcontextprotocol/java-sdk/blob/main/mcp-core/src/main/java/io/modelcontextprotocol/server/McpAsyncServer.java#L732) |
53| Go | `-32002` (custom RESOURCE\_NOT\_FOUND) | [server.go#L786](https://github.com/modelcontextprotocol/go-sdk/blob/main/mcp/server.go#L786) |
54| Kotlin | `-32603` (INTERNAL\_ERROR) | [Server.kt#L618-L621](https://github.com/modelcontextprotocol/kotlin-sdk/blob/main/kotlin-sdk-server/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/server/Server.kt#L618-L621) |
55| PHP | `-32002` (custom RESOURCE\_NOT\_FOUND) | [Error.php#L37](https://github.com/modelcontextprotocol/php-sdk/blob/main/src/Schema/JsonRpc/Error.php#L37) |
56| Ruby | N/A (left to implementor) | [server.rb#L375-L379](https://github.com/modelcontextprotocol/ruby-sdk/blob/main/lib/mcp/server.rb#L375-L379) |
57| Swift | N/A (no built-in handler) | N/A |
5858
5959This inconsistency means clients cannot reliably detect resource-not-found conditions across implementations. Of the 8 SDKs with built-in resource handling, four different error codes are used: `-32002` (C#, Rust, Java, Go, PHP), `-32602` (TypeScript), `-32603` (Kotlin), and `0` (Python). Ruby and Swift leave error handling to the server implementor. Clients that need to distinguish "resource not found" from other errors must handle all variants.
6060
seps/2207-oidc-refresh-token-guidance Changed · +10 / -10 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ------------------------------------------------------------------------------- |
25| **SEP** | 2207 |
26| **Title** | OIDC-Flavored Refresh Token Guidance |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-02-04 |
30| **Author(s)** | Wils Dawson ([@wdawson](https://github.com/wdawson)) |
31| **Sponsor** | Paul Carleton ([@pcarleton](https://github.com/pcarleton)) |
32| **PR** | [#2207](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2207) |
23| Field | Value |
24| - | - |
25| **SEP** | 2207 |
26| **Title** | OIDC-Flavored Refresh Token Guidance |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-02-04 |
30| **Author(s)** | Wils Dawson ([@wdawson](https://github.com/wdawson)) |
31| **Sponsor** | Paul Carleton ([@pcarleton](https://github.com/pcarleton)) |
32| **PR** | [#2207](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2207) |
3333
3434***
3535
seps/2243-http-standardization Changed · +107 / -107 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ------------------------------------------------------------------------------- |
25| **SEP** | 2243 |
26| **Title** | HTTP Header Standardization for Streamable HTTP Transport |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-02-04 |
30| **Author(s)** | MCP Transports Working Group |
31| **Sponsor** | None |
32| **PR** | [#2243](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2243) |
23| Field | Value |
24| - | - |
25| **SEP** | 2243 |
26| **Title** | HTTP Header Standardization for Streamable HTTP Transport |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-02-04 |
30| **Author(s)** | MCP Transports Working Group |
31| **Sponsor** | None |
32| **PR** | [#2243](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2243) |
3333
3434***
3535
from line 54
5454
5555The Streamable HTTP transport will require POST requests to include the following headers mirrored from the request body:
5656
57| Header Name | Source Field | Required For |
58| ------------ | ----------------------------- | ------------------------------------------------------ |
59| `Mcp-Method` | `method` | All requests and notifications |
60| `Mcp-Name` | `params.name` or `params.uri` | `tools/call`, `resources/read`, `prompts/get` requests |
57| Header Name | Source Field | Required For |
58| - | - | - |
59| `Mcp-Method` | `method` | All requests and notifications |
60| `Mcp-Name` | `params.name` or `params.uri` | `tools/call`, `resources/read`, `prompts/get` requests |
6161
6262These headers are **required** for compliance with the MCP version in which they are introduced.
6363
from line 444
444444
445445**Examples**:
446446
447| Original Value | Reason | Encoded Header Value |
448| ---------------------- | ------------------------ | ----------------------------------------------------- |
449| `"us-west1"` | Plain ASCII | `Mcp-Param-Region: us-west1` |
450| `"Hello, 世界"` | Contains non-ASCII | `Mcp-Param-Greeting: =?base64?SGVsbG8sIOS4lueVjA==?=` |
451| `" padded "` | Leading/trailing spaces | `Mcp-Param-Text: =?base64?IHBhZGRlZCA=?=` |
452| `"line1\nline2"` | Contains newline | `Mcp-Param-Text: =?base64?bGluZTEKbGluZTI=?=` |
453| `"=?base64?literal?="` | Matches sentinel pattern | `Mcp-Param-Val: =?base64?PT9iYXNlNjQ/bGl0ZXJhbD89?=` |
447| Original Value | Reason | Encoded Header Value |
448| - | - | - |
449| `"us-west1"` | Plain ASCII | `Mcp-Param-Region: us-west1` |
450| `"Hello, 世界"` | Contains non-ASCII | `Mcp-Param-Greeting: =?base64?SGVsbG8sIOS4lueVjA==?=` |
451| `" padded "` | Leading/trailing spaces | `Mcp-Param-Text: =?base64?IHBhZGRlZCA=?=` |
452| `"line1\nline2"` | Contains newline | `Mcp-Param-Text: =?base64?bGluZTEKbGluZTI=?=` |
453| `"=?base64?literal?="` | Matches sentinel pattern | `Mcp-Param-Val: =?base64?PT9iYXNlNjQ/bGl0ZXJhbD89?=` |
454454
455455#### Client Behavior
456456
from line 474
474474
475475When rejecting a request due to header validation failure, servers MUST return a JSON-RPC error response with the following error code:
476476
477| Code | Name | Description |
478| -------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------- |
477| Code | Name | Description |
478| - | - | - |
479479| `-32001` | `HeaderMismatch` | The HTTP headers do not match the corresponding values in the request body, or required headers are missing/malformed. |
480480
481481This error code is in the JSON-RPC implementation-defined server error range (`-32000` to `-32099`).
from line 508
508508
509509Custom headers (those defined via `x-mcp-header`) follow the same validation rules as standard headers:
510510
511| Scenario | Client Behavior | Server Behavior |
512| ---------------------------------------- | ------------------------------ | ---------------------------------------- |
513| Parameter value provided | Client MUST include the header | Server MUST validate header matches body |
514| Parameter value is `null` | Client MUST omit the header | Server MUST NOT expect the header |
515| Parameter not in arguments | Client MUST omit the header | Server MUST NOT expect the header |
516| Client omits header but value is in body | Non-conforming client | Server MUST reject the request |
511| Scenario | Client Behavior | Server Behavior |
512| - | - | - |
513| Parameter value provided | Client MUST include the header | Server MUST validate header matches body |
514| Parameter value is `null` | Client MUST omit the header | Server MUST NOT expect the header |
515| Parameter not in arguments | Client MUST omit the header | Server MUST NOT expect the header |
516| Client omits header but value is in body | Non-conforming client | Server MUST reject the request |
517517
518518When rejecting requests due to missing or invalid custom headers, the server MUST return HTTP status `400 Bad Request` with JSON-RPC error code `-32001` (`HeaderMismatch`).
519519
from line 538
538538
539539**Trade-offs and Framework Considerations**:
540540
541| Framework | Header-based Routing | Path-based Routing |
542| ----------------- | ------------------------------------------------------------------- | ------------------------------------------------ |
543| Flask (Python) | Requires middleware or decorators to extract headers before routing | Native support via `@app.route('/mcp/<method>')` |
544| Express (Node.js) | Easy via `req.headers` but requires custom routing logic | Native support via `app.post('/mcp/:method')` |
545| Django (Python) | Requires custom middleware | Native URL patterns |
546| Go (net/http) | Easy via `r.Header.Get()` | Native via path patterns |
547| ASP.NET Core | Easy via `[FromHeader]` attribute | Native via route templates |
541| Framework | Header-based Routing | Path-based Routing |
542| - | - | - |
543| Flask (Python) | Requires middleware or decorators to extract headers before routing | Native support via `@app.route('/mcp/<method>')` |
544| Express (Node.js) | Easy via `req.headers` but requires custom routing logic | Native support via `app.post('/mcp/:method')` |
545| Django (Python) | Requires custom middleware | Native URL patterns |
546| Go (net/http) | Easy via `r.Header.Get()` | Native via path patterns |
547| ASP.NET Core | Easy via `[FromHeader]` attribute | Native via route templates |
548548
549549For frameworks like Flask that strongly favor path-based routing, implementing header-based routing requires additional code:
550550
from line 627
627627
6286284. **Always encode**: Base64-encode every `Mcp-Param-{Name}` value unconditionally.
629629
630| Approach | Pros | Cons |
631| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
632| Sentinel wrapping | Single header name per parameter; common case (plain ASCII) is human-readable; intermediaries can route on plain values without decoding | In-band signaling can theoretically collide with literal values; every reader must check for the prefix |
633| Separate header name | No in-band ambiguity; encoding is self-documenting from the header name | Doubles the header namespace; every intermediary must check two header names per parameter; needs a conflict rule if both are present |
634| Implicit encoding | Simplest wire format; no sentinels or extra headers | Intermediaries need access to the tool schema to know whether to decode — defeats the purpose of exposing values in headers; static per-parameter decision doesn't handle the mixed case well |
635| Always encode | Simplest rules; no conditional logic or ambiguity | Plain ASCII values become unreadable; intermediaries must decode Base64 to inspect any value, significantly undermining the core motivation of this SEP |
630| Approach | Pros | Cons |
631| - | - | - |
632| Sentinel wrapping | Single header name per parameter; common case (plain ASCII) is human-readable; intermediaries can route on plain values without decoding | In-band signaling can theoretically collide with literal values; every reader must check for the prefix |
633| Separate header name | No in-band ambiguity; encoding is self-documenting from the header name | Doubles the header namespace; every intermediary must check two header names per parameter; needs a conflict rule if both are present |
634| Implicit encoding | Simplest wire format; no sentinels or extra headers | Intermediaries need access to the tool schema to know whether to decode — defeats the purpose of exposing values in headers; static per-parameter decision doesn't handle the mixed case well |
635| Always encode | Simplest rules; no conditional logic or ambiguity | Plain ASCII values become unreadable; intermediaries must decode Base64 to inspect any value, significantly undermining the core motivation of this SEP |
636636
637637**Conclusion**: The sentinel wrapping approach provides the best trade-off. The primary use case for custom headers is enabling intermediaries to route and filter on simple, readable values like region names and tenant IDs — these are invariably plain ASCII and never trigger Base64 encoding. Option 4 makes all values opaque to intermediaries. Option 3 leaves intermediaries unable to distinguish encoded from literal values without access to the tool schema. Option 2 eliminates in-band ambiguity but doubles the header namespace, requiring intermediaries to check two possible header names per parameter and adding a conflict rule when both are present. The theoretical collision risk of the sentinel in Option 1 is negligible since `=?base64?...?=` is an unlikely literal parameter value in practice.
638638
from line 694
694694
695695#### Case Sensitivity
696696
697| Test Case | Input | Expected Behavior |
698| -------------------------- | ------------------------ | ------------------------------------------------------ |
697| Test Case | Input | Expected Behavior |
698| - | - | - |
699699| Header name case variation | `mcp-method: tools/call` | Server MUST accept (header names are case-insensitive) |
700| Header name mixed case | `MCP-METHOD: tools/call` | Server MUST accept |
701| Method value case | `Mcp-Method: TOOLS/CALL` | Server MUST reject (method values are case-sensitive) |
700| Header name mixed case | `MCP-METHOD: tools/call` | Server MUST accept |
701| Method value case | `Mcp-Method: TOOLS/CALL` | Server MUST reject (method values are case-sensitive) |
702702
703703#### Header/Body Mismatch
704704
705| Test Case | Header Value | Body Value | Expected Behavior |
706| -------------------------- | ------------------------ | --------------------------- | --------------------------------------------------- |
707| Method mismatch | `Mcp-Method: tools/call` | `"method": "prompts/get"` | Server MUST reject with 400 and error code `-32001` |
708| Tool name mismatch | `Mcp-Name: foo` | `"params": {"name": "bar"}` | Server MUST reject with 400 and error code `-32001` |
709| Missing required header | (no `Mcp-Method`) | Valid body | Server MUST reject with 400 and error code `-32001` |
710| Extra whitespace in header | `Mcp-Name: foo ` | `"params": {"name": "foo"}` | Server MUST accept (trim whitespace per HTTP spec) |
705| Test Case | Header Value | Body Value | Expected Behavior |
706| - | - | - | - |
707| Method mismatch | `Mcp-Method: tools/call` | `"method": "prompts/get"` | Server MUST reject with 400 and error code `-32001` |
708| Tool name mismatch | `Mcp-Name: foo` | `"params": {"name": "bar"}` | Server MUST reject with 400 and error code `-32001` |
709| Missing required header | (no `Mcp-Method`) | Valid body | Server MUST reject with 400 and error code `-32001` |
710| Extra whitespace in header | `Mcp-Name: foo ` | `"params": {"name": "foo"}` | Server MUST accept (trim whitespace per HTTP spec) |
711711
712712#### Special Characters in Values
713713
714| Test Case | Value | Expected Behavior |
715| ------------------------------- | ------------------------------------- | ---------------------------------- |
716| Tool name with hyphen | `my-tool-name` | Client sends as-is; server accepts |
717| Tool name with underscore | `my_tool_name` | Client sends as-is; server accepts |
718| Resource URI with special chars | `file:///path/to/file%20name.txt` | Client sends as-is; server accepts |
719| Resource URI with query string | `https://example.com/resource?id=123` | Client sends as-is; server accepts |
714| Test Case | Value | Expected Behavior |
715| - | - | - |
716| Tool name with hyphen | `my-tool-name` | Client sends as-is; server accepts |
717| Tool name with underscore | `my_tool_name` | Client sends as-is; server accepts |
718| Resource URI with special chars | `file:///path/to/file%20name.txt` | Client sends as-is; server accepts |
719| Resource URI with query string | `https://example.com/resource?id=123` | Client sends as-is; server accepts |
720720
721721### Custom Header Edge Cases
722722
723723#### x-mcp-header Name Conflicts
724724
725| Test Case | Schema | Expected Behavior |
726| --------------------------------------- | --------------------------------------------------------- | ---------------------------------------------------------------- |
727| Duplicate header names (same case) | Two properties with `"x-mcp-header": "Region"` | Client MUST reject tool definition |
725| Test Case | Schema | Expected Behavior |
726| - | - | - |
727| Duplicate header names (same case) | Two properties with `"x-mcp-header": "Region"` | Client MUST reject tool definition |
728728| Duplicate header names (different case) | `"x-mcp-header": "Region"` and `"x-mcp-header": "REGION"` | Client MUST reject tool definition (case-insensitive uniqueness) |
729| Header name matches standard header | `"x-mcp-header": "Method"` | Allowed (produces `Mcp-Param-Method`, not `Mcp-Method`) |
730| Empty header name | `"x-mcp-header": ""` | Client MUST reject tool definition |
729| Header name matches standard header | `"x-mcp-header": "Method"` | Allowed (produces `Mcp-Param-Method`, not `Mcp-Method`) |
730| Empty header name | `"x-mcp-header": ""` | Client MUST reject tool definition |
731731
732732#### Invalid x-mcp-header Values
733733
734| Test Case | x-mcp-header Value | Expected Behavior |
735| -------------------------- | ---------------------------------- | ---------------------------------- |
736| Contains space | `"x-mcp-header": "My Region"` | Client MUST reject tool definition |
737| Contains colon | `"x-mcp-header": "Region:Primary"` | Client MUST reject tool definition |
738| Contains non-ASCII | `"x-mcp-header": "Région"` | Client MUST reject tool definition |
739| Contains control character | `"x-mcp-header": "Region\t1"` | Client MUST reject tool definition |
734| Test Case | x-mcp-header Value | Expected Behavior |
735| - | - | - |
736| Contains space | `"x-mcp-header": "My Region"` | Client MUST reject tool definition |
737| Contains colon | `"x-mcp-header": "Region:Primary"` | Client MUST reject tool definition |
738| Contains non-ASCII | `"x-mcp-header": "Région"` | Client MUST reject tool definition |
739| Contains control character | `"x-mcp-header": "Region\t1"` | Client MUST reject tool definition |
740740
741741#### Value Encoding Edge Cases
742742
743| Test Case | Parameter Value | Expected Header Value |
744| ----------------------------------- | ------------------ | ----------------------------------------------- |
745| Plain ASCII string | `"us-west1"` | `Mcp-Param-Region: us-west1` |
746| String with leading space | `" us-west1"` | `Mcp-Param-Region: =?base64?IHVzLXdlc3Qx?=` |
747| String with trailing space | `"us-west1 "` | `Mcp-Param-Region: =?base64?dXMtd2VzdDEg?=` |
748| String with leading/trailing spaces | `" us-west1 "` | `Mcp-Param-Region: =?base64?IHVzLXdlc3QxIA==?=` |
749| String with internal spaces only | `"us west 1"` | `Mcp-Param-Region: us west 1` |
750| Boolean true | `true` | `Mcp-Param-Flag: true` |
751| Boolean false | `false` | `Mcp-Param-Flag: false` |
752| Integer | `42` | `Mcp-Param-Count: 42` |
753| Floating point | `3.14159` | `Mcp-Param-Value: 3.14159` |
754| Non-ASCII characters | `"日本語"` | `Mcp-Param-Text: =?base64?5pel5pys6Kqe?=` |
755| String with newline | `"line1\nline2"` | `Mcp-Param-Text: =?base64?bGluZTEKbGluZTI=?=` |
756| String with carriage return | `"line1\r\nline2"` | `Mcp-Param-Text: =?base64?bGluZTENCmxpbmUy?=` |
757| String with leading tab | `"\tindented"` | `Mcp-Param-Text: =?base64?CWluZGVudGVk?=` |
758| Empty string | `""` | `Mcp-Param-Name: ` (empty value) |
743| Test Case | Parameter Value | Expected Header Value |
744| - | - | - |
745| Plain ASCII string | `"us-west1"` | `Mcp-Param-Region: us-west1` |
746| String with leading space | `" us-west1"` | `Mcp-Param-Region: =?base64?IHVzLXdlc3Qx?=` |
747| String with trailing space | `"us-west1 "` | `Mcp-Param-Region: =?base64?dXMtd2VzdDEg?=` |
748| String with leading/trailing spaces | `" us-west1 "` | `Mcp-Param-Region: =?base64?IHVzLXdlc3QxIA==?=` |
749| String with internal spaces only | `"us west 1"` | `Mcp-Param-Region: us west 1` |
750| Boolean true | `true` | `Mcp-Param-Flag: true` |
751| Boolean false | `false` | `Mcp-Param-Flag: false` |
752| Integer | `42` | `Mcp-Param-Count: 42` |
753| Floating point | `3.14159` | `Mcp-Param-Value: 3.14159` |
754| Non-ASCII characters | `"日本語"` | `Mcp-Param-Text: =?base64?5pel5pys6Kqe?=` |
755| String with newline | `"line1\nline2"` | `Mcp-Param-Text: =?base64?bGluZTEKbGluZTI=?=` |
756| String with carriage return | `"line1\r\nline2"` | `Mcp-Param-Text: =?base64?bGluZTENCmxpbmUy?=` |
757| String with leading tab | `"\tindented"` | `Mcp-Param-Text: =?base64?CWluZGVudGVk?=` |
758| Empty string | `""` | `Mcp-Param-Name: ` (empty value) |
759759
760760#### Type Restriction Violations
761761
762| Test Case | Property Type | x-mcp-header Present | Expected Behavior |
763| --------------- | ---------------------- | -------------------- | ---------------------------------- |
764| Array type | `"type": "array"` | Yes | Server MUST reject tool definition |
765| Object type | `"type": "object"` | Yes | Server MUST reject tool definition |
766| Null type | `"type": "null"` | Yes | Server MUST reject tool definition |
767| Nested property | Property inside object | Yes | Server MUST reject tool definition |
762| Test Case | Property Type | x-mcp-header Present | Expected Behavior |
763| - | - | - | - |
764| Array type | `"type": "array"` | Yes | Server MUST reject tool definition |
765| Object type | `"type": "object"` | Yes | Server MUST reject tool definition |
766| Null type | `"type": "null"` | Yes | Server MUST reject tool definition |
767| Nested property | Property inside object | Yes | Server MUST reject tool definition |
768768
769769### Server Validation Edge Cases
770770
771771#### Base64 Decoding
772772
773| Test Case | Header Value | Expected Behavior |
774| ------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------- |
775| Valid Base64 | `=?base64?SGVsbG8=?=` | Server decodes to `"Hello"` and validates |
776| Invalid Base64 padding | `=?base64?SGVsbG8?=` | Server MUST reject with 400 and error code `-32001`; Intermediary MAY reject with 400 status code |
773| Test Case | Header Value | Expected Behavior |
774| - | - | - |
775| Valid Base64 | `=?base64?SGVsbG8=?=` | Server decodes to `"Hello"` and validates |
776| Invalid Base64 padding | `=?base64?SGVsbG8?=` | Server MUST reject with 400 and error code `-32001`; Intermediary MAY reject with 400 status code |
777777| Invalid Base64 characters | `=?base64?SGVs!!!bG8=?=` | Server MUST reject with 400 and error code `-32001`; Intermediary MAY reject with 400 status code |
778| Missing prefix | `SGVsbG8=` | Server treats as literal value, not Base64 |
779| Missing suffix | `=?base64?SGVsbG8=` | Server treats as literal value, not Base64 |
780| Non-lowercase prefix | `=?BASE64?SGVsbG8=?=` | Server treats as literal value, not Base64 |
778| Missing prefix | `SGVsbG8=` | Server treats as literal value, not Base64 |
779| Missing suffix | `=?base64?SGVsbG8=` | Server treats as literal value, not Base64 |
780| Non-lowercase prefix | `=?BASE64?SGVsbG8=?=` | Server treats as literal value, not Base64 |
781781
782782#### Null and Missing Values
783783
784| Test Case | Scenario | Expected Behavior |
785| -------------------------------------- | --------------------------- | -------------------------- |
786| Parameter with x-mcp-header is null | `"region": null` | Client MUST omit header |
787| Parameter with x-mcp-header is missing | Parameter not in arguments | Client MUST omit header |
788| Optional parameter present | Optional parameter provided | Client MUST include header |
784| Test Case | Scenario | Expected Behavior |
785| - | - | - |
786| Parameter with x-mcp-header is null | `"region": null` | Client MUST omit header |
787| Parameter with x-mcp-header is missing | Parameter not in arguments | Client MUST omit header |
788| Optional parameter present | Optional parameter provided | Client MUST include header |
789789
790790#### Missing Custom Header with Value in Body
791791
792| Test Case | Header Present | Body Value | Expected Behavior |
793| -------------------------------------- | --------------------- | --------------------------- | ------------------------------------------------------------------------------------------------- |
794| Standard header omitted, value in body | No `Mcp-Name` | `"params": {"name": "foo"}` | Server MUST reject with 400 and error code `-32001`; Intermediary MAY reject with 400 status code |
795| Custom header omitted, value in body | No `Mcp-Param-Region` | `"region": "us-west1"` | Server MUST reject with 400 and error code `-32001`; Intermediary MAY reject with 400 status code |
792| Test Case | Header Present | Body Value | Expected Behavior |
793| - | - | - | - |
794| Standard header omitted, value in body | No `Mcp-Name` | `"params": {"name": "foo"}` | Server MUST reject with 400 and error code `-32001`; Intermediary MAY reject with 400 status code |
795| Custom header omitted, value in body | No `Mcp-Param-Region` | `"region": "us-west1"` | Server MUST reject with 400 and error code `-32001`; Intermediary MAY reject with 400 status code |
796796
797797## Reference Implementation
798798
seps/2260-Require-Server-requests-to-be-associated-with-Client-requests Changed · +10 / -10 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ------------------------------------------------------------------------------- |
25| **SEP** | 2260 |
26| **Title** | Require Server requests to be associated with a Client request. |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-02-16 |
30| **Author(s)** | MCP Transports Working Group |
31| **Sponsor** | [@CaitieM20](https://github.com/CaitieM20) - Caitie McCaffrey |
32| **PR** | [#2260](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2260) |
23| Field | Value |
24| - | - |
25| **SEP** | 2260 |
26| **Title** | Require Server requests to be associated with a Client request. |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-02-16 |
30| **Author(s)** | MCP Transports Working Group |
31| **Sponsor** | [@CaitieM20](https://github.com/CaitieM20) - Caitie McCaffrey |
32| **PR** | [#2260](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2260) |
3333
3434***
3535
seps/2322-MRTR Changed · +31 / -31 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
25| **SEP** | 2322 |
26| **Title** | Multi Round-Trip Requests |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-02-03 |
23| Field | Value |
24| - | - |
25| **SEP** | 2322 |
26| **Title** | Multi Round-Trip Requests |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-02-03 |
3030| **Author(s)** | Mark D. Roth ([@markdroth](https://github.com/markdroth)), Caitie McCaffrey ([@CaitieM20](https://github.com/CaitieM20)), Gabriel Zimmerman ([@gjz22](https://github.com/gjz22)) |
31| **Sponsor** | Caitie McCaffrey ([@CaitieM20](https://github.com/CaitieM20)) |
32| **PR** | [#2322](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2322) |
31| **Sponsor** | Caitie McCaffrey ([@CaitieM20](https://github.com/CaitieM20)) |
32| **PR** | [#2322](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2322) |
3333
3434***
3535
from line 380
380380
381381Servers MAY send `InputRequiredResult` responses on the following Client Requests:
382382
383| ClientRequest | ServerResult | InputRequiredResult Supported |
384| ----------------------- | ---------------------- | ----------------------------- |
385| `GetPromptRequest` | `GetPromptResult` | Yes |
386| `ReadResourceRequest` | `ReadResourceResult` | Yes |
387| `CallToolRequest` | `CallToolResult` | Yes |
388| `GetTaskPayloadRequest` | `GetTaskPayloadResult` | Yes |
383| ClientRequest | ServerResult | InputRequiredResult Supported |
384| - | - | - |
385| `GetPromptRequest` | `GetPromptResult` | Yes |
386| `ReadResourceRequest` | `ReadResourceResult` | Yes |
387| `CallToolRequest` | `CallToolResult` | Yes |
388| `GetTaskPayloadRequest` | `GetTaskPayloadResult` | Yes |
389389
390390Servers MUST NOT send `InputRequiredResult` responses on any other Client Requests. The below table represents what `ClientRequest`s this excludes at the writing of this SEP.
391391
392| ClientRequest | InputRequiredResult Supported |
393| ------------------------------ | ----------------------------- |
394| `PingRequest` | No |
395| `InitializeRequest` | No |
396| `CompleteRequest` | No |
397| `SetLevelRequest` | No |
398| `ListPromptsRequest` | No |
399| `ListResourcesRequest` | No |
400| `ListResourceTemplatesRequest` | No |
401| `SubscribeRequest` | No |
402| `UnsubscribeRequest` | No |
403| `ListToolsRequest` | No |
404| `GetTaskRequest` | No |
405| `ListTasksRequest` | No |
406| `CancelTaskRequest` | No |
407| `TaskInputResponseRequest` | No |
392| ClientRequest | InputRequiredResult Supported |
393| - | - |
394| `PingRequest` | No |
395| `InitializeRequest` | No |
396| `CompleteRequest` | No |
397| `SetLevelRequest` | No |
398| `ListPromptsRequest` | No |
399| `ListResourcesRequest` | No |
400| `ListResourceTemplatesRequest` | No |
401| `SubscribeRequest` | No |
402| `UnsubscribeRequest` | No |
403| `ListToolsRequest` | No |
404| `GetTaskRequest` | No |
405| `ListTasksRequest` | No |
406| `CancelTaskRequest` | No |
407| `TaskInputResponseRequest` | No |
408408
409409### Ephemeral Tool Workflow
410410
seps/2468-recommend-issuer-claim-for-auth Changed · +10 / -10 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ------------------------------------------------------------------------------- |
25| **SEP** | 2468 |
26| **Title** | Recommend Issuer (iss) Parameter in MCP Auth Responses |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-03-25 |
30| **Author(s)** | Emily Lauber ([@EmLauber](https://github.com/EmLauber)) |
31| **Sponsor** | [@pcarleton](https://github.com/pcarleton) |
32| **PR** | [#2468](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2468) |
23| Field | Value |
24| - | - |
25| **SEP** | 2468 |
26| **Title** | Recommend Issuer (iss) Parameter in MCP Auth Responses |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-03-25 |
30| **Author(s)** | Emily Lauber ([@EmLauber](https://github.com/EmLauber)) |
31| **Sponsor** | [@pcarleton](https://github.com/pcarleton) |
32| **PR** | [#2468](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2468) |
3333
3434***
3535
seps/2484-conformance-tests-required-for-final-seps Changed · +10 / -10 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ------------------------------------------------------------------------------- |
25| **SEP** | 2484 |
26| **Title** | Require Conformance Tests for Standards Track SEPs to Reach Final Status |
27| **Status** | Final |
28| **Type** | Process |
29| **Created** | 2026-03-27 |
30| **Author(s)** | Paul Carleton ([@pcarleton](https://github.com/pcarleton)) |
31| **Sponsor** | None |
32| **PR** | [#2484](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2484) |
23| Field | Value |
24| - | - |
25| **SEP** | 2484 |
26| **Title** | Require Conformance Tests for Standards Track SEPs to Reach Final Status |
27| **Status** | Final |
28| **Type** | Process |
29| **Created** | 2026-03-27 |
30| **Author(s)** | Paul Carleton ([@pcarleton](https://github.com/pcarleton)) |
31| **Sponsor** | None |
32| **PR** | [#2484](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2484) |
3333
3434***
3535
seps/2549-TTL-for-list-results Changed · +29 / -29 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ------------------------------------------------------------------------------- |
25| **SEP** | 2549 |
26| **Title** | TTL for List Results |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-04-09 |
30| **Author(s)** | Caitie McCaffrey ([@CaitieM20](https://github.com/CaitieM20)) |
31| **Sponsor** | [@CaitieM20](https://github.com/CaitieM20) |
32| **PR** | [#2549](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2549) |
23| Field | Value |
24| - | - |
25| **SEP** | 2549 |
26| **Title** | TTL for List Results |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-04-09 |
30| **Author(s)** | Caitie McCaffrey ([@CaitieM20](https://github.com/CaitieM20)) |
31| **Sponsor** | [@CaitieM20](https://github.com/CaitieM20) |
32| **PR** | [#2549](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2549) |
3333
3434***
3535
from line 41
4141
4242Today, MCP clients discover server features by invoking methods on the server. These calls return the current set of features. To learn about changes, clients rely on push notifications from the server. The below table maps the Server Method to Notification Type.
4343
44| Server Methods | Notification Type |
45| -------------------------- | -------------------------------------- |
46| `tools/list` | `notifications/tools/list_changed` |
47| `prompts/list` | `notifications/prompts/list_changed` |
48| `resources/list` | `notifications/resources/list_changed` |
44| Server Methods | Notification Type |
45| - | - |
46| `tools/list` | `notifications/tools/list_changed` |
47| `prompts/list` | `notifications/prompts/list_changed` |
48| `resources/list` | `notifications/resources/list_changed` |
4949| `resources/templates/list` | `notifications/resources/list_changed` |
50| `resources/read` | `notifications/resources/updated` |
50| `resources/read` | `notifications/resources/updated` |
5151
5252This approach has several limitations:
5353
from line 112
112112
113113`ttlMs` MUST be >= 0. If a server returns a negative value, clients SHOULD ignore it and treat it as 0 (immediately stale).
114114
115| Condition | Client behavior |
116| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
117| `ttlMs` = 0 | The response SHOULD be considered immediately stale, The Client MAY re-fetch every time the result is needed. |
118| `ttlMs` > 0 | Client SHOULD consider the response fresh for `ttlMs` milliseconds from receipt. |
119| Relevant notification received while TTL is active | The notification invalidates the cached response. Client SHOULD re-fetch regardless of remaining TTL. |
120| `cacheScope` = `"public"` | Any client or shared intermediary (gateway, proxy) MAY cache and serve the response to any user. |
121| `cacheScope` = `"private"` | Only the requesting user's client MAY cache. Shared caches MUST NOT serve a cached copy to a different user. |
115| Condition | Client behavior |
116| - | - |
117| `ttlMs` = 0 | The response SHOULD be considered immediately stale, The Client MAY re-fetch every time the result is needed. |
118| `ttlMs` > 0 | Client SHOULD consider the response fresh for `ttlMs` milliseconds from receipt. |
119| Relevant notification received while TTL is active | The notification invalidates the cached response. Client SHOULD re-fetch regardless of remaining TTL. |
120| `cacheScope` = `"public"` | Any client or shared intermediary (gateway, proxy) MAY cache and serve the response to any user. |
121| `cacheScope` = `"private"` | Only the requesting user's client MAY cache. Shared caches MUST NOT serve a cached copy to a different user. |
122122
123123#### Freshness calculation
124124
from line 199
199199
200200Many existing systems use integer seconds for TTLs, but some (e.g., gRPC retry pushback) use milliseconds. The key is to choose a single, consistent unit for all TTLs in MCP. Integer milliseconds provides the necessary precision while remaining simple to implement and understand.
201201
202| System | Mechanism | Notes |
203| ----------------------------- | --------------------- | ---------------------------------------------------------------- |
204| HTTP `Cache-Control: max-age` | Integer seconds | The most widely deployed freshness hint in web infrastructure |
205| DNS TTL | Integer seconds | Controls how long resolvers cache DNS records |
206| GraphQL `@cacheControl` | `maxAge` integer secs | Per-field cache hints in GraphQL responses |
207| gRPC `grpc-retry-pushback-ms` | Milliseconds | Server-provided retry hint (different use case, similar pattern) |
202| System | Mechanism | Notes |
203| - | - | - |
204| HTTP `Cache-Control: max-age` | Integer seconds | The most widely deployed freshness hint in web infrastructure |
205| DNS TTL | Integer seconds | Controls how long resolvers cache DNS records |
206| GraphQL `@cacheControl` | `maxAge` integer secs | Per-field cache hints in GraphQL responses |
207| gRPC `grpc-retry-pushback-ms` | Milliseconds | Server-provided retry hint (different use case, similar pattern) |
208208
209209### Why not use HTTP caching directly?
210210
seps/2567-sessionless-mcp Changed · +27 / -27 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ------------------------------------------------------------------------------- |
25| **SEP** | 2567 |
26| **Title** | Sessionless MCP via Explicit State Handles |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-03-11 |
30| **Author(s)** | Peter Alexander ([@pja-ant](https://github.com/pja-ant)) |
31| **Sponsor** | Peter Alexander ([@pja-ant](https://github.com/pja-ant)) |
32| **PR** | [#2567](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2567) |
23| Field | Value |
24| - | - |
25| **SEP** | 2567 |
26| **Title** | Sessionless MCP via Explicit State Handles |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-03-11 |
30| **Author(s)** | Peter Alexander ([@pja-ant](https://github.com/pja-ant)) |
31| **Sponsor** | Peter Alexander ([@pja-ant](https://github.com/pja-ant)) |
32| **PR** | [#2567](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2567) |
3333
3434***
3535
from line 103
103103
104104No session boundary satisfies both:
105105
106| Session model | Cart (want: shared) | Browser (want: isolated) |
107| ------------------------ | :-----------------: | :----------------------: |
108| Subagents share parent's | ✓ shared | ✗ shared (clobbers) |
109| Subagents get their own | ✗ isolated | ✓ isolated |
106| Session model | Cart (want: shared) | Browser (want: isolated) |
107| - | :-: | :-: |
108| Subagents share parent's | ✓ shared | ✗ shared (clobbers) |
109| Subagents get their own | ✗ isolated | ✓ isolated |
110110
111111With explicit IDs the orchestrator calls `create_basket()` once, passes the resulting `basket_id` to each subagent, and each subagent separately calls `create_browser()` for its own `browser_id`. The model decides what is shared and what is isolated per piece of state, rather than having one scope imposed on everything.
112112
from line 156
156156
157157Nothing here is a protocol extension: `basket_id` is an ordinary string field in `structuredContent` and an ordinary string argument to subsequent tools. This pattern is already the norm in widely-deployed remote MCP servers that manage durable resources:
158158
159| Server (official, remote) | Create tool → returned ID | Operate tools taking that ID |
160| ----------------------------------------------------------- | --------------------------------- | ---------------------------------------------------------------- |
161| [Linear](https://linear.app/docs/mcp) | `create_issue` → issue id | `get_issue`, `update_issue`, `create_comment` |
162| [Notion](https://developers.notion.com/docs/mcp) | `notion-create-pages` → page id | `notion-update-page`, `notion-move-pages` |
159| Server (official, remote) | Create tool → returned ID | Operate tools taking that ID |
160| - | - | - |
161| [Linear](https://linear.app/docs/mcp) | `create_issue` → issue id | `get_issue`, `update_issue`, `create_comment` |
162| [Notion](https://developers.notion.com/docs/mcp) | `notion-create-pages` → page id | `notion-update-page`, `notion-move-pages` |
163163| [GitHub](https://github.com/github/github-mcp-server#tools) | `create_pull_request` → PR number | `pull_request_read`, `update_pull_request`, `merge_pull_request` |
164| [Stripe](https://docs.stripe.com/mcp) | `create_customer` → customer id | `create_invoice`, `list_subscriptions` |
164| [Stripe](https://docs.stripe.com/mcp) | `create_customer` → customer id | `create_invoice`, `list_subscriptions` |
165165
166166The approach can be adopted for less-persistent objects (a browser context, an in-progress cart) by giving the created object a limited lifetime, and/or limiting its discoverability to the principal that created it. The server owns the state, the client holds a name for it, and authorization is checked on every call.
167167
from line 246
246246
247247An automated survey of a 1000-repo random sample of open source MCP servers (classified by per-repo LLM analysis) found:
248248
249| Category | Share | Migration |
250| ------------------------------------------------------------- | ----: | ---------------------------------------------------- |
251| No application-level reference to MCP session ID | 90.0% | None |
252| `Map<sessionId, Transport>` routing (TS SDK boilerplate) | 3.5% | Removed by a sessionless SDK transport |
253| Transport setup only (`sessionIdGenerator`, never read) | 2.8% | Delete one constructor option |
254| **Session-keyed application state** | 2.5% | Migrate to explicit handles or auth principal |
255| **Proxy / gateway sticky routing** | 0.7% | Needs designed replacement |
256| **Auth binding** (JWT claims, PKCE verifier keyed on session) | 0.5% | Replace with server-generated nonce or token subject |
249| Category | Share | Migration |
250| - | -: | - |
251| No application-level reference to MCP session ID | 90.0% | None |
252| `Map<sessionId, Transport>` routing (TS SDK boilerplate) | 3.5% | Removed by a sessionless SDK transport |
253| Transport setup only (`sessionIdGenerator`, never read) | 2.8% | Delete one constructor option |
254| **Session-keyed application state** | 2.5% | Migrate to explicit handles or auth principal |
255| **Proxy / gateway sticky routing** | 0.7% | Needs designed replacement |
256| **Auth binding** (JWT claims, PKCE verifier keyed on session) | 0.5% | Replace with server-generated nonce or token subject |
257257
258258The bolded rows are the repos that use the session ID for application semantics. The hardest-hit category — gateways that spawn one upstream per session — needs a designed replacement rather than a mechanical edit; see [Backward Compatibility](#backward-compatibility).
259259
seps/2575-stateless-mcp Changed · +9 / -9 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
25| **SEP** | 2575 |
26| **Title** | Make MCP Stateless |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2025-06-18 |
23| Field | Value |
24| - | - |
25| **SEP** | 2575 |
26| **Title** | Make MCP Stateless |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2025-06-18 |
3030| **Author(s)** | Jonathan Hefner ([@jonathanhefner](https://github.com/jonathanhefner)), Mark Roth ([@markdroth](https://github.com/markdroth)), Shaun Smith ([@evalstate](https://github.com/evalstate)), Harvey Tuch ([@htuch](https://github.com/htuch)), Kurtis Van Gent ([@kurtisvg](https://github.com/kurtisvg)) |
31| **Sponsor** | Kurtis Van Gent ([@kurtisvg](https://github.com/kurtisvg)) |
32| **PR** | [#2575](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2575) |
31| **Sponsor** | Kurtis Van Gent ([@kurtisvg](https://github.com/kurtisvg)) |
32| **PR** | [#2575](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2575) |
3333
3434***
3535
seps/2577-deprecate-roots-sampling-and-logging Changed · +42 / -42 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ------------------------------------------------------------------------------- |
25| **SEP** | 2577 |
26| **Title** | Deprecate Roots, Sampling, and Logging |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-04-14 |
30| **Author(s)** | Kurtis Van Gent ([@kurtisvg](https://github.com/kurtisvg)) |
31| **Sponsor** | [@kurtisvg](https://github.com/kurtisvg) |
32| **PR** | [#2577](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577) |
23| Field | Value |
24| - | - |
25| **SEP** | 2577 |
26| **Title** | Deprecate Roots, Sampling, and Logging |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2026-04-14 |
30| **Author(s)** | Kurtis Van Gent ([@kurtisvg](https://github.com/kurtisvg)) |
31| **Sponsor** | [@kurtisvg](https://github.com/kurtisvg) |
32| **PR** | [#2577](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577) |
3333
3434***
3535
from line 131
131131
132132#### Deprecated capabilities
133133
134| Capability | Location |
135| -------------------------------------------- | -------------------------------------- |
136| `ClientCapabilities.roots` | Client capability for listing roots |
137| `ClientCapabilities.sampling` | Client capability for LLM sampling |
134| Capability | Location |
135| - | - |
136| `ClientCapabilities.roots` | Client capability for listing roots |
137| `ClientCapabilities.sampling` | Client capability for LLM sampling |
138138| `ClientCapabilities.tasks.requests.sampling` | Task-augmented sampling sub-capability |
139| `ServerCapabilities.logging` | Server capability for log messages |
139| `ServerCapabilities.logging` | Server capability for log messages |
140140
141141#### Deprecated types — Roots
142142
143| Type | Description |
144| ------------------------------ | ----------------------------------------- |
145| `Root` | Represents a root directory or file |
146| `ListRootsRequest` | Server-to-client request for `roots/list` |
147| `ListRootsResult` | Result containing roots array |
148| `ListRootsResultResponse` | JSON-RPC response wrapper |
149| `RootsListChangedNotification` | Client notification when roots change |
143| Type | Description |
144| - | - |
145| `Root` | Represents a root directory or file |
146| `ListRootsRequest` | Server-to-client request for `roots/list` |
147| `ListRootsResult` | Result containing roots array |
148| `ListRootsResultResponse` | JSON-RPC response wrapper |
149| `RootsListChangedNotification` | Client notification when roots change |
150150
151151#### Deprecated types — Sampling
152152
153| Type | Description |
154| ----------------------------- | ---------------------------------------------- |
155| `CreateMessageRequestParams` | Parameters for `sampling/createMessage` |
156| `CreateMessageRequest` | Server-to-client request for sampling |
157| `CreateMessageResult` | Result from a sampling request |
158| `CreateMessageResultResponse` | JSON-RPC response wrapper |
159| `SamplingMessage` | A message in a sampling conversation |
160| `SamplingMessageContentBlock` | Content block union for sampling messages |
161| `ToolChoice` | Controls model tool selection during sampling |
162| `ToolUseContent` | Tool use content block in sampling messages |
163| `ToolResultContent` | Tool result content block in sampling messages |
164| `ModelPreferences` | Server preferences for model selection |
165| `ModelHint` | Hints for model selection |
153| Type | Description |
154| - | - |
155| `CreateMessageRequestParams` | Parameters for `sampling/createMessage` |
156| `CreateMessageRequest` | Server-to-client request for sampling |
157| `CreateMessageResult` | Result from a sampling request |
158| `CreateMessageResultResponse` | JSON-RPC response wrapper |
159| `SamplingMessage` | A message in a sampling conversation |
160| `SamplingMessageContentBlock` | Content block union for sampling messages |
161| `ToolChoice` | Controls model tool selection during sampling |
162| `ToolUseContent` | Tool use content block in sampling messages |
163| `ToolResultContent` | Tool result content block in sampling messages |
164| `ModelPreferences` | Server preferences for model selection |
165| `ModelHint` | Hints for model selection |
166166
167167#### Deprecated types — Logging
168168
169| Type | Description |
170| ---------------------------------- | --------------------------------------- |
171| `LoggingLevel` | Syslog severity level enum |
172| `SetLevelRequestParams` | Parameters for `logging/setLevel` |
173| `SetLevelRequest` | Client-to-server request to set level |
174| `SetLevelResultResponse` | JSON-RPC response wrapper |
169| Type | Description |
170| - | - |
171| `LoggingLevel` | Syslog severity level enum |
172| `SetLevelRequestParams` | Parameters for `logging/setLevel` |
173| `SetLevelRequest` | Client-to-server request to set level |
174| `SetLevelResultResponse` | JSON-RPC response wrapper |
175175| `LoggingMessageNotificationParams` | Parameters for log message notification |
176| `LoggingMessageNotification` | Server-to-client log message |
176| `LoggingMessageNotification` | Server-to-client log message |
177177
178178#### Annotation format
179179
seps/2596-spec-feature-lifecycle-and-deprecation Changed · +27 / -27 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ------------------------------------------------------------------------------- |
25| **SEP** | 2596 |
26| **Title** | Specification Feature Lifecycle and Deprecation Policy |
27| **Status** | Final |
28| **Type** | Process |
29| **Created** | 2026-04-17 |
30| **Author(s)** | Den Delimarsky ([@localden](https://github.com/localden)) |
31| **Sponsor** | [@localden](https://github.com/localden) |
32| **PR** | [#2596](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2596) |
23| Field | Value |
24| - | - |
25| **SEP** | 2596 |
26| **Title** | Specification Feature Lifecycle and Deprecation Policy |
27| **Status** | Final |
28| **Type** | Process |
29| **Created** | 2026-04-17 |
30| **Author(s)** | Den Delimarsky ([@localden](https://github.com/localden)) |
31| **Sponsor** | [@localden](https://github.com/localden) |
32| **PR** | [#2596](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2596) |
3333
3434***
3535
from line 90
9090
9191A specification feature is in exactly one of three states:
9292
93| State | Meaning | Implementer expectation |
94| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
95| **Active** | The feature is part of the Current specification revision with no planned removal. | Implement per the feature's normative requirements. |
96| **Deprecated** | The feature remains in the specification but is scheduled for removal. A migration path is documented (see below). | New implementations SHOULD NOT adopt the feature. Existing implementations SHOULD migrate before the earliest removal date. |
97| **Removed** | The feature has been deleted from `draft` and will be absent from the next Current revision. It remains documented in the Final revision it last appeared in. | Implementations targeting that next Current revision MUST NOT depend on the feature. |
93| State | Meaning | Implementer expectation |
94| - | - | - |
95| **Active** | The feature is part of the Current specification revision with no planned removal. | Implement per the feature's normative requirements. |
96| **Deprecated** | The feature remains in the specification but is scheduled for removal. A migration path is documented (see below). | New implementations SHOULD NOT adopt the feature. Existing implementations SHOULD migrate before the earliest removal date. |
97| **Removed** | The feature has been deleted from `draft` and will be absent from the next Current revision. It remains documented in the Final revision it last appeared in. | Implementations targeting that next Current revision MUST NOT depend on the feature. |
9898
9999The term "soft-deprecated" is retired. Existing uses in the specification are reclassified as
100100Deprecated under this policy (see [Transition](#transition)).
from line 223
223223
224224### Roles
225225
226| Action | Who |
227| ---------------------------------------------- | ----------------------------------------------------------------------------- |
228| Propose deprecation, extension, or restoration | Any contributor, per the SEP process |
229| Sponsor | A Maintainer or Core Maintainer, per the SEP process |
230| Approve a deprecation SEP | Core Maintainers, per the [governance decision process][governance-decisions] |
231| Decide a removal during release preparation | Core Maintainers, per the [governance decision process][governance-decisions] |
232| Approve an extension or restoration SEP | Core Maintainers, per the [governance decision process][governance-decisions] |
233| Approve expedited removal | Core Maintainers, per the [governance decision process][governance-decisions] |
226| Action | Who |
227| - | - |
228| Propose deprecation, extension, or restoration | Any contributor, per the SEP process |
229| Sponsor | A Maintainer or Core Maintainer, per the SEP process |
230| Approve a deprecation SEP | Core Maintainers, per the [governance decision process][governance-decisions] |
231| Decide a removal during release preparation | Core Maintainers, per the [governance decision process][governance-decisions] |
232| Approve an extension or restoration SEP | Core Maintainers, per the [governance decision process][governance-decisions] |
233| Approve expedited removal | Core Maintainers, per the [governance decision process][governance-decisions] |
234234
235235As with all Core Maintainer decisions, Lead Maintainers retain veto authority over each of the
236236approvals above, per the [governance roles][governance-roles] definition.
from line 254
254254permissible window. Removal still follows [Removing a feature](#removing-a-feature): a Core
255255Maintainer decision at release preparation, not an automatic event when the grace period ends.
256256
257| Feature | Migration target | Earliest removal |
258| ----------------------------------------------- | ------------------------------------ | --------------------------------------- |
259| HTTP+SSE transport | [Streamable HTTP][transports-compat] | Three months after this SEP is Final |
260| `includeContext: "thisServer"` / `"allServers"` | Omit the field or use `"none"` | Follows Sampling ([SEP-2577][sep-2577]) |
257| Feature | Migration target | Earliest removal |
258| - | - | - |
259| HTTP+SSE transport | [Streamable HTTP][transports-compat] | Three months after this SEP is Final |
260| `includeContext: "thisServer"` / `"allServers"` | Omit the field or use `"none"` | Follows Sampling ([SEP-2577][sep-2577]) |
261261
262262`includeContext` is a parameter of `sampling/createMessage`. [SEP-2577][sep-2577] deprecates the
263263Sampling feature as a whole; the two affected `includeContext` values follow that feature's
seps/2640-skills-extension Changed · +31 / -31 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
25| **SEP** | 2640 |
26| **Title** | Skills Extension |
27| **Status** | Final |
28| **Type** | Extensions Track |
29| **Created** | 2026-04-23 |
23| Field | Value |
24| - | - |
25| **SEP** | 2640 |
26| **Title** | Skills Extension |
27| **Status** | Final |
28| **Type** | Extensions Track |
29| **Created** | 2026-04-23 |
3030| **Author(s)** | Peter Alexander ([@pja-ant](https://github.com/pja-ant)), Ola Hungerford ([@olaservo](https://github.com/olaservo)), Sambhav Kothari ([@sambhav](https://github.com/sambhav)), Aditya Kumar ([@aditya-scio](https://github.com/aditya-scio)), on behalf of the Skills Over MCP Working Group |
31| **Sponsor** | [@pja-ant](https://github.com/pja-ant) |
32| **PR** | [#2640](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2640) |
31| **Sponsor** | [@pja-ant](https://github.com/pja-ant) |
32| **PR** | [#2640](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2640) |
3333
3434***
3535
from line 94
9494
9595#### Examples
9696
97| Skill path | File | Resource URI |
98| ---------------------- | --------------------- | ------------------------------------------------ |
99| `git-workflow` | `SKILL.md` | `skill://git-workflow/SKILL.md` |
100| `pdf-processing` | `references/FORMS.md` | `skill://pdf-processing/references/FORMS.md` |
101| `pdf-processing` | `scripts/extract.py` | `skill://pdf-processing/scripts/extract.py` |
102| `acme/billing/refunds` | `SKILL.md` | `skill://acme/billing/refunds/SKILL.md` |
103| `acme/billing/refunds` | `examples/email.md` | `skill://acme/billing/refunds/examples/email.md` |
97| Skill path | File | Resource URI |
98| - | - | - |
99| `git-workflow` | `SKILL.md` | `skill://git-workflow/SKILL.md` |
100| `pdf-processing` | `references/FORMS.md` | `skill://pdf-processing/references/FORMS.md` |
101| `pdf-processing` | `scripts/extract.py` | `skill://pdf-processing/scripts/extract.py` |
102| `acme/billing/refunds` | `SKILL.md` | `skill://acme/billing/refunds/SKILL.md` |
103| `acme/billing/refunds` | `examples/email.md` | `skill://acme/billing/refunds/examples/email.md` |
104104
105105#### Resource Metadata
106106
from line 231
231231
232232Result fields:
233233
234| Field | Required | Description |
235| ----------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------- |
236| `skills` | Yes | Array of skill entries. |
237| `skills[].frontmatter` | Yes | Verbatim copy of the skill's `SKILL.md` YAML frontmatter, rendered as JSON. See [Frontmatter](#frontmatter). |
238| `skills[].uri` | Yes | Resource URI of the skill's `SKILL.md`. See [Skill URIs](#skill-uris). |
239| `skills[].resources` | Yes | The skill's files: an array enumerating them with digests and sizes, or the string `"dynamic"`. See [Resources](#resources). |
240| `skills[].resources[].uri` | Yes | Resource URI of the file. |
241| `skills[].resources[].digest` | Yes | SHA-256 digest of the file. See [Integrity](#integrity-and-verification). |
242| `skills[].resources[].size` | Yes | Length in bytes of the file's raw content. See [Limits](#limits). |
234| Field | Required | Description |
235| - | - | - |
236| `skills` | Yes | Array of skill entries. |
237| `skills[].frontmatter` | Yes | Verbatim copy of the skill's `SKILL.md` YAML frontmatter, rendered as JSON. See [Frontmatter](#frontmatter). |
238| `skills[].uri` | Yes | Resource URI of the skill's `SKILL.md`. See [Skill URIs](#skill-uris). |
239| `skills[].resources` | Yes | The skill's files: an array enumerating them with digests and sizes, or the string `"dynamic"`. See [Resources](#resources). |
240| `skills[].resources[].uri` | Yes | Resource URI of the file. |
241| `skills[].resources[].digest` | Yes | SHA-256 digest of the file. See [Integrity](#integrity-and-verification). |
242| `skills[].resources[].size` | Yes | Length in bytes of the file's raw content. See [Limits](#limits). |
243243
244244A skill whose content is generated dynamically carries `"resources": "dynamic"` in place of the array. An entry with no `resources` at all is invalid.
245245
from line 291
291291
292292This extension fixes two per-skill limits so that servers know what every conforming host will accept and hosts know what they must be prepared to handle:
293293
294| Limit | Value | Counted over |
295| ------------------------- | ------------------------- | ----------------------------------------------------------- |
296| Resources per skill | 512 entries | The entries of the skill's `resources`, `SKILL.md` included |
297| Total file size per skill | 16 MiB (16,777,216 bytes) | The sum of `size` over the skill's `resources` |
294| Limit | Value | Counted over |
295| - | - | - |
296| Resources per skill | 512 entries | The entries of the skill's `resources`, `SKILL.md` included |
297| Total file size per skill | 16 MiB (16,777,216 bytes) | The sum of `size` over the skill's `resources` |
298298
299299Hosts MUST support skills up to and including these limits, and MAY support larger ones. Servers SHOULD NOT serve a skill that exceeds either limit; a skill that does is not guaranteed to be loadable by any conforming host. Because `resources` is complete, both limits are checkable from the entry alone, by counting entries and summing `size`, before the host retrieves a single file, and a host that declines a skill on this basis SHOULD tell the user why rather than fail silently on a later read.
300300
from line 401
401401
402402One extension-specific setting is defined:
403403
404| Setting | Type | Default | Meaning |
405| --------------- | ------- | ------- | ----------------------------------------------------------------------- |
404| Setting | Type | Default | Meaning |
405| - | - | - | - |
406406| `directoryRead` | boolean | `false` | The server implements [`resources/directory/read`](#directory-listing). |
407407
408408An empty object indicates support for the extension with no optional features. Declaring the extension itself commits the server to [`skills/list`](#enumeration-via-skillslist) and [`skills/get`](#retrieval-via-skillsget); clients MUST NOT call `resources/directory/read` against a server that has not declared `directoryRead: true`. A server declaring this extension MUST also declare the `resources` capability.
seps/2663-tasks-extension Changed · +13 / -13 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
25| **SEP** | 2663 |
26| **Title** | Tasks Extension |
27| **Status** | Final |
28| **Type** | Extensions Track |
29| **Created** | 2026-04-27 |
23| Field | Value |
24| - | - |
25| **SEP** | 2663 |
26| **Title** | Tasks Extension |
27| **Status** | Final |
28| **Type** | Extensions Track |
29| **Created** | 2026-04-27 |
3030| **Author(s)** | Luca Chang ([@LucaButBoring](https://github.com/LucaButBoring)), Caitie McCaffrey ([@CaitieM20](https://github.com/CaitieM20)); on behalf of the Agents Working Group |
31| **Sponsor** | Caitie McCaffrey ([@CaitieM20](https://github.com/CaitieM20)) |
32| **PR** | [#2663](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2663) |
31| **Sponsor** | Caitie McCaffrey ([@CaitieM20](https://github.com/CaitieM20)) |
32| **PR** | [#2663](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2663) |
3333
3434***
3535
from line 968
968968
969969The experimental tasks feature in the `2025-11-25` release is **not wire-compatible** with this extension. Implementations that need to interoperate with both surfaces can shim at the SDK level by implementing the experimental and extension flows in parallel and dispatching on the negotiated protocol version and the client capability the peer declared. The following table summarizes the expected behavior for each permutation:
970970
971| Protocol Version | `tasks.*` (legacy) | `io.modelcontextprotocol/tasks` |
972| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
973| `2025-11-25` | Legacy experimental tasks per the `2025-11-25` specification. The client opts into task augmentation per request via the `task` parameter on `CallToolRequest`; the server uses `tasks/result`, `tasks/get`, `tasks/cancel`, and (where supported) `tasks/list` per that specification. This extension does not apply. | This extension is not defined under the `2025-11-25` protocol version. Servers **MUST NOT** treat this capability as enabling tasks under that protocol version; requests proceed as if the client had declared no task capability at all. |
974| `2026-06-30` | The legacy capability is not part of this extension. Servers **MUST** treat clients declaring only the legacy capability as non-declaring with respect to this extension. Servers that simultaneously support the `2025-11-25` Tasks specification alongside this extension **SHOULD** continue to permit `tasks/get` and `tasks/cancel` requests from such clients to operate on tasks created under that flow. | The canonical case. Full task lifecycle as specified in this document, with the following wire-level differences from the `2025-11-25` experimental feature:<ul><li>`tasks/result` is removed; clients calling it **MUST** receive `-32601` (Method Not Found).</li><li>The `task` parameter on `CallToolRequest` is removed; servers **MUST** ignore it (treat the field as unknown) rather than using it as an opt-in.</li><li>The `tasks.requests.*`, `tasks.cancel`, and `tasks.list` capability declarations are not part of this extension. Servers that previously advertised these **MUST** migrate to declaring `io.modelcontextprotocol/tasks`, and **MUST NOT** continue to advertise the legacy capabilities under any protocol version that includes this extension.</li></ul> |
971| Protocol Version | `tasks.*` (legacy) | `io.modelcontextprotocol/tasks` |
972| - | - | - |
973| `2025-11-25` | Legacy experimental tasks per the `2025-11-25` specification. The client opts into task augmentation per request via the `task` parameter on `CallToolRequest`; the server uses `tasks/result`, `tasks/get`, `tasks/cancel`, and (where supported) `tasks/list` per that specification. This extension does not apply. | This extension is not defined under the `2025-11-25` protocol version. Servers **MUST NOT** treat this capability as enabling tasks under that protocol version; requests proceed as if the client had declared no task capability at all. |
974| `2026-06-30` | The legacy capability is not part of this extension. Servers **MUST** treat clients declaring only the legacy capability as non-declaring with respect to this extension. Servers that simultaneously support the `2025-11-25` Tasks specification alongside this extension **SHOULD** continue to permit `tasks/get` and `tasks/cancel` requests from such clients to operate on tasks created under that flow. | The canonical case. Full task lifecycle as specified in this document, with the following wire-level differences from the `2025-11-25` experimental feature:<ul><li>`tasks/result` is removed; clients calling it **MUST** receive `-32601` (Method Not Found).</li><li>The `task` parameter on `CallToolRequest` is removed; servers **MUST** ignore it (treat the field as unknown) rather than using it as an opt-in.</li><li>The `tasks.requests.*`, `tasks.cancel`, and `tasks.list` capability declarations are not part of this extension. Servers that previously advertised these **MUST** migrate to declaring `io.modelcontextprotocol/tasks`, and **MUST NOT** continue to advertise the legacy capabilities under any protocol version that includes this extension.</li></ul> |
975975
976976A server that returns the standard `CallToolResult` shape — i.e., never elects to create a task — remains fully spec-compliant under this extension. Clients that have negotiated the extension **MUST** handle both result shapes for any augmented request.
977977
seps/414-request-meta Changed · +10 / -10 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ----------------------------------------------------------------------------- |
25| **SEP** | 414 |
26| **Title** | Document OpenTelemetry Trace Context Propagation Conventions |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2025-04-25 |
30| **Author(s)** | Adrian Cole ([@codefromthecrypt](https://github.com/codefromthecrypt)) |
31| **Sponsor** | Marcelo Trylesinski ([@Kludex](https://github.com/Kludex)) |
32| **PR** | [#414](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/414) |
23| Field | Value |
24| - | - |
25| **SEP** | 414 |
26| **Title** | Document OpenTelemetry Trace Context Propagation Conventions |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2025-04-25 |
30| **Author(s)** | Adrian Cole ([@codefromthecrypt](https://github.com/codefromthecrypt)) |
31| **Sponsor** | Marcelo Trylesinski ([@Kludex](https://github.com/Kludex)) |
32| **PR** | [#414](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/414) |
3333
3434***
3535
seps/932-model-context-protocol-governance Changed · +10 / -10 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ----------------------------------------------------------------------------- |
25| **SEP** | 932 |
26| **Title** | Model Context Protocol Governance |
27| **Status** | Final |
28| **Type** | Process |
29| **Created** | 2025-07-08 |
30| **Author(s)** | David Soria Parra |
31| **Sponsor** | None |
32| **PR** | [#931](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/931) |
23| Field | Value |
24| - | - |
25| **SEP** | 932 |
26| **Title** | Model Context Protocol Governance |
27| **Status** | Final |
28| **Type** | Process |
29| **Created** | 2025-07-08 |
30| **Author(s)** | David Soria Parra |
31| **Sponsor** | None |
32| **PR** | [#931](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/931) |
3333
3434***
3535
seps/973-expose-additional-metadata-for-implementations-res Changed · +10 / -10 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ----------------------------------------------------------------------------- |
25| **SEP** | 973 |
26| **Title** | Expose additional metadata for Implementations, Resources, Tools and Prompts |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2025-07-15 |
30| **Author(s)** | [@jesselumarie](https://github.com/jesselumarie) |
31| **Sponsor** | None |
32| **PR** | [#973](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/973) |
23| Field | Value |
24| - | - |
25| **SEP** | 973 |
26| **Title** | Expose additional metadata for Implementations, Resources, Tools and Prompts |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2025-07-15 |
30| **Author(s)** | [@jesselumarie](https://github.com/jesselumarie) |
31| **Sponsor** | None |
32| **PR** | [#973](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/973) |
3333
3434***
3535
seps/985-align-oauth-20-protected-resource-metadata-with-rf Changed · +10 / -10 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ----------------------------------------------------------------------------- |
25| **SEP** | 985 |
26| **Title** | Align OAuth 2.0 Protected Resource Metadata with RFC 9728 |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2025-07-16 |
30| **Author(s)** | sunishsheth2009 |
31| **Sponsor** | None |
32| **PR** | [#985](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/985) |
23| Field | Value |
24| - | - |
25| **SEP** | 985 |
26| **Title** | Align OAuth 2.0 Protected Resource Metadata with RFC 9728 |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2025-07-16 |
30| **Author(s)** | sunishsheth2009 |
31| **Sponsor** | None |
32| **PR** | [#985](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/985) |
3333
3434***
3535
seps/986-specify-format-for-tool-names Changed · +10 / -10 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ----------------------------------------------------------------------------- |
25| **SEP** | 986 |
26| **Title** | Specify Format for Tool Names |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2025-07-16 |
30| **Author(s)** | kentcdodds |
31| **Sponsor** | None |
32| **PR** | [#986](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/986) |
23| Field | Value |
24| - | - |
25| **SEP** | 986 |
26| **Title** | Specify Format for Tool Names |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2025-07-16 |
30| **Author(s)** | kentcdodds |
31| **Sponsor** | None |
32| **PR** | [#986](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/986) |
3333
3434***
3535
seps/990-enable-enterprise-idp-policy-controls-during-mcp-o Changed · +10 / -10 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ----------------------------------------------------------------------------- |
25| **SEP** | 990 |
26| **Title** | Enable enterprise IdP policy controls during MCP OAuth flows |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2025-06-04 |
30| **Author(s)** | Aaron Parecki ([@aaronpk](https://github.com/aaronpk)) |
31| **Sponsor** | None |
32| **PR** | [#646](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/646) |
23| Field | Value |
24| - | - |
25| **SEP** | 990 |
26| **Title** | Enable enterprise IdP policy controls during MCP OAuth flows |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2025-06-04 |
30| **Author(s)** | Aaron Parecki ([@aaronpk](https://github.com/aaronpk)) |
31| **Sponsor** | None |
32| **PR** | [#646](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/646) |
3333
3434***
3535
seps/991-enable-url-based-client-registration-using-oauth-c Changed · +9 / -9 lines
from line 20
2020 requirements.
2121</Note>
2222
23| Field | Value |
24| ------------- | ----------------------------------------------------------------------------------------------------------------- |
25| **SEP** | 991 |
26| **Title** | Enable URL-based Client Registration using OAuth Client ID Metadata Documents |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2025-07-07 |
23| Field | Value |
24| - | - |
25| **SEP** | 991 |
26| **Title** | Enable URL-based Client Registration using OAuth Client ID Metadata Documents |
27| **Status** | Final |
28| **Type** | Standards Track |
29| **Created** | 2025-07-07 |
3030| **Author(s)** | Paul Carleton ([@pcarleton](https://github.com/pcarleton)) Aaron Parecki ([@aaronpk](https://github.com/aaronpk)) |
31| **Sponsor** | None |
32| **PR** | [#991](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/991) |
31| **Sponsor** | None |
32| **PR** | [#991](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/991) |
3333
3434***
3535