test: add Python MCP conformance CI - #6391
Conversation
3d420b5 to
ad39ce0
Compare
msureshkumar88
left a comment
There was a problem hiding this comment.
Reviewed the full diff (via the GitHub API, not the summarized CLI diff) against main and traced the surrounding code the PR depends on rather than reviewing the diff in isolation.
Scope: purely CI/test-harness — 21 files under .github/workflows/, tests/conformance/, Makefile, .gitignore, .secrets.baseline. No mcpgateway/ application code touched, no Alembic migration needed, not a UI or backend change.
Verified, not just trusted:
RATE_LIMITING_ENABLED=falsein the new compose file correctly maps toSettings.rate_limiting_enabled(mcpgateway/config.py) and actually disablesRateLimitMiddlewareenforcement including its lockout path (rate_limit_middleware.py) — the "disable rate limiting" fix commit isn't a no-op.- All referenced Containerfile build args, the
/healthroute, andMCPGATEWAY_SKIP_MIGRATIONSexist as expected. - Pinned GitHub Action SHAs match what's already used elsewhere in the repo's workflows.
- Cross-checked every count in the PR description's expected-failure tables against
expected-failures-2025-11-25.yml/expected-failures-2026-07-28.ymlline by line — all match exactly. report-baseline-diff.sh(the custom baseline-diff/bless logic) has solid dedicated test coverage inreport-baseline-diff-test.shcovering xfail/xpass/upstream-exclusion/duplicate/bless/missing-results paths.
No blocking issues. A couple of non-blocking suggestions for a fast-follow, not required for this PR:
tests/AGENTS.mdcould document the newtests/conformance/directory and themake conformance/make conformance-blesscommands.- Consider adding a "test-only, do not reuse" banner comment to
tests/conformance/docker-compose.yml, since it intentionally disables SSRF protection and rate limiting and uses a hardcoded (allowlisted) password — reasonable for this isolated, ephemeral harness, but worth flagging so it's never lifted as a starting template elsewhere.
Nice addition — this wires the project into the official, versioned MCP conformance suite for both the current and next protocol revision, with a maintained expected-failure baseline that makes real protocol/behavioral gaps visible in CI instead of undocumented.
msureshkumar88
left a comment
There was a problem hiding this comment.
Re-reviewed after the latest commit (529e963). It's local-output UX polish only — progress spinner, quieter setup logs, a run lock, and renaming expected-failures.yml → baseline.yml with matching test/reporter updates in report-baseline-diff.sh / report-baseline-diff-test.sh. No mcpgateway/ application code touched.
My earlier review had no blocking findings, just two non-blocking suggestions for a fast-follow (documenting tests/conformance/ in tests/AGENTS.md, and a "test-only" banner on the compose file since it disables SSRF protection/rate limiting) — neither is required for this PR.
One heads-up: GitHub shows this branch as conflicting with main (just .secrets.baseline line-number churn and non-overlapping Makefile additions) — worth a quick rebase before merge, unrelated to review content.
Approving.
Signed-off-by: lucarlig <luca.carlig@ibm.com>
Signed-off-by: lucarlig <luca.carlig@ibm.com>
Signed-off-by: lucarlig <luca.carlig@ibm.com>
Signed-off-by: lucarlig <luca.carlig@ibm.com>
529e963 to
87c18bc
Compare
Signed-off-by: lucarlig <luca.carlig@ibm.com>
Pull Request
🔗 Related Issue
closes #6018
📝 Summary
Adds official MCP 2025-11-25 and 2026-07-28 conformance for the gateway server and outbound client paths using the control plane and built-in Python data plane only. Includes
make conformance,make conformance-bless, expected-failure baselines, and PR CI. The isolated harness disables rate limiting/account lockout.📏 Reviewability
triageissue (none linked)🏷️ Type of Change
🧪 Verification
make conformance✅ Checklist
make help📓 Notes
Complete MCP 2025-11-25 expected-failure inventory
dns-rebinding-protection:localhost-host-rebinding-rejectedelicitation-sep1034-defaults,elicitation-sep1330-enumsprompts-get-embedded-resource,prompts-get-with-image[]; the client expects a validGetPromptResult.resources-read-binaryblobfield.resources-templates-readtest://template/123/dataresource is reported as not found.resources-subscribe,resources-unsubscribeMethod not found.server-sse-multiple-streams:server-sse-multiple-streams-sessiontools-call-elicitationtools-call-samplingtools-call-with-loggingThe former valid-localhost, prompt-list, simple-prompt, and argument-prompt 429 findings now pass after disabling harness rate limiting.
Complete MCP 2026-07-28 expected-failure inventory
ContextForge currently supports protocol revisions through 2025-11-25. It rejects
2026-07-28with HTTP 400 and a plain error object rather than a JSON-RPC error. The table accounts for all 89 scored failures; dependent capability and wire-schema checks fail from that same version-negotiation response.caching:*completion-complete:*completion/completeis rejected before execution; the HTTP error body is not valid JSON-RPC.dns-rebinding-protection:localhost-host-valid-acceptedinput-required-result-*(basic elicitation, list-roots, sampling, capability check, extra params, missing response, multi-round, multiple requests, non-tool request, request state, result type, tampered state, unsupported methods, validation)InputRequiredResultflows; each affected response also fails the negotiated wire schema.prompts-list,prompts-get-simple,prompts-get-with-args,prompts-get-with-image,prompts-get-embedded-resourceresources-list,resources-read-text,resources-read-binary,resources-templates-read,sep-2164-resource-not-foundserver-sse-multiple-streams:server-accepts-multiple-post-streamsserver-stateless:*(all scored SEP-2575 checks)_meta, capability, method/error, subscription, and header requirements are not implemented for 2026; rejection responses also omit required JSON-RPC error fields/IDs.tools-call-simple-text,tools-call-image,tools-call-audio,tools-call-embedded-resource,tools-call-mixed-content,tools-call-error,tools-listtools/listfails both behavior and wire-schema validation.Excluded or unscored fixture findings
tools-call-*:wire-schema-validchecks in 2026tools-call-with-progressserver-sse-pollingCI builds the PR merge commit from
Containerfile, runs the resulting local image in Python mode, and never pulls a ContextForgelatestimage or builds Rust. The conformance job takes 1m 30s and runs alongside pytest.