MCP Task State Storage: RocketMQ LiteTopic as Per-Task Ledger
This article explains how RocketMQ LiteTopic solves the task state persistence problem for stateless MCP services by assigning each task a dedicated message channel that acts as an ordered, durable ledger, enabling reliable task tracking, automatic retries, and seamless replica failover without violating the protocol's stateless requirement.
The Model Context Protocol (MCP) Tasks extension (SEP-2663) introduces asynchronous tool invocation for AI Agents: instead of blocking on long-running operations, the server returns a taskId handle and the client either polls via tasks/get or subscribes to notifications/tasks for status updates. The protocol deliberately leaves the storage of task state — from working to completed — to the implementer, while also mandating that MCP servers remain stateless (SEP-2575).
The Problem: Stateless Servers, Stateful Tasks
Storing task state in the memory of the handling replica creates three critical failures in production:
Replica affinity breaks: Load balancing may route a subsequent poll to a different replica that lacks the task in memory. The protocol suggests an Mcp-Name header for routing affinity, but scaling, restarts, or gateway misconfiguration break this guarantee.
Crash loses state: If the replica holding the task crashes, the task may still be executing but the client receives "task not found" despite a valid handle.
Client cannot distinguish errors: The client cannot tell whether a task truly does not exist or simply landed on the wrong replica, forcing it to abandon the task.
These issues directly contradict the stateless-server requirement, creating a fundamental tension.
Solution: Task as LiteTopic
The article proposes using RocketMQ LiteTopic (lightweight topics) as a per-task state ledger. LiteTopic supports millions of independent channels per broker, auto-creation on demand, and TTL-based expiration with minimal operational overhead. Each task maps to a dedicated LiteTopic channel named after its taskId; the sequence of messages in that channel becomes the task's immutable state log.
Three-Step Flow
Submit: The server writes an initial working message (with creation timestamp) to the task's channel and returns the taskId to the client.
Execute: A worker pool picks up the task, runs the tool, and appends a terminal message ( completed + result) to the same channel.
Query: Any replica receiving a query reads the channel's message sequence to reconstruct the current state and responds — no local state required.
Messages are state; RocketMQ is the state store. This eliminates both the affinity and crash-loss problems.
Why LiteTopic Channels Work as Ledgers
Ordered Channel, Last Message Wins
A LiteTopic channel maps to a single queue on one broker, guaranteeing write-order equals read-order. The latest message always represents the current state; no replay or priority reduction is needed. Even state regressions (e.g., back to working for additional user input) are naturally expressed as new appended records.
One Write, Two Consumption Paths
LiteTopic internally indexes each message twice — once in the parent topic's queue and once in the channel's queue. This allows two independent consumers to read the same message without a second topic or redundant snapshots: the execution pool consumes from the parent topic for task dispatch, while query replicas consume from the channel for state reconstruction.
Four Capabilities from One Ledger
Tasks never lost: The taskId is returned only after the initial message is durably persisted in RocketMQ; replica restarts or scale-down cannot lose tasks.
Automatic retry: Failed task messages are re-delivered by the message system without client re-submission (requires tool idempotency; side-effecting tools like transfers or emails need business-level idempotency).
Migratable execution: A shared consumer group decides which worker executes; the execution replica is decoupled from the creation replica, enabling horizontal scaling of workers.
Addressable results: Results remain permanently in the task's channel; any replica can answer queries without storing task state locally.
Open-Source Implementation: mcp-tasks-rocketmq
The solution is implemented in Python under the Apache RocketMQ AI repository: apache/rocketmq-ai (GitHub: https://github.com/apache/rocketmq-ai). The mcp-tasks-rocketmq/ directory contains the MCP Tasks extension (SEP-2663) implementation on RocketMQ LiteTopic: a RocketMQ execution pool handles task execution, each task maps to a LiteTopic channel serving as its state ledger. Usage details are in the directory's README.md; runnable end-to-end examples are in examples/.
Conclusion
MCP cleanly defines asynchronous task semantics while delegating state storage to the infrastructure layer. By giving each task a dedicated LiteTopic channel — making the message sequence the task's own ledger — MCP servers stay truly stateless, freely restartable and scalable. Task dispatch and state storage converge on a single message backbone already proven at tens of thousands of concurrent AI inference instances. For RocketMQ, this extends its role from message middleware to AI Agent collaboration infrastructure; LiteTopic is merged into the Apache RocketMQ main branch, and the MCP integration is open-sourced in apache/rocketmq-ai.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Alibaba Cloud Native
We publish cloud-native tech news, curate in-depth content, host regular events and live streams, and share Alibaba product and user case studies. Join us to explore and share the cloud-native insights you need.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
