Skip to main content

TaskRouter

Trait TaskRouter 

Source
pub trait TaskRouter: Send + Sync {
Show 13 methods // Required methods fn handle_task_call<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, tool_name: &'life1 str, arguments: Value, task_params: Value, owner_id: &'life2 str, progress_token: Option<Value>, ) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn handle_tasks_get<'life0, 'life1, 'async_trait>( &'life0 self, params: Value, owner_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn handle_tasks_result<'life0, 'life1, 'async_trait>( &'life0 self, params: Value, owner_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn handle_tasks_list<'life0, 'life1, 'async_trait>( &'life0 self, params: Value, owner_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn handle_tasks_cancel<'life0, 'life1, 'async_trait>( &'life0 self, params: Value, owner_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn resolve_owner( &self, subject: Option<&str>, client_id: Option<&str>, session_id: Option<&str>, ) -> String; fn tool_requires_task( &self, tool_name: &str, tool_execution: Option<&Value>, ) -> bool; fn task_capabilities(&self) -> Value; // Provided methods fn handle_tasks_update<'life0, 'life1, 'async_trait>( &'life0 self, _params: Value, _owner_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait { ... } fn create_workflow_task<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, _workflow_name: &'life1 str, _owner_id: &'life2 str, _progress: Value, ) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait { ... } fn set_task_variables<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, _task_id: &'life1 str, _owner_id: &'life2 str, _variables: Value, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait { ... } fn handle_workflow_continuation<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, _task_id: &'life1 str, _tool_name: &'life2 str, _tool_result: Value, _owner_id: &'life3 str, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait { ... } fn complete_workflow_task<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, _task_id: &'life1 str, _owner_id: &'life2 str, _result: Value, ) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait { ... }
}
Available on non-WebAssembly only.
Expand description

Trait for routing MCP task requests.

This trait is implemented by pmcp-tasks to handle task lifecycle operations without requiring pmcp to depend on pmcp-tasks.

All params and return values use serde_json::Value to avoid circular crate dependencies. The implementing crate parses these into strongly-typed structs (e.g., TaskGetParams, CreateTaskResult).

Required Methods§

Source

fn handle_task_call<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, tool_name: &'life1 str, arguments: Value, task_params: Value, owner_id: &'life2 str, progress_token: Option<Value>, ) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Handle a task-augmented tools/call request.

When a client sends a tools/call request with a task field, the server delegates to this method instead of calling the tool handler directly. The router creates a task, spawns the tool execution, and returns a CreateTaskResult as Value.

Returns the CreateTaskResult serialized as Value.

Source

fn handle_tasks_get<'life0, 'life1, 'async_trait>( &'life0 self, params: Value, owner_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Handle tasks/get request.

Returns the task status for the given task ID.

Source

fn handle_tasks_result<'life0, 'life1, 'async_trait>( &'life0 self, params: Value, owner_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Handle tasks/result request.

Returns the task result (content) for a completed task.

v1-only (Phase 114). tasks/result is ABSENT from the io.modelcontextprotocol/tasks extension, so dispatch answers -32601 on a v2-negotiated request and this method is never reached there. v2 inlines result / error on the terminal tasks/get. The method stays on the trait, unchanged, because v1 still serves it.

Source

fn handle_tasks_list<'life0, 'life1, 'async_trait>( &'life0 self, params: Value, owner_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Handle tasks/list request.

Returns a list of tasks visible to the given owner.

v1-only (Phase 114). tasks/list is ABSENT from the io.modelcontextprotocol/tasks extension — removed as a SECURITY improvement, since without an enumeration primitive a server cannot leak the existence of one caller’s tasks to another. Dispatch answers -32601 on a v2-negotiated request and this method is never reached there. The method stays on the trait, unchanged, because v1 still serves it.

Source

fn handle_tasks_cancel<'life0, 'life1, 'async_trait>( &'life0 self, params: Value, owner_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Handle tasks/cancel request.

Requests cancellation of the given task.

Source

fn resolve_owner( &self, subject: Option<&str>, client_id: Option<&str>, session_id: Option<&str>, ) -> String

Resolve owner ID from authentication context fields.

The owner ID determines task visibility and access control. Implementations typically derive this from the OAuth subject, client ID, or session ID (in order of preference).

Source

fn tool_requires_task( &self, tool_name: &str, tool_execution: Option<&Value>, ) -> bool

Check if a tool requires task augmentation (taskSupport: required).

When a tool has execution.taskSupport == "required", the client must send a task field with the tools/call request.

Source

fn task_capabilities(&self) -> Value

Get the server task capabilities as a Value for experimental.tasks.

v1 spelling only (Phase 114). The returned value is advertised on the 2025-11-25 path; a v2 (2026-07-28) client never receives it, because project_capabilities_for_v2 strips experimental and v2 declares tasks through the extensions map key io.modelcontextprotocol/tasks, whose value is an EMPTY object with no per-method sub-capabilities.

This is inserted into the server’s capabilities during initialization so clients know the server supports the tasks protocol extension.

Provided Methods§

Source

fn handle_tasks_update<'life0, 'life1, 'async_trait>( &'life0 self, _params: Value, _owner_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Handle tasks/update request.

Delivers a client’s inputResponses to a task that is awaiting input.

This is an additive trait method with a default implementation, so every existing TaskRouter implementation keeps compiling untouched.

§Arguments
  • params - The already-validated request params as a Value.
  • owner_id - Owner identity, ALREADY RESOLVED by the caller.
§The owner must NOT be re-derived from params

By the time this method is called, TaskDispatch has already resolved the owner through the v2 identity table, bounds-checked the delivered inputResponses, and decoded them KIND-DIRECTED against the kinds the server itself recorded. An implementation must therefore take the owner from the owner_id argument and must not read any owner, subject or task ownership hint out of params — a client-supplied owner would be an insecure direct object reference, which is precisely what passing the resolved owner alongside the params exists to prevent.

§Default

Returns an error indicating tasks/update is not supported. The default is an explicit error and never a silent success, so dispatch can answer honestly when a router cannot accept inputs instead of reporting an acceptance that never happened.

Source

fn create_workflow_task<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, _workflow_name: &'life1 str, _owner_id: &'life2 str, _progress: Value, ) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Create a workflow-backed task. Returns CreateTaskResult as Value.

Called by TaskWorkflowPromptHandler when a task-aware workflow prompt is invoked. The implementation creates a task with the workflow’s initial progress stored in task variables.

§Arguments
  • workflow_name - Name of the workflow (becomes the task title).
  • owner_id - Owner identity for the new task.
  • progress - Serialized WorkflowProgress to store in task variables.
§Default

Returns an error indicating workflow tasks are not supported.

Source

fn set_task_variables<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, _task_id: &'life1 str, _owner_id: &'life2 str, _variables: Value, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Update task variables with workflow step results.

Called after each step completes to persist the step result and updated progress to the task’s variable store.

§Arguments
  • task_id - ID of the task to update.
  • owner_id - Owner identity for authorization.
  • variables - JSON object of key-value pairs to set on the task.
§Default

Returns an error indicating workflow tasks are not supported.

Source

fn handle_workflow_continuation<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, _task_id: &'life1 str, _tool_name: &'life2 str, _tool_result: Value, _owner_id: &'life3 str, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Record a tool call result against a workflow task.

Called by ServerCore when a tools/call includes _task_id in _meta. The implementation matches the tool name to a remaining workflow step and updates task variables with the step result and updated progress.

Best-effort: if the tool does not match any step, the result is stored under _workflow.extra.<tool_name> for observability.

§Default

Returns Ok(()) – no-op for routers that don’t support workflow continuation.

Source

fn complete_workflow_task<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, _task_id: &'life1 str, _owner_id: &'life2 str, _result: Value, ) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Complete a workflow task with final result.

Called when all steps have been executed (or the workflow determines completion). Sets the task status to Completed and stores the final result.

§Arguments
  • task_id - ID of the task to complete.
  • owner_id - Owner identity for authorization.
  • result - Final result value to store on the task.
§Default

Returns an error indicating workflow tasks are not supported.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§