MCP 2026-07-28 Conformance

August 3, 2026 ยท View on GitHub

Labby targets the 2026-07-28 MCP protocol through rmcp = "=3.1.0". The gate verifies that production dependency exactly, exercises Labby's real authenticated /mcp boundary, runs the matching upstream rmcp fixture, and covers Labby-native gateway and multi-hop scenarios. Dated protocol, extension, and native-product results are reported separately so fixture coverage cannot hide a product regression or inflate the dated-protocol score.

Reproducible Pins

ComponentPin
MCP protocol2026-07-28
Labby rmcp dependency3.1.0
rmcp conformance fixture3.1.0
rmcp fixture tag commit1f9358eddca42d3a510c70ae6446dd6548c7c856
MCP conformance package0.2.0-alpha.10

Run the complete gate locally with:

scripts/ci/mcp-conformance.sh

The script verifies the exact production Cargo dependency and matching upstream fixture tag commit, installs the JavaScript conformance dependency once, builds a fresh Labby binary, and then runs:

  1. a Labby-native client -> root Labby -> middle Labby -> synthetic leaf chain
  2. the authenticated stateless Labby HTTP boundary smoke checks
  3. every dated 2026-07-28 server scenario
  4. every Tasks extension server scenario
  5. every dated 2026-07-28 client scenario
  6. the complete client extension suite

Reports are written under target/mcp-conformance/. Known dated fixture gaps use the strict conformance/expected-failures-dated.yaml baseline, while experimental extension gaps use conformance/expected-failures-extensions.yaml. An unexpected failure or an expected failure that starts passing both fail CI.

Labby-Native Multi-Hop Matrix

The mcp_multihop_conformance driver launches production Labby transports with isolated configuration:

MCP client -> root Labby (stdio) -> middle Labby (authenticated HTTP) -> leaf MCP server (stdio)

Middle and root are warmed through Labby's real gateway.reload lifecycle, not by test-only pool mutation. The leaf publishes more than one page of every catalog family so the chain proves ownership and pagination beyond the first page.

ScenarioMulti-hop assertion
DiscoveryRoot negotiates 2026-07-28 and identifies itself as Labby
Tools75 late-page tools plus an MRTR tool survive both gateways
Tool callsA late-page tool executes through root and middle with its arguments intact
MRTRinput_required remains first-class through both gateways
TasksCreate, get, update, and cancel route through both gateways; gateway IDs remain stable and task-status notifications are translated
ProgressProgress tokens and messages survive both gateway hops
CancellationA downstream cancellation traverses root -> middle -> leaf, where the leaf observes it
Prompts70 prompts aggregate; a late-page prompt can be fetched
Resources70 resources aggregate; nested gateway URIs remain routable on read
Resource templates70 templates aggregate without flattening nested gateway namespaces
CompletionCompletion against a nested resource template reaches the leaf
SubscriptionsTool, prompt, and resource list changes plus an exact resource update cross both gateways; re-listing exposes the dynamically added catalog entries
ProvenanceLabby stamps the responding server while preserving leaf identity and custom metadata

The driver discovered and now guards a critical namespace rule: an upstream resource URI is opaque. If middle returns lab://upstream/leaf/fixture://resource/069, root exposes lab://upstream/middle/lab://upstream/leaf/fixture://resource/069. Each hop removes only its own outer prefix. Flattening the inner prefix makes the URI unroutable.

Labby Product Contract

AreaLabby postureRegression evidence
Protocol lifecycleModern clients use stateless server/discover; legacy initialize is adapted only at the transport edgediscovery tests, bridge tests, and the multi-hop driver
Stateless HTTPNo Mcp-Session-Id; NeverSessionManager; JSON responsesHTTP lifecycle tests and rmcp dated suite
SEP-2243 headersrmcp validates method/name headers before dispatchHTTP method/name header tests
Request envelopesMetadata, input responses, request state, cancellation, and progress association survive proxy routesrequest-envelope tests and relay module
Cache hintsDynamic Labby lists/reads emit ttlMs: 0 with private scopetool, prompt, resource, and server serialization tests
MRTRTool, prompt, and resource intermediate results remain first-classrelay tests and multi-hop driver
TasksGateway-owned handles route get/update/cancel and translate task-status IDstask routing tests and relay task-status regression
SubscriptionsLabby consumes upstream listen streams and forwards subscribed list/resource notificationsupstream subscription and peer fanout tests
Resource subscriptionsLabby acknowledges only exact URIs an upstream acceptedsubscription filter tests
Progress and cancellationRequest IDs and progress tokens are translated per relay connection; cancellation targets the actual upstream requestcomplete relay module, 15 passing tests
ProvenanceOrdinary results identify Labby and preserve distinct upstream server identity under ai.dinglebear.labby/upstreamServerInfoprovenance unit test and multi-hop driver
Error fidelityTool error classification is observational; original content, structured content, and metadata pass throughupstream normalization tests
Auth and scope step-upLabby owns inbound OAuth 2.1 policy, CIMD, RFC 9207 issuer binding, revocation, client credentials, ID-JAG exchange, and RFC 9728 challengesdated client suite plus Labby auth contract tests

Lifecycle compatibility

Labby's internal contract is stateless 2026-07-28 discovery. A legacy initialize request is accepted as an edge adapter for existing hosts: Labby records the peer information and returns the negotiated legacy version without changing internal request handling or creating a resumable session.

MRTR and tasks

Destructive actions return an MRTR input_required result with an elicitation form. The client resubmits normal MCP input responses; Labby does not replace this with a private confirmation protocol.

Labby also does not create a second task scheduler. An upstream task receives a subject-bound gateway handle. Subsequent tasks/get, tasks/update, and tasks/cancel calls route over the connection that created it. Incoming notifications/tasks messages translate the native task ID back to the gateway handle before reaching the downstream client.

Cache and subscriptions

Catalog-derived responses are dynamic and private:

{
  "ttlMs": 0,
  "cacheScope": "private"
}

Labby establishes upstream subscriptions/listen streams, consumes list and resource updates, and publishes normalized events to downstream subscription sinks. Downstream acknowledgement is filtered to notification categories and resource URIs Labby can actually deliver. Protected-route scope remains applied when notifications fan out. A tool-list change first re-lists the exact named upstream and atomically replaces that upstream's cached tools before peer-visible contracts are evaluated. Both long-lived subscription streams and request-scoped relay connections publish through this refresh path.

Multi-hop cancellation

Stateless HTTP sessions cannot use transport-local request IDs to correlate a cancellation reliably across gateway hops. Labby therefore attaches an opaque relay token to the proxied request and sends an acknowledgement-bearing custom JSON-RPC request using MCP_RELAY_CANCELLATION_REQUEST_METHOD. A negative acknowledgement is retried within a bounded delivery window after the upstream request ID is published. Standard MCP cancellation remains the compatibility fallback for peers that do not understand the relay request.

OAuth extensions and scope step-up

Labby's inbound authorization server supports authorization-code flow, refresh-token rotation and revocation, and the optional MCP OAuth client credentials extension. Machine clients are preregistered out of band and may authenticate with client_secret_basic or RFC 7523 private_key_jwt; assertions are audience-bound to /token and replay-protected.

Trusted enterprise issuers may be configured for enterprise-managed authorization. Labby validates oauth-id-jag+jwt assertions against pinned inline or HTTPS JWKS and enforces issuer, audience, client, resource, scope, expiry, and one-time jti.

The expected-failure entries for enterprise-managed authorization, DPoP, DPoP nonce, and WIF JWT-bearer describe experimental outbound flows not implemented by the pinned rmcp conformance client. They do not describe Labby's inbound authorization server. Product-server coverage runs before the SDK fixture harness in the same CI job.

Event stores and disconnect

The hosted Labby endpoint is intentionally stateless. It uses NeverSessionManager, so there is no server-side resume cursor or disconnect cleanup contract. Event-store examples remain validated by the pinned rmcp SDK harness; a durable event-store deployment would be a separate mode.

CI and Maintenance

The MCP 2026-07-28 conformance job is part of ci-gate. JavaScript dependency installation is serialized before scenarios start. The production rmcp dependency and upstream fixture remain explicit pins even when they match; adopt version changes together only after reviewing the dated fixture baseline, and review the Labby-native matrix plus dated and extension baselines on every update.

The separate MCP upstream drift workflow compares conformance/upstream-baseline.json with the current specification branch and latest rmcp release. Detected drift opens or updates one stable issue; advance the baseline only in the PR that adopts and verifies the upstream change.

Primary references: