@mcpdesc/validator 0.11.0 → 0.12.0-rc.1

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
@@ -8,6 +8,28 @@ Dates for published releases are the UTC publication dates recorded by npm.
8
8
 
9
9
  ## [Unreleased]
10
10
 
11
+ ## [0.12.0-rc.1] - 2026-09-09
12
+
13
+ ### Added
14
+
15
+ - Added the immutable stable `0.8.0` selector, its frozen conformance fixtures,
16
+ and component reference resolution with terminal-target provenance.
17
+
18
+ ### Changed
19
+
20
+ - Advanced active runtime support to RC.4 and stable `0.8.0`, deprecated RC.4,
21
+ and retired RC.3 from current registries, declarations, bundles, and package
22
+ contents while retaining its immutable source and fixtures in Git.
23
+
24
+ ## [0.11.1] - 2026-09-08
25
+
26
+ ### Fixed
27
+
28
+ - Added terminal-target provenance to RC.4 component reference resolution and
29
+ enabled RC.4 through the public resolver. This is an approved additive
30
+ tooling-metadata correction; schemas, conformance results, diagnostics, and
31
+ frozen fixtures are unchanged.
32
+
11
33
  ## [0.11.0] - 2026-09-08
12
34
 
13
35
  ### Added
@@ -31,8 +53,6 @@ Dates for published releases are the UTC publication dates recorded by npm.
31
53
  - Narrowed active runtime support to RC.2 and RC.3 and marked RC.2 deprecated.
32
54
  - Excluded retired runtime snapshots from generated bundles and package
33
55
  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
56
 
37
57
  ## [0.10.0] - 2026-09-07
38
58
 
@@ -96,10 +116,9 @@ Dates for published releases are the UTC publication dates recorded by npm.
96
116
 
97
117
  ### Changed
98
118
 
99
- - Moved package maintenance and publication from the MCP Description
100
- specification repository to the MCP Description tooling repository without
101
- changing public APIs, immutable snapshots, diagnostics, or validation
102
- behavior.
119
+ - Updated shipped repository metadata and provenance files to identify the MCP
120
+ Description tooling repository as the package maintenance location. Public
121
+ APIs, immutable snapshots, diagnostics, and validation behavior are unchanged.
103
122
 
104
123
  ## [0.6.0] - 2026-09-02
105
124
 
@@ -155,7 +174,9 @@ Dates for published releases are the UTC publication dates recorded by npm.
155
174
  - Added synchronous structural and semantic validation for parsed JavaScript values with deterministic diagnostics and exact selector dispatch.
156
175
  - Added ESM browser support, TypeScript declarations, embedded schema provenance, frozen fixtures, and package-content checks.
157
176
 
158
- [Unreleased]: https://github.com/mcpdesc/core/compare/validator-v0.11.0...HEAD
177
+ [Unreleased]: https://github.com/mcpdesc/core/compare/validator-v0.12.0-rc.1...HEAD
178
+ [0.12.0-rc.1]: https://github.com/mcpdesc/core/compare/validator-v0.11.1...validator-v0.12.0-rc.1
179
+ [0.11.1]: https://github.com/mcpdesc/core/compare/validator-v0.11.0...validator-v0.11.1
159
180
  [0.11.0]: https://github.com/mcpdesc/core/compare/validator-v0.10.1...validator-v0.11.0
160
181
  [0.10.1]: https://github.com/mcpdesc/core/compare/validator-v0.10.0...validator-v0.10.1
161
182
  [0.10.0]: https://github.com/mcpdesc/core/compare/validator-v0.9.0...validator-v0.10.0
package/README.md CHANGED
@@ -10,7 +10,7 @@ snapshots. The package:
10
10
 
11
11
  Use it when accepting, generating, migrating, or transforming MCP Description
12
12
  documents and you need to know whether the result conforms to a specific
13
- published draft or release candidate. It validates MCP Description documents,
13
+ published draft, release candidate, or stable version. It validates MCP Description documents,
14
14
  not live MCP servers or MCP protocol messages.
15
15
 
16
16
  ## Install
@@ -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.4',
28
+ specification: '0.8.0',
29
29
  });
30
30
 
31
31
  for (const diagnostic of result.diagnostics) {
@@ -48,22 +48,23 @@ 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.4` | `0.11.0` | `d38e54db859813b63be2a5c91dde91250035f18bcb5910208cf71fa6875d6eef` |
52
- | `0.8.0-rc.3` (deprecated) | `0.10.0` | `a9c3ff77ba37c72362909f538f6e957d055e6fdb372f8b3d529e3651af3fecf4` |
51
+ | `0.8.0` | `0.12.0-rc.1` | `36686f92ba0cc98bde2c34eaad31c0304d6e5cebdd2c4d2be1be06aecef41119` |
52
+ | `0.8.0-rc.4` (deprecated) | `0.11.0` | `d38e54db859813b63be2a5c91dde91250035f18bcb5910208cf71fa6875d6eef` |
53
53
 
54
54
  The validator package embeds the schema and executable behavior for each
55
- selector. RC.3 remains available for migration compatibility; new integrations
56
- should select RC.4. Earlier selectors remain available by pinning an older
55
+ selector. RC.4 remains available for migration compatibility; new integrations
56
+ should select stable `0.8.0`. Earlier selectors remain available by pinning an older
57
57
  immutable validator release. npm integrity and trusted-publishing provenance identify released
58
58
  package bytes; specification repository tags and commits are informational.
59
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.
60
+ Component reference resolution is available for RC.4 and stable `0.8.0` with
61
+ terminal-target provenance for each authored reference.
63
62
 
64
63
  ## Usage
65
64
 
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.
65
+ The `options` argument and exact `specification` selector are required. Stable,
66
+ draft, and release-candidate selectors remain distinct immutable compatibility
67
+ contracts.
67
68
 
68
69
  ### Entry points
69
70
 
@@ -131,19 +132,19 @@ Structural paths start with AJV's instance path. A `required` error appends its
131
132
 
132
133
  ## Support metadata
133
134
 
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.
135
+ 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.4` and `0.8.0`; `deprecatedSpecifications` contains RC.4. The protocol-version export is the deduplicated union supported by active snapshots.
135
136
 
136
137
  The package also exports the frozen `mcpExtensionCatalogue` and
137
- `mcpExtensionMaturity` classifier pinned by the RC.3 snapshot. The catalogue
138
+ `mcpExtensionMaturity` classifier pinned by the stable snapshot. The catalogue
138
139
  records its authoritative source, effective date, and official or experimental
139
140
  identifier assignments. Catalogue recognition establishes authority and
140
141
  maturity only; it does not validate extension-specific settings.
141
142
 
142
143
  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.
143
144
 
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.
145
+ The RC.4 and stable component resolvers report authored and terminal target paths
146
+ for successful substitutions. Additive tooling corrections that provide this
147
+ metadata are recorded explicitly in the integrity manifest.
147
148
 
148
149
  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.
149
150
 
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type McpDescriptionSpecification = '0.8.0-rc.3' | '0.8.0-rc.4';
1
+ export type McpDescriptionSpecification = '0.8.0-rc.4' | '0.8.0';
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.3';
41
+ readonly specification: '0.8.0-rc.4' | '0.8.0';
42
42
  }
43
43
 
44
44
  export type McpExtensionMaturity = 'official' | 'experimental' | 'uncatalogued';
@@ -56,16 +56,16 @@ export interface McpExtensionCatalogue {
56
56
  }
57
57
 
58
58
  export interface SpecificationProvenance {
59
- readonly '0.8.0-rc.3': {
60
- readonly snapshotTag: 'v0.8.0-rc.3';
61
- readonly schemaUri: 'https://mcpdesc.org/schema/mcp-description/0.8.0-rc.3.json';
62
- readonly schemaSha256: 'a9c3ff77ba37c72362909f538f6e957d055e6fdb372f8b3d529e3651af3fecf4';
63
- };
64
59
  readonly '0.8.0-rc.4': {
65
60
  readonly snapshotTag: 'v0.8.0-rc.4';
66
61
  readonly schemaUri: 'https://mcpdesc.org/schema/mcp-description/0.8.0-rc.4.json';
67
62
  readonly schemaSha256: 'd38e54db859813b63be2a5c91dde91250035f18bcb5910208cf71fa6875d6eef';
68
63
  };
64
+ readonly '0.8.0': {
65
+ readonly snapshotTag: 'v0.8.0';
66
+ readonly schemaUri: 'https://mcpdesc.org/schema/mcp-description/0.8.0.json';
67
+ readonly schemaSha256: '36686f92ba0cc98bde2c34eaad31c0304d6e5cebdd2c4d2be1be06aecef41119';
68
+ };
69
69
  }
70
70
 
71
71
  export interface ResolveMcpDescriptionSpecificationOptions {
@@ -89,8 +89,8 @@ export type McpDescriptionSpecificationResolution =
89
89
  | ResolvedMcpDescriptionSpecification
90
90
  | UnresolvedMcpDescriptionSpecification;
91
91
 
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'];
92
+ export declare const supportedSpecifications: readonly ['0.8.0-rc.4', '0.8.0'];
93
+ export declare const deprecatedSpecifications: readonly ['0.8.0-rc.4'];
94
94
 
95
95
  export declare const supportedProtocolVersions: readonly [
96
96
  '2024-11-05',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcpdesc/validator",
3
- "version": "0.11.0",
3
+ "version": "0.12.0-rc.1",
4
4
  "description": "Structural and semantic validation for MCP Description snapshots",
5
5
  "type": "module",
6
6
  "types": "./index.d.ts",
@@ -31,8 +31,8 @@
31
31
  },
32
32
  "files": [
33
33
  "src/index.js",
34
- "src/snapshots/0.8.0-rc.3",
35
34
  "src/snapshots/0.8.0-rc.4",
35
+ "src/snapshots/0.8.0",
36
36
  "standalone.js",
37
37
  "index.d.ts",
38
38
  "CHANGELOG.md",
package/src/index.js CHANGED
@@ -1,29 +1,31 @@
1
- import * as rc3 from './snapshots/0.8.0-rc.3/index.js';
2
1
  import * as rc4 from './snapshots/0.8.0-rc.4/index.js';
3
- import { resolveComponentReferences as resolveRc3ComponentReferences } from './snapshots/0.8.0-rc.3/semantic.js';
2
+ import * as stable from './snapshots/0.8.0/index.js';
3
+ import { resolveComponentReferences as resolveRc4ComponentReferences } from './snapshots/0.8.0-rc.4/semantic.js';
4
+ import { resolveComponentReferences as resolveStableComponentReferences } from './snapshots/0.8.0/semantic.js';
4
5
  import {
5
6
  mcpExtensionCatalogue,
6
7
  mcpExtensionMaturity
7
- } from './snapshots/0.8.0-rc.3/semantic.js';
8
+ } from './snapshots/0.8.0/semantic.js';
8
9
 
9
10
  export { mcpExtensionCatalogue, mcpExtensionMaturity };
10
11
 
11
12
  const snapshots = Object.freeze({
12
- [rc3.specification]: rc3,
13
- [rc4.specification]: rc4
13
+ [rc4.specification]: rc4,
14
+ [stable.specification]: stable
14
15
  });
15
16
 
16
17
  const componentResolvers = Object.freeze({
17
- '0.8.0-rc.3': resolveRc3ComponentReferences
18
+ '0.8.0-rc.4': resolveRc4ComponentReferences,
19
+ '0.8.0': resolveStableComponentReferences
18
20
  });
19
21
 
20
22
  const schemaUris = Object.freeze({
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'
23
+ '0.8.0-rc.4': 'https://mcpdesc.org/schema/mcp-description/0.8.0-rc.4.json',
24
+ '0.8.0': 'https://mcpdesc.org/schema/mcp-description/0.8.0.json'
23
25
  });
24
26
 
25
27
  export const supportedSpecifications = Object.freeze(Object.keys(snapshots));
26
- export const deprecatedSpecifications = Object.freeze(['0.8.0-rc.3']);
28
+ export const deprecatedSpecifications = Object.freeze(['0.8.0-rc.4']);
27
29
  export const supportedProtocolVersions = Object.freeze([
28
30
  ...new Set(Object.values(snapshots).flatMap((snapshot) => snapshot.supportedProtocolVersions))
29
31
  ]);
@@ -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.3';
7
- export const snapshotTag = 'v0.8.0-rc.3';
8
- export const schemaSha256 = 'a9c3ff77ba37c72362909f538f6e957d055e6fdb372f8b3d529e3651af3fecf4';
6
+ export const specification = '0.8.0';
7
+ export const snapshotTag = 'v0.8.0';
8
+ export const schemaSha256 = '36686f92ba0cc98bde2c34eaad31c0304d6e5cebdd2c4d2be1be06aecef41119';
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.3.json",
4
- "title": "MCP Description",
5
- "description": "MCP Description 0.8.0 Release Candidate 3 (v0.8.0-rc.3; prerelease).",
3
+ "$id": "https://mcpdesc.org/schema/mcp-description/0.8.0.json",
4
+ "title": "MCP Description (mcpdesc)",
5
+ "description": "A static, curated format to describe 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-rc.3 snapshot using only snapshot-local artifacts.
1
+ // Validate the immutable 0.8.0 snapshot using only snapshot-local artifacts.
2
2
 
3
3
  import Ajv from 'ajv';
4
4
  import Ajv2020 from 'ajv/dist/2020.js';
@@ -62,6 +62,7 @@ function componentDiagnostic(code, rel, message, path) {
62
62
  export function resolveComponentReferences(document, rel = 'document') {
63
63
  const resolved = structuredClone(document);
64
64
  const diagnostics = [];
65
+ const provenance = [];
65
66
  let substitutions = 0;
66
67
 
67
68
  function resolve(reference, expectedNamespace, path, stack = []) {
@@ -75,7 +76,7 @@ export function resolveComponentReferences(document, rel = 'document') {
75
76
  `must target #/components/${expectedNamespace}, not #/components/${namespace}`,
76
77
  path
77
78
  ));
78
- return reference;
79
+ return { value: reference };
79
80
  }
80
81
 
81
82
  const key = `${namespace}/${name}`;
@@ -86,7 +87,7 @@ export function resolveComponentReferences(document, rel = 'document') {
86
87
  `forms a cycle through ${[...stack, key].join(' -> ')}`,
87
88
  path
88
89
  ));
89
- return reference;
90
+ return { value: reference };
90
91
  }
91
92
 
92
93
  const target = document?.components?.[namespace]?.[name];
@@ -97,18 +98,29 @@ export function resolveComponentReferences(document, rel = 'document') {
97
98
  `targets missing component ${JSON.stringify(reference.$componentRef)}`,
98
99
  path
99
100
  ));
100
- return reference;
101
+ return { value: reference };
101
102
  }
102
103
  substitutions += 1;
103
104
  return isReferenceObject(target)
104
105
  ? resolve(target, expectedNamespace, path, [...stack, key])
105
- : structuredClone(target);
106
+ : {
107
+ value: structuredClone(target),
108
+ targetPath: ['components', namespace, name]
109
+ };
110
+ }
111
+
112
+ function substitute(reference, expectedNamespace, path, stack = []) {
113
+ const result = resolve(reference, expectedNamespace, path, stack);
114
+ if (result.targetPath) {
115
+ provenance.push({ referencePath: path, targetPath: result.targetPath });
116
+ }
117
+ return result.value;
106
118
  }
107
119
 
108
120
  for (const namespace of componentNamespaces) {
109
121
  for (const [name, value] of Object.entries(document?.components?.[namespace] ?? {})) {
110
122
  if (isReferenceObject(value)) {
111
- resolved.components[namespace][name] = resolve(value, namespace, ['components', namespace, name], [`${namespace}/${name}`]);
123
+ resolved.components[namespace][name] = substitute(value, namespace, ['components', namespace, name], [`${namespace}/${name}`]);
112
124
  }
113
125
  }
114
126
  }
@@ -124,7 +136,7 @@ export function resolveComponentReferences(document, rel = 'document') {
124
136
  if (collection === 'tools') {
125
137
  for (const field of ['inputSchema', 'outputSchema']) {
126
138
  if (isReferenceObject(declaration[field])) {
127
- resolvedDeclaration[field] = resolve(declaration[field], 'schemas', [collection, declarationIndex, field]);
139
+ resolvedDeclaration[field] = substitute(declaration[field], 'schemas', [collection, declarationIndex, field]);
128
140
  }
129
141
  }
130
142
  }
@@ -138,7 +150,7 @@ export function resolveComponentReferences(document, rel = 'document') {
138
150
  : 'promptExamples';
139
151
  for (const [name, example] of Object.entries(declaration.examples ?? {})) {
140
152
  if (isReferenceObject(example)) {
141
- resolvedDeclaration.examples[name] = resolve(
153
+ resolvedDeclaration.examples[name] = substitute(
142
154
  example,
143
155
  exampleNamespace,
144
156
  [collection, declarationIndex, 'examples', name]
@@ -152,7 +164,7 @@ export function resolveComponentReferences(document, rel = 'document') {
152
164
  for (const [declarationIndex, declaration] of (document?.[collection] ?? []).entries()) {
153
165
  for (const [elicitationIndex, elicitation] of (declaration.elicitations ?? []).entries()) {
154
166
  if (isReferenceObject(elicitation.requestedSchema)) {
155
- resolved[collection][declarationIndex].elicitations[elicitationIndex].requestedSchema = resolve(
167
+ resolved[collection][declarationIndex].elicitations[elicitationIndex].requestedSchema = substitute(
156
168
  elicitation.requestedSchema,
157
169
  'schemas',
158
170
  [collection, declarationIndex, 'elicitations', elicitationIndex, 'requestedSchema']
@@ -162,7 +174,7 @@ export function resolveComponentReferences(document, rel = 'document') {
162
174
  }
163
175
  }
164
176
 
165
- return { document: resolved, diagnostics, substitutions };
177
+ return { document: resolved, diagnostics, substitutions, provenance };
166
178
  }
167
179
 
168
180
  function structuralPath(document, error) {