ADR-0022 — MCP 2026-07-28 features mocapi deliberately does not implement¶
- Status: Accepted — supersedes ADR-0018
- Date: 2026-06-11
Context¶
ADR-0018 was the canonical
list of MCP spec features mocapi declared not supported, written against
the 2025-11-25 revision. The clean break to 2026-07-28
(ADR-0019) changes the list in both
directions: the new revision deprecates features mocapi previously
implemented (Roots handling, Sampling, MCP Logging), removes mechanisms
some old entries referenced (listChanged capabilities, the stateful
session model), and introduces new optional surface
(subscriptions/listen, official extensions, custom parameter headers)
that needs an explicit stance.
As before: a user evaluating mocapi needs a single place to look up "does mocapi do X?" with the rationale, and conformance tooling needs a stable declared-not-supported list. This ADR is the canonical record for the 2026-07-28 revision. Spec references point at the draft specification (release candidate locked 2026-05-21) and the SEPs that shaped it.
Decision¶
Mocapi declares the following 2026-07-28 features unimplemented (or, in one case, partially implemented) and documents the rationale for each.
Roots, Sampling, and MCP Logging¶
Spec reference: SEP-2577 (draft changelog)
Not implemented. SEP-2577 deprecates all three; the spec says new
implementations should not adopt them. ctx.sample(...) and
ctx.log(...) are removed from the mocapi API, and the server neither
reads root information nor emits notifications/message.
Rationale: a framework rewritten as if designed against 2026-07-28 from the start (ADR-0019) would not adopt features the same revision deprecates. The spec's suggested migrations apply directly:
- Roots → pass directories/files via tool parameters, resource URIs, or server configuration.
- Sampling → integrate directly with LLM provider APIs.
- Logging → stderr on stdio, or OpenTelemetry — which
mocapi-otel(ADR-0017) already covers.
Note: notifications/progress is not deprecated and remains
supported, flowing on the request's own response stream.
subscriptions/listen¶
Spec reference: draft changelog
Not implemented.
Rationale: mocapi discovers tools, prompts, and resources
statically at application startup
(ADR-0010), so it has no
list-change or resource-update notifications to push. This carries
forward ADR-0018's resource-subscription and listChanged rationale
into the new mechanism: change detection and subscriber tracking add
significant complexity for a capability the framework's static
discovery model cannot feed. If dynamic registration ever lands,
subscriptions/listen is the place this decision gets reopened.
Tasks extension (io.modelcontextprotocol/tasks)¶
Spec reference: SEP-2663 (draft changelog)
Accepted — implemented in ADR-0037
(mocapi-tasks); notifications/tasks push remains declined.
Originally declined here on the grounds that the task lifecycle was a
substantial state machine mocapi's synchronous handler model didn't
need; a 2026-08-02 redesign found that the replay pattern
ADR-0021 already built for wire
elicitation generalizes directly to task resume — one execution core,
two ledger carriers — so the extension fits as a shallow, opt-in module
rather than a bespoke parked-thread state machine. mocapi-tasks
implements tasks/get/tasks/update/tasks/cancel (polling only,
tools/call-augmentation only) via a single @McpTask annotation on an
otherwise-ordinary tool. notifications/tasks push rides the same
subscriptions/listen mechanism this ADR already declines above
(mocapi's static handler discovery model has no change-notification
source to feed it) and stays unimplemented — see ADR-0037 for the full
scope.
MCP Apps extension¶
Spec reference: SEP-1865 (2026-07-28 release candidate announcement)
Accepted — implemented in ADR-0033
(mocapi-apps); the postMessage/JS-bridge layer remains out of
scope. Originally declined here on the grounds that Apps was a
presentation-layer concern outside mocapi's handler model; revisiting
the spec showed the extension splits into a server surface (ui://
resource serving, _meta.ui linkage, capability declaration — a
shallow, additive fit for the existing annotation-driven model) and a
host/in-iframe JavaScript surface (the postMessage bridge,
ui/initialize, display-mode negotiation, app-registered tools).
mocapi implements the former and does not implement the latter — see
ADR-0033 for the full scope boundary.
URL-Mode Elicitation¶
Spec reference: draft changelog
Mocapi supports form-mode elicitation via MRTR replay (ADR-0021). URL-mode elicitation is not implemented.
Rationale: carried forward from ADR-0018. URL mode involves out-of-band browser interactions and OAuth flows that are significantly more complex than form mode, and its design remains subject to change across protocol revisions. Mocapi will revisit when it stabilizes.
JSON-RPC Batching¶
Spec reference: Transports / Streamable HTTP
Not supported. The spec continues to require that a POST body be a single JSON-RPC message; batching (arrays of messages) remains prohibited by the spec. Carried forward from ADR-0018: mocapi follows the spec.
Cancellation Processing (partial)¶
Spec reference: Transports / Streamable HTTP
Partially implemented — this stance is recorded explicitly. The 2026-07-28 transport rules state that the client closing the SSE response stream MUST be treated as cancellation of the in-flight request. Mocapi honors the MUST: once the stream is closed, no further messages are sent for that request (automatic on disconnect). Mocapi does not interrupt the in-flight handler's execution.
Rationale: carried forward from ADR-0018. Handlers run on virtual threads without cooperative cancellation (ADR-0006); interrupting them safely is not feasible without handler-author cooperation. The "SHOULD stop processing" half of the rule is best-effort: the work completes, but its output goes nowhere.
Ratified for 1.0.0 (2026-07-29). Re-reviewed during the 1.0 release
sweep against the project's "adhere to SHOULD-level requirements by
default" posture, which this entry is a deliberate exception to. The
MUST half is honored unconditionally; the SHOULD half stays best-effort
for 1.0. Interrupting a handler mid-execution would mean
Thread.interrupt() on the per-call virtual thread, which is only
observable at interruptible blocking points — a handler doing CPU work,
a non-interruptible I/O call, or a synchronized section would ignore
it, while one holding a lock or mid-write to an external system could be
torn down at an unsafe point. Correct cancellation therefore requires a
handler-visible cancellation token that authors opt into and check;
that is a public API addition, not a 1.0 bug fix. The cost is bounded
and non-protocol-visible: the client already sees nothing after
disconnect, so the only consequence is wasted server-side work.
Revisitable post-1.0 by threading a cancellation signal through
MrtrContext (ADR-0025),
which is the natural carrier now that it is the shared handler-context
base.
Custom Parameter Headers (x-mcp-header)¶
Spec reference: SEP-2243 (Transports / Streamable HTTP)
Mocapi designates no custom parameter headers — declined on principle in
ADR-0028 (an HTTP-only
feature that would breach the transport-agnostic server contract). SEP-2243 makes
x-mcp-header support mandatory for clients but optional for servers —
a server MAY designate none, and mocapi designates none. Unrecognized
Mcp-Param-* headers on incoming requests are ignored, per RFC 9110's
treatment of unrecognized header fields.
Possible future: an @McpTool parameter annotation that designates
a tool parameter as header-supplied. Not currently planned.
Extensions¶
Spec reference: draft changelog
The extensions capability map is advertised empty by core. Two
official extensions populate an entry when their optional module is
present, both via ServerCapabilitiesCustomizer
(ADR-0031): io.modelcontextprotocol/ui
from mocapi-apps (ADR-0033)
and io.modelcontextprotocol/tasks from mocapi-tasks
(ADR-0037). Core itself still enumerates
none.
2026-07-28 authorization review (record of verification)¶
Spec references: SEP-2468 (RFC 9207 iss validation), SEP-837
(application_type at DCR), SEP-2352 (issuer-bound credentials),
SEP-2207 (refresh tokens), SEP-2350 (scope accumulation), SEP-2351
(.well-known suffix), and the RFC 7591 DCR deprecation in favor of
Client ID Metadata Documents.
Reviewed 2026-06-12 against the draft authorization spec. All seven
changes are client- or authorization-server-side; none impose new
resource-server MUSTs. Mocapi's resource-server obligations remain met
without code changes: bearer validation with mandatory audience
enforcement (MocapiOAuth2Compliance,
AudienceCheckingOpaqueTokenIntrospector) in both JWT and opaque-token
modes; RFC 9728 Protected Resource Metadata at
/.well-known/oauth-protected-resource with the standard field set
(shape unchanged in the draft); 401 on missing/invalid tokens; no
offline_access in scopes_supported.
SHOULD-level challenge enhancements (no protocol impact): the
scope parameter on 401 WWW-Authenticate challenges, and 403
insufficient_scope challenges for step-up authorization flows. Recorded
as deferred at the time of this review; decided for 1.0 in
ADR-0029, which
supersedes this paragraph. In short: RFC 9728 resource_metadata on the
401 is emitted (inherited from Spring Security 7's default entry point);
the scope parameter on a bare 401 is declined as duplicate of the
metadata document's scopes_supported; resource-level 403
insufficient_scope is adopted through the new
mocapi.oauth2.required-scopes property; and per-tool step-up is declined
because it conflicts with visibility ≡ invocation
(ADR-0012) and would leak hidden handlers.
Consequences¶
What this buys us. A single, citable list of declared-not-supported features for the 2026-07-28 revision. Conformance tooling can assert against this list and trust it — conformance failures should map 1:1 to entries here. Users evaluating mocapi can compare needs to omissions in one read, and each omission has a stated reason that's reviewable when the constraint changes.
Costs. Use cases needing URL-mode elicitation or true mid-execution cancellation require a different framework today; Tasks and MCP Apps have since moved to Accepted (see above). Each omission is revisitable — the rationale is recorded so future revisions can reopen the decision.
Non-goals. This ADR does not list every minor protocol feature; it lists the ones we have explicitly evaluated and declined. Any feature not mentioned here and not present in the code is a gap that has not been formally decided either way — file an issue.
This ADR supersedes ADR-0018, which recorded the equivalent stances for the 2025-11-25 revision.
Code anchors: mocapi-server/.../server/discover/DiscoverHandler.java
(builds the server/discover result advertising supported capabilities)
and mocapi-model/.../model/ServerCapabilities.java (the advertised
capability set, whose extensions map is empty — no extension
implemented).