SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP - #655

Merged
localden merged 76 commits into
modelcontextprotocol:mainfrom
olaservo:clarify-json-schema-version
Nov 14, 2025
Merged

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP#655
localden merged 76 commits into
modelcontextprotocol:mainfrom
olaservo:clarify-json-schema-version

Conversation

@olaservo

@olaservoolaservo commented Jun 5, 2025

Copy link
Copy Markdown
Member

This PR implements SEP-1613, which establishes JSON Schema 2020-12 as the default dialect for embedded schemas within MCP messages.

Summary

Clarifies JSON Schema dialect usage for embedded schemas within MCP messages by establishing 2020-12 as the default dialect and allowing explicit dialect declaration via the $schema field.

Changes

  • Updates specification documentation to specify JSON Schema 2020-12 as default
  • Adds guidance on explicit $schema field usage for alternative dialects
  • Clarifies schema validation requirements for tools with no parameters
  • Updates generated JSON schema files to declare 2020-12 as their meta-schema (patching in the schema generation script since typescript-json-schema only supports draft-07)

Historical Context

Related Issues


Checklist

@jba

jba commented Jun 5, 2025

Copy link
Copy Markdown

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)?
I think it should be the latter.

Comment threaddocs/specification/draft/basic/index.mdx Outdated
Comment threaddocs/specification/draft/basic/index.mdx Outdated
@jviotti

jviotti commented Jun 5, 2025

Copy link
Copy Markdown
Contributor

Awesome! I made a couple little suggestions, but looks pretty good otherwise 💪🏻

@jviotti

Copy link
Copy Markdown
Contributor

This is a good point from @jba though (maybe as a separate PR?)

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)?I think it should be the latter

Maybe better to default to 2020-12 but still suggest support for previous versions in case some users need it?

olaservoand others added 2 commits June 5, 2025 09:15
Co-authored-by: Juan Cruz Viotti <jv@jviotti.com>
@olaservo
olaservo requested a review from evalstateJune 5, 2025 16:20
@olaservo

Copy link
Copy Markdown
MemberAuthor

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)? I think it should be the latter.

Using draft-07 as default came from the original discussion where @jviotti recommended this approach. Since that was a general suggestion based on general tooling support, we still need to take into account MCP implementers' pending feedback on what would make the most sense to reduce the most schema validation challenges.

@mikekistler

Copy link
Copy Markdown

In case it benefits anyone else, I'll share this (AI generated) comparison of JSON Schema Draft-7 and Draft-2020-12:

Major Structural Changes

Draft-07 used a single monolithic specification document, while Draft 2020-12 split into modular specifications:

  • Core vocabulary
  • Validation vocabulary
  • Meta-data vocabulary
  • Format assertion vocabulary

Key New Features in Draft 2020-12

Vocabulary System: Introduced a formal vocabulary system allowing custom vocabularies and better extensibility. You can now define which vocabularies your schema uses via $vocabulary.

New Keywords:

  • unevaluatedProperties and unevaluatedItems - Handle properties/items not covered by other schema keywords
  • dependentSchemas and dependentRequired - Replace and expand on Draft-07's dependencies
  • maxContains and minContains - Provide bounds for contains validation
  • prefixItems - Validates array items by position (replaces positional array validation pattern)

Enhanced Conditionals: if/then/else logic works more intuitively with the new unevaluated keywords.

Breaking Changes

Dependencies Restructure: Draft-07's dependencies keyword is split into dependentSchemas and dependentRequired with slightly different semantics.

Array Validation: The way positional array validation works changed significantly with prefixItems replacing the old tuple validation pattern.

Format Behavior: Format validation became vocabulary-dependent rather than implementation-dependent.

Backward Compatibility

Schemas using only basic Draft-07 features will generally work, but schemas using dependencies or complex array validation patterns need updates. The meta-schema identifier changed from http://json-schema.org/draft-07/schema# to https://json-schema.org/draft/2020-12/schema.

Adoption Considerations

Draft 2020-12 offers more powerful validation capabilities and better composability, but Draft-07 still has broader tooling support across languages and platforms. Consider your ecosystem's library support when choosing between versions.

Comment threaddocs/specification/draft/basic/index.mdx Outdated
…no parameters more flexible
- Replace restrictive 'use true for tools with no parameters' guidance
- Provide multiple valid options: true, {}, {type: object}, etc.
- Include example showing how tools can use additional schema keywords
- Addresses comment about recommendation being too restrictive for tools
that may want to include other keywords beyond properties/required
@Kludex

Copy link
Copy Markdown
Member

To make it easier for implementers, I do think it makes more sense to use 2020-12.

Pydantic (the data parsing library we use in the Python SDK) will by default use the version 2020-12 when converting to JSON. Having worked for a long time in the FastAPI ecosystem (which leverages the OpenAPI schema), and the amount of issues that were created because of draft-07, I would suggest we actually use the latest version of the spec by default.

Also, it does add a lot of work to comply to another version.

- Follows the [JSON Schema usage guidelines](/specification/draft/basic#json-schema-usage)
- Defaults to 2020-12 if no `$schema` field is present
- **MUST** be a valid JSON Schema object (not `null`)
- For tools with no parameters, use one of these valid approaches:

@olaservoolaservoNov 13, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We chatted about whether this guidance is really needed here, since technically the schema for MCP already says that it has to be an object.

However, the original GitHub discussions showed widespread confusion around this, especially since JSON Schema 2020-12 would allow boolean schemas like true for no-parameter cases, but MCP requires an object. Given this is an MCP-specific restriction, it seems worth calling out explicitly in the spec verbiage.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dsp-ant I left this extra explanation in, but didn't add anything explicit for other schemas (such as output schemas) because this seemed to be the main need for extra clarification.

localden
localden previously approved these changes Nov 14, 2025

@localdenlocalden left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM for spec release.

- `title`: Optional human-readable name of the tool for display purposes.
- `description`: Human-readable description of functionality
- `inputSchema`: JSON Schema defining expected parameters
- Follows the [JSON Schema usage guidelines](/specification/draft/basic#json-schema-usage)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this link point to /draft/ now and be edited later to point to /2025-11-24/? How are such links being handled in general?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, do you think its better not to link directly here?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like @jonathanhefner might have ideas or thoughts on this? :)

cliffhall
cliffhall previously approved these changes Nov 14, 2025

@cliffhallcliffhall left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 👍

@olaservo
olaservo dismissed stale reviews from cliffhall and localden via 0aae433November 14, 2025 23:00
@localden
localden merged commit 8ad0ac7 into modelcontextprotocol:mainNov 14, 2025
2 checks passed
panyam added a commit to panyam/mcpkit that referenced this pull request May 23, 2026
…heck counts
Two upstream specReferences[].url strings in modelcontextprotocol/conformance
point at files that no longer exist (verified curl 404):
- SEP-986 cites SEP/SEP-986.md in the modelcontextprotocol repo; that path
was removed when the SEP was merged into the spec. Now linking to the
spec page itself at specification/draft/server/tools.
- SEP-990-Enterprise-Managed-OAuth cites enterprise-oauth.mdx in ext-auth;
the actual file is enterprise-managed-authorization.mdx. Now linking to
the correct file.
Added a SPEC_URL_OVERRIDES map in scripts/conformance-audit-report.ts so we
keep tracking these locally until upstream's source is fixed. Each entry
documents why and which upstream file holds the stale string. Drop entries
as upstream fixes its references.
Also: spell out the check-count column. 14P / 2F / 28I becomes
14 pass / 2 fail / 28 info — one column wider per row but no decoder ring
needed when scanning the By SEP table.
Snapshot regenerated. All URLs in the report now return 200 (one stays
at 301: github.com/modelcontextprotocol/modelcontextprotocol/pull/655 redirects
to the renamed modelcontextprotocol/modelcontextprotocol repo, harmless).
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: In Review

Development

Successfully merging this pull request may close these issues.

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP

16 participants

@olaservo@jba@jviotti@mikekistler@Kludex@samthanawalla@localden@jokemanfire@pcarleton@cliffhall@evalstate@eiriktsarpalis@jpmcb@paoloricciuti@dsp-ant@bhosmer-ant
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP - #655

Merged
localden merged 76 commits into
modelcontextprotocol:mainfrom
olaservo:clarify-json-schema-version
Nov 14, 2025
Merged

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP#655
localden merged 76 commits into
modelcontextprotocol:mainfrom
olaservo:clarify-json-schema-version

Conversation

@olaservo

@olaservoolaservo commented Jun 5, 2025

Copy link
Copy Markdown
Member

This PR implements SEP-1613, which establishes JSON Schema 2020-12 as the default dialect for embedded schemas within MCP messages.

Summary

Clarifies JSON Schema dialect usage for embedded schemas within MCP messages by establishing 2020-12 as the default dialect and allowing explicit dialect declaration via the $schema field.

Changes

  • Updates specification documentation to specify JSON Schema 2020-12 as default
  • Adds guidance on explicit $schema field usage for alternative dialects
  • Clarifies schema validation requirements for tools with no parameters
  • Updates generated JSON schema files to declare 2020-12 as their meta-schema (patching in the schema generation script since typescript-json-schema only supports draft-07)

Historical Context

Related Issues


Checklist

@jba

jba commented Jun 5, 2025

Copy link
Copy Markdown

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)?
I think it should be the latter.

Comment threaddocs/specification/draft/basic/index.mdx Outdated
Comment threaddocs/specification/draft/basic/index.mdx Outdated
@jviotti

jviotti commented Jun 5, 2025

Copy link
Copy Markdown
Contributor

Awesome! I made a couple little suggestions, but looks pretty good otherwise 💪🏻

@jviotti

Copy link
Copy Markdown
Contributor

This is a good point from @jba though (maybe as a separate PR?)

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)?I think it should be the latter

Maybe better to default to 2020-12 but still suggest support for previous versions in case some users need it?

olaservoand others added 2 commits June 5, 2025 09:15
Co-authored-by: Juan Cruz Viotti <jv@jviotti.com>
@olaservo
olaservo requested a review from evalstateJune 5, 2025 16:20
@olaservo

Copy link
Copy Markdown
MemberAuthor

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)? I think it should be the latter.

Using draft-07 as default came from the original discussion where @jviotti recommended this approach. Since that was a general suggestion based on general tooling support, we still need to take into account MCP implementers' pending feedback on what would make the most sense to reduce the most schema validation challenges.

@mikekistler

Copy link
Copy Markdown

In case it benefits anyone else, I'll share this (AI generated) comparison of JSON Schema Draft-7 and Draft-2020-12:

Major Structural Changes

Draft-07 used a single monolithic specification document, while Draft 2020-12 split into modular specifications:

  • Core vocabulary
  • Validation vocabulary
  • Meta-data vocabulary
  • Format assertion vocabulary

Key New Features in Draft 2020-12

Vocabulary System: Introduced a formal vocabulary system allowing custom vocabularies and better extensibility. You can now define which vocabularies your schema uses via $vocabulary.

New Keywords:

  • unevaluatedProperties and unevaluatedItems - Handle properties/items not covered by other schema keywords
  • dependentSchemas and dependentRequired - Replace and expand on Draft-07's dependencies
  • maxContains and minContains - Provide bounds for contains validation
  • prefixItems - Validates array items by position (replaces positional array validation pattern)

Enhanced Conditionals: if/then/else logic works more intuitively with the new unevaluated keywords.

Breaking Changes

Dependencies Restructure: Draft-07's dependencies keyword is split into dependentSchemas and dependentRequired with slightly different semantics.

Array Validation: The way positional array validation works changed significantly with prefixItems replacing the old tuple validation pattern.

Format Behavior: Format validation became vocabulary-dependent rather than implementation-dependent.

Backward Compatibility

Schemas using only basic Draft-07 features will generally work, but schemas using dependencies or complex array validation patterns need updates. The meta-schema identifier changed from http://json-schema.org/draft-07/schema# to https://json-schema.org/draft/2020-12/schema.

Adoption Considerations

Draft 2020-12 offers more powerful validation capabilities and better composability, but Draft-07 still has broader tooling support across languages and platforms. Consider your ecosystem's library support when choosing between versions.

Comment threaddocs/specification/draft/basic/index.mdx Outdated
…no parameters more flexible
- Replace restrictive 'use true for tools with no parameters' guidance
- Provide multiple valid options: true, {}, {type: object}, etc.
- Include example showing how tools can use additional schema keywords
- Addresses comment about recommendation being too restrictive for tools
that may want to include other keywords beyond properties/required
@Kludex

Copy link
Copy Markdown
Member

To make it easier for implementers, I do think it makes more sense to use 2020-12.

Pydantic (the data parsing library we use in the Python SDK) will by default use the version 2020-12 when converting to JSON. Having worked for a long time in the FastAPI ecosystem (which leverages the OpenAPI schema), and the amount of issues that were created because of draft-07, I would suggest we actually use the latest version of the spec by default.

Also, it does add a lot of work to comply to another version.

- Follows the [JSON Schema usage guidelines](/specification/draft/basic#json-schema-usage)
- Defaults to 2020-12 if no `$schema` field is present
- **MUST** be a valid JSON Schema object (not `null`)
- For tools with no parameters, use one of these valid approaches:

@olaservoolaservoNov 13, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We chatted about whether this guidance is really needed here, since technically the schema for MCP already says that it has to be an object.

However, the original GitHub discussions showed widespread confusion around this, especially since JSON Schema 2020-12 would allow boolean schemas like true for no-parameter cases, but MCP requires an object. Given this is an MCP-specific restriction, it seems worth calling out explicitly in the spec verbiage.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dsp-ant I left this extra explanation in, but didn't add anything explicit for other schemas (such as output schemas) because this seemed to be the main need for extra clarification.

localden
localden previously approved these changes Nov 14, 2025

@localdenlocalden left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM for spec release.

- `title`: Optional human-readable name of the tool for display purposes.
- `description`: Human-readable description of functionality
- `inputSchema`: JSON Schema defining expected parameters
- Follows the [JSON Schema usage guidelines](/specification/draft/basic#json-schema-usage)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this link point to /draft/ now and be edited later to point to /2025-11-24/? How are such links being handled in general?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, do you think its better not to link directly here?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like @jonathanhefner might have ideas or thoughts on this? :)

cliffhall
cliffhall previously approved these changes Nov 14, 2025

@cliffhallcliffhall left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 👍

@olaservo
olaservo dismissed stale reviews from cliffhall and localden via 0aae433November 14, 2025 23:00
@localden
localden merged commit 8ad0ac7 into modelcontextprotocol:mainNov 14, 2025
2 checks passed
panyam added a commit to panyam/mcpkit that referenced this pull request May 23, 2026
…heck counts
Two upstream specReferences[].url strings in modelcontextprotocol/conformance
point at files that no longer exist (verified curl 404):
- SEP-986 cites SEP/SEP-986.md in the modelcontextprotocol repo; that path
was removed when the SEP was merged into the spec. Now linking to the
spec page itself at specification/draft/server/tools.
- SEP-990-Enterprise-Managed-OAuth cites enterprise-oauth.mdx in ext-auth;
the actual file is enterprise-managed-authorization.mdx. Now linking to
the correct file.
Added a SPEC_URL_OVERRIDES map in scripts/conformance-audit-report.ts so we
keep tracking these locally until upstream's source is fixed. Each entry
documents why and which upstream file holds the stale string. Drop entries
as upstream fixes its references.
Also: spell out the check-count column. 14P / 2F / 28I becomes
14 pass / 2 fail / 28 info — one column wider per row but no decoder ring
needed when scanning the By SEP table.
Snapshot regenerated. All URLs in the report now return 200 (one stays
at 301: github.com/modelcontextprotocol/modelcontextprotocol/pull/655 redirects
to the renamed modelcontextprotocol/modelcontextprotocol repo, harmless).
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: In Review

Development

Successfully merging this pull request may close these issues.

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP

16 participants

@olaservo@jba@jviotti@mikekistler@Kludex@samthanawalla@localden@jokemanfire@pcarleton@cliffhall@evalstate@eiriktsarpalis@jpmcb@paoloricciuti@dsp-ant@bhosmer-ant
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP - #655

Merged
localden merged 76 commits into
modelcontextprotocol:mainfrom
olaservo:clarify-json-schema-version
Nov 14, 2025
Merged

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP#655
localden merged 76 commits into
modelcontextprotocol:mainfrom
olaservo:clarify-json-schema-version

Conversation

@olaservo

@olaservoolaservo commented Jun 5, 2025

Copy link
Copy Markdown
Member

This PR implements SEP-1613, which establishes JSON Schema 2020-12 as the default dialect for embedded schemas within MCP messages.

Summary

Clarifies JSON Schema dialect usage for embedded schemas within MCP messages by establishing 2020-12 as the default dialect and allowing explicit dialect declaration via the $schema field.

Changes

  • Updates specification documentation to specify JSON Schema 2020-12 as default
  • Adds guidance on explicit $schema field usage for alternative dialects
  • Clarifies schema validation requirements for tools with no parameters
  • Updates generated JSON schema files to declare 2020-12 as their meta-schema (patching in the schema generation script since typescript-json-schema only supports draft-07)

Historical Context

Related Issues


Checklist

@jba

jba commented Jun 5, 2025

Copy link
Copy Markdown

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)?
I think it should be the latter.

Comment threaddocs/specification/draft/basic/index.mdx Outdated
Comment threaddocs/specification/draft/basic/index.mdx Outdated
@jviotti

jviotti commented Jun 5, 2025

Copy link
Copy Markdown
Contributor

Awesome! I made a couple little suggestions, but looks pretty good otherwise 💪🏻

@jviotti

Copy link
Copy Markdown
Contributor

This is a good point from @jba though (maybe as a separate PR?)

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)?I think it should be the latter

Maybe better to default to 2020-12 but still suggest support for previous versions in case some users need it?

olaservoand others added 2 commits June 5, 2025 09:15
Co-authored-by: Juan Cruz Viotti <jv@jviotti.com>
@olaservo
olaservo requested a review from evalstateJune 5, 2025 16:20
@olaservo

Copy link
Copy Markdown
MemberAuthor

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)? I think it should be the latter.

Using draft-07 as default came from the original discussion where @jviotti recommended this approach. Since that was a general suggestion based on general tooling support, we still need to take into account MCP implementers' pending feedback on what would make the most sense to reduce the most schema validation challenges.

@mikekistler

Copy link
Copy Markdown

In case it benefits anyone else, I'll share this (AI generated) comparison of JSON Schema Draft-7 and Draft-2020-12:

Major Structural Changes

Draft-07 used a single monolithic specification document, while Draft 2020-12 split into modular specifications:

  • Core vocabulary
  • Validation vocabulary
  • Meta-data vocabulary
  • Format assertion vocabulary

Key New Features in Draft 2020-12

Vocabulary System: Introduced a formal vocabulary system allowing custom vocabularies and better extensibility. You can now define which vocabularies your schema uses via $vocabulary.

New Keywords:

  • unevaluatedProperties and unevaluatedItems - Handle properties/items not covered by other schema keywords
  • dependentSchemas and dependentRequired - Replace and expand on Draft-07's dependencies
  • maxContains and minContains - Provide bounds for contains validation
  • prefixItems - Validates array items by position (replaces positional array validation pattern)

Enhanced Conditionals: if/then/else logic works more intuitively with the new unevaluated keywords.

Breaking Changes

Dependencies Restructure: Draft-07's dependencies keyword is split into dependentSchemas and dependentRequired with slightly different semantics.

Array Validation: The way positional array validation works changed significantly with prefixItems replacing the old tuple validation pattern.

Format Behavior: Format validation became vocabulary-dependent rather than implementation-dependent.

Backward Compatibility

Schemas using only basic Draft-07 features will generally work, but schemas using dependencies or complex array validation patterns need updates. The meta-schema identifier changed from http://json-schema.org/draft-07/schema# to https://json-schema.org/draft/2020-12/schema.

Adoption Considerations

Draft 2020-12 offers more powerful validation capabilities and better composability, but Draft-07 still has broader tooling support across languages and platforms. Consider your ecosystem's library support when choosing between versions.

Comment threaddocs/specification/draft/basic/index.mdx Outdated
…no parameters more flexible
- Replace restrictive 'use true for tools with no parameters' guidance
- Provide multiple valid options: true, {}, {type: object}, etc.
- Include example showing how tools can use additional schema keywords
- Addresses comment about recommendation being too restrictive for tools
that may want to include other keywords beyond properties/required
@Kludex

Copy link
Copy Markdown
Member

To make it easier for implementers, I do think it makes more sense to use 2020-12.

Pydantic (the data parsing library we use in the Python SDK) will by default use the version 2020-12 when converting to JSON. Having worked for a long time in the FastAPI ecosystem (which leverages the OpenAPI schema), and the amount of issues that were created because of draft-07, I would suggest we actually use the latest version of the spec by default.

Also, it does add a lot of work to comply to another version.

- Follows the [JSON Schema usage guidelines](/specification/draft/basic#json-schema-usage)
- Defaults to 2020-12 if no `$schema` field is present
- **MUST** be a valid JSON Schema object (not `null`)
- For tools with no parameters, use one of these valid approaches:

@olaservoolaservoNov 13, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We chatted about whether this guidance is really needed here, since technically the schema for MCP already says that it has to be an object.

However, the original GitHub discussions showed widespread confusion around this, especially since JSON Schema 2020-12 would allow boolean schemas like true for no-parameter cases, but MCP requires an object. Given this is an MCP-specific restriction, it seems worth calling out explicitly in the spec verbiage.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dsp-ant I left this extra explanation in, but didn't add anything explicit for other schemas (such as output schemas) because this seemed to be the main need for extra clarification.

localden
localden previously approved these changes Nov 14, 2025

@localdenlocalden left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM for spec release.

- `title`: Optional human-readable name of the tool for display purposes.
- `description`: Human-readable description of functionality
- `inputSchema`: JSON Schema defining expected parameters
- Follows the [JSON Schema usage guidelines](/specification/draft/basic#json-schema-usage)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this link point to /draft/ now and be edited later to point to /2025-11-24/? How are such links being handled in general?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, do you think its better not to link directly here?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like @jonathanhefner might have ideas or thoughts on this? :)

cliffhall
cliffhall previously approved these changes Nov 14, 2025

@cliffhallcliffhall left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 👍

@olaservo
olaservo dismissed stale reviews from cliffhall and localden via 0aae433November 14, 2025 23:00
@localden
localden merged commit 8ad0ac7 into modelcontextprotocol:mainNov 14, 2025
2 checks passed
panyam added a commit to panyam/mcpkit that referenced this pull request May 23, 2026
…heck counts
Two upstream specReferences[].url strings in modelcontextprotocol/conformance
point at files that no longer exist (verified curl 404):
- SEP-986 cites SEP/SEP-986.md in the modelcontextprotocol repo; that path
was removed when the SEP was merged into the spec. Now linking to the
spec page itself at specification/draft/server/tools.
- SEP-990-Enterprise-Managed-OAuth cites enterprise-oauth.mdx in ext-auth;
the actual file is enterprise-managed-authorization.mdx. Now linking to
the correct file.
Added a SPEC_URL_OVERRIDES map in scripts/conformance-audit-report.ts so we
keep tracking these locally until upstream's source is fixed. Each entry
documents why and which upstream file holds the stale string. Drop entries
as upstream fixes its references.
Also: spell out the check-count column. 14P / 2F / 28I becomes
14 pass / 2 fail / 28 info — one column wider per row but no decoder ring
needed when scanning the By SEP table.
Snapshot regenerated. All URLs in the report now return 200 (one stays
at 301: github.com/modelcontextprotocol/modelcontextprotocol/pull/655 redirects
to the renamed modelcontextprotocol/modelcontextprotocol repo, harmless).
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: In Review

Development

Successfully merging this pull request may close these issues.

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP

16 participants

@olaservo@jba@jviotti@mikekistler@Kludex@samthanawalla@localden@jokemanfire@pcarleton@cliffhall@evalstate@eiriktsarpalis@jpmcb@paoloricciuti@dsp-ant@bhosmer-ant
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP - #655

Merged
localden merged 76 commits into
modelcontextprotocol:mainfrom
olaservo:clarify-json-schema-version
Nov 14, 2025
Merged

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP#655
localden merged 76 commits into
modelcontextprotocol:mainfrom
olaservo:clarify-json-schema-version

Conversation

@olaservo

@olaservoolaservo commented Jun 5, 2025

Copy link
Copy Markdown
Member

This PR implements SEP-1613, which establishes JSON Schema 2020-12 as the default dialect for embedded schemas within MCP messages.

Summary

Clarifies JSON Schema dialect usage for embedded schemas within MCP messages by establishing 2020-12 as the default dialect and allowing explicit dialect declaration via the $schema field.

Changes

  • Updates specification documentation to specify JSON Schema 2020-12 as default
  • Adds guidance on explicit $schema field usage for alternative dialects
  • Clarifies schema validation requirements for tools with no parameters
  • Updates generated JSON schema files to declare 2020-12 as their meta-schema (patching in the schema generation script since typescript-json-schema only supports draft-07)

Historical Context

Related Issues


Checklist

@jba

jba commented Jun 5, 2025

Copy link
Copy Markdown

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)?
I think it should be the latter.

Comment threaddocs/specification/draft/basic/index.mdx Outdated
Comment threaddocs/specification/draft/basic/index.mdx Outdated
@jviotti

jviotti commented Jun 5, 2025

Copy link
Copy Markdown
Contributor

Awesome! I made a couple little suggestions, but looks pretty good otherwise 💪🏻

@jviotti

Copy link
Copy Markdown
Contributor

This is a good point from @jba though (maybe as a separate PR?)

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)?I think it should be the latter

Maybe better to default to 2020-12 but still suggest support for previous versions in case some users need it?

olaservoand others added 2 commits June 5, 2025 09:15
Co-authored-by: Juan Cruz Viotti <jv@jviotti.com>
@olaservo
olaservo requested a review from evalstateJune 5, 2025 16:20
@olaservo

Copy link
Copy Markdown
MemberAuthor

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)? I think it should be the latter.

Using draft-07 as default came from the original discussion where @jviotti recommended this approach. Since that was a general suggestion based on general tooling support, we still need to take into account MCP implementers' pending feedback on what would make the most sense to reduce the most schema validation challenges.

@mikekistler

Copy link
Copy Markdown

In case it benefits anyone else, I'll share this (AI generated) comparison of JSON Schema Draft-7 and Draft-2020-12:

Major Structural Changes

Draft-07 used a single monolithic specification document, while Draft 2020-12 split into modular specifications:

  • Core vocabulary
  • Validation vocabulary
  • Meta-data vocabulary
  • Format assertion vocabulary

Key New Features in Draft 2020-12

Vocabulary System: Introduced a formal vocabulary system allowing custom vocabularies and better extensibility. You can now define which vocabularies your schema uses via $vocabulary.

New Keywords:

  • unevaluatedProperties and unevaluatedItems - Handle properties/items not covered by other schema keywords
  • dependentSchemas and dependentRequired - Replace and expand on Draft-07's dependencies
  • maxContains and minContains - Provide bounds for contains validation
  • prefixItems - Validates array items by position (replaces positional array validation pattern)

Enhanced Conditionals: if/then/else logic works more intuitively with the new unevaluated keywords.

Breaking Changes

Dependencies Restructure: Draft-07's dependencies keyword is split into dependentSchemas and dependentRequired with slightly different semantics.

Array Validation: The way positional array validation works changed significantly with prefixItems replacing the old tuple validation pattern.

Format Behavior: Format validation became vocabulary-dependent rather than implementation-dependent.

Backward Compatibility

Schemas using only basic Draft-07 features will generally work, but schemas using dependencies or complex array validation patterns need updates. The meta-schema identifier changed from http://json-schema.org/draft-07/schema# to https://json-schema.org/draft/2020-12/schema.

Adoption Considerations

Draft 2020-12 offers more powerful validation capabilities and better composability, but Draft-07 still has broader tooling support across languages and platforms. Consider your ecosystem's library support when choosing between versions.

Comment threaddocs/specification/draft/basic/index.mdx Outdated
…no parameters more flexible
- Replace restrictive 'use true for tools with no parameters' guidance
- Provide multiple valid options: true, {}, {type: object}, etc.
- Include example showing how tools can use additional schema keywords
- Addresses comment about recommendation being too restrictive for tools
that may want to include other keywords beyond properties/required
@Kludex

Copy link
Copy Markdown
Member

To make it easier for implementers, I do think it makes more sense to use 2020-12.

Pydantic (the data parsing library we use in the Python SDK) will by default use the version 2020-12 when converting to JSON. Having worked for a long time in the FastAPI ecosystem (which leverages the OpenAPI schema), and the amount of issues that were created because of draft-07, I would suggest we actually use the latest version of the spec by default.

Also, it does add a lot of work to comply to another version.

- Follows the [JSON Schema usage guidelines](/specification/draft/basic#json-schema-usage)
- Defaults to 2020-12 if no `$schema` field is present
- **MUST** be a valid JSON Schema object (not `null`)
- For tools with no parameters, use one of these valid approaches:

@olaservoolaservoNov 13, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We chatted about whether this guidance is really needed here, since technically the schema for MCP already says that it has to be an object.

However, the original GitHub discussions showed widespread confusion around this, especially since JSON Schema 2020-12 would allow boolean schemas like true for no-parameter cases, but MCP requires an object. Given this is an MCP-specific restriction, it seems worth calling out explicitly in the spec verbiage.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dsp-ant I left this extra explanation in, but didn't add anything explicit for other schemas (such as output schemas) because this seemed to be the main need for extra clarification.

localden
localden previously approved these changes Nov 14, 2025

@localdenlocalden left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM for spec release.

- `title`: Optional human-readable name of the tool for display purposes.
- `description`: Human-readable description of functionality
- `inputSchema`: JSON Schema defining expected parameters
- Follows the [JSON Schema usage guidelines](/specification/draft/basic#json-schema-usage)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this link point to /draft/ now and be edited later to point to /2025-11-24/? How are such links being handled in general?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, do you think its better not to link directly here?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like @jonathanhefner might have ideas or thoughts on this? :)

cliffhall
cliffhall previously approved these changes Nov 14, 2025

@cliffhallcliffhall left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 👍

@olaservo
olaservo dismissed stale reviews from cliffhall and localden via 0aae433November 14, 2025 23:00
@localden
localden merged commit 8ad0ac7 into modelcontextprotocol:mainNov 14, 2025
2 checks passed
panyam added a commit to panyam/mcpkit that referenced this pull request May 23, 2026
…heck counts
Two upstream specReferences[].url strings in modelcontextprotocol/conformance
point at files that no longer exist (verified curl 404):
- SEP-986 cites SEP/SEP-986.md in the modelcontextprotocol repo; that path
was removed when the SEP was merged into the spec. Now linking to the
spec page itself at specification/draft/server/tools.
- SEP-990-Enterprise-Managed-OAuth cites enterprise-oauth.mdx in ext-auth;
the actual file is enterprise-managed-authorization.mdx. Now linking to
the correct file.
Added a SPEC_URL_OVERRIDES map in scripts/conformance-audit-report.ts so we
keep tracking these locally until upstream's source is fixed. Each entry
documents why and which upstream file holds the stale string. Drop entries
as upstream fixes its references.
Also: spell out the check-count column. 14P / 2F / 28I becomes
14 pass / 2 fail / 28 info — one column wider per row but no decoder ring
needed when scanning the By SEP table.
Snapshot regenerated. All URLs in the report now return 200 (one stays
at 301: github.com/modelcontextprotocol/modelcontextprotocol/pull/655 redirects
to the renamed modelcontextprotocol/modelcontextprotocol repo, harmless).
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: In Review

Development

Successfully merging this pull request may close these issues.

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP

16 participants

@olaservo@jba@jviotti@mikekistler@Kludex@samthanawalla@localden@jokemanfire@pcarleton@cliffhall@evalstate@eiriktsarpalis@jpmcb@paoloricciuti@dsp-ant@bhosmer-ant
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP - #655

Merged
localden merged 76 commits into
modelcontextprotocol:mainfrom
olaservo:clarify-json-schema-version
Nov 14, 2025
Merged

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP#655
localden merged 76 commits into
modelcontextprotocol:mainfrom
olaservo:clarify-json-schema-version

Conversation

@olaservo

@olaservoolaservo commented Jun 5, 2025

Copy link
Copy Markdown
Member

This PR implements SEP-1613, which establishes JSON Schema 2020-12 as the default dialect for embedded schemas within MCP messages.

Summary

Clarifies JSON Schema dialect usage for embedded schemas within MCP messages by establishing 2020-12 as the default dialect and allowing explicit dialect declaration via the $schema field.

Changes

  • Updates specification documentation to specify JSON Schema 2020-12 as default
  • Adds guidance on explicit $schema field usage for alternative dialects
  • Clarifies schema validation requirements for tools with no parameters
  • Updates generated JSON schema files to declare 2020-12 as their meta-schema (patching in the schema generation script since typescript-json-schema only supports draft-07)

Historical Context

Related Issues


Checklist

@jba

jba commented Jun 5, 2025

Copy link
Copy Markdown

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)?
I think it should be the latter.

Comment threaddocs/specification/draft/basic/index.mdx Outdated
Comment threaddocs/specification/draft/basic/index.mdx Outdated
@jviotti

jviotti commented Jun 5, 2025

Copy link
Copy Markdown
Contributor

Awesome! I made a couple little suggestions, but looks pretty good otherwise 💪🏻

@jviotti

Copy link
Copy Markdown
Contributor

This is a good point from @jba though (maybe as a separate PR?)

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)?I think it should be the latter

Maybe better to default to 2020-12 but still suggest support for previous versions in case some users need it?

olaservoand others added 2 commits June 5, 2025 09:15
Co-authored-by: Juan Cruz Viotti <jv@jviotti.com>
@olaservo
olaservo requested a review from evalstateJune 5, 2025 16:20
@olaservo

Copy link
Copy Markdown
MemberAuthor

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)? I think it should be the latter.

Using draft-07 as default came from the original discussion where @jviotti recommended this approach. Since that was a general suggestion based on general tooling support, we still need to take into account MCP implementers' pending feedback on what would make the most sense to reduce the most schema validation challenges.

@mikekistler

Copy link
Copy Markdown

In case it benefits anyone else, I'll share this (AI generated) comparison of JSON Schema Draft-7 and Draft-2020-12:

Major Structural Changes

Draft-07 used a single monolithic specification document, while Draft 2020-12 split into modular specifications:

  • Core vocabulary
  • Validation vocabulary
  • Meta-data vocabulary
  • Format assertion vocabulary

Key New Features in Draft 2020-12

Vocabulary System: Introduced a formal vocabulary system allowing custom vocabularies and better extensibility. You can now define which vocabularies your schema uses via $vocabulary.

New Keywords:

  • unevaluatedProperties and unevaluatedItems - Handle properties/items not covered by other schema keywords
  • dependentSchemas and dependentRequired - Replace and expand on Draft-07's dependencies
  • maxContains and minContains - Provide bounds for contains validation
  • prefixItems - Validates array items by position (replaces positional array validation pattern)

Enhanced Conditionals: if/then/else logic works more intuitively with the new unevaluated keywords.

Breaking Changes

Dependencies Restructure: Draft-07's dependencies keyword is split into dependentSchemas and dependentRequired with slightly different semantics.

Array Validation: The way positional array validation works changed significantly with prefixItems replacing the old tuple validation pattern.

Format Behavior: Format validation became vocabulary-dependent rather than implementation-dependent.

Backward Compatibility

Schemas using only basic Draft-07 features will generally work, but schemas using dependencies or complex array validation patterns need updates. The meta-schema identifier changed from http://json-schema.org/draft-07/schema# to https://json-schema.org/draft/2020-12/schema.

Adoption Considerations

Draft 2020-12 offers more powerful validation capabilities and better composability, but Draft-07 still has broader tooling support across languages and platforms. Consider your ecosystem's library support when choosing between versions.

Comment threaddocs/specification/draft/basic/index.mdx Outdated
…no parameters more flexible
- Replace restrictive 'use true for tools with no parameters' guidance
- Provide multiple valid options: true, {}, {type: object}, etc.
- Include example showing how tools can use additional schema keywords
- Addresses comment about recommendation being too restrictive for tools
that may want to include other keywords beyond properties/required
@Kludex

Copy link
Copy Markdown
Member

To make it easier for implementers, I do think it makes more sense to use 2020-12.

Pydantic (the data parsing library we use in the Python SDK) will by default use the version 2020-12 when converting to JSON. Having worked for a long time in the FastAPI ecosystem (which leverages the OpenAPI schema), and the amount of issues that were created because of draft-07, I would suggest we actually use the latest version of the spec by default.

Also, it does add a lot of work to comply to another version.

- Follows the [JSON Schema usage guidelines](/specification/draft/basic#json-schema-usage)
- Defaults to 2020-12 if no `$schema` field is present
- **MUST** be a valid JSON Schema object (not `null`)
- For tools with no parameters, use one of these valid approaches:

@olaservoolaservoNov 13, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We chatted about whether this guidance is really needed here, since technically the schema for MCP already says that it has to be an object.

However, the original GitHub discussions showed widespread confusion around this, especially since JSON Schema 2020-12 would allow boolean schemas like true for no-parameter cases, but MCP requires an object. Given this is an MCP-specific restriction, it seems worth calling out explicitly in the spec verbiage.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dsp-ant I left this extra explanation in, but didn't add anything explicit for other schemas (such as output schemas) because this seemed to be the main need for extra clarification.

localden
localden previously approved these changes Nov 14, 2025

@localdenlocalden left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM for spec release.

- `title`: Optional human-readable name of the tool for display purposes.
- `description`: Human-readable description of functionality
- `inputSchema`: JSON Schema defining expected parameters
- Follows the [JSON Schema usage guidelines](/specification/draft/basic#json-schema-usage)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this link point to /draft/ now and be edited later to point to /2025-11-24/? How are such links being handled in general?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, do you think its better not to link directly here?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like @jonathanhefner might have ideas or thoughts on this? :)

cliffhall
cliffhall previously approved these changes Nov 14, 2025

@cliffhallcliffhall left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 👍

@olaservo
olaservo dismissed stale reviews from cliffhall and localden via 0aae433November 14, 2025 23:00
@localden
localden merged commit 8ad0ac7 into modelcontextprotocol:mainNov 14, 2025
2 checks passed
panyam added a commit to panyam/mcpkit that referenced this pull request May 23, 2026
…heck counts
Two upstream specReferences[].url strings in modelcontextprotocol/conformance
point at files that no longer exist (verified curl 404):
- SEP-986 cites SEP/SEP-986.md in the modelcontextprotocol repo; that path
was removed when the SEP was merged into the spec. Now linking to the
spec page itself at specification/draft/server/tools.
- SEP-990-Enterprise-Managed-OAuth cites enterprise-oauth.mdx in ext-auth;
the actual file is enterprise-managed-authorization.mdx. Now linking to
the correct file.
Added a SPEC_URL_OVERRIDES map in scripts/conformance-audit-report.ts so we
keep tracking these locally until upstream's source is fixed. Each entry
documents why and which upstream file holds the stale string. Drop entries
as upstream fixes its references.
Also: spell out the check-count column. 14P / 2F / 28I becomes
14 pass / 2 fail / 28 info — one column wider per row but no decoder ring
needed when scanning the By SEP table.
Snapshot regenerated. All URLs in the report now return 200 (one stays
at 301: github.com/modelcontextprotocol/modelcontextprotocol/pull/655 redirects
to the renamed modelcontextprotocol/modelcontextprotocol repo, harmless).
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: In Review

Development

Successfully merging this pull request may close these issues.

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP

16 participants

@olaservo@jba@jviotti@mikekistler@Kludex@samthanawalla@localden@jokemanfire@pcarleton@cliffhall@evalstate@eiriktsarpalis@jpmcb@paoloricciuti@dsp-ant@bhosmer-ant
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP - #655

Merged
localden merged 76 commits into
modelcontextprotocol:mainfrom
olaservo:clarify-json-schema-version
Nov 14, 2025
Merged

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP#655
localden merged 76 commits into
modelcontextprotocol:mainfrom
olaservo:clarify-json-schema-version

Conversation

@olaservo

@olaservoolaservo commented Jun 5, 2025

Copy link
Copy Markdown
Member

This PR implements SEP-1613, which establishes JSON Schema 2020-12 as the default dialect for embedded schemas within MCP messages.

Summary

Clarifies JSON Schema dialect usage for embedded schemas within MCP messages by establishing 2020-12 as the default dialect and allowing explicit dialect declaration via the $schema field.

Changes

  • Updates specification documentation to specify JSON Schema 2020-12 as default
  • Adds guidance on explicit $schema field usage for alternative dialects
  • Clarifies schema validation requirements for tools with no parameters
  • Updates generated JSON schema files to declare 2020-12 as their meta-schema (patching in the schema generation script since typescript-json-schema only supports draft-07)

Historical Context

Related Issues


Checklist

@jba

jba commented Jun 5, 2025

Copy link
Copy Markdown

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)?
I think it should be the latter.

Comment threaddocs/specification/draft/basic/index.mdx Outdated
Comment threaddocs/specification/draft/basic/index.mdx Outdated
@jviotti

jviotti commented Jun 5, 2025

Copy link
Copy Markdown
Contributor

Awesome! I made a couple little suggestions, but looks pretty good otherwise 💪🏻

@jviotti

Copy link
Copy Markdown
Contributor

This is a good point from @jba though (maybe as a separate PR?)

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)?I think it should be the latter

Maybe better to default to 2020-12 but still suggest support for previous versions in case some users need it?

olaservoand others added 2 commits June 5, 2025 09:15
Co-authored-by: Juan Cruz Viotti <jv@jviotti.com>
@olaservo
olaservo requested a review from evalstateJune 5, 2025 16:20
@olaservo

Copy link
Copy Markdown
MemberAuthor

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)? I think it should be the latter.

Using draft-07 as default came from the original discussion where @jviotti recommended this approach. Since that was a general suggestion based on general tooling support, we still need to take into account MCP implementers' pending feedback on what would make the most sense to reduce the most schema validation challenges.

@mikekistler

Copy link
Copy Markdown

In case it benefits anyone else, I'll share this (AI generated) comparison of JSON Schema Draft-7 and Draft-2020-12:

Major Structural Changes

Draft-07 used a single monolithic specification document, while Draft 2020-12 split into modular specifications:

  • Core vocabulary
  • Validation vocabulary
  • Meta-data vocabulary
  • Format assertion vocabulary

Key New Features in Draft 2020-12

Vocabulary System: Introduced a formal vocabulary system allowing custom vocabularies and better extensibility. You can now define which vocabularies your schema uses via $vocabulary.

New Keywords:

  • unevaluatedProperties and unevaluatedItems - Handle properties/items not covered by other schema keywords
  • dependentSchemas and dependentRequired - Replace and expand on Draft-07's dependencies
  • maxContains and minContains - Provide bounds for contains validation
  • prefixItems - Validates array items by position (replaces positional array validation pattern)

Enhanced Conditionals: if/then/else logic works more intuitively with the new unevaluated keywords.

Breaking Changes

Dependencies Restructure: Draft-07's dependencies keyword is split into dependentSchemas and dependentRequired with slightly different semantics.

Array Validation: The way positional array validation works changed significantly with prefixItems replacing the old tuple validation pattern.

Format Behavior: Format validation became vocabulary-dependent rather than implementation-dependent.

Backward Compatibility

Schemas using only basic Draft-07 features will generally work, but schemas using dependencies or complex array validation patterns need updates. The meta-schema identifier changed from http://json-schema.org/draft-07/schema# to https://json-schema.org/draft/2020-12/schema.

Adoption Considerations

Draft 2020-12 offers more powerful validation capabilities and better composability, but Draft-07 still has broader tooling support across languages and platforms. Consider your ecosystem's library support when choosing between versions.

Comment threaddocs/specification/draft/basic/index.mdx Outdated
…no parameters more flexible
- Replace restrictive 'use true for tools with no parameters' guidance
- Provide multiple valid options: true, {}, {type: object}, etc.
- Include example showing how tools can use additional schema keywords
- Addresses comment about recommendation being too restrictive for tools
that may want to include other keywords beyond properties/required
@Kludex

Copy link
Copy Markdown
Member

To make it easier for implementers, I do think it makes more sense to use 2020-12.

Pydantic (the data parsing library we use in the Python SDK) will by default use the version 2020-12 when converting to JSON. Having worked for a long time in the FastAPI ecosystem (which leverages the OpenAPI schema), and the amount of issues that were created because of draft-07, I would suggest we actually use the latest version of the spec by default.

Also, it does add a lot of work to comply to another version.

- Follows the [JSON Schema usage guidelines](/specification/draft/basic#json-schema-usage)
- Defaults to 2020-12 if no `$schema` field is present
- **MUST** be a valid JSON Schema object (not `null`)
- For tools with no parameters, use one of these valid approaches:

@olaservoolaservoNov 13, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We chatted about whether this guidance is really needed here, since technically the schema for MCP already says that it has to be an object.

However, the original GitHub discussions showed widespread confusion around this, especially since JSON Schema 2020-12 would allow boolean schemas like true for no-parameter cases, but MCP requires an object. Given this is an MCP-specific restriction, it seems worth calling out explicitly in the spec verbiage.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dsp-ant I left this extra explanation in, but didn't add anything explicit for other schemas (such as output schemas) because this seemed to be the main need for extra clarification.

localden
localden previously approved these changes Nov 14, 2025

@localdenlocalden left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM for spec release.

- `title`: Optional human-readable name of the tool for display purposes.
- `description`: Human-readable description of functionality
- `inputSchema`: JSON Schema defining expected parameters
- Follows the [JSON Schema usage guidelines](/specification/draft/basic#json-schema-usage)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this link point to /draft/ now and be edited later to point to /2025-11-24/? How are such links being handled in general?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, do you think its better not to link directly here?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like @jonathanhefner might have ideas or thoughts on this? :)

cliffhall
cliffhall previously approved these changes Nov 14, 2025

@cliffhallcliffhall left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 👍

@olaservo
olaservo dismissed stale reviews from cliffhall and localden via 0aae433November 14, 2025 23:00
@localden
localden merged commit 8ad0ac7 into modelcontextprotocol:mainNov 14, 2025
2 checks passed
panyam added a commit to panyam/mcpkit that referenced this pull request May 23, 2026
…heck counts
Two upstream specReferences[].url strings in modelcontextprotocol/conformance
point at files that no longer exist (verified curl 404):
- SEP-986 cites SEP/SEP-986.md in the modelcontextprotocol repo; that path
was removed when the SEP was merged into the spec. Now linking to the
spec page itself at specification/draft/server/tools.
- SEP-990-Enterprise-Managed-OAuth cites enterprise-oauth.mdx in ext-auth;
the actual file is enterprise-managed-authorization.mdx. Now linking to
the correct file.
Added a SPEC_URL_OVERRIDES map in scripts/conformance-audit-report.ts so we
keep tracking these locally until upstream's source is fixed. Each entry
documents why and which upstream file holds the stale string. Drop entries
as upstream fixes its references.
Also: spell out the check-count column. 14P / 2F / 28I becomes
14 pass / 2 fail / 28 info — one column wider per row but no decoder ring
needed when scanning the By SEP table.
Snapshot regenerated. All URLs in the report now return 200 (one stays
at 301: github.com/modelcontextprotocol/modelcontextprotocol/pull/655 redirects
to the renamed modelcontextprotocol/modelcontextprotocol repo, harmless).
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: In Review

Development

Successfully merging this pull request may close these issues.

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP

16 participants

@olaservo@jba@jviotti@mikekistler@Kludex@samthanawalla@localden@jokemanfire@pcarleton@cliffhall@evalstate@eiriktsarpalis@jpmcb@paoloricciuti@dsp-ant@bhosmer-ant
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP - #655

Merged
localden merged 76 commits into
modelcontextprotocol:mainfrom
olaservo:clarify-json-schema-version
Nov 14, 2025
Merged

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP#655
localden merged 76 commits into
modelcontextprotocol:mainfrom
olaservo:clarify-json-schema-version

Conversation

@olaservo

@olaservoolaservo commented Jun 5, 2025

Copy link
Copy Markdown
Member

This PR implements SEP-1613, which establishes JSON Schema 2020-12 as the default dialect for embedded schemas within MCP messages.

Summary

Clarifies JSON Schema dialect usage for embedded schemas within MCP messages by establishing 2020-12 as the default dialect and allowing explicit dialect declaration via the $schema field.

Changes

  • Updates specification documentation to specify JSON Schema 2020-12 as default
  • Adds guidance on explicit $schema field usage for alternative dialects
  • Clarifies schema validation requirements for tools with no parameters
  • Updates generated JSON schema files to declare 2020-12 as their meta-schema (patching in the schema generation script since typescript-json-schema only supports draft-07)

Historical Context

Related Issues


Checklist

@jba

jba commented Jun 5, 2025

Copy link
Copy Markdown

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)?
I think it should be the latter.

Comment threaddocs/specification/draft/basic/index.mdx Outdated
Comment threaddocs/specification/draft/basic/index.mdx Outdated
@jviotti

jviotti commented Jun 5, 2025

Copy link
Copy Markdown
Contributor

Awesome! I made a couple little suggestions, but looks pretty good otherwise 💪🏻

@jviotti

Copy link
Copy Markdown
Contributor

This is a good point from @jba though (maybe as a separate PR?)

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)?I think it should be the latter

Maybe better to default to 2020-12 but still suggest support for previous versions in case some users need it?

olaservoand others added 2 commits June 5, 2025 09:15
Co-authored-by: Juan Cruz Viotti <jv@jviotti.com>
@olaservo
olaservo requested a review from evalstateJune 5, 2025 16:20
@olaservo

Copy link
Copy Markdown
MemberAuthor

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)? I think it should be the latter.

Using draft-07 as default came from the original discussion where @jviotti recommended this approach. Since that was a general suggestion based on general tooling support, we still need to take into account MCP implementers' pending feedback on what would make the most sense to reduce the most schema validation challenges.

@mikekistler

Copy link
Copy Markdown

In case it benefits anyone else, I'll share this (AI generated) comparison of JSON Schema Draft-7 and Draft-2020-12:

Major Structural Changes

Draft-07 used a single monolithic specification document, while Draft 2020-12 split into modular specifications:

  • Core vocabulary
  • Validation vocabulary
  • Meta-data vocabulary
  • Format assertion vocabulary

Key New Features in Draft 2020-12

Vocabulary System: Introduced a formal vocabulary system allowing custom vocabularies and better extensibility. You can now define which vocabularies your schema uses via $vocabulary.

New Keywords:

  • unevaluatedProperties and unevaluatedItems - Handle properties/items not covered by other schema keywords
  • dependentSchemas and dependentRequired - Replace and expand on Draft-07's dependencies
  • maxContains and minContains - Provide bounds for contains validation
  • prefixItems - Validates array items by position (replaces positional array validation pattern)

Enhanced Conditionals: if/then/else logic works more intuitively with the new unevaluated keywords.

Breaking Changes

Dependencies Restructure: Draft-07's dependencies keyword is split into dependentSchemas and dependentRequired with slightly different semantics.

Array Validation: The way positional array validation works changed significantly with prefixItems replacing the old tuple validation pattern.

Format Behavior: Format validation became vocabulary-dependent rather than implementation-dependent.

Backward Compatibility

Schemas using only basic Draft-07 features will generally work, but schemas using dependencies or complex array validation patterns need updates. The meta-schema identifier changed from http://json-schema.org/draft-07/schema# to https://json-schema.org/draft/2020-12/schema.

Adoption Considerations

Draft 2020-12 offers more powerful validation capabilities and better composability, but Draft-07 still has broader tooling support across languages and platforms. Consider your ecosystem's library support when choosing between versions.

Comment threaddocs/specification/draft/basic/index.mdx Outdated
…no parameters more flexible
- Replace restrictive 'use true for tools with no parameters' guidance
- Provide multiple valid options: true, {}, {type: object}, etc.
- Include example showing how tools can use additional schema keywords
- Addresses comment about recommendation being too restrictive for tools
that may want to include other keywords beyond properties/required
@Kludex

Copy link
Copy Markdown
Member

To make it easier for implementers, I do think it makes more sense to use 2020-12.

Pydantic (the data parsing library we use in the Python SDK) will by default use the version 2020-12 when converting to JSON. Having worked for a long time in the FastAPI ecosystem (which leverages the OpenAPI schema), and the amount of issues that were created because of draft-07, I would suggest we actually use the latest version of the spec by default.

Also, it does add a lot of work to comply to another version.

- Follows the [JSON Schema usage guidelines](/specification/draft/basic#json-schema-usage)
- Defaults to 2020-12 if no `$schema` field is present
- **MUST** be a valid JSON Schema object (not `null`)
- For tools with no parameters, use one of these valid approaches:

@olaservoolaservoNov 13, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We chatted about whether this guidance is really needed here, since technically the schema for MCP already says that it has to be an object.

However, the original GitHub discussions showed widespread confusion around this, especially since JSON Schema 2020-12 would allow boolean schemas like true for no-parameter cases, but MCP requires an object. Given this is an MCP-specific restriction, it seems worth calling out explicitly in the spec verbiage.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dsp-ant I left this extra explanation in, but didn't add anything explicit for other schemas (such as output schemas) because this seemed to be the main need for extra clarification.

localden
localden previously approved these changes Nov 14, 2025

@localdenlocalden left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM for spec release.

- `title`: Optional human-readable name of the tool for display purposes.
- `description`: Human-readable description of functionality
- `inputSchema`: JSON Schema defining expected parameters
- Follows the [JSON Schema usage guidelines](/specification/draft/basic#json-schema-usage)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this link point to /draft/ now and be edited later to point to /2025-11-24/? How are such links being handled in general?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, do you think its better not to link directly here?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like @jonathanhefner might have ideas or thoughts on this? :)

cliffhall
cliffhall previously approved these changes Nov 14, 2025

@cliffhallcliffhall left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 👍

@olaservo
olaservo dismissed stale reviews from cliffhall and localden via 0aae433November 14, 2025 23:00
@localden
localden merged commit 8ad0ac7 into modelcontextprotocol:mainNov 14, 2025
2 checks passed
panyam added a commit to panyam/mcpkit that referenced this pull request May 23, 2026
…heck counts
Two upstream specReferences[].url strings in modelcontextprotocol/conformance
point at files that no longer exist (verified curl 404):
- SEP-986 cites SEP/SEP-986.md in the modelcontextprotocol repo; that path
was removed when the SEP was merged into the spec. Now linking to the
spec page itself at specification/draft/server/tools.
- SEP-990-Enterprise-Managed-OAuth cites enterprise-oauth.mdx in ext-auth;
the actual file is enterprise-managed-authorization.mdx. Now linking to
the correct file.
Added a SPEC_URL_OVERRIDES map in scripts/conformance-audit-report.ts so we
keep tracking these locally until upstream's source is fixed. Each entry
documents why and which upstream file holds the stale string. Drop entries
as upstream fixes its references.
Also: spell out the check-count column. 14P / 2F / 28I becomes
14 pass / 2 fail / 28 info — one column wider per row but no decoder ring
needed when scanning the By SEP table.
Snapshot regenerated. All URLs in the report now return 200 (one stays
at 301: github.com/modelcontextprotocol/modelcontextprotocol/pull/655 redirects
to the renamed modelcontextprotocol/modelcontextprotocol repo, harmless).
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: In Review

Development

Successfully merging this pull request may close these issues.

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP

16 participants

@olaservo@jba@jviotti@mikekistler@Kludex@samthanawalla@localden@jokemanfire@pcarleton@cliffhall@evalstate@eiriktsarpalis@jpmcb@paoloricciuti@dsp-ant@bhosmer-ant
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP - #655

Merged
localden merged 76 commits into
modelcontextprotocol:mainfrom
olaservo:clarify-json-schema-version
Nov 14, 2025
Merged

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP#655
localden merged 76 commits into
modelcontextprotocol:mainfrom
olaservo:clarify-json-schema-version

Conversation

@olaservo

@olaservoolaservo commented Jun 5, 2025

Copy link
Copy Markdown
Member

This PR implements SEP-1613, which establishes JSON Schema 2020-12 as the default dialect for embedded schemas within MCP messages.

Summary

Clarifies JSON Schema dialect usage for embedded schemas within MCP messages by establishing 2020-12 as the default dialect and allowing explicit dialect declaration via the $schema field.

Changes

  • Updates specification documentation to specify JSON Schema 2020-12 as default
  • Adds guidance on explicit $schema field usage for alternative dialects
  • Clarifies schema validation requirements for tools with no parameters
  • Updates generated JSON schema files to declare 2020-12 as their meta-schema (patching in the schema generation script since typescript-json-schema only supports draft-07)

Historical Context

Related Issues


Checklist

@jba

jba commented Jun 5, 2025

Copy link
Copy Markdown

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)?
I think it should be the latter.

Comment threaddocs/specification/draft/basic/index.mdx Outdated
Comment threaddocs/specification/draft/basic/index.mdx Outdated
@jviotti

jviotti commented Jun 5, 2025

Copy link
Copy Markdown
Contributor

Awesome! I made a couple little suggestions, but looks pretty good otherwise 💪🏻

@jviotti

Copy link
Copy Markdown
Contributor

This is a good point from @jba though (maybe as a separate PR?)

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)?I think it should be the latter

Maybe better to default to 2020-12 but still suggest support for previous versions in case some users need it?

olaservoand others added 2 commits June 5, 2025 09:15
Co-authored-by: Juan Cruz Viotti <jv@jviotti.com>
@olaservo
olaservo requested a review from evalstateJune 5, 2025 16:20
@olaservo

Copy link
Copy Markdown
MemberAuthor

Why is the default the older version of JSON Schema (draft7) instead of the newer one (2020-12)? I think it should be the latter.

Using draft-07 as default came from the original discussion where @jviotti recommended this approach. Since that was a general suggestion based on general tooling support, we still need to take into account MCP implementers' pending feedback on what would make the most sense to reduce the most schema validation challenges.

@mikekistler

Copy link
Copy Markdown

In case it benefits anyone else, I'll share this (AI generated) comparison of JSON Schema Draft-7 and Draft-2020-12:

Major Structural Changes

Draft-07 used a single monolithic specification document, while Draft 2020-12 split into modular specifications:

  • Core vocabulary
  • Validation vocabulary
  • Meta-data vocabulary
  • Format assertion vocabulary

Key New Features in Draft 2020-12

Vocabulary System: Introduced a formal vocabulary system allowing custom vocabularies and better extensibility. You can now define which vocabularies your schema uses via $vocabulary.

New Keywords:

  • unevaluatedProperties and unevaluatedItems - Handle properties/items not covered by other schema keywords
  • dependentSchemas and dependentRequired - Replace and expand on Draft-07's dependencies
  • maxContains and minContains - Provide bounds for contains validation
  • prefixItems - Validates array items by position (replaces positional array validation pattern)

Enhanced Conditionals: if/then/else logic works more intuitively with the new unevaluated keywords.

Breaking Changes

Dependencies Restructure: Draft-07's dependencies keyword is split into dependentSchemas and dependentRequired with slightly different semantics.

Array Validation: The way positional array validation works changed significantly with prefixItems replacing the old tuple validation pattern.

Format Behavior: Format validation became vocabulary-dependent rather than implementation-dependent.

Backward Compatibility

Schemas using only basic Draft-07 features will generally work, but schemas using dependencies or complex array validation patterns need updates. The meta-schema identifier changed from http://json-schema.org/draft-07/schema# to https://json-schema.org/draft/2020-12/schema.

Adoption Considerations

Draft 2020-12 offers more powerful validation capabilities and better composability, but Draft-07 still has broader tooling support across languages and platforms. Consider your ecosystem's library support when choosing between versions.

Comment threaddocs/specification/draft/basic/index.mdx Outdated
…no parameters more flexible
- Replace restrictive 'use true for tools with no parameters' guidance
- Provide multiple valid options: true, {}, {type: object}, etc.
- Include example showing how tools can use additional schema keywords
- Addresses comment about recommendation being too restrictive for tools
that may want to include other keywords beyond properties/required
@Kludex

Copy link
Copy Markdown
Member

To make it easier for implementers, I do think it makes more sense to use 2020-12.

Pydantic (the data parsing library we use in the Python SDK) will by default use the version 2020-12 when converting to JSON. Having worked for a long time in the FastAPI ecosystem (which leverages the OpenAPI schema), and the amount of issues that were created because of draft-07, I would suggest we actually use the latest version of the spec by default.

Also, it does add a lot of work to comply to another version.

- Follows the [JSON Schema usage guidelines](/specification/draft/basic#json-schema-usage)
- Defaults to 2020-12 if no `$schema` field is present
- **MUST** be a valid JSON Schema object (not `null`)
- For tools with no parameters, use one of these valid approaches:

@olaservoolaservoNov 13, 2025

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We chatted about whether this guidance is really needed here, since technically the schema for MCP already says that it has to be an object.

However, the original GitHub discussions showed widespread confusion around this, especially since JSON Schema 2020-12 would allow boolean schemas like true for no-parameter cases, but MCP requires an object. Given this is an MCP-specific restriction, it seems worth calling out explicitly in the spec verbiage.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dsp-ant I left this extra explanation in, but didn't add anything explicit for other schemas (such as output schemas) because this seemed to be the main need for extra clarification.

localden
localden previously approved these changes Nov 14, 2025

@localdenlocalden left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM for spec release.

- `title`: Optional human-readable name of the tool for display purposes.
- `description`: Human-readable description of functionality
- `inputSchema`: JSON Schema defining expected parameters
- Follows the [JSON Schema usage guidelines](/specification/draft/basic#json-schema-usage)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this link point to /draft/ now and be edited later to point to /2025-11-24/? How are such links being handled in general?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, do you think its better not to link directly here?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like @jonathanhefner might have ideas or thoughts on this? :)

cliffhall
cliffhall previously approved these changes Nov 14, 2025

@cliffhallcliffhall left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 👍

@olaservo
olaservo dismissed stale reviews from cliffhall and localden via 0aae433November 14, 2025 23:00
@localden
localden merged commit 8ad0ac7 into modelcontextprotocol:mainNov 14, 2025
2 checks passed
panyam added a commit to panyam/mcpkit that referenced this pull request May 23, 2026
…heck counts
Two upstream specReferences[].url strings in modelcontextprotocol/conformance
point at files that no longer exist (verified curl 404):
- SEP-986 cites SEP/SEP-986.md in the modelcontextprotocol repo; that path
was removed when the SEP was merged into the spec. Now linking to the
spec page itself at specification/draft/server/tools.
- SEP-990-Enterprise-Managed-OAuth cites enterprise-oauth.mdx in ext-auth;
the actual file is enterprise-managed-authorization.mdx. Now linking to
the correct file.
Added a SPEC_URL_OVERRIDES map in scripts/conformance-audit-report.ts so we
keep tracking these locally until upstream's source is fixed. Each entry
documents why and which upstream file holds the stale string. Drop entries
as upstream fixes its references.
Also: spell out the check-count column. 14P / 2F / 28I becomes
14 pass / 2 fail / 28 info — one column wider per row but no decoder ring
needed when scanning the By SEP table.
Snapshot regenerated. All URLs in the report now return 200 (one stays
at 301: github.com/modelcontextprotocol/modelcontextprotocol/pull/655 redirects
to the renamed modelcontextprotocol/modelcontextprotocol repo, harmless).
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: In Review

Development

Successfully merging this pull request may close these issues.

SEP-1613: Establish JSON Schema 2020-12 as Default Dialect for MCP

16 participants

@olaservo@jba@jviotti@mikekistler@Kludex@samthanawalla@localden@jokemanfire@pcarleton@cliffhall@evalstate@eiriktsarpalis@jpmcb@paoloricciuti@dsp-ant@bhosmer-ant