Tasks, Queues & Durable Workflows API¶
API reference for the MCP Tasks protocol runtime (MCPTaskExecutor, MCPTaskRuntime, MCPTaskStore, TaskRecord, ToolTaskCall, TaskLookupError, TaskStateError) and the litestar_mcp.queues distributed execution layer (QueueTaskExecutor, DurableWorkflowEngine, WorkflowStore, WorkflowRun, NodeRecord, TaskDependencyChain, QueuedAgentChatController, QueuedTurnManager, QueuedTurn, AgentRegistry, PrincipalSnapshot).
For architectural guides, see MCP Tasks & Human-in-the-Loop, Distributed Task Queues, Durable DAG Workflows, and Queued Agent Turns.
MCP Tasks Store & Executor Protocol (io.modelcontextprotocol/tasks)¶
MCPTaskExecutor
¶
Bases: Protocol
Runs task-augmented tool calls outside the request that created them.
LitestarMCP calls configure during app init so the executor can
wire itself into other plugins, and bind at startup with the
collaborators that need the running application.
configure
¶
Register executor hooks or dependencies on the Litestar AppConfig during initialization.
bind
¶
Bind the running application, task store, and attempt runner callback at startup.
submit
¶
Enqueue or schedule initial execution of a newly created task-augmented tool call.
resume
¶
Schedule a resumed execution attempt after client input responses are received.
MCPTaskRuntime
¶
Collaborators an executor needs once the application has started.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app
|
Litestar
|
The running Litestar application instance. |
required |
task_store
|
MCPTaskStore
|
The active |
required |
run_attempt
|
Callable[list, Awaitable[None]]
|
Async callback that executes a single |
required |
Attributes:
| Name | Type | Description |
|---|---|---|
app | Litestar | The running Litestar application instance. |
task_store | MCPTaskStore | The active |
run_attempt | Callable[[ToolTaskCall, Any], Awaitable[None]] | Async callback that executes a single |
MCPTaskStore
¶
Task records backed by a Litestar Store.
Only serializable records are persisted. Runner tasks, cancellation flags, and input queues are process-local coordination primitives; production deployments use a shared Store for retrieval and a shared notification backend for fan-out.
create
¶
Durably create a task before returning its handle.
has_local_runner
¶
Return whether a process-local runner is attached to task_id.
set_job_id
¶
Persist the executor's job id for the task's current attempt under a separate key.
set_dispatch
¶
Save the serializable dispatch envelope on the record before executor submission.
require_input
¶
Pause a task until the client supplies input via tasks/update.
update
¶
Submit client responses to a task waiting for input.
TaskRecord
¶
Persisted Tasks extension state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task_id
|
str
|
Unique task identifier ( |
required |
owner_id
|
str | None
|
Optional owner identifier restricting task access to the creating principal. |
required |
status
|
str
|
Current MCP task lifecycle status ( |
required |
created_at
|
datetime
|
UTC timestamp when the task record was created. |
required |
last_updated_at
|
datetime
|
UTC timestamp of the most recent task state transition. |
required |
ttl_ms
|
int | None
|
Time-to-live in milliseconds for the persisted task record. |
required |
poll_interval_ms
|
int | None
|
Suggested client polling interval in milliseconds. |
required |
status_message
|
str | None
|
Optional human-readable status message describing current task progress. |
None
|
input_requests
|
dict[str, dict[str, Any]] | None
|
Pending multi-round-trip input request descriptors when |
None
|
request_state
|
str | None
|
Opaque round-tripped state token preserved across |
None
|
result
|
dict[str, Any] | None
|
Final MCP tool result dictionary when |
None
|
error
|
JSONRPCError | None
|
Terminal JSON-RPC error object when |
None
|
dispatch
|
dict[str, Any] | None
|
Serialized |
None
|
input_responses
|
dict[str, Any] | None
|
Most recent client input responses submitted via |
None
|
Attributes:
| Name | Type | Description |
|---|---|---|
task_id | str | Unique task identifier ( |
owner_id | str | None | Optional owner identifier restricting task access to the creating principal. |
status | str | Current MCP task lifecycle status ( |
created_at | datetime | UTC timestamp when the task record was created. |
last_updated_at | datetime | UTC timestamp of the most recent task state transition. |
ttl_ms | int | None | Time-to-live in milliseconds for the persisted task record. |
poll_interval_ms | int | None | Suggested client polling interval in milliseconds. |
status_message | str | None | Optional human-readable status message describing current task progress. |
input_requests | dict[str, dict[str, Any]] | None | Pending multi-round-trip input request descriptors when |
request_state | str | None | Opaque round-tripped state token preserved across |
result | dict[str, Any] | None | Final MCP tool result dictionary when |
error | JSONRPCError | None | Terminal JSON-RPC error object when |
dispatch | dict[str, Any] | None | Serialized |
input_responses | dict[str, Any] | None | Most recent client input responses submitted via |
ToolTaskCall
¶
Bases: Struct
Serializable dispatch envelope for one task-augmented tools/call attempt.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task_id
|
str
|
Unique identifier of the task record in |
required |
tool_name
|
str
|
Registered name of the MCP tool being executed. |
required |
arguments
|
dict[str, Any]
|
Tool invocation arguments supplied by the caller. |
required |
owner_id
|
str | None
|
Optional task-owner identifier scoping access to the task record. |
None
|
principal
|
dict[str, Any] | None
|
Serialized principal snapshot captured from the creating request. |
None
|
queue
|
str | None
|
Optional target |
None
|
client_id
|
str
|
Identifier of the originating MCP client. |
'queue'
|
protocol_version
|
str
|
Negotiated MCP protocol version for the task execution. |
'2026-07-28'
|
client_capabilities
|
dict[str, Any] | None
|
Client capabilities dictionary captured from the creating request. |
None
|
client_info
|
dict[str, Any] | None
|
Client implementation metadata captured from the creating request. |
None
|
input_responses
|
dict[str, Any] | None
|
Accumulated interactive input responses supplied via |
None
|
request_state
|
str | None
|
Opaque round-tripped state token accompanying |
None
|
attempt
|
int
|
1-based execution attempt counter incremented on each |
1
|
Attributes:
| Name | Type | Description |
|---|---|---|
task_id | str | Unique identifier of the task record in |
tool_name | str | Registered name of the MCP tool being executed. |
arguments | dict[str, Any] | Tool invocation arguments supplied by the caller. |
owner_id | str | None | Optional task-owner identifier scoping access to the task record. |
principal | dict[str, Any] | None | Serialized principal snapshot captured from the creating request. |
queue | str | None | Optional target |
client_id | str | Identifier of the originating MCP client. |
protocol_version | str | Negotiated MCP protocol version for the task execution. |
client_capabilities | dict[str, Any] | None | Client capabilities dictionary captured from the creating request. |
client_info | dict[str, Any] | None | Client implementation metadata captured from the creating request. |
input_responses | dict[str, Any] | None | Accumulated interactive input responses supplied via |
request_state | str | None | Opaque round-tripped state token accompanying |
attempt | int | 1-based execution attempt counter incremented on each |
TaskLookupError
¶
Bases: ValueError
Raised when a task cannot be found or accessed.
TaskStateError
¶
Bases: ValueError
Raised when a task transition is invalid.
Distributed Queue Task Execution (litestar_mcp.queues)¶
QueueTaskExecutor
¶
Run MCP Tasks attempts on litestar-queues.
LitestarMCP calls configure during app init, which attaches the
executor's task dependencies to the application's QueuePlugin; no queue
wiring is needed beyond registering QueuePlugin on the same app.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
principal_loader
|
Callable[[str], Awaitable[Any]] | None
|
Optional callback rehydrating |
None
|
queue
|
str
|
Default queue name for tool attempts (overridable per controller
or route via |
'mcp'
|
timeout
|
int
|
Per-attempt timeout in seconds. |
3600
|
Attributes:
| Name | Type | Description |
|---|---|---|
runtime | MCPTaskRuntime | Collaborators bound at application startup. |
configure
¶
Attach the executor's task dependencies to the application's QueuePlugin.
resolve_task_dependencies
¶
Inject this executor into tool task attempts.
Returns:
| Type | Description |
|---|---|
Mapping[str, object]
|
|
cancel
¶
Cancel the task's current attempt and persist cancelled when this replica wins.
run_mcp_tool_task
¶
Run one MCP Tasks attempt in the worker and return the record status.
Durable DAG Workflow Engine & Persistence¶
DurableWorkflowEngine
¶
Bases: InitPluginProtocol
Runs DynamicWorkflow definitions on litestar-queues with Store-backed state.
Register the engine as a Litestar plugin next to QueuePlugin. On app
init it attaches its task dependencies to the queue configuration, resolves
its store from the application's store registry, and exposes itself to
route handlers as the workflow_engine dependency.
Attributes:
| Name | Type | Description |
|---|---|---|
store | WorkflowStore | Durable run and node records. |
on_app_init
¶
Wire task dependencies, the default store, the workflow_engine dependency, and app capture.
Returns:
| Type | Description |
|---|---|
AppConfig
|
The updated application configuration. |
resolve_task_dependencies
¶
Inject this engine into the workflow tasks.
Returns:
| Type | Description |
|---|---|
Mapping[str, object]
|
|
start
¶
Start a new durable workflow run and enqueue initial advance task.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workflow
|
str
|
Registered workflow name. |
required |
initial_state
|
dict[str, Any] | None
|
Optional initial state dictionary. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The generated run_id string. |
Raises:
| Type | Description |
|---|---|
ImproperlyConfiguredException
|
If immediate execution backend is used with watchdog. |
snapshot
¶
Load the durable run record and reconstructed WorkflowContext.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run_id
|
str
|
Unique workflow run identifier. |
required |
Returns:
| Type | Description |
|---|---|
tuple[WorkflowRun, WorkflowContext]
|
Tuple of (WorkflowRun, WorkflowContext). |
Raises:
| Type | Description |
|---|---|
KeyError
|
If the workflow run does not exist. |
advance
¶
Advance a durable workflow run by scheduling ready nodes or finalizing terminal state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run_id
|
str
|
Unique workflow run identifier. |
required |
Returns:
| Type | Description |
|---|---|
RunStatus | None
|
The updated RunStatus, or None if run does not exist. |
execute_node
¶
Execute a single workflow node, record its outcome, and re-enqueue advance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run_id
|
str
|
Unique workflow run identifier. |
required |
node
|
str
|
Target node name to execute. |
required |
watch
¶
Execute one watchdog tick for a durable run.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run_id
|
str
|
Unique workflow run identifier. |
required |
tick
|
int
|
Current tick iteration number. |
1
|
Returns:
| Type | Description |
|---|---|
RunStatus | None
|
The resulting RunStatus, or None if run does not exist. |
WorkflowStore
¶
Store-backed run and node records with single-writer keys.
create_run
¶
Create a new durable workflow run record.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run
|
WorkflowRun
|
WorkflowRun record to persist. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If a run with the same run_id already exists. |
get_run
¶
Retrieve a workflow run record by run_id.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run_id
|
str
|
Unique workflow run identifier. |
required |
Returns:
| Type | Description |
|---|---|
WorkflowRun | None
|
The decoded WorkflowRun record or None if not found. |
set_run_status
¶
Update the status of a workflow run.
Terminal statuses ('completed' and 'failed') are monotonic and will not be overwritten by subsequent calls.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run_id
|
str
|
Unique workflow run identifier. |
required |
status
|
RunStatus
|
New RunStatus for the run. |
required |
error
|
str | None
|
Optional error message when transitioning to failed. |
None
|
Returns:
| Type | Description |
|---|---|
WorkflowRun
|
The updated (or unchanged terminal) WorkflowRun record. |
Raises:
| Type | Description |
|---|---|
KeyError
|
If the workflow run does not exist. |
put_node
¶
Persist a write-once node record for a workflow run.
Encodes output first, propagating serialization errors. Existing node records are not overwritten.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run_id
|
str
|
Unique workflow run identifier. |
required |
record
|
NodeRecord
|
NodeRecord to store. |
required |
get_node
¶
Retrieve a node record by run_id and node name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run_id
|
str
|
Unique workflow run identifier. |
required |
node
|
str
|
Node name. |
required |
Returns:
| Type | Description |
|---|---|
NodeRecord | None
|
The decoded NodeRecord or None if not found. |
get_nodes
¶
Retrieve multiple node records by names.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run_id
|
str
|
Unique workflow run identifier. |
required |
names
|
Iterable[str]
|
Iterable of node names to fetch. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, NodeRecord]
|
Dictionary mapping node names to their decoded NodeRecord instances. |
to_context
¶
Reconstruct an in-process WorkflowContext from durable run and node records.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run
|
WorkflowRun
|
WorkflowRun record providing run_id and initial state. |
required |
nodes
|
Mapping[str, NodeRecord]
|
Mapping of node names to NodeRecord outcomes. |
required |
Returns:
| Type | Description |
|---|---|
WorkflowContext
|
Reconstructed WorkflowContext instance. |
WorkflowRun
¶
Bases: Struct
Durable state of one workflow run.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run_id
|
str
|
Unique identifier of the workflow run. |
required |
workflow
|
str
|
Name of the |
required |
state
|
dict[str, Any]
|
dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2) |
<class 'dict'>
|
status
|
Literal['running', 'completed', 'failed']
|
Current lifecycle status of the workflow run ( |
'running'
|
error
|
str | None
|
Optional error description recorded when |
None
|
created_at
|
float
|
time() -> floating-point number Return the current time in seconds since the Epoch. Fractions of a second may be present if the system clock provides them. |
1793739870.647042
|
Attributes:
| Name | Type | Description |
|---|---|---|
run_id | str | Unique identifier of the workflow run. |
workflow | str | Name of the |
state | dict[str, Any] | Initial workflow state persisted when the run was created. |
status | RunStatus | Current lifecycle status of the workflow run ( |
error | str | None | Optional error description recorded when |
created_at | float | Unix epoch timestamp (seconds) when the workflow run was created. |
NodeRecord
¶
Bases: Struct
Write-once outcome of one node in one run.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
node
|
str
|
Name of the workflow node within the DAG. |
required |
status
|
Literal['completed', 'skipped', 'failed']
|
Terminal step status ( |
required |
output
|
Any
|
JSON-serializable output produced by the node when completed. |
None
|
error
|
str | None
|
Optional error description recorded when the node failed. |
None
|
Attributes:
| Name | Type | Description |
|---|---|---|
node | str | Name of the workflow node within the DAG. |
status | StepStatus | Terminal step status ( |
output | Any | JSON-serializable output produced by the node when completed. |
error | str | None | Optional error description recorded when the node failed. |
TaskDependencyChain
¶
Ordered task dependency resolvers merged into one resolver.
Later resolvers win on key collisions. QueueConfig accepts a single
task_dependency_resolver, so integrations append themselves to the
application's queue configuration through attach instead of asking
users to combine resolvers by hand.
attach
¶
Add resolver to the QueuePlugin registered on app_config.
The queue reads task_dependency_resolver on every attempt, so the
order in which plugins initialize does not matter. Attaching the same
resolver twice is a no-op. An existing user resolver is kept and runs
before resolver.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app_config
|
AppConfig
|
Application configuration being initialized. |
required |
resolver
|
TaskDependencyResolver
|
Resolver supplying the integration's task keyword arguments. |
required |
owner
|
str
|
Integration name used in configuration error messages. |
required |
Returns:
| Type | Description |
|---|---|
QueuePlugin
|
The application's |
Raises:
| Type | Description |
|---|---|
ImproperlyConfiguredException
|
If no |
Queued Agent Turns & Streaming Bridge¶
QueuedAgentChatController
¶
Bases: Controller
Litestar controller enqueuing agent turns and streaming frames from Channels.
Attributes:
| Name | Type | Description |
|---|---|---|
replay_limit | int | Default: 1000 |
ping_interval | float | Default: 15.0 |
emit_agent_frame
¶
Serialize and publish an AgentStreamFrame to the turn's Litestar Channel.
agent_turn_channel
¶
Return the canonical Litestar Channels topic for a queued agent turn.
QueuedTurnManager
¶
Manages queuing agent turns and publishing realtime frames to Channels.
enqueue_turn
¶
enqueue_turn(
session_id,
user_message,
*,
turn_id=None,
agent_name="root",
dynamic_context=None,
principal=None,
)
Enqueue an agent turn for background execution.
QueuedTurn
¶
Bases: Struct
Serializable envelope for background turn execution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session_id
|
str
|
Conversation session identifier for the queued turn. |
required |
turn_id
|
str
|
Unique identifier assigned to the queued turn. |
required |
user_message
|
str | dict[str, Any]
|
User message string or structured payload initiating the turn. |
required |
agent_name
|
str
|
Registered agent runtime name in |
'root'
|
dynamic_context
|
str | None
|
Optional per-turn context prepended to the agent's system instructions. |
None
|
principal
|
PrincipalSnapshot | None
|
Optional serialized security principal snapshot for worker rehydration. |
None
|
Attributes:
| Name | Type | Description |
|---|---|---|
session_id | str | Conversation session identifier for the queued turn. |
turn_id | str | Unique identifier assigned to the queued turn. |
user_message | str | dict[str, Any] | User message string or structured payload initiating the turn. |
agent_name | str | Registered agent runtime name in |
dynamic_context | str | None | Optional per-turn context prepended to the agent's system instructions. |
principal | PrincipalSnapshot | None | Optional serialized security principal snapshot for worker rehydration. |
AgentRegistry
¶
PrincipalSnapshot
¶
Bases: Struct
Snapshot of security principal attributes for queued execution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str | None
|
Authenticated user identifier captured at enqueue time. |
None
|
tenant
|
str | None
|
Optional tenant identifier associated with the principal. |
None
|
roles
|
list[str]
|
Built-in mutable sequence. If no argument is given, the constructor creates a new empty list. The argument must be an iterable if specified. |
<dynamic>
|
scopes
|
list[str]
|
Built-in mutable sequence. If no argument is given, the constructor creates a new empty list. The argument must be an iterable if specified. |
<dynamic>
|
Attributes:
| Name | Type | Description |
|---|---|---|
user_id | str | None | Authenticated user identifier captured at enqueue time. |
tenant | str | None | Optional tenant identifier associated with the principal. |
roles | list[str] | Role names granted to the principal. |
scopes | list[str] | Authorization scopes granted to the principal. |
run_agent_turn
¶
run_agent_turn = task(
"litestar_mcp.agent.run_turn", queue="agent", retries=0, timeout=1800
)(_run_agent_turn_body)