Skip to main content

McpToolset

Struct McpToolset 

Source
pub struct McpToolset<S = ()>
where S: Service<RoleClient> + Send + Sync + 'static,
{ /* private fields */ }
Available on crate features mcp and 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:

  1. Connects to an MCP server via the provided transport
  2. Discovers available tools from the server
  3. Converts MCP tools to ADK-compatible Tool implementations
  4. 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>
where S: Service<RoleClient> + Send + Sync + 'static,

Source

pub fn new(client: RunningService<RoleClient, S>) -> McpToolset<S>

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);
Source

pub fn with_client_handler( client: RunningService<RoleClient, S>, ) -> McpToolset<S>

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);
Source

pub fn with_name(self, name: impl Into<String>) -> McpToolset<S>

Set a custom name for this toolset.

Source

pub fn with_task_support(self, config: McpTaskConfig) -> McpToolset<S>

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)));
Source

pub fn with_connection_factory<F>(self, factory: Arc<F>) -> McpToolset<S>
where F: ConnectionFactory<S> + 'static,

Provide a connection factory to enable automatic MCP reconnection.

Source

pub fn with_refresh_config(self, config: RefreshConfig) -> McpToolset<S>

Configure MCP reconnect/retry behavior.

Source

pub fn with_tool_call_retries(self) -> McpToolset<S>

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();
Source

pub fn with_filter<F>(self, filter: F) -> McpToolset<S>
where F: Fn(&str) -> bool + Send + Sync + 'static,

Add a filter to select which tools to expose.

The filter function receives a tool name and returns true if the tool should be included.

§Example
let toolset = McpToolset::new(client)
    .with_filter(|name| {
        matches!(name, "read_file" | "list_directory" | "search_files")
    });
Source

pub fn with_tools(self, tool_names: &[&str]) -> McpToolset<S>

Add a filter that only includes tools with the specified names.

§Example
let toolset = McpToolset::new(client)
    .with_tools(&["read_file", "write_file"]);
Source

pub async fn cancellation_token(&self) -> RunningServiceCancellationToken

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();
Source

pub async fn is_closed(&self) -> bool

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");
}
Source

pub async fn call_tool_value( &self, name: &str, arguments: Map<String, Value>, ) -> Result<Value, AdkError>

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.

Source

pub async fn list_resources(&self) -> Result<Vec<Resource>, AdkError>

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.

Source

pub async fn list_resource_templates( &self, ) -> Result<Vec<ResourceTemplate>, AdkError>

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.

Source

pub async fn read_resource( &self, uri: &str, ) -> Result<Vec<ResourceContents>, AdkError>

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.

Source

pub async fn list_prompts(&self) -> Result<Vec<Prompt>, AdkError>

Return the prompt templates published by the connected MCP server.

Source

pub async fn get_prompt( &self, name: &str, arguments: Option<Map<String, Value>>, ) -> Result<GetPromptResult, AdkError>

Resolve one published MCP prompt with optional typed arguments.

Source

pub async fn complete_prompt_argument( &self, prompt_name: &str, argument_name: &str, current_value: &str, context: Option<CompletionContext>, ) -> Result<CompletionInfo, AdkError>

Request completion suggestions for one prompt argument.

Source

pub async fn complete_resource_argument( &self, uri_template: &str, argument_name: &str, current_value: &str, context: Option<CompletionContext>, ) -> Result<CompletionInfo, AdkError>

Request completion suggestions for one resource-template argument.

Source

pub async fn subscribe_resource(&self, uri: &str) -> Result<(), AdkError>

Subscribe to change notifications for a resource URI.

Source

pub async fn unsubscribe_resource(&self, uri: &str) -> Result<(), AdkError>

Remove a resource subscription created by subscribe_resource.

Source§

impl McpToolset<AdkClientHandler>

Source

pub async fn with_elicitation_handler<T, E, A>( transport: T, handler: Arc<dyn ElicitationHandler>, ) -> Result<McpToolset<AdkClientHandler>, AdkError>
where T: IntoTransport<RoleClient, E, A> + Send + 'static, E: Error + Send + Sync + 'static,

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.
Source

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>
where T: IntoTransport<RoleClient, E, A> + Send + 'static, E: Error + Send + Sync + 'static,

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>
where S: Service<RoleClient> + Send + Sync + 'static,

Source§

fn clone(&self) -> McpToolset<S>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<S> Toolset for McpToolset<S>
where S: Service<RoleClient> + Send + Sync + 'static,

Source§

fn name(&self) -> &str

Returns the name of this toolset.
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,

Returns the tools available in this toolset for the given context.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> FmtForward for T

Source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
Source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
Source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
Source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
Source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
Source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
Source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
Source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
Source§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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 more
Source§

impl<T> MaybeSend for T
where T: Send,

Source§

impl<T> Pipe for T
where T: ?Sized,

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows 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
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows 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
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .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
where Self: BorrowMut<B>, B: ?Sized,

Calls .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
where Self: AsRef<R>, R: ?Sized,

Calls .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
where Self: AsMut<R>, R: ?Sized,

Calls .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
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more