Task management for long-running MCP operations (experimental).
Tasks provide a durable state machine for operations that may take time to complete. Clients can poll for status, cancel in-flight operations, and receive results asynchronously.
Task Lifecycle
working → completed
working → failed
working → cancelled
working → input_required → working (after elicitation)Storage
Storage is delegated to a pluggable store module implementing
ConduitMcp.Tasks.Store. The default store is
ConduitMcp.Tasks.EtsStore (in-memory, single-node). For durable,
multi-node deployments — or to back tasks with a job queue like Oban —
implement the behaviour and configure it as the application's task store:
config :conduit_mcp, :tasks_store, MyApp.MyTasksStoreThe standard tasks/get, tasks/cancel, tasks/result, and
tasks/list JSON-RPC routes dispatch through this module, so swapping
the store requires no handler changes. See
examples/oban_tasks_server/ for an Oban + SQLite implementation and
examples/oban_task_store.ex for a Postgres-flavored reference.
Configuration
Enable tasks in your transport config:
{ConduitMcp.Transport.StreamableHTTP,
server_module: MyServer,
tasks: [enabled: true]}
Summary
Functions
Cancels a task. Dispatches to the configured store's cancel/1 callback;
falls back to update(task_id, %{"status" => "cancelled"}) for stores
that don't implement it.
Prunes terminal-state tasks older than ttl_ms. Dispatches to the
configured store's cleanup/1 callback; returns 0 for stores that
don't implement it (e.g., stores backed by native TTL like Redis).
Creates a new task. See ConduitMcp.Tasks.Store.
Deletes a task by ID. See ConduitMcp.Tasks.Store.
Generates a unique task ID.
Gets a task by ID. See ConduitMcp.Tasks.Store.
Lists tasks, optionally filtered by :status. See ConduitMcp.Tasks.Store.
Returns the configured task store module. Reads from
Application.get_env(:conduit_mcp, :tasks_store), defaulting to
ConduitMcp.Tasks.EtsStore.
Updates a task's status and/or metadata. See ConduitMcp.Tasks.Store.
Returns the list of valid task statuses.
Validates that a status transition is allowed.
Types
@type status() :: :working | :input_required | :completed | :failed | :cancelled
@type task_id() :: String.t()
Functions
Cancels a task. Dispatches to the configured store's cancel/1 callback;
falls back to update(task_id, %{"status" => "cancelled"}) for stores
that don't implement it.
Prunes terminal-state tasks older than ttl_ms. Dispatches to the
configured store's cleanup/1 callback; returns 0 for stores that
don't implement it (e.g., stores backed by native TTL like Redis).
Creates a new task. See ConduitMcp.Tasks.Store.
Deletes a task by ID. See ConduitMcp.Tasks.Store.
Generates a unique task ID.
Gets a task by ID. See ConduitMcp.Tasks.Store.
Lists tasks, optionally filtered by :status. See ConduitMcp.Tasks.Store.
Returns the configured task store module. Reads from
Application.get_env(:conduit_mcp, :tasks_store), defaulting to
ConduitMcp.Tasks.EtsStore.
Updates a task's status and/or metadata. See ConduitMcp.Tasks.Store.
Returns the list of valid task statuses.
Validates that a status transition is allowed.