Skip to content

Preserve MCP identifiers for single-backend hosts - #57

Merged
dawid-nowak merged 1 commit into
mainfrom
user/luca/preserve-mcp-identifiers
Jul 14, 2026
Merged

Preserve MCP identifiers for single-backend hosts#57
dawid-nowak merged 1 commit into
mainfrom
user/luca/preserve-mcp-identifiers

Conversation

@lucarlig

@lucarlig lucarlig commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Why

MCP tool names, prompt names, resource URIs, resource-template URIs, and completion references are protocol-visible identifiers. A transparent gateway should preserve them unless a namespace is needed to disambiguate multiple backends.

The conformance virtual host has one backend. Prefixing its identifiers with the backend UUID changes the upstream MCP contract, leaks an internal control-plane identifier, and prevents clients from using canonical values such as test_simple_text and test://template/{id}/data.

Routing contract

Configuration Downstream identifier Upstream routing
Explicit tool alias Exact alias published by the control plane Map the alias to its upstream original name
One backend, no alias Preserve the upstream identifier byte-for-byte Select the only backend
Multiple backends, no alias {backend-map-key}-{identifier} Split the prefix and select that backend

This rule applies to tool calls, prompts, resources and resource templates, completion references, resource subscriptions, and resource-update notification URIs. Multi-backend virtual hosts retain collision-safe prefixing.

What changed

  • preserve canonical tool, prompt, resource, resource-template, and completion identifiers for single-backend virtual hosts
  • retain exact control-plane tool aliases and route them to their upstream original names
  • route subscribe and unsubscribe with the same single-versus-multi-backend rule
  • preserve single-backend resource-update notification URIs
  • retain backend-prefixed identifiers for multi-backend virtual hosts without aliases
  • update regression tests and the gateway book to document the contract

Conformance evidence

The original pinned conformance profile was rerun through the full public route against merged commit 0c24df5 (tree-identical to PR head 5e811d4) using cf-integration@6bf4000:

CF_DATAPLANE_REF=0c24df5e0affd3febe3e7589503a4b26000ed66f \
  cargo run --locked -- compliance conformance \
    --mode dataplane --start --spec-version 2025-11-25 --suite all
  • oracle: @modelcontextprotocol/conformance@0.1.16
  • fixture: official TypeScript server at 21a9a2febd7100d7c17ac1021ee7f2ed9f66a1e0
  • suite: all for specification 2025-11-25 — 32 scenarios
  • route: nginx → Rust dataplane → official TypeScript conformance server
  • scenario result: 25 passed, 7 failed
  • raw check result: 31 passed, 7 failed, plus one non-failing SSE reconnection warning
  • change from the pre-fix baseline: passing scenarios 9 → 25 (+16); failing scenarios 23 → 7 (-16)

Completion, JSON Schema 2020-12, prompts, resources, resource templates, subscriptions, and tool calls using canonical identifiers pass. The seven remaining failures are outside identifier routing:

  • logging: logging-set-level, tools-call-with-logging
  • callback forwarding: tools-call-sampling, tools-call-elicitation, elicitation-sep1034-defaults, elicitation-sep1330-enums
  • transport security: dns-rebinding-protection

The command exits non-zero because the default expected-failure baseline does not suppress these known gaps; all 32 scenarios completed and the result artifacts were marked complete.

Validation

The merged commit 0c24df5 is tree-identical to tested PR head 5e811d4.

  • cargo test -p contextforge-gateway-rs-lib — 42 passed
  • cargo clippy -p contextforge-gateway-rs-lib --all-targets -- -D warnings
  • cargo fmt --all --check
  • mdbook build docs/book
  • mdbook test docs/book
  • git diff --check
  • GitHub CI: fmt, clippy, cargo-deny, cargo-shear, test, build, bench, and book build passed

@lucarlig
lucarlig marked this pull request as ready for review July 13, 2026 13:03
@lucarlig lucarlig self-assigned this Jul 14, 2026
Signed-off-by: lucarlig <luca.carlig@ibm.com>
@lucarlig
lucarlig force-pushed the user/luca/preserve-mcp-identifiers branch from 507f0a4 to 5e811d4 Compare July 14, 2026 15:43
@dawid-nowak
dawid-nowak self-requested a review July 14, 2026 15:54
@dawid-nowak
dawid-nowak merged commit 0c24df5 into main Jul 14, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants