Class McpMrtrConfig
McpRevision.
Mirrors McpCacheConfig's exact placement precedent (spec Open item #2): MRTR is as
2026-07-28-only as cache hints, so its configuration lives here, on the v2 adapter, never on the
revision-neutral McpServerConfig.
Mutable during setup, effectively immutable once published. This is a builder-less mutable-setup
bean: its fluent setters exist to configure it during construction, but a binding must fully configure it
before handing it to a McpRevision and must never mutate it afterward. The dispatcher reads
the codec/TTL/max-rounds on every request with no synchronization, so a post-publication mutation is a data
race; treat a published instance as read-only.
Defaults: AeadRequestStateCodec (a fresh instance per McpMrtrConfig), a 5-minute
requestState TTL, a max-rounds cap of 10, no ReplayCache (replay rejection is opt-in; see
setReplayCache(ReplayCache)), and a Clock.systemUTC() clock for stamping and checking token
expiry (see setClock(Clock)). Operators inject a shared/rotating-key RequestStateCodec here
for multi-instance or restart-durable resumption.
Trust model:
requestStateis a bearer token. Anyone holding a sealedrequestStatecan resume the paused operation until it expires; the token is not bound to a caller identity. It must be transported only over authenticated TLS and never logged (it is opaque ciphertext, but logging it hands a replayable credential to anyone with log access). SeeRequestStateCodec.- Resume side effects must be idempotent by default. A captured token can be replayed any number
of times within its
TTLunless aReplayCacheis configured (seesetReplayCache(ReplayCache)) to enforce single-use — the built-inInMemoryReplayCacheis per-process only, so cross-node single-use requires a shared implementation. Themax-rounds capbounds the depth of a single resume chain, not the total number of times a given token can be re-submitted, so a handler must not treat a resume as a once-only event unless it knows single-use is enforced.
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intDefault max-rounds cap.static final longDefaultrequestStateTTL in milliseconds: 5 minutes. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptiongetClock()The clock used to stamp a newrequestState's expiry and to check an echoed one against it.getCodec()The codec used to seal/unsealrequestStatetokens.intThe max-rounds cap.TheReplayCacheused to reject reuse of a consumedrequestStatetoken, ornull if none is configured.longgetTtlMs()TherequestStatetime-to-live in milliseconds.Sets the clock.setCodec(RequestStateCodec value) Sets the codec.setKeyProvider(KeyProvider value) Sets the key provider, wrapping it in a freshAeadRequestStateCodec.setMaxRounds(int value) Sets the max-rounds cap.setReplayCache(ReplayCache value) Sets the replay cache, enabling replay rejection.setTtlMs(long value) Sets the TTL.
-
Field Details
-
DEFAULT_TTL_MS
DefaultrequestStateTTL in milliseconds: 5 minutes.- See Also:
-
DEFAULT_MAX_ROUNDS
Default max-rounds cap.- See Also:
-
-
Constructor Details
-
McpMrtrConfig
public McpMrtrConfig()
-
-
Method Details
-
getCodec
The codec used to seal/unsealrequestStatetokens.- Returns:
- The codec. Never
null.
-
setCodec
Sets the codec.- Parameters:
value- The new value. Must not benull.- Returns:
- This object.
- Throws:
IllegalArgumentException- Ifvalueisnull.
-
setKeyProvider
Sets the key provider, wrapping it in a freshAeadRequestStateCodec.Sugar for the common "keep AES-GCM, just supply my keys" case — equivalent to
setCodec(new AeadRequestStateCodec(value)).setKeyProvider(org.apache.juneau.rest.server.mcp.v20260728.KeyProvider)andsetCodec(org.apache.juneau.rest.server.mcp.v20260728.RequestStateCodec)are last-wins: both assign the samecodecfield, so whichever is called more recently determines the effective codec. There is no getter for the provider itself —getCodec()remains the sole accessor, since the codec (not the provider) is the source of truth once either setter has been called.- Parameters:
value- The new value. Must not benull.- Returns:
- This object.
- Throws:
IllegalArgumentException- Ifvalueisnull.
-
getTtlMs
TherequestStatetime-to-live in milliseconds.- Returns:
- The TTL. Always
> 0.
-
setTtlMs
Sets the TTL.- Parameters:
value- The new value. Must be> 0.- Returns:
- This object.
- Throws:
IllegalArgumentException- Ifvalueis not> 0.
-
getMaxRounds
The max-rounds cap.Counts total handler invocations in a single resume chain, not just the resumes: the default of 10 permits 1 initial call plus 9 resumes before
McpRevision.CODE_MAX_ROUNDS_EXCEEDEDis returned.- Returns:
- The cap. Always
>= 1.
-
setMaxRounds
Sets the max-rounds cap.- Parameters:
value- The new value. Must be>= 1.- Returns:
- This object.
- Throws:
IllegalArgumentException- Ifvalueis not>= 1.
-
getReplayCache
TheReplayCacheused to reject reuse of a consumedrequestStatetoken, ornull if none is configured.Unset (
null ) by default — replay rejection is opt-in. A dispatcher only performs a replay check when this returns non-null (seeMcpRevision#resolveMrtrContext); with noReplayCacheconfigured, arequestStatetoken remains multi-use within its TTL, exactly as documented onRequestStateCodec.- Returns:
- The configured replay cache, or
null if replay rejection is disabled (the default).
-
setReplayCache
Sets the replay cache, enabling replay rejection.Passing
null is allowed and explicitly reverts to the default, opt-out behavior (no replay check; a token stays multi-use within its TTL) — unlikesetCodec(RequestStateCodec), there is no always-non-null invariant to preserve here, since "no replay cache" is itself the documented default.- Parameters:
value- The replay cache to use, ornull to disable replay rejection.- Returns:
- This object.
-
getClock
The clock used to stamp a newrequestState's expiry and to check an echoed one against it.- Returns:
- The clock. Never
null.
-
setClock
Sets the clock.Defaults to
Clock.systemUTC(). Tests can supply afixedor manually-advanced clock to driverequestStateexpiry deterministically instead of sleeping past theTTL.- Parameters:
value- The new value. Must not benull.- Returns:
- This object.
- Throws:
IllegalArgumentException- Ifvalueisnull.
-