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 { ... }
}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§
Sourcefn 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_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.
Sourcefn 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_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.
Sourcefn 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_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.
Sourcefn 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_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.
Sourcefn 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 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.
Sourcefn resolve_owner(
&self,
subject: Option<&str>,
client_id: Option<&str>,
session_id: Option<&str>,
) -> String
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).
Sourcefn tool_requires_task(
&self,
tool_name: &str,
tool_execution: Option<&Value>,
) -> bool
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.
Sourcefn task_capabilities(&self) -> Value
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§
Sourcefn 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 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 aValue.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.
Sourcefn 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 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- SerializedWorkflowProgressto store in task variables.
§Default
Returns an error indicating workflow tasks are not supported.
Sourcefn 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 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.
Sourcefn 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 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.
Sourcefn 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,
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".