pub struct McpToolset<S = ()>{ /* private fields */ }tools only.Expand description
MCP Toolset - connects to an MCP server and exposes its tools as ADK tools.
This toolset implements the ADK Toolset trait and bridges the gap between
MCP servers and ADK agents. It:
- Connects to an MCP server via the provided transport
- Discovers available tools from the server
- Converts MCP tools to ADK-compatible
Toolimplementations - Proxies tool execution calls to the MCP server
§Example
use adk_tool::{
McpToolset,
mcp::rmcp::{ServiceExt, transport::TokioChildProcess},
};
use tokio::process::Command;
// Create MCP client connection to a local server
let client = ().serve(TokioChildProcess::new(
Command::new("/opt/company/bin/workspace-mcp")
.arg("--stdio")
.arg("--root")
.arg("/srv/workspace")
)?).await?;
// Create toolset from the client
let toolset = McpToolset::new(client);
// Add to agent
let agent = LlmAgentBuilder::new("assistant")
.toolset(Arc::new(toolset))
.build()?;Implementations§
Source§impl<S> McpToolset<S>
impl<S> McpToolset<S>
Sourcepub fn new(client: RunningService<RoleClient, S>) -> McpToolset<S>
Available on crate feature mcp only.
pub fn new(client: RunningService<RoleClient, S>) -> McpToolset<S>
mcp only.Create a new MCP toolset from a running MCP client service.
The client should already be connected and initialized.
Use adk_tool::mcp::rmcp::ServiceExt::serve() to create the client.
§Example
use adk_tool::mcp::rmcp::{ServiceExt, transport::TokioChildProcess};
use tokio::process::Command;
let client = ().serve(TokioChildProcess::new(
Command::new("my-mcp-server")
)?).await?;
let toolset = McpToolset::new(client);Sourcepub fn with_client_handler(
client: RunningService<RoleClient, S>,
) -> McpToolset<S>
Available on crate feature mcp only.
pub fn with_client_handler( client: RunningService<RoleClient, S>, ) -> McpToolset<S>
mcp only.Create a McpToolset from a RunningService with a custom ClientHandler.
This is functionally identical to new() but makes the intent explicit
when using a custom ClientHandler type.
§Example
use adk_tool::{McpToolset, mcp::rmcp::ServiceExt};
let client = my_custom_handler.serve(transport).await?;
let toolset = McpToolset::with_client_handler(client);Sourcepub fn with_name(self, name: impl Into<String>) -> McpToolset<S>
Available on crate feature mcp only.
pub fn with_name(self, name: impl Into<String>) -> McpToolset<S>
mcp only.Set a custom name for this toolset.
Sourcepub fn with_task_support(self, config: McpTaskConfig) -> McpToolset<S>
Available on crate feature mcp only.
pub fn with_task_support(self, config: McpTaskConfig) -> McpToolset<S>
mcp only.Enable negotiated MCP task support for long-running operations.
A tool declared with required task support always uses the task flow.
A tool declaring optional task support uses it when this configuration
is enabled and the server negotiated tasks.requests.tools.call.
§Example
let toolset = McpToolset::new(client)
.with_task_support(McpTaskConfig::enabled()
.poll_interval(Duration::from_secs(2))
.timeout(Duration::from_secs(300)));Sourcepub fn with_connection_factory<F>(self, factory: Arc<F>) -> McpToolset<S>where
F: ConnectionFactory<S> + 'static,
Available on crate feature mcp only.
pub fn with_connection_factory<F>(self, factory: Arc<F>) -> McpToolset<S>where
F: ConnectionFactory<S> + 'static,
mcp only.Provide a connection factory to enable automatic MCP reconnection.
Sourcepub fn with_refresh_config(self, config: RefreshConfig) -> McpToolset<S>
Available on crate feature mcp only.
pub fn with_refresh_config(self, config: RefreshConfig) -> McpToolset<S>
mcp only.Configure MCP reconnect/retry behavior.
Sourcepub fn with_tool_call_retries(self) -> McpToolset<S>
Available on crate feature mcp only.
pub fn with_tool_call_retries(self) -> McpToolset<S>
mcp only.Allow MCP tool calls to be replayed after reconnecting.
A transport failure after request transmission is an ambiguous outcome: a mutating tool may have completed its external effect before the response was lost. Enable this only for read-only tools or operations protected by a stable provider idempotency guarantee. Discovery and resource operations keep their normal reconnect behavior without this.
§Example
let toolset = McpToolset::new(client)
.with_connection_factory(Arc::new(factory))
.with_tool_call_retries();Sourcepub fn with_filter<F>(self, filter: F) -> McpToolset<S>
Available on crate feature mcp only.
pub fn with_filter<F>(self, filter: F) -> McpToolset<S>
mcp only.Sourcepub fn with_tools(self, tool_names: &[&str]) -> McpToolset<S>
Available on crate feature mcp only.
pub fn with_tools(self, tool_names: &[&str]) -> McpToolset<S>
mcp only.Sourcepub async fn cancellation_token(&self) -> RunningServiceCancellationToken
Available on crate feature mcp only.
pub async fn cancellation_token(&self) -> RunningServiceCancellationToken
mcp only.Get a cancellation token that can be used to shutdown the MCP server.
Call cancel() on the returned token to cleanly shutdown the MCP server.
This should be called before exiting to avoid EPIPE errors.
§Example
let toolset = McpToolset::new(client);
let cancel_token = toolset.cancellation_token().await;
// ... use the toolset ...
// Before exiting:
cancel_token.cancel();Sourcepub async fn is_closed(&self) -> bool
Available on crate feature mcp only.
pub async fn is_closed(&self) -> bool
mcp only.Check whether the underlying MCP service connection has been closed or cancelled.
Returns true if the service loop has terminated (transport closed,
cancellation token fired, or the background task completed). This is
useful for health monitoring — a closed connection indicates the server
process has crashed or the transport has been lost.
§Example
if toolset.is_closed().await {
tracing::warn!("MCP server connection lost");
}Sourcepub async fn call_tool_value(
&self,
name: &str,
arguments: Map<String, Value>,
) -> Result<Value, AdkError>
Available on crate feature mcp only.
pub async fn call_tool_value( &self, name: &str, arguments: Map<String, Value>, ) -> Result<Value, AdkError>
mcp only.Call one MCP tool and preserve structured, text, image, audio, and resource content in the same ADK multimodal value shape used by model-facing tool execution.
Sourcepub async fn list_resources(&self) -> Result<Vec<Resource>, AdkError>
Available on crate feature mcp only.
pub async fn list_resources(&self) -> Result<Vec<Resource>, AdkError>
mcp only.List static resources from the connected MCP server.
Returns the list of resources advertised by the server via the
resources/list protocol method. Returns an empty Vec when the
server does not support resources (i.e. responds with
MethodNotFound).
§Errors
Returns AdkError::Tool on transport or unexpected server errors.
Sourcepub async fn list_resource_templates(
&self,
) -> Result<Vec<ResourceTemplate>, AdkError>
Available on crate feature mcp only.
pub async fn list_resource_templates( &self, ) -> Result<Vec<ResourceTemplate>, AdkError>
mcp only.List URI template resources from the connected MCP server.
Returns the list of resource templates advertised by the server via
the resourceTemplates/list protocol method. Returns an empty Vec
when the server does not support resource templates (i.e. responds
with MethodNotFound).
§Errors
Returns AdkError::Tool on transport or unexpected server errors.
Sourcepub async fn read_resource(
&self,
uri: &str,
) -> Result<Vec<ResourceContents>, AdkError>
Available on crate feature mcp only.
pub async fn read_resource( &self, uri: &str, ) -> Result<Vec<ResourceContents>, AdkError>
mcp only.Read a resource by URI from the connected MCP server.
Delegates to the resources/read protocol method. Returns the
resource contents on success.
§Errors
Returns AdkError::Tool("resource not found: {uri}") when the URI
does not match any resource on the server. Returns a generic
AdkError::Tool on transport or other server errors.
Sourcepub async fn list_prompts(&self) -> Result<Vec<Prompt>, AdkError>
Available on crate feature mcp only.
pub async fn list_prompts(&self) -> Result<Vec<Prompt>, AdkError>
mcp only.Return the prompt templates published by the connected MCP server.
Sourcepub async fn get_prompt(
&self,
name: &str,
arguments: Option<Map<String, Value>>,
) -> Result<GetPromptResult, AdkError>
Available on crate feature mcp only.
pub async fn get_prompt( &self, name: &str, arguments: Option<Map<String, Value>>, ) -> Result<GetPromptResult, AdkError>
mcp only.Resolve one published MCP prompt with optional typed arguments.
Sourcepub async fn complete_prompt_argument(
&self,
prompt_name: &str,
argument_name: &str,
current_value: &str,
context: Option<CompletionContext>,
) -> Result<CompletionInfo, AdkError>
Available on crate feature mcp only.
pub async fn complete_prompt_argument( &self, prompt_name: &str, argument_name: &str, current_value: &str, context: Option<CompletionContext>, ) -> Result<CompletionInfo, AdkError>
mcp only.Request completion suggestions for one prompt argument.
Sourcepub async fn complete_resource_argument(
&self,
uri_template: &str,
argument_name: &str,
current_value: &str,
context: Option<CompletionContext>,
) -> Result<CompletionInfo, AdkError>
Available on crate feature mcp only.
pub async fn complete_resource_argument( &self, uri_template: &str, argument_name: &str, current_value: &str, context: Option<CompletionContext>, ) -> Result<CompletionInfo, AdkError>
mcp only.Request completion suggestions for one resource-template argument.
Sourcepub async fn subscribe_resource(&self, uri: &str) -> Result<(), AdkError>
Available on crate feature mcp only.
pub async fn subscribe_resource(&self, uri: &str) -> Result<(), AdkError>
mcp only.Subscribe to change notifications for a resource URI.
Sourcepub async fn unsubscribe_resource(&self, uri: &str) -> Result<(), AdkError>
Available on crate feature mcp only.
pub async fn unsubscribe_resource(&self, uri: &str) -> Result<(), AdkError>
mcp only.Remove a resource subscription created by subscribe_resource.
Source§impl McpToolset<AdkClientHandler>
impl McpToolset<AdkClientHandler>
Sourcepub async fn with_elicitation_handler<T, E, A>(
transport: T,
handler: Arc<dyn ElicitationHandler>,
) -> Result<McpToolset<AdkClientHandler>, AdkError>
Available on crate feature mcp only.
pub async fn with_elicitation_handler<T, E, A>( transport: T, handler: Arc<dyn ElicitationHandler>, ) -> Result<McpToolset<AdkClientHandler>, AdkError>
mcp only.Create a McpToolset with elicitation support from a transport.
This creates the MCP client using AdkClientHandler, which advertises
elicitation capabilities and delegates requests to the provided handler.
§Example
use adk_tool::{McpToolset, ElicitationHandler, AutoDeclineElicitationHandler};
use adk_tool::mcp::rmcp::transport::TokioChildProcess;
use tokio::process::Command;
use std::sync::Arc;
let transport = TokioChildProcess::new(Command::new("my-mcp-server"))?;
let handler = Arc::new(AutoDeclineElicitationHandler);
let toolset = McpToolset::with_elicitation_handler(transport, handler).await?;§ConnectionFactory with Elicitation
To preserve elicitation across reconnections, clone the Arc<dyn ElicitationHandler>
into your ConnectionFactory implementation:
use adk_tool::{McpToolset, ElicitationHandler};
use adk_tool::mcp::ConnectionFactory;
use adk_tool::mcp::rmcp::{
ServiceExt,
service::{RoleClient, RunningService},
transport::TokioChildProcess,
};
use tokio::process::Command;
use std::sync::Arc;
struct MyReconnectFactory {
handler: Arc<dyn ElicitationHandler>,
server_command: String,
}
// The factory creates a fresh AdkClientHandler on each reconnection,
// so the new connection advertises elicitation capabilities.
// The ConnectionFactory trait itself is unchanged.Sourcepub async fn with_handlers<T, E, A>(
transport: T,
elicitation_handler: Arc<dyn ElicitationHandler>,
resource_notification_handler: Arc<dyn ResourceNotificationHandler>,
) -> Result<McpToolset<AdkClientHandler>, AdkError>
Available on crate feature mcp only.
pub async fn with_handlers<T, E, A>( transport: T, elicitation_handler: Arc<dyn ElicitationHandler>, resource_notification_handler: Arc<dyn ResourceNotificationHandler>, ) -> Result<McpToolset<AdkClientHandler>, AdkError>
mcp only.Create an MCP toolset with elicitation and resource notification handlers.
Both handlers are installed before the protocol handshake, so resource update notifications can be received immediately after subscribing.
Trait Implementations§
Source§impl<S> Clone for McpToolset<S>
impl<S> Clone for McpToolset<S>
Source§fn clone(&self) -> McpToolset<S>
fn clone(&self) -> McpToolset<S>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<S> Toolset for McpToolset<S>
impl<S> Toolset for McpToolset<S>
Source§fn tools<'life0, 'async_trait>(
&'life0 self,
_ctx: Arc<dyn ReadonlyContext>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Arc<dyn Tool>>, AdkError>> + Send + 'async_trait>>where
'life0: 'async_trait,
McpToolset<S>: 'async_trait,
fn tools<'life0, 'async_trait>(
&'life0 self,
_ctx: Arc<dyn ReadonlyContext>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Arc<dyn Tool>>, AdkError>> + Send + 'async_trait>>where
'life0: 'async_trait,
McpToolset<S>: 'async_trait,
Auto Trait Implementations§
impl<S = ()> !RefUnwindSafe for McpToolset<S>
impl<S = ()> !UnwindSafe for McpToolset<S>
impl<S> Freeze for McpToolset<S>
impl<S> Send for McpToolset<S>
impl<S> Sync for McpToolset<S>
impl<S> Unpin for McpToolset<S>
impl<S> UnsafeUnpin for McpToolset<S>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreimpl<T> MaybeSend for Twhere
T: Send,
Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.