pub trait ToolHandler: Send + Sync {
Show 26 methods
// Required methods
fn definition(&self) -> Tool;
fn call(
&self,
ctx: &McpContext,
arguments: Value,
) -> McpResult<Vec<Content>>;
// Provided methods
fn icon(&self) -> Option<&Icon> { ... }
fn version(&self) -> Option<&str> { ... }
fn tags(&self) -> &[String] { ... }
fn annotations(&self) -> Option<&ToolAnnotations> { ... }
fn output_schema(&self) -> Option<Value> { ... }
fn final_title(&self) -> Option<&str> { ... }
fn final_icons(&self) -> Option<&[RawIcon]> { ... }
fn final_metadata(&self) -> Option<&OpenMetadata> { ... }
fn final_definition(&self) -> Option<FinalTool> { ... }
fn final_tool_schema_authority(&self) -> FinalToolSchemaAuthority { ... }
fn upstream_final_tool_schema_registration(
&self,
) -> Option<UpstreamFinalToolSchemaRegistration> { ... }
fn final_tool_error_structured_content(
&self,
_kind: ToolErrorKind,
) -> Option<Value> { ... }
fn timeout(&self) -> Option<Duration> { ... }
fn call_async<'a>(
&'a self,
ctx: &'a McpContext,
arguments: Value,
) -> BoxFuture<'a, McpOutcome<Vec<Content>>> { ... }
fn call_final(
&self,
ctx: &McpContext,
arguments: Value,
) -> McpResult<CompleteResult<FinalCallToolResult>> { ... }
fn call_final_async<'a>(
&'a self,
ctx: &'a McpContext,
arguments: Value,
) -> BoxFuture<'a, McpOutcome<CompleteResult<FinalCallToolResult>>> { ... }
fn call_async_in_request<'a>(
&'a self,
ctx: &'a McpContext,
_request_cx: &'a Cx,
arguments: Value,
) -> BoxFuture<'a, McpOutcome<Vec<Content>>> { ... }
fn call_final_async_in_request<'a>(
&'a self,
ctx: &'a McpContext,
_request_cx: &'a Cx,
arguments: Value,
) -> BoxFuture<'a, McpOutcome<CompleteResult<FinalCallToolResult>>> { ... }
fn declares_final_tasks(&self) -> bool { ... }
fn declares_final_mrtr(&self) -> bool { ... }
fn call_final_outcome(
&self,
ctx: &McpContext,
arguments: Value,
) -> McpResult<FinalToolOutcome> { ... }
fn call_final_outcome_async<'a>(
&'a self,
ctx: &'a McpContext,
arguments: Value,
) -> BoxFuture<'a, McpOutcome<FinalToolOutcome>> { ... }
fn call_final_outcome_async_in_request<'a>(
&'a self,
ctx: &'a McpContext,
_request_cx: &'a Cx,
arguments: Value,
) -> BoxFuture<'a, McpOutcome<FinalToolOutcome>> { ... }
fn call_final_outcome_async_resuming_in_request<'a>(
&'a self,
ctx: &'a McpContext,
request_cx: &'a Cx,
arguments: Value,
_resume_inputs: Option<&'a MrtrCompletedInputs>,
) -> BoxFuture<'a, McpOutcome<FinalToolOutcome>> { ... }
}Expand description
Handler for a tool.
This trait is typically implemented via the #[tool] macro.
§Sync vs Async
By default, implement call() for synchronous execution. For async tools,
override call_async() instead. The router always calls call_async(),
which defaults to running call() in an async block.
§Return Type
Async handlers return McpOutcome<Vec<Content>>, a 4-valued type supporting:
Ok(content)- Successful resultErr(McpError)- Recoverable errorCancelled- Request was cancelledPanicked- Unrecoverable failure
Required Methods§
Sourcefn definition(&self) -> Tool
fn definition(&self) -> Tool
Returns the tool definition.
Provided Methods§
Sourcefn icon(&self) -> Option<&Icon>
fn icon(&self) -> Option<&Icon>
Returns the tool’s icon, if any.
Default implementation returns None. Override to provide an icon.
Note: Icons can also be set directly in definition().
Sourcefn version(&self) -> Option<&str>
fn version(&self) -> Option<&str>
Returns the tool’s version, if any.
Default implementation returns None. Override to provide a version.
Note: Version can also be set directly in definition().
Returns the tool’s tags for filtering and organization.
Default implementation returns an empty slice. Override to provide tags.
Note: Tags can also be set directly in definition().
Sourcefn annotations(&self) -> Option<&ToolAnnotations>
fn annotations(&self) -> Option<&ToolAnnotations>
Returns the tool’s annotations providing behavioral hints.
Default implementation returns None. Override to provide annotations
like destructive, idempotent, read_only, or open_world_hint.
Note: Annotations can also be set directly in definition().
Sourcefn output_schema(&self) -> Option<Value>
fn output_schema(&self) -> Option<Value>
Returns the tool’s output schema (JSON Schema).
Default implementation returns None. Override to provide a schema
that describes the structure of the tool’s output.
Note: Output schema can also be set directly in definition().
Sourcefn final_title(&self) -> Option<&str>
fn final_title(&self) -> Option<&str>
Returns the final display title for this tool.
This final-only field is deliberately separate from the legacy tool definition so modern catalog projection never synthesizes or leaks a legacy version/tag field.
Sourcefn final_icons(&self) -> Option<&[RawIcon]>
fn final_icons(&self) -> Option<&[RawIcon]>
Returns the validated final icon set for this tool.
A legacy singular icon is not projected automatically because its optional source and scalar size hint do not form an exact final icon.
Sourcefn final_metadata(&self) -> Option<&OpenMetadata>
fn final_metadata(&self) -> Option<&OpenMetadata>
Returns final open metadata for this tool’s catalog entry.
Sourcefn final_definition(&self) -> Option<FinalTool>
fn final_definition(&self) -> Option<FinalTool>
Returns an exact final catalog definition when this handler owns one.
Legacy-first handlers normally leave this as None; the router then
freezes the ordinary Self::definition plus the individual final
metadata hooks into a final definition. A native final handler or proxy
should override this hook so title-bearing annotations, the complete
icon collection, and open metadata are never projected through the
narrower legacy Tool model.
Returns the legacy diagnostic label for this handler’s exact-final schemas.
Ordinary and legacy-backed handlers keep local schema admission. The
router does not use this forgeable label for admission; exact proxy
registration supplies a sealed token through
Self::upstream_final_tool_schema_registration instead.
Sourcefn upstream_final_tool_schema_registration(
&self,
) -> Option<UpstreamFinalToolSchemaRegistration>
fn upstream_final_tool_schema_registration( &self, ) -> Option<UpstreamFinalToolSchemaRegistration>
Returns a sealed upstream-schema registration for an exact proxy.
Ordinary handlers must use the default. The token has no public constructor, so only server-owned proxy registration can opt out of local input/output validation and framework-error synthesis.
Sourcefn final_tool_error_structured_content(
&self,
_kind: ToolErrorKind,
) -> Option<Value>
fn final_tool_error_structured_content( &self, _kind: ToolErrorKind, ) -> Option<Value>
Maps a framework-authored tool error into this tool’s structured output.
A handler that declares outputSchema must return a truthful value for
both closed error kinds. Registration invokes this hook once for each
kind, bounds and validates the returned JSON, and stores immutable
copies beside the admitted schemas. Returning None, an over-limit
value, or a value rejected by outputSchema rejects registration
before any catalog mutation.
Sourcefn timeout(&self) -> Option<Duration>
fn timeout(&self) -> Option<Duration>
Returns the tool’s custom timeout duration.
Default implementation returns None, meaning no additional handler
ceiling is added. Override to specify a per-handler timeout.
A non-zero value tightens the ambient/request/server budget. It never
replaces or relaxes an earlier absolute deadline. A zero value is
treated like None and therefore cannot disable an outer timeout.
Pending async work is dropped when the legacy synchronous dispatcher’s
timer observes a comparable deadline, and a late completion is rejected.
The dispatcher does not drive a caller’s foreign virtual clock. This
cannot preempt a blocking synchronous call() or guarantee child-work
drain; handlers must still cooperate with McpContext::checkpoint.
Sourcefn call_async<'a>(
&'a self,
ctx: &'a McpContext,
arguments: Value,
) -> BoxFuture<'a, McpOutcome<Vec<Content>>>
fn call_async<'a>( &'a self, ctx: &'a McpContext, arguments: Value, ) -> BoxFuture<'a, McpOutcome<Vec<Content>>>
Calls the tool asynchronously with the given arguments.
Override this for tools that need true async execution (e.g., I/O-bound operations, database queries, HTTP requests).
Returns McpOutcome to properly represent all four states: success,
error, cancellation, and panic.
The default implementation delegates to the sync call() method and
converts the McpResult to McpOutcome.
Sourcefn call_final(
&self,
ctx: &McpContext,
arguments: Value,
) -> McpResult<CompleteResult<FinalCallToolResult>>
fn call_final( &self, ctx: &McpContext, arguments: Value, ) -> McpResult<CompleteResult<FinalCallToolResult>>
Calls the tool through the final MCP 2026-07-28 result surface.
Legacy-only handlers retain their exact Self::call result and are
promoted without loss into a complete final result. Handlers that
author final-only metadata, annotations, resource links, or a tool
error result should override this method (or its async counterpart) so
the router can preserve the supplied final result algebra exactly.
Sourcefn call_final_async<'a>(
&'a self,
ctx: &'a McpContext,
arguments: Value,
) -> BoxFuture<'a, McpOutcome<CompleteResult<FinalCallToolResult>>>
fn call_final_async<'a>( &'a self, ctx: &'a McpContext, arguments: Value, ) -> BoxFuture<'a, McpOutcome<CompleteResult<FinalCallToolResult>>>
Asynchronously calls the tool through the final result surface.
The default delegates to Self::call_final.
Sourcefn call_async_in_request<'a>(
&'a self,
ctx: &'a McpContext,
_request_cx: &'a Cx,
arguments: Value,
) -> BoxFuture<'a, McpOutcome<Vec<Content>>>
fn call_async_in_request<'a>( &'a self, ctx: &'a McpContext, _request_cx: &'a Cx, arguments: Value, ) -> BoxFuture<'a, McpOutcome<Vec<Content>>>
Calls the tool from a request-owned structured child.
Modern router dispatch supplies the child Cx that owns this handler
invocation. Implementations that spawn or otherwise coordinate nested
work must use this context so cancellation and completion remain within
the request’s structured lifetime. Existing handlers keep their exact
behavior through the default delegation to Self::call_async.
Sourcefn call_final_async_in_request<'a>(
&'a self,
ctx: &'a McpContext,
_request_cx: &'a Cx,
arguments: Value,
) -> BoxFuture<'a, McpOutcome<CompleteResult<FinalCallToolResult>>>
fn call_final_async_in_request<'a>( &'a self, ctx: &'a McpContext, _request_cx: &'a Cx, arguments: Value, ) -> BoxFuture<'a, McpOutcome<CompleteResult<FinalCallToolResult>>>
Calls the tool’s final result hook from a request-owned child.
Existing final async handlers keep their behavior through the default
delegation to Self::call_final_async.
Sourcefn declares_final_tasks(&self) -> bool
fn declares_final_tasks(&self) -> bool
Declares whether this handler can return a final Tasks CreateTask outcome.
The router verifies this declaration only if the handler actually
returns [FinalToolOutcome::CreateTask], then admits negotiated Tasks
capability and runtime readiness before mutating task state. Handlers
that return [FinalToolOutcome::CreateTask] must override this to
return true.
Sourcefn declares_final_mrtr(&self) -> bool
fn declares_final_mrtr(&self) -> bool
Declares whether this handler can use final MRTR continuations.
This is an immutable handler capability, rather than an inference from
a runtime outcome. A declared-capable handler requires a modern
connection partition before the router invokes it, so an
InputRequired outcome can never be produced without durable
continuation ownership.
Sourcefn call_final_outcome(
&self,
ctx: &McpContext,
arguments: Value,
) -> McpResult<FinalToolOutcome>
fn call_final_outcome( &self, ctx: &McpContext, arguments: Value, ) -> McpResult<FinalToolOutcome>
Calls the tool through the final complete, input-required, or task-creation surface.
Existing handlers remain complete-only. A task-capable handler
overrides this method, or its async/request-owned counterpart, and
returns [FinalToolOutcome::CreateTask] without mutating task state.
Sourcefn call_final_outcome_async<'a>(
&'a self,
ctx: &'a McpContext,
arguments: Value,
) -> BoxFuture<'a, McpOutcome<FinalToolOutcome>>
fn call_final_outcome_async<'a>( &'a self, ctx: &'a McpContext, arguments: Value, ) -> BoxFuture<'a, McpOutcome<FinalToolOutcome>>
Asynchronously calls the final complete, input-required, or task-creation surface.
Sourcefn call_final_outcome_async_in_request<'a>(
&'a self,
ctx: &'a McpContext,
_request_cx: &'a Cx,
arguments: Value,
) -> BoxFuture<'a, McpOutcome<FinalToolOutcome>>
fn call_final_outcome_async_in_request<'a>( &'a self, ctx: &'a McpContext, _request_cx: &'a Cx, arguments: Value, ) -> BoxFuture<'a, McpOutcome<FinalToolOutcome>>
Calls the disjoint final outcome from a request-owned structured child.
Sourcefn call_final_outcome_async_resuming_in_request<'a>(
&'a self,
ctx: &'a McpContext,
request_cx: &'a Cx,
arguments: Value,
_resume_inputs: Option<&'a MrtrCompletedInputs>,
) -> BoxFuture<'a, McpOutcome<FinalToolOutcome>>
fn call_final_outcome_async_resuming_in_request<'a>( &'a self, ctx: &'a McpContext, request_cx: &'a Cx, arguments: Value, _resume_inputs: Option<&'a MrtrCompletedInputs>, ) -> BoxFuture<'a, McpOutcome<FinalToolOutcome>>
Resumes a final tool invocation after framework-admitted MRTR input.
resume_inputs exists only after the router consumed a
framework-minted request state bound to the original modern operation.
Handlers inspect its typed accessors rather than decoding client wire
values. #[tool] exposes this as an
Option<&MrtrCompletedInputs> user-function parameter: initial calls
receive None and admitted retries receive Some. Existing handlers
preserve their normal final hook by default.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".