Class McpMrtrConfig

java.lang.Object
org.apache.juneau.rest.server.mcp.v20260728.McpMrtrConfig

public class McpMrtrConfig extends Object
Binding-owned MRTR (Multi-Round-Trip Request) configuration for a v2 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:
  • requestState is a bearer token. Anyone holding a sealed requestState can 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). See RequestStateCodec.
  • Resume side effects must be idempotent by default. A captured token can be replayed any number of times within its TTL unless a ReplayCache is configured (see setReplayCache(ReplayCache)) to enforce single-use — the built-in InMemoryReplayCache is per-process only, so cross-node single-use requires a shared implementation. The max-rounds cap bounds 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 Details

  • Constructor Details

  • Method Details

    • getCodec

      The codec used to seal/unseal requestState tokens.
      Returns:
      The codec. Never null.
    • setCodec

      Sets the codec.
      Parameters:
      value - The new value. Must not be null.
      Returns:
      This object.
      Throws:
      IllegalArgumentException - If value is null.
    • setKeyProvider

      Sets the key provider, wrapping it in a fresh AeadRequestStateCodec.

      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) and setCodec(org.apache.juneau.rest.server.mcp.v20260728.RequestStateCodec) are last-wins: both assign the same codec field, 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 be null.
      Returns:
      This object.
      Throws:
      IllegalArgumentException - If value is null.
    • getTtlMs

      public long getTtlMs()
      The requestState time-to-live in milliseconds.
      Returns:
      The TTL. Always > 0.
    • setTtlMs

      public McpMrtrConfig setTtlMs(long value)
      Sets the TTL.
      Parameters:
      value - The new value. Must be > 0.
      Returns:
      This object.
      Throws:
      IllegalArgumentException - If value is not > 0.
    • getMaxRounds

      public int 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_EXCEEDED is returned.

      Returns:
      The cap. Always >= 1.
    • setMaxRounds

      public McpMrtrConfig setMaxRounds(int value)
      Sets the max-rounds cap.
      Parameters:
      value - The new value. Must be >= 1.
      Returns:
      This object.
      Throws:
      IllegalArgumentException - If value is not >= 1.
    • getReplayCache

      The ReplayCache used to reject reuse of a consumed requestState token, or null 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 (see McpRevision#resolveMrtrContext); with no ReplayCache configured, a requestState token remains multi-use within its TTL, exactly as documented on RequestStateCodec.

      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) — unlike setCodec(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, or null to disable replay rejection.
      Returns:
      This object.
    • getClock

      public Clock getClock()
      The clock used to stamp a new requestState's expiry and to check an echoed one against it.
      Returns:
      The clock. Never null.
    • setClock

      public McpMrtrConfig setClock(Clock value)
      Sets the clock.

      Defaults to Clock.systemUTC(). Tests can supply a fixed or manually-advanced clock to drive requestState expiry deterministically instead of sleeping past the TTL.

      Parameters:
      value - The new value. Must not be null.
      Returns:
      This object.
      Throws:
      IllegalArgumentException - If value is null.