From 830f0b76e7d4ed2f2b77ca9eb4c481d880771fff Mon Sep 17 00:00:00 2001 From: Guglielmo Colombo Date: Thu, 3 Sep 2026 11:27:42 +0200 Subject: [PATCH] mcp: update conformance tests (#1231) Fixes #1230 --- .github/workflows/conformance.yml | 12 ++++---- conformance/everything-client/main.go | 41 +++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/.github/workflows/conformance.yml b/.github/workflows/conformance.yml index 7d6cca4..6f54df4 100644 --- a/.github/workflows/conformance.yml +++ b/.github/workflows/conformance.yml @@ -14,7 +14,7 @@ permissions: contents: read env: - CONFORMANCE_VERSION: "0.2.0-alpha.10" + CONFORMANCE_VERSION: "0.2.0-alpha.11" jobs: server-conformance: @@ -32,7 +32,7 @@ jobs: node-version: 22 - name: Build everything-server run: go build -o everything-server ./conformance/everything-server - - name: Run conformance tests (stateful, legacy spec versions) + - name: Run conformance tests (2025-11-25, stateful) run: | ./everything-server -http=":3001" -stateless=false & SERVER_PID=$! @@ -40,10 +40,9 @@ jobs: timeout 30 bash -c 'until curl -s http://localhost:3001/mcp > /dev/null; do sleep 0.5; done' npx -y "@modelcontextprotocol/conformance@${CONFORMANCE_VERSION}" server \ --url http://localhost:3001/mcp \ - --suite active \ - --spec-version 2025-11-25 \ + --requirements 2025-11-25 \ --expected-failures ./conformance/baseline.yml - - name: Run conformance tests (stateless, 2026-07-28, full suite) + - name: Run conformance tests (2026-07-28, stateless) run: | ./everything-server -http=":3001" -stateless & SERVER_PID=$! @@ -51,8 +50,7 @@ jobs: timeout 30 bash -c 'until curl -s http://localhost:3001/mcp > /dev/null; do sleep 0.5; done' npx -y "@modelcontextprotocol/conformance@${CONFORMANCE_VERSION}" server \ --url http://localhost:3001/mcp \ - --suite all \ - --spec-version 2026-07-28 \ + --requirements 2026-07-28 \ --expected-failures ./conformance/baseline.yml client-conformance: diff --git a/conformance/everything-client/main.go b/conformance/everything-client/main.go index 3776522..b7d8ba0 100644 --- a/conformance/everything-client/main.go +++ b/conformance/everything-client/main.go @@ -49,6 +49,7 @@ func init() { registerScenario("elicitation-sep1034-client-defaults", runElicitationDefaultsClient) registerScenario("sse-retry", runSSERetryClient) registerScenario("json-schema-ref-no-deref", runJSONSchemaRefNoDerefClient) + registerScenario("json-schema-2020-12-preservation", runJSONSchemaPreservationClient) registerScenario("sep-2322-client-request-state", runMrtrClient) registerScenario("http-standard-headers", runHTTPStandardHeadersClient) registerScenario("http-custom-headers", runHTTPCustomHeadersClient) @@ -343,6 +344,46 @@ func runJSONSchemaRefNoDerefClient(ctx context.Context, serverURL string, _ map[ return nil } +// ============================================================================ +// json-schema-2020-12-preservation scenario (SEP-1613, SEP-2106) +// ============================================================================ + +// runJSONSchemaPreservationClient echoes the focal tool's inputSchema back to +// the referee verbatim, through the permissive json_schema_echo tool, so that +// it can observe which 2020-12 keywords survived the client's parse of +// tools/list. The Go SDK surfaces a server's schema as the raw JSON object it +// received, so nothing is stripped. +func runJSONSchemaPreservationClient(ctx context.Context, serverURL string, _ map[string]any) error { + session, err := connectToServer(ctx, serverURL) + if err != nil { + return err + } + defer session.Close() + + tools, err := session.ListTools(ctx, nil) + if err != nil { + return fmt.Errorf("session.ListTools(): %v", err) + } + + const focalTool = "json_schema_2020_12_tool" + idx := slices.IndexFunc(tools.Tools, func(t *mcp.Tool) bool { + return t.Name == focalTool + }) + if idx == -1 { + return fmt.Errorf("tool %q not found", focalTool) + } + + const echoTool = "json_schema_echo" + if _, err := session.CallTool(ctx, &mcp.CallToolParams{ + Name: echoTool, + Arguments: map[string]any{"schema": tools.Tools[idx].InputSchema}, + }); err != nil { + return fmt.Errorf("session.CallTool(%q): %v", echoTool, err) + } + + return nil +} + // ============================================================================ // SEP-2322 multi-round-trip client scenario // ============================================================================