@emseepea/testing 0.21.0 → 0.21.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/README.md CHANGED
@@ -90,6 +90,86 @@ never production. Resources and prompts need deterministic protocol tests;
90
90
  this library does not pretend that manually injecting their content proves a
91
91
  native user journey.
92
92
 
93
+ ## Qualify an MCP journey from the command line
94
+
95
+ Use `emseepea-qualify` for repeatable protocol checks against an explicitly
96
+ configured MCP endpoint. The command can verify OAuth protected-resource
97
+ metadata, tool and resource catalogues, resource templates, exact authorized
98
+ reads, original byte hashes, tool-returned resource links, progress,
99
+ completion, client cancellation, and access denial.
100
+
101
+ Keep the endpoint, fixture values, expected results, and token environment
102
+ names in an adopter-owned scenario module. Scenario modules are trusted
103
+ application code: importing one executes it with the command process's full
104
+ authority, including access to that process's environment.
105
+
106
+ ```js
107
+ import { defineMcpCliQualification } from "@emseepea/testing";
108
+
109
+ export default defineMcpCliQualification({
110
+ name: "synthetic document journey",
111
+ endpoint: new URL(process.env.TEST_MCP_URL),
112
+ tokenEnvironment: "TEST_MCP_TOKEN",
113
+ checkpoints: [
114
+ { id: "tools", operation: "tools/list", expectedNames: ["get-document"] },
115
+ { id: "resources", operation: "resources/list", expectedUris: ["fixture://documents/example.pdf"] },
116
+ {
117
+ id: "original",
118
+ operation: "resources/read",
119
+ uri: "fixture://documents/example.pdf",
120
+ expectedContents: [{
121
+ mimeType: "application/pdf",
122
+ bytes: 1240,
123
+ sha256: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
124
+ }],
125
+ },
126
+ {
127
+ id: "limited-user-denied",
128
+ operation: "resources/read",
129
+ uri: "fixture://documents/example.pdf",
130
+ tokenEnvironment: "TEST_LIMITED_MCP_TOKEN",
131
+ expect: "denied",
132
+ },
133
+ ],
134
+ });
135
+ ```
136
+
137
+ Expose the command through a project-local package script:
138
+
139
+ ```json
140
+ {
141
+ "scripts": {
142
+ "qualify:mcp": "emseepea-qualify --scenario test/mcp-qualification.mjs --output artifacts/mcp-cli/evidence.json"
143
+ }
144
+ }
145
+ ```
146
+
147
+ Run the script with:
148
+
149
+ ```sh
150
+ npm run qualify:mcp
151
+ ```
152
+
153
+ The framework reads configured tokens from the named environment variables. It
154
+ does not accept them as command arguments or include values it handles in its
155
+ evidence. Your trusted scenario code still has normal process access and is
156
+ responsible for anything it reads or writes.
157
+
158
+ Evidence contains bounded counts, hashes, MIME types, categorical outcomes,
159
+ and checkpoint status. It is written with mode `0600` where supported. Use only
160
+ synthetic or explicitly approved fixture data in scenario names and
161
+ expectations.
162
+
163
+ Each checkpoint records `passed`, `failed`, `blocked`, or `incomplete`.
164
+ `record` checkpoints can preserve a known missing fixture or unavailable
165
+ authority without turning it into success. The report is always labelled
166
+ `evidenceKind: "mcp-cli"` and `nativeChatgpt: "not-tested"`.
167
+
168
+ This command does not drive ChatGPT. It cannot prove ChatGPT connection or
169
+ consent screens, attachments, fresh-conversation behavior, Sources previews,
170
+ visible images, generated links, MCP App cards, viewport interactions, or
171
+ native streaming and cancellation presentation.
172
+
93
173
  ## Scripted Confirmation Input
94
174
 
95
175
  For tools that request form elicitation, supply an explicit simulated human
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ import { serveEmseepea, type AuthenticationOptions } from "@emseepea/server";
3
3
  export { createMcpAppHostSimulator, type McpAppHostSimulator, type McpAppHostSimulatorOptions, type McpAppMessageRequest, } from "./mcp-app-host.js";
4
4
  export { assertPublishedMcpContractCompatible, comparePublishedMcpContracts, extractPublishedMcpContract, writePublishedMcpContractBaseline, type PublishedMcpContract, type PublishedMcpContractBaseline, type PublishedMcpContractBaselineInput, type PublishedMcpContractBreak, type PublishedMcpContractCheckPolicy, type PublishedMcpContractCheckPolicyInput, type PublishedMcpContractClient, type PublishedMcpResource, } from "./published-contract.js";
5
5
  export { assertWcagContrast, wcagContrastRatio } from "./contrast.js";
6
+ export { defineMcpCliQualification, runMcpCliQualification, type McpCliCheckpoint, type McpCliCheckpointEvidence, type McpCliContentExpectation, type McpCliQualificationEvidence, type McpCliQualificationScenario, type McpCliQualificationStatus, type McpCliResourceLinkExpectation, } from "./mcp-cli-qualification.js";
6
7
  export type SupportedProtocolVersion = "2026-07-28" | "2025-11-25" | "2025-06-18" | "2025-03-26" | "2024-11-05" | "2024-10-07";
7
8
  export interface TestCleanup {
8
9
  after(cleanup: () => Promise<void>): void;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAiC,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAE7E,OAAO,EACL,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAC/B,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,oCAAoC,EACpC,4BAA4B,EAC5B,2BAA2B,EAC3B,iCAAiC,EACjC,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,KAAK,iCAAiC,EACtC,KAAK,yBAAyB,EAC9B,KAAK,+BAA+B,EACpC,KAAK,oCAAoC,EACzC,KAAK,0BAA0B,EAC/B,KAAK,oBAAoB,GAC1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEtE,MAAM,MAAM,wBAAwB,GAChC,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,CAAC;AAEjB,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAChC,eAAe,CAAC,EAAE,wBAAwB,CAAC;IAC3C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,IAAI,QAAQ,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvD,GAAG,EAAE,GAAG,CAAC;CACV;AAED,6DAA6D;AAC7D,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,SAAS,GAAE,QAAQ,GAAG,WAAyB,GAC9C,qBAAqB,CAyBvB;AAED,KAAK,oBAAoB,GAAG,IAAI,CAAC,qBAAqB,EAAE,YAAY,GAAG,iBAAiB,GAAG,OAAO,CAAC,CAAC;AACpG,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AAEvD,wBAAgB,aAAa,CAC3B,GAAG,EAAE,WAAW,EAChB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAC7B,wBAAgB,aAAa,CAC3B,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,WAAW,EAChB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,gBAAgB,CAAC,CAAC;AA4B7B,wBAAgB,cAAc,CAC5B,SAAS,EAAE,GAAG,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAC7B,wBAAgB,cAAc,CAC5B,IAAI,EAAE,WAAW,EACjB,SAAS,EAAE,GAAG,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAiC,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAE7E,OAAO,EACL,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAC/B,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,oCAAoC,EACpC,4BAA4B,EAC5B,2BAA2B,EAC3B,iCAAiC,EACjC,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,KAAK,iCAAiC,EACtC,KAAK,yBAAyB,EAC9B,KAAK,+BAA+B,EACpC,KAAK,oCAAoC,EACzC,KAAK,0BAA0B,EAC/B,KAAK,oBAAoB,GAC1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,2BAA2B,EAChC,KAAK,yBAAyB,EAC9B,KAAK,6BAA6B,GACnC,MAAM,4BAA4B,CAAC;AAEpC,MAAM,MAAM,wBAAwB,GAChC,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,CAAC;AAEjB,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAChC,eAAe,CAAC,EAAE,wBAAwB,CAAC;IAC3C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,IAAI,QAAQ,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvD,GAAG,EAAE,GAAG,CAAC;CACV;AAED,6DAA6D;AAC7D,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,SAAS,GAAE,QAAQ,GAAG,WAAyB,GAC9C,qBAAqB,CAyBvB;AAED,KAAK,oBAAoB,GAAG,IAAI,CAAC,qBAAqB,EAAE,YAAY,GAAG,iBAAiB,GAAG,OAAO,CAAC,CAAC;AACpG,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AAEvD,wBAAgB,aAAa,CAC3B,GAAG,EAAE,WAAW,EAChB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAC7B,wBAAgB,aAAa,CAC3B,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,WAAW,EAChB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,gBAAgB,CAAC,CAAC;AA4B7B,wBAAgB,cAAc,CAC5B,SAAS,EAAE,GAAG,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAC7B,wBAAgB,cAAc,CAC5B,IAAI,EAAE,WAAW,EACjB,SAAS,EAAE,GAAG,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAAC"}
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ import { serveEmseepea } from "@emseepea/server";
5
5
  export { createMcpAppHostSimulator, } from "./mcp-app-host.js";
6
6
  export { assertPublishedMcpContractCompatible, comparePublishedMcpContracts, extractPublishedMcpContract, writePublishedMcpContractBaseline, } from "./published-contract.js";
7
7
  export { assertWcagContrast, wcagContrastRatio } from "./contrast.js";
8
+ export { defineMcpCliQualification, runMcpCliQualification, } from "./mcp-cli-qualification.js";
8
9
  /** Test-only verifier. Never use it in a deployed server. */
9
10
  export function insecureTestAuthentication(permissions, discovery = "protected") {
10
11
  const resourceServerUrl = new URL("https://test.example/mcp");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ export type McpCliQualificationStatus = "passed" | "failed" | "blocked" | "incomplete";
2
+ export interface McpCliContentExpectation {
3
+ readonly sha256: string;
4
+ readonly bytes?: number;
5
+ readonly mimeType?: string;
6
+ }
7
+ export interface McpCliResourceLinkExpectation {
8
+ readonly uri: string;
9
+ readonly mimeType?: string;
10
+ }
11
+ interface McpCliCheckpointBase {
12
+ readonly id: string;
13
+ readonly tokenEnvironment?: string;
14
+ }
15
+ export type McpCliCheckpoint = (McpCliCheckpointBase & {
16
+ readonly operation: "oauth/discover";
17
+ readonly expectedScopes?: readonly string[];
18
+ }) | (McpCliCheckpointBase & {
19
+ readonly operation: "tools/list";
20
+ readonly expectedNames?: readonly string[];
21
+ readonly expect?: "success" | "denied";
22
+ }) | (McpCliCheckpointBase & {
23
+ readonly operation: "resources/list";
24
+ readonly expectedUris?: readonly string[];
25
+ readonly expect?: "success" | "denied";
26
+ }) | (McpCliCheckpointBase & {
27
+ readonly operation: "resources/templates/list";
28
+ readonly expectedUriTemplates?: readonly string[];
29
+ readonly expect?: "success" | "denied";
30
+ }) | (McpCliCheckpointBase & {
31
+ readonly operation: "resources/read";
32
+ readonly uri: string;
33
+ readonly expectedContents?: readonly McpCliContentExpectation[];
34
+ readonly maxContentBytes?: number;
35
+ readonly expect?: "success" | "denied";
36
+ }) | (McpCliCheckpointBase & {
37
+ readonly operation: "tools/call";
38
+ readonly name: string;
39
+ readonly arguments?: Readonly<Record<string, unknown>>;
40
+ readonly expectedResourceLinks?: readonly McpCliResourceLinkExpectation[];
41
+ readonly minimumProgress?: number;
42
+ readonly cancelAfterMs?: number;
43
+ readonly expect?: "success" | "denied" | "cancelled";
44
+ }) | {
45
+ readonly id: string;
46
+ readonly operation: "record";
47
+ readonly outcome: "blocked" | "incomplete";
48
+ readonly category: string;
49
+ };
50
+ export interface McpCliQualificationScenario {
51
+ readonly name: string;
52
+ readonly endpoint: URL;
53
+ readonly protocolVersion?: "2026-07-28" | "2025-11-25" | "2025-06-18" | "2025-03-26";
54
+ readonly requestTimeoutMs?: number;
55
+ readonly tokenEnvironment?: string;
56
+ readonly checkpoints: readonly McpCliCheckpoint[];
57
+ }
58
+ export interface McpCliCheckpointEvidence {
59
+ readonly id: string;
60
+ readonly operation: McpCliCheckpoint["operation"];
61
+ readonly status: McpCliQualificationStatus;
62
+ readonly category: string;
63
+ readonly observation?: Readonly<Record<string, unknown>>;
64
+ }
65
+ export interface McpCliQualificationEvidence {
66
+ readonly schemaVersion: 1;
67
+ readonly evidenceKind: "mcp-cli";
68
+ readonly nativeChatgpt: "not-tested";
69
+ readonly name: string;
70
+ readonly endpointSha256: string;
71
+ readonly protocolVersion: string;
72
+ readonly startedAt: string;
73
+ readonly finishedAt: string;
74
+ readonly status: McpCliQualificationStatus;
75
+ readonly checkpoints: readonly McpCliCheckpointEvidence[];
76
+ }
77
+ /** Preserve TypeScript checking for an adopter-owned qualification scenario. */
78
+ export declare function defineMcpCliQualification(scenario: McpCliQualificationScenario): McpCliQualificationScenario;
79
+ /**
80
+ * Run deterministic MCP protocol checks and write bounded private evidence.
81
+ * This does not exercise or qualify native ChatGPT.
82
+ */
83
+ export declare function runMcpCliQualification(scenario: McpCliQualificationScenario, output: string): Promise<McpCliQualificationEvidence>;
84
+ export {};
85
+ //# sourceMappingURL=mcp-cli-qualification.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-cli-qualification.d.ts","sourceRoot":"","sources":["../src/mcp-cli-qualification.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,507 @@
1
+ import { createHash } from "node:crypto";
2
+ import { chmod, mkdir, writeFile } from "node:fs/promises";
3
+ import { dirname } from "node:path";
4
+ import { Client, InsufficientScopeError, ProtocolError, SdkHttpError, StreamableHTTPClientTransport, UnauthorizedError, discoverOAuthProtectedResourceMetadata, } from "@modelcontextprotocol/client";
5
+ const MAX_CHECKPOINTS = 128;
6
+ const MAX_EXPECTATIONS = 512;
7
+ const MAX_CONTENT_EXPECTATIONS = 128;
8
+ const MAX_PROGRESS_EVENTS = 10_000;
9
+ const DEFAULT_MAX_CONTENT_BYTES = 16 * 1024 * 1024;
10
+ const DEFAULT_REQUEST_TIMEOUT_MS = 15_000;
11
+ const SHA256 = /^[a-f0-9]{64}$/;
12
+ const ENVIRONMENT_NAME = /^[A-Z_][A-Z0-9_]{0,127}$/;
13
+ const IDENTIFIER = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$/;
14
+ /** Preserve TypeScript checking for an adopter-owned qualification scenario. */
15
+ export function defineMcpCliQualification(scenario) {
16
+ return scenario;
17
+ }
18
+ /**
19
+ * Run deterministic MCP protocol checks and write bounded private evidence.
20
+ * This does not exercise or qualify native ChatGPT.
21
+ */
22
+ export async function runMcpCliQualification(scenario, output) {
23
+ validateScenario(scenario, output);
24
+ const startedAt = new Date().toISOString();
25
+ const checkpoints = [];
26
+ for (const checkpoint of scenario.checkpoints) {
27
+ checkpoints.push(await runCheckpoint(scenario, checkpoint, checkpoints));
28
+ }
29
+ const evidence = Object.freeze({
30
+ schemaVersion: 1,
31
+ evidenceKind: "mcp-cli",
32
+ nativeChatgpt: "not-tested",
33
+ name: scenario.name,
34
+ endpointSha256: sha256(scenario.endpoint.href),
35
+ protocolVersion: scenario.protocolVersion ?? "2026-07-28",
36
+ startedAt,
37
+ finishedAt: new Date().toISOString(),
38
+ status: overallStatus(checkpoints),
39
+ checkpoints: Object.freeze(checkpoints),
40
+ });
41
+ const serialized = `${JSON.stringify(evidence, null, 2)}\n`;
42
+ for (const secret of configuredSecrets(scenario)) {
43
+ if (serialized.includes(secret)) {
44
+ throw new Error("MCP CLI qualification evidence contains a configured credential");
45
+ }
46
+ }
47
+ await mkdir(dirname(output), { recursive: true });
48
+ await writeFile(output, serialized, { mode: 0o600 });
49
+ await chmod(output, 0o600);
50
+ return evidence;
51
+ }
52
+ async function runCheckpoint(scenario, checkpoint, previous) {
53
+ if (checkpoint.operation === "record") {
54
+ return frozenEvidence(checkpoint, checkpoint.outcome, checkpoint.category);
55
+ }
56
+ if (checkpoint.operation === "oauth/discover") {
57
+ return runOAuthCheckpoint(scenario, checkpoint);
58
+ }
59
+ const tokenEnvironment = checkpoint.tokenEnvironment ?? scenario.tokenEnvironment;
60
+ const token = tokenEnvironment === undefined ? undefined : process.env[tokenEnvironment];
61
+ if (tokenEnvironment !== undefined && !token) {
62
+ return frozenEvidence(checkpoint, "blocked", "missing-credential");
63
+ }
64
+ const client = new Client({ name: "emseepea-mcp-cli-qualification", version: "0.0.0" }, scenario.protocolVersion === undefined || scenario.protocolVersion === "2026-07-28"
65
+ ? { versionNegotiation: { mode: { pin: scenario.protocolVersion ?? "2026-07-28" } } }
66
+ : {
67
+ supportedProtocolVersions: [scenario.protocolVersion],
68
+ versionNegotiation: { mode: "legacy" },
69
+ });
70
+ const timeout = scenario.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
71
+ try {
72
+ await client.connect(new StreamableHTTPClientTransport(scenario.endpoint, token ? { authProvider: { token: async () => token } } : undefined), { timeout });
73
+ return await executeConnectedCheckpoint(client, checkpoint, timeout);
74
+ }
75
+ catch (error) {
76
+ const category = errorCategory(error);
77
+ const expected = checkpoint.expect ?? "success";
78
+ if (expected === "denied" && category === "denied") {
79
+ return frozenEvidence(checkpoint, "passed", "denial-observed");
80
+ }
81
+ if (expected === "denied" && category === "hidden-or-missing" &&
82
+ hasSuccessfulBaseline(checkpoint, previous)) {
83
+ return frozenEvidence(checkpoint, "passed", "denial-observed");
84
+ }
85
+ if (expected === "cancelled" && category === "cancelled") {
86
+ return frozenEvidence(checkpoint, "passed", "cancellation-observed");
87
+ }
88
+ const status = category === "unreachable" || category === "missing-credential"
89
+ ? "blocked"
90
+ : "failed";
91
+ return frozenEvidence(checkpoint, status, category);
92
+ }
93
+ finally {
94
+ await client.close().catch(() => undefined);
95
+ }
96
+ }
97
+ async function runOAuthCheckpoint(scenario, checkpoint) {
98
+ try {
99
+ const timeout = scenario.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
100
+ const metadata = await discoverOAuthProtectedResourceMetadata(scenario.endpoint, undefined, (input, init) => fetch(input, { ...init, signal: AbortSignal.timeout(timeout) }));
101
+ if (!metadata)
102
+ return frozenEvidence(checkpoint, "failed", "metadata-missing");
103
+ const scopes = [...(metadata.scopes_supported ?? [])].sort();
104
+ const servers = [...(metadata.authorization_servers ?? [])].sort();
105
+ const observation = {
106
+ resourceSha256: sha256(metadata.resource),
107
+ authorizationServerCount: servers.length,
108
+ authorizationServersSha256: sha256(JSON.stringify(servers)),
109
+ scopeCount: scopes.length,
110
+ scopesSha256: sha256(JSON.stringify(scopes)),
111
+ };
112
+ if (checkpoint.expectedScopes !== undefined &&
113
+ !sameStrings(scopes, [...checkpoint.expectedScopes].sort())) {
114
+ return frozenEvidence(checkpoint, "failed", "scope-mismatch", observation);
115
+ }
116
+ return frozenEvidence(checkpoint, "passed", "metadata-observed", observation);
117
+ }
118
+ catch (error) {
119
+ const category = errorCategory(error);
120
+ return frozenEvidence(checkpoint, category === "unreachable" ? "blocked" : "failed", category);
121
+ }
122
+ }
123
+ async function executeConnectedCheckpoint(client, checkpoint, timeout) {
124
+ const expected = checkpoint.expect ?? "success";
125
+ let observation;
126
+ if (checkpoint.operation === "tools/list") {
127
+ const names = (await client.listTools(undefined, { cacheMode: "bypass", timeout })).tools
128
+ .map(({ name }) => name).sort();
129
+ observation = listObservation(names);
130
+ if (checkpoint.expectedNames !== undefined &&
131
+ !sameStrings(names, [...checkpoint.expectedNames].sort())) {
132
+ return frozenEvidence(checkpoint, "failed", "catalogue-mismatch", observation);
133
+ }
134
+ }
135
+ else if (checkpoint.operation === "resources/list") {
136
+ const uris = (await client.listResources(undefined, { cacheMode: "bypass", timeout })).resources
137
+ .map(({ uri }) => uri).sort();
138
+ observation = listObservation(uris);
139
+ if (checkpoint.expectedUris !== undefined &&
140
+ !sameStrings(uris, [...checkpoint.expectedUris].sort())) {
141
+ return frozenEvidence(checkpoint, "failed", "catalogue-mismatch", observation);
142
+ }
143
+ }
144
+ else if (checkpoint.operation === "resources/templates/list") {
145
+ const templates = (await client.listResourceTemplates(undefined, { cacheMode: "bypass", timeout }))
146
+ .resourceTemplates.map(({ uriTemplate }) => uriTemplate).sort();
147
+ observation = listObservation(templates);
148
+ if (checkpoint.expectedUriTemplates !== undefined &&
149
+ !sameStrings(templates, [...checkpoint.expectedUriTemplates].sort())) {
150
+ return frozenEvidence(checkpoint, "failed", "catalogue-mismatch", observation);
151
+ }
152
+ }
153
+ else if (checkpoint.operation === "resources/read") {
154
+ const result = await client.readResource({ uri: checkpoint.uri }, { cacheMode: "bypass", timeout });
155
+ if (result.contents.length > MAX_CONTENT_EXPECTATIONS) {
156
+ throw new Error("resource response contains too many content items");
157
+ }
158
+ const contents = result.contents.map((content) => contentObservation(content, checkpoint.maxContentBytes ?? DEFAULT_MAX_CONTENT_BYTES));
159
+ observation = {
160
+ requestedUriSha256: sha256(checkpoint.uri),
161
+ contents,
162
+ };
163
+ if (checkpoint.expectedContents !== undefined &&
164
+ !sameContentExpectations(contents, checkpoint.expectedContents)) {
165
+ return frozenEvidence(checkpoint, "failed", "content-mismatch", observation);
166
+ }
167
+ }
168
+ else {
169
+ return runToolCheckpoint(client, checkpoint, timeout);
170
+ }
171
+ if (expected !== "success") {
172
+ return frozenEvidence(checkpoint, "failed", "unexpected-success", observation);
173
+ }
174
+ return frozenEvidence(checkpoint, "passed", "expectation-met", observation);
175
+ }
176
+ async function runToolCheckpoint(client, checkpoint, timeout) {
177
+ let progressCount = 0;
178
+ let progressTruncated = false;
179
+ const controller = checkpoint.cancelAfterMs === undefined ? undefined : new AbortController();
180
+ const timer = controller === undefined ? undefined : setTimeout(() => controller.abort(new Error("qualification cancellation")), checkpoint.cancelAfterMs);
181
+ let result;
182
+ try {
183
+ result = await client.callTool({ name: checkpoint.name, arguments: checkpoint.arguments ?? {} }, {
184
+ ...(controller ? { signal: controller.signal } : {}),
185
+ timeout,
186
+ onprogress: () => {
187
+ if (progressCount < MAX_PROGRESS_EVENTS)
188
+ progressCount += 1;
189
+ else
190
+ progressTruncated = true;
191
+ },
192
+ });
193
+ }
194
+ catch (error) {
195
+ if (controller?.signal.aborted) {
196
+ if ((checkpoint.expect ?? "success") === "cancelled") {
197
+ return frozenEvidence(checkpoint, "passed", "client-cancellation-observed", {
198
+ argumentsSha256: sha256(JSON.stringify(checkpoint.arguments ?? {})),
199
+ progressCount,
200
+ progressTruncated,
201
+ });
202
+ }
203
+ return frozenEvidence(checkpoint, "failed", "unexpected-cancellation");
204
+ }
205
+ throw error;
206
+ }
207
+ finally {
208
+ if (timer !== undefined)
209
+ clearTimeout(timer);
210
+ }
211
+ const links = resourceLinks(result).map(({ uri, mimeType }) => ({
212
+ uriSha256: sha256(uri),
213
+ ...(mimeType === undefined ? {} : { mimeType }),
214
+ }));
215
+ const observation = {
216
+ toolNameSha256: sha256(checkpoint.name),
217
+ argumentsSha256: sha256(JSON.stringify(checkpoint.arguments ?? {})),
218
+ progressCount,
219
+ progressTruncated,
220
+ isError: result.isError === true,
221
+ resourceLinks: links,
222
+ resultSha256: sha256(JSON.stringify(result)),
223
+ };
224
+ if ((checkpoint.expect ?? "success") !== "success") {
225
+ return frozenEvidence(checkpoint, "failed", "unexpected-success", observation);
226
+ }
227
+ if (result.isError === true) {
228
+ return frozenEvidence(checkpoint, "failed", "tool-error", observation);
229
+ }
230
+ if (checkpoint.minimumProgress !== undefined && progressCount < checkpoint.minimumProgress) {
231
+ return frozenEvidence(checkpoint, "failed", "progress-missing", observation);
232
+ }
233
+ if (checkpoint.expectedResourceLinks !== undefined &&
234
+ !sameLinks(links, checkpoint.expectedResourceLinks)) {
235
+ return frozenEvidence(checkpoint, "failed", "resource-link-mismatch", observation);
236
+ }
237
+ return frozenEvidence(checkpoint, "passed", "expectation-met", observation);
238
+ }
239
+ function validateScenario(scenario, output) {
240
+ if (!scenario || typeof scenario !== "object")
241
+ throw new TypeError("qualification scenario is required");
242
+ if (typeof scenario.name !== "string" || !scenario.name.trim() || scenario.name.length > 128) {
243
+ throw new TypeError("qualification name must contain 1 to 128 characters");
244
+ }
245
+ if (!(scenario.endpoint instanceof URL) || !["http:", "https:"].includes(scenario.endpoint.protocol)) {
246
+ throw new TypeError("qualification endpoint must be an HTTP or HTTPS URL");
247
+ }
248
+ if (scenario.endpoint.username || scenario.endpoint.password || scenario.endpoint.hash) {
249
+ throw new TypeError("qualification endpoint must not contain credentials or a fragment");
250
+ }
251
+ if (scenario.endpoint.protocol === "http:" && !isLoopbackHost(scenario.endpoint.hostname)) {
252
+ throw new TypeError("plain HTTP qualification endpoints must use a loopback host");
253
+ }
254
+ for (const name of scenario.endpoint.searchParams.keys()) {
255
+ if (/(?:token|secret|key|auth|credential)/i.test(name)) {
256
+ throw new TypeError("qualification endpoint must not contain credential-like query parameters");
257
+ }
258
+ }
259
+ if (typeof output !== "string" || !output.trim())
260
+ throw new TypeError("qualification output is required");
261
+ if (scenario.requestTimeoutMs !== undefined &&
262
+ (!Number.isSafeInteger(scenario.requestTimeoutMs) || scenario.requestTimeoutMs < 100 ||
263
+ scenario.requestTimeoutMs > 60_000)) {
264
+ throw new TypeError("requestTimeoutMs must be an integer from 100 to 60000");
265
+ }
266
+ if (!Array.isArray(scenario.checkpoints) || scenario.checkpoints.length === 0 ||
267
+ scenario.checkpoints.length > MAX_CHECKPOINTS) {
268
+ throw new TypeError(`qualification checkpoints must contain 1 to ${MAX_CHECKPOINTS} entries`);
269
+ }
270
+ const ids = new Set();
271
+ if (scenario.tokenEnvironment !== undefined)
272
+ validateEnvironmentName(scenario.tokenEnvironment);
273
+ for (const checkpoint of scenario.checkpoints) {
274
+ if (!IDENTIFIER.test(checkpoint.id) || ids.has(checkpoint.id)) {
275
+ throw new TypeError("qualification checkpoint IDs must be unique bounded identifiers");
276
+ }
277
+ ids.add(checkpoint.id);
278
+ if ("tokenEnvironment" in checkpoint && checkpoint.tokenEnvironment !== undefined) {
279
+ validateEnvironmentName(checkpoint.tokenEnvironment);
280
+ }
281
+ validateCheckpoint(checkpoint, scenario.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS);
282
+ }
283
+ }
284
+ function validateCheckpoint(checkpoint, requestTimeoutMs) {
285
+ if (checkpoint.operation === "record") {
286
+ if (!IDENTIFIER.test(checkpoint.category))
287
+ throw new TypeError("record category must be a bounded identifier");
288
+ return;
289
+ }
290
+ if (checkpoint.operation === "oauth/discover") {
291
+ validateArrayBound(checkpoint.expectedScopes, "expected scopes", MAX_EXPECTATIONS);
292
+ }
293
+ if (checkpoint.operation === "tools/list") {
294
+ validateArrayBound(checkpoint.expectedNames, "expected tool names", MAX_EXPECTATIONS);
295
+ }
296
+ if (checkpoint.operation === "resources/list") {
297
+ validateArrayBound(checkpoint.expectedUris, "expected resource URIs", MAX_EXPECTATIONS);
298
+ }
299
+ if (checkpoint.operation === "resources/templates/list") {
300
+ validateArrayBound(checkpoint.expectedUriTemplates, "expected resource templates", MAX_EXPECTATIONS);
301
+ }
302
+ if (checkpoint.operation === "resources/read") {
303
+ if (!checkpoint.uri || checkpoint.uri.length > 4_096)
304
+ throw new TypeError("resource URI is required and bounded");
305
+ validateArrayBound(checkpoint.expectedContents, "expected resource contents", MAX_CONTENT_EXPECTATIONS);
306
+ for (const expected of checkpoint.expectedContents ?? [])
307
+ validateContentExpectation(expected);
308
+ if (checkpoint.maxContentBytes !== undefined &&
309
+ (!Number.isSafeInteger(checkpoint.maxContentBytes) || checkpoint.maxContentBytes < 1 ||
310
+ checkpoint.maxContentBytes > 64 * 1024 * 1024)) {
311
+ throw new TypeError("maxContentBytes must be an integer from 1 to 67108864");
312
+ }
313
+ }
314
+ if (checkpoint.operation === "tools/call") {
315
+ validateArrayBound(checkpoint.expectedResourceLinks, "expected resource links", MAX_CONTENT_EXPECTATIONS);
316
+ for (const expected of checkpoint.expectedResourceLinks ?? []) {
317
+ if (!expected.uri || expected.uri.length > 4_096) {
318
+ throw new TypeError("resource link URI is required and bounded");
319
+ }
320
+ if (expected.mimeType !== undefined)
321
+ validateMimeType(expected.mimeType);
322
+ }
323
+ }
324
+ if (checkpoint.operation === "tools/call") {
325
+ if (!checkpoint.name || checkpoint.name.length > 256)
326
+ throw new TypeError("tool name is required and bounded");
327
+ const argumentsText = JSON.stringify(checkpoint.arguments ?? {});
328
+ if (argumentsText.length > 65_536)
329
+ throw new TypeError("tool arguments exceed 65536 JSON characters");
330
+ if (checkpoint.minimumProgress !== undefined &&
331
+ (!Number.isSafeInteger(checkpoint.minimumProgress) || checkpoint.minimumProgress < 0 ||
332
+ checkpoint.minimumProgress > MAX_PROGRESS_EVENTS)) {
333
+ throw new TypeError(`minimumProgress must be an integer from 0 to ${MAX_PROGRESS_EVENTS}`);
334
+ }
335
+ if (checkpoint.cancelAfterMs !== undefined &&
336
+ (!Number.isSafeInteger(checkpoint.cancelAfterMs) || checkpoint.cancelAfterMs < 1 ||
337
+ checkpoint.cancelAfterMs > 60_000)) {
338
+ throw new TypeError("cancelAfterMs must be an integer from 1 to 60000");
339
+ }
340
+ if (checkpoint.expect === "cancelled" && checkpoint.cancelAfterMs === undefined) {
341
+ throw new TypeError("cancelled tool checkpoints require cancelAfterMs");
342
+ }
343
+ if (checkpoint.cancelAfterMs !== undefined &&
344
+ checkpoint.cancelAfterMs >= requestTimeoutMs) {
345
+ throw new TypeError("cancelAfterMs must be shorter than the request timeout");
346
+ }
347
+ }
348
+ }
349
+ function validateArrayBound(value, label, maximum) {
350
+ if (value !== undefined && (!Array.isArray(value) || value.length > maximum)) {
351
+ throw new TypeError(`${label} must contain at most ${maximum} entries`);
352
+ }
353
+ }
354
+ function isLoopbackHost(hostname) {
355
+ return hostname === "localhost" || hostname === "[::1]" ||
356
+ /^127(?:\.[0-9]{1,3}){3}$/.test(hostname);
357
+ }
358
+ function validateContentExpectation(expected) {
359
+ if (!SHA256.test(expected.sha256))
360
+ throw new TypeError("content sha256 must be lowercase hexadecimal");
361
+ if (expected.bytes !== undefined && (!Number.isSafeInteger(expected.bytes) || expected.bytes < 0)) {
362
+ throw new TypeError("content bytes must be a non-negative integer");
363
+ }
364
+ if (expected.mimeType !== undefined)
365
+ validateMimeType(expected.mimeType);
366
+ }
367
+ function validateMimeType(value) {
368
+ const hasControlCharacter = [...value].some((character) => {
369
+ const code = character.charCodeAt(0);
370
+ return code <= 0x1f || code === 0x7f;
371
+ });
372
+ if (!value || value.length > 256 || hasControlCharacter) {
373
+ throw new TypeError("MIME type must contain 1 to 256 printable characters");
374
+ }
375
+ }
376
+ function validateEnvironmentName(name) {
377
+ if (!ENVIRONMENT_NAME.test(name))
378
+ throw new TypeError("token environment name is invalid");
379
+ }
380
+ function contentObservation(content, maximum) {
381
+ if (content.mimeType !== undefined)
382
+ validateMimeType(content.mimeType);
383
+ let bytes;
384
+ if (typeof content.text === "string") {
385
+ bytes = Buffer.from(content.text, "utf8");
386
+ }
387
+ else if (typeof content.blob === "string") {
388
+ if (content.blob.length > Math.ceil(maximum / 3) * 4 + 4) {
389
+ throw new Error("resource content exceeds configured byte limit");
390
+ }
391
+ bytes = Buffer.from(content.blob, "base64");
392
+ }
393
+ else {
394
+ throw new Error("resource content has no text or blob bytes");
395
+ }
396
+ if (bytes.byteLength > maximum)
397
+ throw new Error("resource content exceeds configured byte limit");
398
+ return Object.freeze({
399
+ uriSha256: sha256(content.uri),
400
+ ...(content.mimeType === undefined ? {} : { mimeType: content.mimeType }),
401
+ bytes: bytes.byteLength,
402
+ sha256: sha256(bytes),
403
+ });
404
+ }
405
+ function sameContentExpectations(observed, expected) {
406
+ return observed.length === expected.length && observed.every((item, index) => {
407
+ const wanted = expected[index];
408
+ return wanted !== undefined && item.sha256 === wanted.sha256 &&
409
+ (wanted.bytes === undefined || item.bytes === wanted.bytes) &&
410
+ (wanted.mimeType === undefined || item.mimeType === wanted.mimeType);
411
+ });
412
+ }
413
+ function resourceLinks(result) {
414
+ const links = [];
415
+ for (const content of result.content) {
416
+ if (content.type !== "resource_link")
417
+ continue;
418
+ if (links.length === MAX_CONTENT_EXPECTATIONS) {
419
+ throw new Error("tool response contains too many resource links");
420
+ }
421
+ if (content.mimeType !== undefined)
422
+ validateMimeType(content.mimeType);
423
+ links.push({ uri: content.uri, ...(content.mimeType === undefined ? {} : { mimeType: content.mimeType }) });
424
+ }
425
+ return links;
426
+ }
427
+ function sameLinks(observed, expected) {
428
+ return observed.length === expected.length && observed.every((item, index) => {
429
+ const wanted = expected[index];
430
+ return wanted !== undefined && item.uriSha256 === sha256(wanted.uri) &&
431
+ (wanted.mimeType === undefined || item.mimeType === wanted.mimeType);
432
+ });
433
+ }
434
+ function listObservation(values) {
435
+ return Object.freeze({ count: values.length, valuesSha256: sha256(JSON.stringify(values)) });
436
+ }
437
+ function sameStrings(left, right) {
438
+ return left.length === right.length && left.every((value, index) => value === right[index]);
439
+ }
440
+ function frozenEvidence(checkpoint, status, category, observation) {
441
+ return Object.freeze({
442
+ id: checkpoint.id,
443
+ operation: checkpoint.operation,
444
+ status,
445
+ category,
446
+ ...(observation === undefined ? {} : { observation: Object.freeze(observation) }),
447
+ });
448
+ }
449
+ function overallStatus(checkpoints) {
450
+ if (checkpoints.some(({ status }) => status === "failed"))
451
+ return "failed";
452
+ if (checkpoints.some(({ status }) => status === "blocked"))
453
+ return "blocked";
454
+ if (checkpoints.some(({ status }) => status === "incomplete"))
455
+ return "incomplete";
456
+ return "passed";
457
+ }
458
+ function hasSuccessfulBaseline(checkpoint, previous) {
459
+ const target = checkpointTarget(checkpoint);
460
+ if (target === undefined)
461
+ return false;
462
+ return previous.some((item) => item.status === "passed" && item.operation === checkpoint.operation &&
463
+ item.observation?.[target.field] === target.sha256);
464
+ }
465
+ function checkpointTarget(checkpoint) {
466
+ if (checkpoint.operation === "resources/read") {
467
+ return { field: "requestedUriSha256", sha256: sha256(checkpoint.uri) };
468
+ }
469
+ if (checkpoint.operation === "tools/call") {
470
+ return { field: "toolNameSha256", sha256: sha256(checkpoint.name) };
471
+ }
472
+ return undefined;
473
+ }
474
+ function errorCategory(error) {
475
+ if (error instanceof UnauthorizedError || error instanceof InsufficientScopeError)
476
+ return "denied";
477
+ if (error instanceof ProtocolError && error.message === "Capability not found") {
478
+ return "hidden-or-missing";
479
+ }
480
+ if (error instanceof SdkHttpError) {
481
+ if (error.status === 401 || error.status === 403)
482
+ return "denied";
483
+ return error.status >= 500 ? "unreachable" : "protocol-error";
484
+ }
485
+ if (error instanceof Error) {
486
+ if (error.name === "AbortError" || /cancel/i.test(error.name))
487
+ return "cancelled";
488
+ if (error.name === "TypeError" || /fetch|connect|network|ECONN/i.test(error.message))
489
+ return "unreachable";
490
+ }
491
+ return "unexpected-error";
492
+ }
493
+ function configuredSecrets(scenario) {
494
+ const names = new Set();
495
+ if (scenario.tokenEnvironment)
496
+ names.add(scenario.tokenEnvironment);
497
+ for (const checkpoint of scenario.checkpoints) {
498
+ if ("tokenEnvironment" in checkpoint && checkpoint.tokenEnvironment) {
499
+ names.add(checkpoint.tokenEnvironment);
500
+ }
501
+ }
502
+ return [...names].flatMap((name) => process.env[name] ? [process.env[name]] : []);
503
+ }
504
+ function sha256(value) {
505
+ return createHash("sha256").update(value).digest("hex");
506
+ }
507
+ //# sourceMappingURL=mcp-cli-qualification.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-cli-qualification.js","sourceRoot":"","sources":["../src/mcp-cli-qualification.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env node
2
+ import { pathToFileURL } from "node:url";
3
+ import { resolve } from "node:path";
4
+
5
+ import { runMcpCliQualification } from "../dist/mcp-cli-qualification.js";
6
+
7
+ const values = process.argv.slice(2);
8
+ if (values.includes("--help")) {
9
+ console.log("Usage: emseepea-qualify --scenario <module.mjs> --output <evidence.json>");
10
+ process.exit(0);
11
+ }
12
+
13
+ const scenarioPath = option("--scenario");
14
+ const output = option("--output");
15
+ if (!scenarioPath || !output || values.length !== 4) fail("Expected --scenario and --output");
16
+
17
+ try {
18
+ const loaded = await import(pathToFileURL(resolve(scenarioPath)).href);
19
+ const scenario = typeof loaded.default === "function" ? await loaded.default() : loaded.default;
20
+ const evidence = await runMcpCliQualification(scenario, resolve(output));
21
+ console.log(`MCP CLI qualification ${evidence.status}; evidence: ${output}`);
22
+ if (evidence.status !== "passed") process.exitCode = 1;
23
+ } catch {
24
+ fail("MCP CLI qualification could not run");
25
+ }
26
+
27
+ function option(name) {
28
+ const index = values.indexOf(name);
29
+ if (index < 0 || index === values.length - 1 || values[index + 1].startsWith("--")) return undefined;
30
+ if (values.indexOf(name, index + 1) >= 0) fail(`Duplicate ${name}`);
31
+ return values[index + 1];
32
+ }
33
+
34
+ function fail(message) {
35
+ console.error(message);
36
+ process.exit(2);
37
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emseepea/testing",
3
- "version": "0.21.0",
3
+ "version": "0.21.1",
4
4
  "description": "MCP integration and semantic testing helpers",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -31,10 +31,12 @@
31
31
  },
32
32
  "bin": {
33
33
  "emseepea-contract": "./published-contract/cli.mjs",
34
+ "emseepea-qualify": "./mcp-cli/cli.mjs",
34
35
  "emseepea-test": "./semantic/cli.mjs"
35
36
  },
36
37
  "files": [
37
38
  "dist",
39
+ "mcp-cli",
38
40
  "published-contract",
39
41
  "semantic",
40
42
  "LICENSE",