@mcpdesc/validator 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,34 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this package follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
  Dates for published releases are the UTC publication dates recorded by npm.
8
8
 
9
+ ## [Unreleased]
10
+
11
+ ## [0.11.0] - 2026-09-08
12
+
13
+ ### Added
14
+
15
+ - Added the immutable `0.8.0-rc.4` selector, including protocol-independent
16
+ root info metadata behavior and its frozen conformance fixture corpus.
17
+
18
+ ### Changed
19
+
20
+ - Narrowed active runtime support to RC.3 and RC.4, deprecated RC.3, and removed
21
+ RC.2 from current registries, declarations, generated bundles, and package
22
+ contents while retaining its immutable source and fixtures in Git.
23
+ - Kept component reference resolution on RC.3 because RC.4's snapshot resolver
24
+ does not expose the terminal-target provenance required by the public result
25
+ contract.
26
+
27
+ ## [0.10.1] - 2026-09-07
28
+
29
+ ### Changed
30
+
31
+ - Narrowed active runtime support to RC.2 and RC.3 and marked RC.2 deprecated.
32
+ - Excluded retired runtime snapshots from generated bundles and package
33
+ contents while retaining their source and frozen fixtures in Git.
34
+ - Removed the retained snapshot-intake manifest; intake bundles are disposable
35
+ inputs and imported bytes remain protected by the snapshot integrity manifest.
36
+
9
37
  ## [0.10.0] - 2026-09-07
10
38
 
11
39
  ### Added
@@ -127,7 +155,10 @@ Dates for published releases are the UTC publication dates recorded by npm.
127
155
  - Added synchronous structural and semantic validation for parsed JavaScript values with deterministic diagnostics and exact selector dispatch.
128
156
  - Added ESM browser support, TypeScript declarations, embedded schema provenance, frozen fixtures, and package-content checks.
129
157
 
130
- [Unreleased]: https://github.com/mcpdesc/core/compare/validator-v0.9.0...HEAD
158
+ [Unreleased]: https://github.com/mcpdesc/core/compare/validator-v0.11.0...HEAD
159
+ [0.11.0]: https://github.com/mcpdesc/core/compare/validator-v0.10.1...validator-v0.11.0
160
+ [0.10.1]: https://github.com/mcpdesc/core/compare/validator-v0.10.0...validator-v0.10.1
161
+ [0.10.0]: https://github.com/mcpdesc/core/compare/validator-v0.9.0...validator-v0.10.0
131
162
  [0.9.0]: https://github.com/mcpdesc/core/compare/validator-v0.8.0...validator-v0.9.0
132
163
  [0.8.0]: https://github.com/mcpdesc/core/compare/validator-v0.7.1...validator-v0.8.0
133
164
  [0.7.1]: https://github.com/mcpdesc/core/compare/validator-v0.7.0...validator-v0.7.1
package/README.md CHANGED
@@ -25,7 +25,7 @@ npm install @mcpdesc/validator
25
25
  import { validateMcpDescription } from '@mcpdesc/validator';
26
26
 
27
27
  const result = validateMcpDescription(parsedDocument, {
28
- specification: '0.8.0-rc.2',
28
+ specification: '0.8.0-rc.4',
29
29
  });
30
30
 
31
31
  for (const diagnostic of result.diagnostics) {
@@ -44,22 +44,23 @@ a later draft is published.
44
44
 
45
45
  ## Supported snapshots
46
46
 
47
- The current workspace supports these immutable selectors, newest first:
47
+ The package supports these immutable selectors, newest first:
48
48
 
49
49
  | Selector | First validator release | Embedded schema SHA-256 |
50
50
  |---|---|---|
51
- | `0.8.0-rc.3` | `0.10.0` | `a9c3ff77ba37c72362909f538f6e957d055e6fdb372f8b3d529e3651af3fecf4` |
52
- | `0.8.0-rc.2` | `0.9.0` | `40f6775dde052224114e91d6aa484d826eecf56b77f7ac87b4cf707ffbcb6ce8` |
53
- | `0.8.0-rc.1` | `0.5.0` | `936a0f24ade501fcabf3d6498c0440c445daa672a575573a35954cee49430ac4` |
54
- | `0.8.0-draft.4` | `0.4.0` | `93ed03f74059b5b3ce7509a96b59161bdab2c3cf7734397a9bec5a7588d0b03b` |
55
- | `0.8.0-draft.3` | `0.3.0` | `8823c1f1946360b2a44d00920e2092e5e4acd139a1964befad4eb0bf3ce96002` |
56
- | `0.8.0-draft.2` | `0.2.0` | `ab692c1a5a0f7e5f29be1940aa8c64a56d4620be0a19d00cf0a64680b7e517fa` |
57
- | `0.8.0-draft.1` | `0.1.0` | `4ceb6042c3fd31703199cd3db869ec5c35c17d2fe9ab7b2f5b96a2a3af0cebe4` |
51
+ | `0.8.0-rc.4` | `0.11.0` | `d38e54db859813b63be2a5c91dde91250035f18bcb5910208cf71fa6875d6eef` |
52
+ | `0.8.0-rc.3` (deprecated) | `0.10.0` | `a9c3ff77ba37c72362909f538f6e957d055e6fdb372f8b3d529e3651af3fecf4` |
58
53
 
59
54
  The validator package embeds the schema and executable behavior for each
60
- selector. npm integrity and trusted-publishing provenance identify released
55
+ selector. RC.3 remains available for migration compatibility; new integrations
56
+ should select RC.4. Earlier selectors remain available by pinning an older
57
+ immutable validator release. npm integrity and trusted-publishing provenance identify released
61
58
  package bytes; specification repository tags and commits are informational.
62
59
 
60
+ Component reference resolution remains available for RC.3. RC.4 validation is
61
+ supported, but its snapshot resolver does not expose the terminal-target
62
+ provenance required by the package's public resolution result contract.
63
+
63
64
  ## Usage
64
65
 
65
66
  The `options` argument and exact `specification` selector are required. The unqualified selector `0.8.0` is intentionally unsupported because draft and release-candidate iterations are immutable compatibility contracts.
@@ -100,17 +101,10 @@ if (resolution.status === 'resolved') {
100
101
 
101
102
  Resolution is pure and performs no network retrieval. It does not validate the
102
103
  document and never infers a draft snapshot from `mcpdesc: "0.8.0"` alone.
103
- Draft 4's format-qualified schema URI resolves uniquely. Drafts 1 through 3
104
- share the legacy `https://mcpdesc.org/schema/0.8.0.json` URI, so that URI is
105
- ambiguous unless the caller supplies a consistent exact selector:
106
-
107
- ```js
108
- const resolution = resolveMcpDescriptionSpecification(parsedDocument, {
109
- specification: '0.8.0-draft.3'
110
- });
111
- ```
104
+ Retired schema identities are reported as unknown by current releases. Pin an
105
+ older package release to resolve or validate a retired selector.
112
106
 
113
- Unresolved results distinguish missing, invalid, unknown, ambiguous, and
107
+ Unresolved results distinguish missing, invalid, unknown, and
114
108
  contradictory identity, as well as unsupported caller selectors. A supplied
115
109
  selector can resolve a document with no `$schema`; when `$schema` is present it
116
110
  must match the selected snapshot's recorded schema URI.
@@ -137,20 +131,19 @@ Structural paths start with AJV's instance path. A `required` error appends its
137
131
 
138
132
  ## Support metadata
139
133
 
140
- The package exports frozen `supportedSpecifications`, `supportedProtocolVersions`, and `specificationProvenance` values. Provenance records include the snapshot tag, recorded schema URI, and embedded schema SHA-256 digest. Public validation dispatches through a registry keyed by exact specification selectors. The current repository selector set is `0.8.0-draft.1`, `0.8.0-draft.2`, `0.8.0-draft.3`, `0.8.0-draft.4`, `0.8.0-rc.1`, `0.8.0-rc.2`, and `0.8.0-rc.3`; the protocol-version export is the deduplicated union supported by those snapshots.
134
+ The package exports frozen `supportedSpecifications`, `deprecatedSpecifications`, `supportedProtocolVersions`, and `specificationProvenance` values. Provenance records include the snapshot tag, recorded schema URI, and embedded schema SHA-256 digest. Public validation dispatches through a registry keyed by exact specification selectors. The active selector set is `0.8.0-rc.3` and `0.8.0-rc.4`; `deprecatedSpecifications` contains RC.3. The protocol-version export is the deduplicated union supported by active snapshots.
141
135
 
142
- RC.2 and RC.3 also export the frozen `mcpExtensionCatalogue` and
143
- `mcpExtensionMaturity` classifier. The catalogue pins its authoritative source,
144
- effective date, and official or experimental identifier assignments. Catalogue
145
- recognition establishes authority and maturity only; it does not validate
146
- extension-specific settings.
136
+ The package also exports the frozen `mcpExtensionCatalogue` and
137
+ `mcpExtensionMaturity` classifier pinned by the RC.3 snapshot. The catalogue
138
+ records its authoritative source, effective date, and official or experimental
139
+ identifier assignments. Catalogue recognition establishes authority and
140
+ maturity only; it does not validate extension-specific settings.
147
141
 
148
142
  npm package SemVer tracks implementation releases independently from specification snapshot identity. Adding a later snapshot is additive: it must use a sibling implementation and selector rather than changing an existing snapshot's schema, semantics, metadata, fixtures, or results.
149
143
 
150
- The RC.1, RC.2, and RC.3 component resolvers report authored and terminal target
151
- paths for successful substitutions. The additive tooling corrections do not
152
- change snapshot schemas, validation results, diagnostics, or fixtures and are
153
- recorded in the integrity manifest.
144
+ The RC.3 component resolver reports authored and terminal target paths for
145
+ successful substitutions. RC.4 component resolution is unavailable because its
146
+ snapshot resolver does not expose that provenance result.
154
147
 
155
148
  The runtime bundles its schema, performs no network fetches for external schema references, and imports no Node.js built-ins. Unresolved external Tool-schema references produce incomplete-validation warnings and are preserved. All three ESM entry points support Node.js 20 or later and browser bundlers.
156
149
 
@@ -164,7 +157,7 @@ exact specification repository tag or commit and then:
164
157
  3. Add the exact selector to the runtime registry and update support metadata, TypeScript declarations, tests, the package changelog, and expected package contents. Unqualified versions, aliases, ranges, and not-yet-published selectors remain unsupported.
165
158
  4. Run the package and repository validation suites. The schema digest, immutable metadata, fixture behavior, browser bundle, declarations, and tarball contents must all pass.
166
159
 
167
- The test snapshots are repository-only development assets and are excluded from the npm tarball. Runtime snapshot implementations and embedded schemas do ship so installed packages remain self-contained.
160
+ The test snapshots are repository-only development assets and are excluded from the npm tarball. Historical runtime sources remain in Git for integrity history. Only active runtime snapshot implementations and embedded schemas ship, so installed packages remain self-contained without accumulating retired selectors.
168
161
 
169
162
  Specification approval and imported supporting code do not authorize package
170
163
  publication. During release review, a maintainer explicitly decides the
@@ -187,4 +180,4 @@ npm run test:browser --workspace @mcpdesc/validator
187
180
  npm run test:package --workspace @mcpdesc/validator
188
181
  ```
189
182
 
190
- The package test runs each immutable snapshot against its own frozen valid, invalid, and warning fixture corpus. YAML source fixtures are decoded by the test harness before validation; the public API continues to accept parsed JavaScript values only. The other checks compile the declarations, bundle the public browser entry with esbuild and Vite, reject runtime AJV compiler inputs and dynamic code generation in those bundles, and inspect `npm pack --dry-run --json` against the intended tarball contents and declared export targets.
183
+ The package test runs each active snapshot against its own frozen valid, invalid, and warning fixture corpus and verifies historical artifact integrity separately. YAML source fixtures are decoded by the test harness before validation; the public API continues to accept parsed JavaScript values only. The other checks compile the declarations, bundle the public browser entry with esbuild and Vite, reject runtime AJV compiler inputs and dynamic code generation in those bundles, and inspect `npm pack --dry-run --json` against the intended tarball contents and declared export targets.
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type McpDescriptionSpecification = '0.8.0-draft.1' | '0.8.0-draft.2' | '0.8.0-draft.3' | '0.8.0-draft.4' | '0.8.0-rc.1' | '0.8.0-rc.2' | '0.8.0-rc.3';
1
+ export type McpDescriptionSpecification = '0.8.0-rc.3' | '0.8.0-rc.4';
2
2
 
3
3
  export type SupportedProtocolVersion =
4
4
  | '2024-11-05'
@@ -38,7 +38,7 @@ export interface McpDescriptionComponentResolutionResult {
38
38
  }
39
39
 
40
40
  export interface ResolveMcpDescriptionComponentReferencesOptions {
41
- readonly specification: '0.8.0-rc.1' | '0.8.0-rc.2' | '0.8.0-rc.3';
41
+ readonly specification: '0.8.0-rc.3';
42
42
  }
43
43
 
44
44
  export type McpExtensionMaturity = 'official' | 'experimental' | 'uncatalogued';
@@ -56,41 +56,16 @@ export interface McpExtensionCatalogue {
56
56
  }
57
57
 
58
58
  export interface SpecificationProvenance {
59
- readonly '0.8.0-draft.1': {
60
- readonly snapshotTag: 'v0.8.0-draft.1';
61
- readonly schemaUri: 'https://mcpdesc.org/schema/0.8.0.json';
62
- readonly schemaSha256: '4ceb6042c3fd31703199cd3db869ec5c35c17d2fe9ab7b2f5b96a2a3af0cebe4';
63
- };
64
- readonly '0.8.0-draft.2': {
65
- readonly snapshotTag: 'v0.8.0-draft.2';
66
- readonly schemaUri: 'https://mcpdesc.org/schema/0.8.0.json';
67
- readonly schemaSha256: 'ab692c1a5a0f7e5f29be1940aa8c64a56d4620be0a19d00cf0a64680b7e517fa';
68
- };
69
- readonly '0.8.0-draft.3': {
70
- readonly snapshotTag: 'v0.8.0-draft.3';
71
- readonly schemaUri: 'https://mcpdesc.org/schema/0.8.0.json';
72
- readonly schemaSha256: '8823c1f1946360b2a44d00920e2092e5e4acd139a1964befad4eb0bf3ce96002';
73
- };
74
- readonly '0.8.0-draft.4': {
75
- readonly snapshotTag: 'v0.8.0-draft.4';
76
- readonly schemaUri: 'https://mcpdesc.org/schema/mcp-description/0.8.0-draft.4.json';
77
- readonly schemaSha256: '93ed03f74059b5b3ce7509a96b59161bdab2c3cf7734397a9bec5a7588d0b03b';
78
- };
79
- readonly '0.8.0-rc.1': {
80
- readonly snapshotTag: 'v0.8.0-rc.1';
81
- readonly schemaUri: 'https://mcpdesc.org/schema/mcp-description/0.8.0-rc.1.json';
82
- readonly schemaSha256: '936a0f24ade501fcabf3d6498c0440c445daa672a575573a35954cee49430ac4';
83
- };
84
- readonly '0.8.0-rc.2': {
85
- readonly snapshotTag: 'v0.8.0-rc.2';
86
- readonly schemaUri: 'https://mcpdesc.org/schema/mcp-description/0.8.0-rc.2.json';
87
- readonly schemaSha256: '40f6775dde052224114e91d6aa484d826eecf56b77f7ac87b4cf707ffbcb6ce8';
88
- };
89
59
  readonly '0.8.0-rc.3': {
90
60
  readonly snapshotTag: 'v0.8.0-rc.3';
91
61
  readonly schemaUri: 'https://mcpdesc.org/schema/mcp-description/0.8.0-rc.3.json';
92
62
  readonly schemaSha256: 'a9c3ff77ba37c72362909f538f6e957d055e6fdb372f8b3d529e3651af3fecf4';
93
63
  };
64
+ readonly '0.8.0-rc.4': {
65
+ readonly snapshotTag: 'v0.8.0-rc.4';
66
+ readonly schemaUri: 'https://mcpdesc.org/schema/mcp-description/0.8.0-rc.4.json';
67
+ readonly schemaSha256: 'd38e54db859813b63be2a5c91dde91250035f18bcb5910208cf71fa6875d6eef';
68
+ };
94
69
  }
95
70
 
96
71
  export interface ResolveMcpDescriptionSpecificationOptions {
@@ -114,7 +89,8 @@ export type McpDescriptionSpecificationResolution =
114
89
  | ResolvedMcpDescriptionSpecification
115
90
  | UnresolvedMcpDescriptionSpecification;
116
91
 
117
- export declare const supportedSpecifications: readonly ['0.8.0-draft.1', '0.8.0-draft.2', '0.8.0-draft.3', '0.8.0-draft.4', '0.8.0-rc.1', '0.8.0-rc.2', '0.8.0-rc.3'];
92
+ export declare const supportedSpecifications: readonly ['0.8.0-rc.3', '0.8.0-rc.4'];
93
+ export declare const deprecatedSpecifications: readonly ['0.8.0-rc.3'];
118
94
 
119
95
  export declare const supportedProtocolVersions: readonly [
120
96
  '2024-11-05',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcpdesc/validator",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "Structural and semantic validation for MCP Description snapshots",
5
5
  "type": "module",
6
6
  "types": "./index.d.ts",
@@ -31,7 +31,8 @@
31
31
  },
32
32
  "files": [
33
33
  "src/index.js",
34
- "src/snapshots",
34
+ "src/snapshots/0.8.0-rc.3",
35
+ "src/snapshots/0.8.0-rc.4",
35
36
  "standalone.js",
36
37
  "index.d.ts",
37
38
  "CHANGELOG.md",
package/src/index.js CHANGED
@@ -1,47 +1,29 @@
1
- import * as draft1 from './snapshots/0.8.0-draft.1/index.js';
2
- import * as draft2 from './snapshots/0.8.0-draft.2/index.js';
3
- import * as draft3 from './snapshots/0.8.0-draft.3/index.js';
4
- import * as draft4 from './snapshots/0.8.0-draft.4/index.js';
5
- import * as rc1 from './snapshots/0.8.0-rc.1/index.js';
6
- import * as rc2 from './snapshots/0.8.0-rc.2/index.js';
7
1
  import * as rc3 from './snapshots/0.8.0-rc.3/index.js';
8
- import { resolveComponentReferences as resolveRc1ComponentReferences } from './snapshots/0.8.0-rc.1/semantic.js';
9
- import { resolveComponentReferences as resolveRc2ComponentReferences } from './snapshots/0.8.0-rc.2/semantic.js';
2
+ import * as rc4 from './snapshots/0.8.0-rc.4/index.js';
10
3
  import { resolveComponentReferences as resolveRc3ComponentReferences } from './snapshots/0.8.0-rc.3/semantic.js';
11
4
  import {
12
5
  mcpExtensionCatalogue,
13
6
  mcpExtensionMaturity
14
- } from './snapshots/0.8.0-rc.2/semantic.js';
7
+ } from './snapshots/0.8.0-rc.3/semantic.js';
15
8
 
16
9
  export { mcpExtensionCatalogue, mcpExtensionMaturity };
17
10
 
18
11
  const snapshots = Object.freeze({
19
- [draft1.specification]: draft1,
20
- [draft2.specification]: draft2,
21
- [draft3.specification]: draft3,
22
- [draft4.specification]: draft4,
23
- [rc1.specification]: rc1,
24
- [rc2.specification]: rc2,
25
- [rc3.specification]: rc3
12
+ [rc3.specification]: rc3,
13
+ [rc4.specification]: rc4
26
14
  });
27
15
 
28
16
  const componentResolvers = Object.freeze({
29
- '0.8.0-rc.1': resolveRc1ComponentReferences,
30
- '0.8.0-rc.2': resolveRc2ComponentReferences,
31
17
  '0.8.0-rc.3': resolveRc3ComponentReferences
32
18
  });
33
19
 
34
20
  const schemaUris = Object.freeze({
35
- '0.8.0-draft.1': 'https://mcpdesc.org/schema/0.8.0.json',
36
- '0.8.0-draft.2': 'https://mcpdesc.org/schema/0.8.0.json',
37
- '0.8.0-draft.3': 'https://mcpdesc.org/schema/0.8.0.json',
38
- '0.8.0-draft.4': 'https://mcpdesc.org/schema/mcp-description/0.8.0-draft.4.json',
39
- '0.8.0-rc.1': 'https://mcpdesc.org/schema/mcp-description/0.8.0-rc.1.json',
40
- '0.8.0-rc.2': 'https://mcpdesc.org/schema/mcp-description/0.8.0-rc.2.json',
41
- '0.8.0-rc.3': 'https://mcpdesc.org/schema/mcp-description/0.8.0-rc.3.json'
21
+ '0.8.0-rc.3': 'https://mcpdesc.org/schema/mcp-description/0.8.0-rc.3.json',
22
+ '0.8.0-rc.4': 'https://mcpdesc.org/schema/mcp-description/0.8.0-rc.4.json'
42
23
  });
43
24
 
44
25
  export const supportedSpecifications = Object.freeze(Object.keys(snapshots));
26
+ export const deprecatedSpecifications = Object.freeze(['0.8.0-rc.3']);
45
27
  export const supportedProtocolVersions = Object.freeze([
46
28
  ...new Set(Object.values(snapshots).flatMap((snapshot) => snapshot.supportedProtocolVersions))
47
29
  ]);
@@ -691,11 +691,6 @@ function validateVersionSpecificSemantics(document, rel, diagnostics) {
691
691
  }
692
692
  }
693
693
 
694
- checkMinimumVersion('info', ['info'], document.info ?? {}, 'title', '2025-06-18', rootScope);
695
- checkMinimumVersion('info', ['info'], document.info ?? {}, 'description', '2025-11-25', rootScope);
696
- checkMinimumVersion('info', ['info'], document.info ?? {}, 'icons', '2025-11-25', rootScope);
697
- checkMinimumVersion('info', ['info'], document.info ?? {}, 'websiteUrl', '2025-11-25', rootScope);
698
-
699
694
  (document.transports ?? []).forEach((transport, index) => {
700
695
  const scope = effectiveScope(document, transport, rootScope);
701
696
  if (transport.type === 'streamable-http') {
@@ -3,9 +3,9 @@ import {
3
3
  validateMcpdesc08Document
4
4
  } from './semantic.js';
5
5
 
6
- export const specification = '0.8.0-rc.1';
7
- export const snapshotTag = 'v0.8.0-rc.1';
8
- export const schemaSha256 = '936a0f24ade501fcabf3d6498c0440c445daa672a575573a35954cee49430ac4';
6
+ export const specification = '0.8.0-rc.4';
7
+ export const snapshotTag = 'v0.8.0-rc.4';
8
+ export const schemaSha256 = 'd38e54db859813b63be2a5c91dde91250035f18bcb5910208cf71fa6875d6eef';
9
9
  export { supportedProtocolVersions };
10
10
 
11
11
  export function validate(document) {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://mcpdesc.org/schema/mcp-description/0.8.0-rc.2.json",
4
- "title": "MCP Description",
5
- "description": "MCP Description 0.8.0 Release Candidate 2 (v0.8.0-rc.2; prerelease).",
3
+ "$id": "https://mcpdesc.org/schema/mcp-description/0.8.0-rc.4.json",
4
+ "title": "MCP Server Description (mcpdesc format)",
5
+ "description": "A static, curated description of what an MCP server offers. Uses MCP-native terminology, an OpenAPI-aligned info and security structure, and support for multiple transports, protocol revisions, and specification extensions. Supports MCP protocol revisions 2024-11-05, 2025-03-26, 2025-06-18, 2025-11-25, and 2026-07-28.",
6
6
  "type": "object",
7
7
  "required": [
8
8
  "mcpdesc",
@@ -1,4 +1,4 @@
1
- // Validate the immutable 0.8.0-draft.4 snapshot using only snapshot-local artifacts.
1
+ // Validate the immutable 0.8.0-rc.4 snapshot using only snapshot-local artifacts.
2
2
 
3
3
  import Ajv from 'ajv';
4
4
  import Ajv2020 from 'ajv/dist/2020.js';
@@ -6,11 +6,13 @@ import addFormats from 'ajv-formats';
6
6
  import { UriTemplateMatcher } from 'uri-template-matcher';
7
7
  import schema from './schema.json' with { type: 'json' };
8
8
  import {
9
+ mcpExtensionCatalogue,
10
+ mcpExtensionMaturity,
9
11
  semanticValidateDocument as validateBaseSemantics,
10
12
  supportedProtocolVersions
11
13
  } from './base.js';
12
14
 
13
- export { supportedProtocolVersions };
15
+ export { mcpExtensionCatalogue, mcpExtensionMaturity, supportedProtocolVersions };
14
16
 
15
17
  const TOOL_INTERACTION_SENTINEL = '__interaction_example__';
16
18
  const ajv = new Ajv2020({ allErrors: true, strict: false });
@@ -21,7 +23,6 @@ const validateStructure = ajv.compile(schema);
21
23
  const primitiveCollections = ['tools', 'resources', 'resourceTemplates', 'prompts'];
22
24
  const componentNamespaces = ['schemas', 'toolExamples', 'resourceExamples', 'resourceTemplateExamples', 'promptExamples'];
23
25
  const knownClientCapabilities = new Set(['roots', 'sampling', 'elicitation', 'tasks', 'extensions', 'experimental']);
24
- const knownReservedCapabilityExtensions = new Set(['io.modelcontextprotocol/tasks']);
25
26
  const protocolOrder = new Map(supportedProtocolVersions.map((version, index) => [version, index]));
26
27
 
27
28
  const clientCapabilitiesByVersion = {
@@ -569,7 +570,17 @@ function validateClientRequirements(document) {
569
570
  validateTasks(value, location, path, version);
570
571
  } else if (capability === 'extensions') {
571
572
  for (const extension of Object.keys(value)) {
572
- if (usesMcpReservedPrefix(extension) && !knownReservedCapabilityExtensions.has(extension)) {
573
+ if (!usesMcpReservedPrefix(extension)) continue;
574
+ const maturity = mcpExtensionMaturity(extension);
575
+ if (maturity === 'official') continue;
576
+ if (maturity === 'experimental') {
577
+ diagnostics.push(semanticDiagnostic(
578
+ 'experimental-reserved-extension-identifier',
579
+ 'warning',
580
+ `${location} contains experimental MCP extension ${JSON.stringify(extension)}; preserve it and review its maturity before relying on it`,
581
+ [...path, extension]
582
+ ));
583
+ } else {
573
584
  diagnostics.push(semanticDiagnostic(
574
585
  'unknown-reserved-extension-identifier',
575
586
  'warning',