From 3ca5670c37079ceb7a182c746c4bf41c86832b86 Mon Sep 17 00:00:00 2001 From: Dmitry Sergeev Date: Sat, 10 Oct 2026 11:14:35 +0200 Subject: [PATCH 1/2] chore(conformance): run against 0.2.0-alpha.12 0.2.0-alpha.11 added the json-schema-2020-12-preservation client scenario. The conformance client does not handle it and exits with "Unsupported conformance scenario", so both client suites fail on it once CI moves past alpha.10. Handle the scenario as it asks: list tools, then send the inputSchema of json_schema_2020_12_tool back through json_schema_echo. rmcp keeps every keyword the scenario checks. Bump CONFORMANCE_VERSION to alpha.12. --- .github/workflows/conformance.yml | 2 +- conformance/src/bin/client.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/.github/workflows/conformance.yml b/.github/workflows/conformance.yml index 1233deb56..23ccc9cca 100644 --- a/.github/workflows/conformance.yml +++ b/.github/workflows/conformance.yml @@ -12,7 +12,7 @@ concurrency: cancel-in-progress: true env: - CONFORMANCE_VERSION: "0.2.0-alpha.10" + CONFORMANCE_VERSION: "0.2.0-alpha.12" permissions: contents: read diff --git a/conformance/src/bin/client.rs b/conformance/src/bin/client.rs index aef2c2755..5d753049d 100644 --- a/conformance/src/bin/client.rs +++ b/conformance/src/bin/client.rs @@ -993,6 +993,31 @@ async fn run_elicitation_defaults_client(server_url: &str) -> anyhow::Result<()> Ok(()) } +/// SEP-1613/SEP-2106: send the focal tool's `inputSchema` back through the +/// echo tool, so the scenario can diff it against what the server listed. +async fn run_json_schema_preservation_client(server_url: &str) -> anyhow::Result<()> { + let transport = StreamableHttpClientTransport::from_uri(server_url); + let client = FullClientHandler + .serve_with_lifecycle(transport, conformance_lifecycle()) + .await?; + let tools = client.list_tools(Default::default()).await?; + let tool = tools + .tools + .iter() + .find(|t| t.name.as_ref() == "json_schema_2020_12_tool") + .ok_or_else(|| anyhow::anyhow!("json_schema_2020_12_tool was not listed"))?; + let mut args = serde_json::Map::new(); + args.insert( + "schema".to_string(), + Value::Object(tool.input_schema.as_ref().clone()), + ); + client + .call_tool(call_tool_params("json_schema_echo".into(), Some(args))) + .await?; + client.cancel().await?; + Ok(()) +} + fn conformance_protocol_version() -> ProtocolVersion { std::env::var("MCP_CONFORMANCE_PROTOCOL_VERSION") .ok() @@ -1115,6 +1140,9 @@ async fn run_scenario( // close is sufficient; the scenario's mock server does not implement // the discover lifecycle, so `run_discover_client` hangs against it. "json-schema-ref-no-deref" => run_basic_client(server_url).await?, + "json-schema-2020-12-preservation" => { + run_json_schema_preservation_client(server_url).await? + } "tools_call" => run_tools_call_client(server_url, ctx).await?, "elicitation-sep1034-client-defaults" => { run_elicitation_defaults_client(server_url).await? From f42dad57275a6a3028d50a66479291edb2a1474c Mon Sep 17 00:00:00 2001 From: Dmitry Sergeev Date: Sat, 10 Oct 2026 16:58:01 +0200 Subject: [PATCH 2/2] chore(conformance): fail the schema preservation run on a tool error The json_schema_echo result was dropped, so a tool-level error still let the client exit 0. Check is_error so local runs fail loudly. --- conformance/src/bin/client.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/conformance/src/bin/client.rs b/conformance/src/bin/client.rs index 5d753049d..08c604529 100644 --- a/conformance/src/bin/client.rs +++ b/conformance/src/bin/client.rs @@ -1011,9 +1011,15 @@ async fn run_json_schema_preservation_client(server_url: &str) -> anyhow::Result "schema".to_string(), Value::Object(tool.input_schema.as_ref().clone()), ); - client + let result = client .call_tool(call_tool_params("json_schema_echo".into(), Some(args))) .await?; + if result.is_error == Some(true) { + anyhow::bail!( + "json_schema_echo returned a tool error: {:?}", + result.content + ); + } client.cancel().await?; Ok(()) }