adk-tool
Tool system for Rust Agent Development Kit (ADK-Rust) agents (FunctionTool, MCP, Google Search).
Overview
adk-tool provides the tool infrastructure for the Rust Agent Development Kit (ADK-Rust):
- FunctionTool - Create tools from async Rust functions
- StatefulTool<S> - Wrap shared state (
Arc<S>) with a tool handler - SimpleToolContext - Lightweight
ToolContextfor non-agent callers (testing, MCP servers) - AgentTool - Use agents as callable tools for composition (runs sub-agents in non-streaming mode for reliable response capture)
- GoogleSearchTool - Web search via Gemini's grounding
- Provider-native wrappers - Typed declarations for Gemini, Anthropic, and OpenAI built-in tools
- McpToolset - Model Context Protocol integration (local & remote servers)
- McpServerManager - Multi-server lifecycle management with health monitoring and auto-restart
- BasicToolset - Group multiple tools together
- FilteredToolset - Filter tools from any toolset by predicate
- MergedToolset - Combine multiple toolsets into one
- PrefixedToolset - Namespace tool names with a prefix
- ExitLoopTool - Control flow for loop agents
- LoadArtifactsTool - Inject binary artifacts into context
- LoadMemoryTool - Agent-callable tool for on-demand memory search (feature:
memory-tools) - PreloadMemoryTool - Auto-loads relevant memories at turn start (feature:
memory-tools)
Installation
[]
= "2.0.0"
# For local MCP servers via stdio:
= { = "2.0.0", = ["mcp"] }
# For remote MCP servers via HTTP:
= { = "2.0.0", = ["mcp", "http-transport"] }
Or use the meta-crate:
[]
= { = "2.0.0", = ["tools"] }
Quick Start
Function Tool
use FunctionTool;
use ;
use ;
use Arc;
async
let tool = new;
With Parameter Schema (Recommended)
Always add a schema so the LLM knows what parameters to pass:
use JsonSchema;
use ;
let tool = new
.;
Tool Metadata
Mark tools as read-only or concurrency-safe for smarter dispatch:
let lookup = new
.with_read_only
.with_concurrency_safe; // both signals are required by Auto mode
StatefulTool
Wrap shared state with a tool handler — the Arc<S> is cloned per invocation:
use StatefulTool;
use RwLock;
let state = new;
let tool = new;
SimpleToolContext
Call tools outside the agent loop (testing, MCP servers, sub-agent delegation):
use SimpleToolContext;
let ctx = new;
let result = my_tool.execute.await?;
Defaults: user_id() → "anonymous", session_id() → "", unique UUIDs for invocation and function call IDs.
MCP Server Manager (Multi-Server Lifecycle)
Manage a changing registry of local MCP server processes with connection monitoring, bounded restart, configuration persistence, and tool aggregation:
use McpServerManager;
use Arc;
use Duration;
// Load from Kiro mcp.json format
let manager = new;
// Start all non-disabled servers
let results = manager.start_all.await;
// Use as a Toolset — tools from all servers are aggregated
// Name collisions are resolved with {server_id}__{tool_name} prefixes
let agent = new
.model
.toolset
.build?;
// Dynamic management at runtime
manager.add_server.await?;
manager.start_server.await?;
manager.update_server.await?;
manager.disable_server.await?;
manager.enable_server.await?;
manager.save_json_file.await?;
manager.remove_server.await?;
// Graceful shutdown
manager.shutdown.await?;
Use absolute, versioned executable paths in deployment configuration. The
manager preserves autoApprove for configuration compatibility but does not
turn that field into authorization or human approval policy.
MCP Tools (Local Server via stdio)
Connect to local MCP servers running as child processes:
use ;
use Command;
// Connect to a local MCP server
let cmd = new
.arg
.arg
.arg;
let client = .serve.await?;
let toolset = new
.with_name
.with_filter;
// Get cancellation token for graceful shutdown
let cancel_token = toolset.cancellation_token.await;
// ... use toolset with agent ...
// Cleanup before exit
cancel_token.cancel;
MCP Tools (Remote Server via HTTP)
Connect to remote MCP servers using HTTP transport (requires http-transport feature):
use McpHttpClientBuilder;
use Duration;
// Connect to a service owned by your organization or integration provider
let toolset = new
.timeout
.connect
.await?;
MCP Authentication
Connect to authenticated MCP servers:
use ;
use Duration;
// Static bearer token supplied by your deployment identity system
let toolset = new
.with_auth
.timeout
.connect
.await?;
// API key in custom header
let toolset = new
.with_auth
.connect
.await?;
// OAuth2 client credentials flow
let oauth_config = new
.with_secret
.with_scopes;
let toolset = new
.with_auth
.connect
.await?;
MCP Task Support (Long-Running Operations)
Enable the negotiated MCP 2025-11-25 task lifecycle for long-running tool operations:
use ;
use Duration;
let toolset = new
.with_task_support;
Task mode is used only when the server advertises task support and the selected
tool declares it. ADK-Rust sends task metadata with tools/call, polls
tasks/get, reads tasks/result, and requests tasks/cancel when the local
timeout or poll bound is reached.
MCP Auto-Reconnect (Connection Resilience)
For one custom connection, ConnectionRefresher accepts a
ConnectionFactory that can create the same concrete rmcp::RunningService
again after a retryable failure. Configure bounded attempts and delay with
RefreshConfig. For a changing set of local stdio processes, prefer
McpServerManager, whose registry, monitoring, restart, and persistence model
is easier to operate.
The refresher handles these error conditions automatically:
- Connection closed / EOF
- Broken pipe / transport errors
- Session not found (server restart)
- Connection reset
Discovery calls reconnect and retry automatically. Discovered tool wrappers
also replay when the server publishes readOnlyHint: true or
idempotentHint: true. Missing hints keep replay disabled because a lost
response can leave a mutating tool's external result uncertain. The direct
call_tool_value and ConnectionRefresher::call_tool paths do not have
discovered per-tool metadata; opt them in only for read-only tools or operations
protected by a stable provider idempotency guarantee:
let refresher = new
.with_tool_call_retries;
let toolset = new
.with_connection_factory
.with_tool_call_retries;
MCP annotations are server-published hints. Trust them only for servers inside the application's security boundary.
Google Search
use GoogleSearchTool;
let search = new;
// Add to agent - enables grounded web search
Code Execution Tools (code feature)
Language-preset tool wrappers over the adk-code execution substrate: CodeTool (Rust), JavaScriptCodeTool (embedded JS via code-embedded-js), PythonCodeTool (container-backed CPython), and MontyPythonCodeTool (in-process Python via code-embedded-python).
MontyPythonCodeTool runs model-written Python in the Monty interpreter — no container, no subprocess. It supports one-shot mode (fresh interpreter per call) and REPL mode (state persists across calls, scoped per ADK session), with host-granted filesystem/environment/clock access and registered host functions. Its LLM-facing description is composed from the executor's own capability report, so it always matches the built environment. For the full Python ecosystem (pip packages, C extensions, the complete standard library), use the container-backed PythonCodeTool instead.
use PathAccess;
use MontyPythonCodeTool;
let tool = builder
.allow_path
.environ_var
.system_clock
.build_repl?;
Features
| Feature | Description |
|---|---|
mcp |
Local MCP clients via stdio, McpToolset, and McpServerManager |
http-transport |
Remote MCP servers via streamable HTTP |
mcp-sampling |
Deprecated upstream sampling compatibility |
code |
Code execution tools over the adk-code substrate |
code-embedded-js |
JavaScriptCodeTool live path (boa_engine) |
code-embedded-python |
MontyPythonCodeTool live path (Monty interpreter) |
MCP examples and guides
examples/mcp_manager runs a real Rust stdio server locally and verifies
discovery, tool execution, dynamic registry changes, persistence, and shutdown
without a package download or network dependency. examples/mcp_elicitation
demonstrates a server asking its client application for additional information.
The complete official guide covers client construction, server authoring,
dynamic management, security, testing, resources, prompts, completion,
reconnect-safe subscriptions with ResourceNotificationHandler, elicitation,
and tasks in docs/official_docs/mcp/.
Toolset Composition
Compose, filter, and namespace toolsets for complex agent configurations:
use ;
use Arc;
// Group tools into named toolsets
let weather = new;
let utils = new;
// Filter: expose only specific tools from a toolset
let filtered = new;
// Or use a custom predicate
let custom = with_name;
// Merge: combine multiple toolsets (first-wins deduplication)
let merged = new;
// Prefix: namespace tool names to avoid collisions
let prefixed = new; // wx_get_weather, wx_get_forecast
// Chain them: prefix → filter → merge
let composed = new;
// Register with an agent
let agent = new
.model
.toolset
.build?;
All composition utilities implement Toolset and work with any Toolset implementation including McpToolset and BrowserToolset.
rmcp compatibility
ADK-Rust 2 uses rmcp 3.1, the official Rust SDK. McpToolset::new(client)
remains the primary adapter. Advanced server authoring, transports, protocol
extensions, and SDK types are available through adk_tool::mcp::rmcp, keeping
them on the same version used internally.
Protocol revisions
The client advertises MCP 2025-11-25, the same revision ADK-Rust 2 has always
sent. A 2026-07-28 server still answers that handshake, so one client reaches
both generations of server and no existing configuration changes behaviour.
2026-07-28 also adds a stateless server/discover handshake. It is opt-in,
because a server that predates it is free to refuse an unknown method with
something other than METHOD_NOT_FOUND, and the SDK treats only that one code
as proof of a legacy peer. Select it per connection:
| Mode | Sends first | Against an older server |
|---|---|---|
Initialize (default) |
initialize |
Works |
Auto |
server/discover |
Falls back only on METHOD_NOT_FOUND |
Discover |
server/discover |
Fails; no fallback |
use ;
use ProtocolVersion;
let client = new
.serve_with_lifecycle
.await?;
let toolset = new;
Tasks
SEP-2663 replaced the experimental task design. A tool no longer declares
whether it supports task execution; the server decides per call, and the client
reads the response to find out. Tool::is_long_running therefore reports per
connection rather than per tool: it is true when tasks are enabled and the server
negotiated them.
Sampling, roots, and logging are deprecated upstream by SEP-2577. The
mcp-sampling feature exists for compatible deployments and should not be the
default design for a new system.
When migrating code that imports rmcp types directly, align it to rmcp 3.1
or import the SDK through adk_tool::mcp::rmcp.
Related Crates
- adk-rust - Meta-crate with all components
- adk-core - Core
Tooltrait - adk-agent - Agents that use tools
License
Apache-2.0
Part of ADK-Rust
This crate is part of the ADK-Rust framework for building AI agents in Rust.