pub trait Tool: Send + Sync {
// Required methods
fn name(&self) -> &str;
fn description(&self) -> &str;
fn parameters_schema(&self) -> Value;
fn execute<'life0, 'life1, 'async_trait>(
&'life0 self,
params: Value,
ctx: &'life1 ToolContext,
) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
// Provided methods
fn capabilities(&self) -> Option<Vec<Capability>> { ... }
fn binding_metadata(&self) -> Option<Value> { ... }
fn runtime_dispatch(&self) -> ToolRuntimeDispatch { ... }
fn preparation(&self) -> Option<ToolPreparation> { ... }
fn prepare<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 ToolContext,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn is_builtin(&self) -> bool { ... }
fn validate_arguments(&self, params: &Value) -> Result<()> { ... }
fn approval_arguments(&self, params: &Value) -> Result<Value> { ... }
}Expand description
A custom MCP tool that agents can discover and call.
Implement this trait to create a compiled Rust tool. Tools are
registered at server startup and exposed via GET /tools/list
for agent discovery and POST /tools/{name} for invocation.
§Lifecycle
- The tool is registered via
ToolRegistry::register. name,description, andparameters_schemaare called at startup for the tool list.executeis called each time an agent invokes the tool.
§Example
use async_trait::async_trait;
use anyhow::Result;
use serde_json::{json, Value};
use context_harness::traits::{Tool, ToolContext};
pub struct HealthCheckTool;
#[async_trait]
impl Tool for HealthCheckTool {
fn name(&self) -> &str { "health_check" }
fn description(&self) -> &str { "Check connector health" }
fn parameters_schema(&self) -> Value {
json!({
"type": "object",
"properties": {},
"required": []
})
}
async fn execute(&self, _params: Value, ctx: &ToolContext) -> Result<Value> {
let sources = ctx.sources()?;
Ok(json!({ "sources": sources.len() }))
}
}Required Methods§
Sourcefn name(&self) -> &str
fn name(&self) -> &str
Returns the tool’s name.
Used as the route path (POST /tools/{name}) and in
GET /tools/list responses. Should be a lowercase
identifier with underscores (e.g., "create_ticket").
Sourcefn description(&self) -> &str
fn description(&self) -> &str
Returns a one-line description for agent discovery.
Agents use this to decide whether to call the tool.
Sourcefn parameters_schema(&self) -> Value
fn parameters_schema(&self) -> Value
Returns the OpenAI function-calling JSON Schema for parameters.
Must be a valid JSON Schema object with type: "object",
properties, and optionally required.
Sourcefn execute<'life0, 'life1, 'async_trait>(
&'life0 self,
params: Value,
ctx: &'life1 ToolContext,
) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn execute<'life0, 'life1, 'async_trait>(
&'life0 self,
params: Value,
ctx: &'life1 ToolContext,
) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Execute the tool with validated parameters.
Called each time an agent invokes the tool via POST /tools/{name}.
§Arguments
params— JSON parameters (always a JSON object).ctx— Bridge to the Context Harness knowledge base.
§Returns
A JSON value that will be wrapped in { "result": ... } in the
HTTP response.
Provided Methods§
Sourcefn capabilities(&self) -> Option<Vec<Capability>>
fn capabilities(&self) -> Option<Vec<Capability>>
Runtime capability requirements. Unknown metadata is denied by the local agent runtime; existing MCP tools retain their existing behavior.
Sourcefn binding_metadata(&self) -> Option<Value>
fn binding_metadata(&self) -> Option<Value>
Sanitized immutable identity for declaratively bound tools. History and recovery use this without loading implementations or resolving secrets.
Sourcefn runtime_dispatch(&self) -> ToolRuntimeDispatch
fn runtime_dispatch(&self) -> ToolRuntimeDispatch
Select runtime-owned execution context without coupling the dispatcher to a public tool name. Most tools execute directly.
Sourcefn preparation(&self) -> Option<ToolPreparation>
fn preparation(&self) -> Option<ToolPreparation>
Optional host-owned preparation that must complete through the durable approval lifecycle before this tool can be advertised to a model.
fn prepare<'life0, 'life1, 'async_trait>(
&'life0 self,
_ctx: &'life1 ToolContext,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Sourcefn is_builtin(&self) -> bool
fn is_builtin(&self) -> bool
Whether this tool is a built-in (true for search/get/sources).
Built-in tools are marked with "builtin": true in the
GET /tools/list response. Defaults to false.
Sourcefn validate_arguments(&self, params: &Value) -> Result<()>
fn validate_arguments(&self, params: &Value) -> Result<()>
Validate model-visible arguments before authorization and tool start. Bound adapters override this with their resolved public contract.
Sourcefn approval_arguments(&self, params: &Value) -> Result<Value>
fn approval_arguments(&self, params: &Value) -> Result<Value>
Sanitized effective arguments covered by approval. Bound tools override this to include immutable fixed values and reject override attempts.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".