No breaking changes. 1.3.0 adds a distributed, durable TaskStore for the MCP Tasks extension and fixes two serialization defects surfaced while building it.
Added
- Substrate-backed TaskStore (
mocapi-tasks-substrate) — a distributed, durableTaskStorefor the MCP Tasks extension, backed by SubstrateAtoms (token compare-and-set) across any of Substrate's nine backends (ADR-0040). Add the module, a Substrate backend, andcodec-jacksonto your app and it activates automatically once anAtomFactorybean exists, backing off theInMemoryTaskStoredefault with no other code changes. Configurable backend key prefix viamocapi.tasks.substrate.key-prefix(defaultmocapi:tasks:). Verified with the sameTaskStoreContractTestTCKInMemoryTaskStoreis held to (in-memory Atom SPI + real Redis via Testcontainers), a full autoconfiguration-chain proof test, and end-to-end lifecycle runs — including a mid-task elicitation task throughworking → input_required → tasks/update → completed— on both a live JVM and a genuine GraalVM native image. See the Tasks guide. The Substrate baseline is 0.8.1, which ships the upstream fix for the codec/substrate auto-configuration ordering bug this work surfaced; mocapi'sSubstrateOrderingAutoConfigurationshim is retained as defense-in-depth for applications pinned to Substrate 0.8.0. A runnable Redis-backed example (examples/tasks-redis) demonstrates kill-and-resume: Spring Boot's Docker Compose support starts Redis, the app is killed atinput_required, and after a restart the elicitation answer resumes the task via MRTR replay through the store.
Fixed
PrimitiveSchemaDefinitiondeserialization routing (mocapi-model). The sealed elicitation-schema hierarchy had no deserialization routing at all, breakingtasks/getwith-32603for any task whoseinputRequestsheld a pending elicitation'srequestedSchema, through any serializingTaskStore.PrimitiveSchemaDefinitionDeserializernow shape-sniffs the wire payload to route to the correct one of the eight leaf types per the pinned 2026-07-28 schema, including the documentedLegacyTitledEnumSchema(noenumNames) vsUntitledSingleSelectEnumSchemawire ambiguity, resolved toward the non-deprecated variant. Wire serialization is unchanged; the released 1.2.0 wire path was not affected, sinceRequestStateCodeconly ever carries response ledgers, never schema definitions.InMemoryTaskStorenow serializes records (mocapi-tasks). Records are held as JSON strings and round-tripped on every read/write instead of as live object graphs, giving the shipped default the same serialization coverage as every external store (closing the blind spot the fix above hid behind) and removing an aliasing hazard where a caller could mutate a returned record'sJsonNodeand corrupt stored state. The sweeper is hardened against a malformed stored entry (logged and skipped, rather than killing the sweeper thread). Public constructors are unchanged.
Requirements
- Building from source now requires a running Docker daemon:
mocapi-tasks-substrate's Redis Testcontainers IT runs duringmvn verify. Consuming the published artifacts requires nothing new.