@mcpdesc/validator 0.1.0 → 0.2.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/README.md CHANGED
@@ -2,7 +2,14 @@
2
2
 
3
3
  Isomorphic structural and semantic validation for immutable MCP Description specification snapshots.
4
4
 
5
- The initial implementation supports exactly MCP Description `0.8.0-draft.1`, bound to tag `v0.8.0-draft.1` and the embedded `schemas/mcp-description/0.8.0.json` SHA-256 digest `4ceb6042c3fd31703199cd3db869ec5c35c17d2fe9ab7b2f5b96a2a3af0cebe4`.
5
+ Version `0.2.0` cumulatively supports these immutable snapshots:
6
+
7
+ | Selector | Tag | Embedded schema SHA-256 |
8
+ |---|---|---|
9
+ | `0.8.0-draft.1` | `v0.8.0-draft.1` | `4ceb6042c3fd31703199cd3db869ec5c35c17d2fe9ab7b2f5b96a2a3af0cebe4` |
10
+ | `0.8.0-draft.2` | `v0.8.0-draft.2` | `ab692c1a5a0f7e5f29be1940aa8c64a56d4620be0a19d00cf0a64680b7e517fa` |
11
+
12
+ This cumulative release is intended to receive the npm `latest` dist-tag after the Draft 2 tag and tarball are reviewed. Repository changes alone do not publish the package or create either tag.
6
13
 
7
14
  ## Usage
8
15
 
@@ -10,7 +17,7 @@ The initial implementation supports exactly MCP Description `0.8.0-draft.1`, bou
10
17
  import { validateMcpDescription } from '@mcpdesc/validator';
11
18
 
12
19
  const result = validateMcpDescription(parsedDocument, {
13
- specification: '0.8.0-draft.1'
20
+ specification: '0.8.0-draft.2'
14
21
  });
15
22
 
16
23
  if (!result.valid) {
@@ -44,10 +51,25 @@ Structural paths start with AJV's instance path. A `required` error appends its
44
51
 
45
52
  ## Support metadata
46
53
 
47
- The package exports frozen `supportedSpecifications`, `supportedProtocolVersions`, and `specificationProvenance` values. npm package SemVer tracks implementation releases independently from specification snapshot identity. A future draft snapshot must use a sibling implementation and selector rather than changing Draft 1 behavior.
54
+ The package exports frozen `supportedSpecifications`, `supportedProtocolVersions`, and `specificationProvenance` values. Public validation dispatches through a registry keyed by exact specification selectors. The current selector set is `0.8.0-draft.1` and `0.8.0-draft.2`; the protocol-version export is the deduplicated union supported by those snapshots.
55
+
56
+ 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.
48
57
 
49
58
  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. The same ESM entry point supports Node.js 20 or later and browser bundlers.
50
59
 
60
+ ## Snapshot lifecycle
61
+
62
+ For each approved specification snapshot, maintainers:
63
+
64
+ 1. Add a versioned implementation under `src/snapshots/<selector>/` with its exact selector, snapshot tag, embedded schema, schema SHA-256 digest, and semantic rules. Existing snapshot directories remain unchanged.
65
+ 2. Freeze the matching fixture corpus under `test/snapshots/<selector>/fixtures/`. Package tests must not read mutable `spec/draft/fixtures/` for an already published selector.
66
+ 3. Add the exact selector to the runtime registry and update support metadata, TypeScript declarations, tests, and expected package contents. Unqualified versions, aliases, ranges, and not-yet-published selectors remain unsupported.
67
+ 4. Run the package and repository validation suites. The schema digest, immutable metadata, fixture behavior, browser bundle, declarations, and tarball contents must all pass.
68
+
69
+ 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.
70
+
71
+ Supporting code does not authorize publication. During release review, a maintainer explicitly decides the validator package version and intended npm dist-tag so the reviewed specification-tag commit contains the chosen package metadata. Only after that specification snapshot is tagged does a maintainer review the tarball and push an annotated `validator-v<semver>` tag. The trusted-publishing workflow requires that exact tag/package version match, reruns the package checks, and publishes SemVer prereleases with npm `next` or stable versions with `latest`. Repository scripts and other CI workflows do not choose versions, create release tags, or publish packages. No package version or publication choice for a later draft is made by this lifecycle description.
72
+
51
73
  ## Development checks
52
74
 
53
75
  From the repository root:
@@ -59,4 +81,4 @@ npm run test:browser --workspace @mcpdesc/validator
59
81
  npm run test:package --workspace @mcpdesc/validator
60
82
  ```
61
83
 
62
- The package test covers every official Draft 1 valid, invalid, and warning fixture. The other checks compile the declarations, build for a browser target, and inspect `npm pack --dry-run --json` against the intended tarball contents.
84
+ 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, build both runtime snapshots for a browser target, and inspect `npm pack --dry-run --json` against the intended tarball contents, including both runtime snapshots and exclusion of test snapshots.
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type McpDescriptionSpecification = '0.8.0-draft.1';
1
+ export type McpDescriptionSpecification = '0.8.0-draft.1' | '0.8.0-draft.2';
2
2
 
3
3
  export type SupportedProtocolVersion =
4
4
  | '2024-11-05'
@@ -26,11 +26,17 @@ export interface ValidateMcpDescriptionOptions {
26
26
  }
27
27
 
28
28
  export interface SpecificationProvenance {
29
- readonly snapshotTag: 'v0.8.0-draft.1';
30
- readonly schemaSha256: '4ceb6042c3fd31703199cd3db869ec5c35c17d2fe9ab7b2f5b96a2a3af0cebe4';
29
+ readonly '0.8.0-draft.1': {
30
+ readonly snapshotTag: 'v0.8.0-draft.1';
31
+ readonly schemaSha256: '4ceb6042c3fd31703199cd3db869ec5c35c17d2fe9ab7b2f5b96a2a3af0cebe4';
32
+ };
33
+ readonly '0.8.0-draft.2': {
34
+ readonly snapshotTag: 'v0.8.0-draft.2';
35
+ readonly schemaSha256: 'ab692c1a5a0f7e5f29be1940aa8c64a56d4620be0a19d00cf0a64680b7e517fa';
36
+ };
31
37
  }
32
38
 
33
- export declare const supportedSpecifications: readonly ['0.8.0-draft.1'];
39
+ export declare const supportedSpecifications: readonly ['0.8.0-draft.1', '0.8.0-draft.2'];
34
40
 
35
41
  export declare const supportedProtocolVersions: readonly [
36
42
  '2024-11-05',
@@ -40,9 +46,7 @@ export declare const supportedProtocolVersions: readonly [
40
46
  '2026-07-28'
41
47
  ];
42
48
 
43
- export declare const specificationProvenance: Readonly<{
44
- readonly '0.8.0-draft.1': Readonly<SpecificationProvenance>;
45
- }>;
49
+ export declare const specificationProvenance: Readonly<SpecificationProvenance>;
46
50
 
47
51
  export declare function validateMcpDescription(
48
52
  document: unknown,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcpdesc/validator",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Structural and semantic validation for MCP Description snapshots",
5
5
  "type": "module",
6
6
  "types": "./index.d.ts",
package/src/index.js CHANGED
@@ -1,28 +1,30 @@
1
- import {
2
- schemaSha256,
3
- snapshotTag,
4
- specification,
5
- supportedProtocolVersions,
6
- validate
7
- } from './snapshots/0.8.0-draft.1/index.js';
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';
8
3
 
9
- export const supportedSpecifications = Object.freeze([specification]);
10
- export { supportedProtocolVersions };
11
-
12
- export const specificationProvenance = Object.freeze({
13
- [specification]: Object.freeze({
14
- snapshotTag,
15
- schemaSha256
16
- })
4
+ const snapshots = Object.freeze({
5
+ [draft1.specification]: draft1,
6
+ [draft2.specification]: draft2
17
7
  });
18
8
 
9
+ export const supportedSpecifications = Object.freeze(Object.keys(snapshots));
10
+ export const supportedProtocolVersions = Object.freeze([
11
+ ...new Set(Object.values(snapshots).flatMap((snapshot) => snapshot.supportedProtocolVersions))
12
+ ]);
13
+
14
+ export const specificationProvenance = Object.freeze(Object.fromEntries(
15
+ Object.entries(snapshots).map(([selector, snapshot]) => [selector, Object.freeze({
16
+ snapshotTag: snapshot.snapshotTag,
17
+ schemaSha256: snapshot.schemaSha256
18
+ })])
19
+ ));
20
+
19
21
  export function validateMcpDescription(document, options) {
20
22
  if (!options || typeof options !== 'object' || Array.isArray(options) || !Object.hasOwn(options, 'specification')) {
21
23
  throw new TypeError('options.specification is required');
22
24
  }
23
- if (options.specification !== specification) {
25
+ if (typeof options.specification !== 'string' || !Object.hasOwn(snapshots, options.specification)) {
24
26
  throw new RangeError(`Unsupported MCP Description specification: ${String(options.specification)}`);
25
27
  }
26
28
 
27
- return validate(document);
29
+ return snapshots[options.specification].validate(document);
28
30
  }