Skip to content

Commit 01a76c4

Browse files
test(conformance): drive json-schema-2020-12-preservation and pin the alpha.11 referee
Register the client-side json-schema-2020-12-preservation scenario in the everything client (tools/list, then echo the observed inputSchema through json_schema_echo; modern lifecycle under a 2026-07-28 run), bump @modelcontextprotocol/conformance 0.2.0-alpha.10 -> 0.2.0-alpha.11 and record the reconciliation in both expected-failures baselines. All four legs pass with no new entries.
1 parent 65fd0e2 commit 01a76c4

5 files changed

Lines changed: 98 additions & 11 deletions

File tree

pnpm-lock.yaml

Lines changed: 23 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/conformance/expected-failures.2026-07-28.yaml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,16 @@
1212
# 2025 legs.
1313
#
1414
# Baseline established against the published @modelcontextprotocol/conformance
15-
# release pinned in package.json. Newer conformance releases are adopted by
16-
# deliberately bumping the pin and reconciling this file in the same change.
15+
# release pinned in package.json (0.2.0-alpha.11). Newer conformance releases
16+
# are adopted by deliberately bumping the pin and reconciling this file in the
17+
# same change.
18+
#
19+
# alpha.10 -> alpha.11 reconciliation: `json-schema-2020-12-preservation`
20+
# (client leg; everythingClient negotiates via server/discover like tools_call)
21+
# passes at 2026-07-28 — the referee reports it as added-after-release, unscored
22+
# on the frozen 2026-07-28 set — and `server-session-lifecycle` is not
23+
# applicable at 2026-07-28 (removed in that revision, skipped by
24+
# --spec-version), so both sections stay empty.
1725
#
1826
# NOTE: the SDK's modern-path rejection codes are aligned with what this
1927
# referee asserts — both sides have adopted the spec#2907 / conformance#353

test/conformance/expected-failures.yaml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,17 @@
22
# CI exits 0 if only these fail, exits 1 on unexpected failures or stale entries.
33
#
44
# Baseline established against the published @modelcontextprotocol/conformance
5-
# release pinned in package.json (0.2.0-alpha.10). Newer conformance releases
5+
# release pinned in package.json (0.2.0-alpha.11). Newer conformance releases
66
# are adopted by deliberately bumping the package.json pin and reconciling
77
# this file in the same change.
88
#
9+
# alpha.10 -> alpha.11 reconciliation: the referee added two scenarios, both
10+
# passing, so neither is baselined — `json-schema-2020-12-preservation`
11+
# (client; SEP-1613/SEP-2106 keyword round-trip, driven by everythingClient.ts)
12+
# and `server-session-lifecycle` (server; Streamable HTTP session teardown).
13+
# The referee now also sends HTTP DELETE after every session-bound scenario
14+
# (conformance#316); the everything server already answers it.
15+
#
916
# NOTE: the SDK's modern-path rejection codes are aligned with what this
1017
# referee asserts — both sides have adopted the spec#2907 / conformance#353
1118
# renumber (-32020 HeaderMismatch / -32021 MissingRequiredClientCapability /

test/conformance/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"test:conformance:all": "pnpm run test:conformance:client:all && pnpm run test:conformance:server:all"
3939
},
4040
"devDependencies": {
41-
"@modelcontextprotocol/conformance": "0.2.0-alpha.10",
41+
"@modelcontextprotocol/conformance": "0.2.0-alpha.11",
4242
"@modelcontextprotocol/client": "workspace:^",
4343
"@modelcontextprotocol/server": "workspace:^",
4444
"@modelcontextprotocol/core-internal": "workspace:^",

test/conformance/src/everythingClient.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,62 @@ async function runJsonSchemaRefNoDerefClient(serverUrl: string): Promise<void> {
802802

803803
registerScenario('json-schema-ref-no-deref', runJsonSchemaRefNoDerefClient);
804804

805+
// ============================================================================
806+
// JSON Schema 2020-12 keyword preservation scenario (SEP-1613, SEP-2106)
807+
// ============================================================================
808+
809+
/** The tool whose `inputSchema` carries the full JSON Schema 2020-12 fixture. */
810+
const JSON_SCHEMA_2020_12_TOOL = 'json_schema_2020_12_tool';
811+
/** The permissive echo tool that hands the observed schema back to the referee. */
812+
const JSON_SCHEMA_ECHO_TOOL = 'json_schema_echo';
813+
814+
/**
815+
* The scenario advertises a focal tool whose inputSchema uses `$schema`,
816+
* `$defs` (with `$anchor`), `additionalProperties`, composition
817+
* (`allOf`/`anyOf`) and conditional (`if`/`then`/`else`) keywords. The client
818+
* lists tools and passes that inputSchema back verbatim — exactly as
819+
* `listTools()` exposes it — through `tools/call json_schema_echo`, so the
820+
* referee can diff what survived the SDK's parsing against its fixture.
821+
*
822+
* The scenario spans both eras: under a 2026-07-28 run the client negotiates
823+
* the modern lifecycle via server/discover (as tools_call does) and drives the
824+
* same list → echo flow.
825+
*/
826+
async function runJsonSchema2020_12PreservationClient(serverUrl: string): Promise<void> {
827+
const client = new Client(
828+
{ name: 'json-schema-2020-12-preservation-client', version: '1.0.0' },
829+
isModernConformanceRun() ? { capabilities: {}, versionNegotiation: { mode: 'auto' } } : { capabilities: {} }
830+
);
831+
832+
const transport = new StreamableHTTPClientTransport(new URL(serverUrl));
833+
834+
await client.connect(transport);
835+
logger.debug('Successfully connected to MCP server');
836+
837+
const tools = await client.listTools();
838+
logger.debug(
839+
'Available tools:',
840+
tools.tools.map(t => t.name)
841+
);
842+
843+
const focal = tools.tools.find(t => t.name === JSON_SCHEMA_2020_12_TOOL);
844+
if (!focal) {
845+
throw new Error(`Tool '${JSON_SCHEMA_2020_12_TOOL}' not advertised by the server`);
846+
}
847+
logger.debug('Observed inputSchema:', JSON.stringify(focal.inputSchema, null, 2));
848+
849+
const result = await client.callTool({
850+
name: JSON_SCHEMA_ECHO_TOOL,
851+
arguments: { schema: focal.inputSchema }
852+
});
853+
logger.debug('Echo result:', JSON.stringify(result, null, 2));
854+
855+
await client.close();
856+
logger.debug('Connection closed successfully');
857+
}
858+
859+
registerScenario('json-schema-2020-12-preservation', runJsonSchema2020_12PreservationClient);
860+
805861
// ============================================================================
806862
// Main entry point
807863
// ============================================================================

0 commit comments

Comments
 (0)