Skip to main content

McpClient

Struct McpClient 

Source
pub struct McpClient { /* private fields */ }
Expand description

MCP client with a background message loop.

Unlike previous versions, this type is not generic over the transport. The transport is consumed during connect() and moved into a background Tokio task that handles message multiplexing.

All public methods take &self, enabling concurrent use from multiple tasks.

§Construction

use tower_mcp::client::{McpClient, StdioClientTransport};

// Simple: no handler for server-initiated requests
let transport = StdioClientTransport::spawn("server", &[]).await?;
let client = McpClient::connect(transport).await?;

// With configuration
use tower_mcp::protocol::Root;
let transport = StdioClientTransport::spawn("server", &[]).await?;
let client = McpClient::builder()
    .with_roots(vec![Root::new("file:///project")])
    .connect_simple(transport)
    .await?;

Implementations§

Source§

impl McpClient

Source

pub async fn connect<T: ClientTransport>(transport: T) -> Result<Self>

Connect with default settings and no handler.

Shorthand for McpClient::builder().connect_simple(transport).

Source

pub async fn connect_with_handler<T, H>( transport: T, handler: H, ) -> Result<Self>

Connect with a handler for server-initiated requests.

Source

pub fn builder() -> McpClientBuilder

Create a builder for advanced configuration.

Source

pub fn is_initialized(&self) -> bool

Check if the client has been initialized.

Source

pub fn is_connected(&self) -> bool

Check if the transport is still connected.

Source

pub async fn server_info(&self) -> Option<InitializeResult>

Get the server info (available after initialization).

Source

pub fn protocol_support(&self) -> &ProtocolSupport

Return the exact ordered protocol implementations enabled for this client.

Source

pub async fn clear_response_cache(&self)

Clear every cached final-protocol response held by this client.

Source

pub async fn set_cache_partition(&self, partition: impl Into<String>)

Change the authorization-context partition used for private responses.

Previously cached private entries become inaccessible, while public entries remain reusable. Call this before issuing requests after the authenticated principal changes.

Source

pub async fn response_cache_len(&self) -> usize

Return the number of response-cache entries held by this client.

Source

pub async fn discovery(&self) -> Option<DiscoverResult>

Get the server discovery result after the final lifecycle is active.

Source

pub async fn selected_protocol_version(&self) -> Option<String>

Get the protocol version selected for the discover-based lifecycle.

Source

pub fn server_info_blocking(&self) -> Option<InitializeResult>

Get the server info synchronously (best-effort, non-blocking).

Returns None if the lock is currently held by a writer or if initialization hasn’t completed. Prefer server_info() in async contexts.

Source

pub async fn initialize( &self, client_name: &str, client_version: &str, ) -> Result<InitializeResult>

Initialize the MCP connection.

Sends the initialize request and notifications/initialized notification. Must be called before any other operations.

Source

pub async fn discover( &self, client_name: &str, client_version: &str, ) -> Result<DiscoverResult>

Start the sessionless 2026-07-28 lifecycle with server/discover.

This path is available only when the final implementation was compiled. The client sends required per-request metadata from the first request, retries one Unsupported protocol version response using the server’s advertised intersection, and then repeats the selected version, capabilities, and client identity on every subsequent request.

Source

pub async fn list_tools(&self) -> Result<ListToolsResult>

List available tools.

Source

pub async fn call_tool( &self, name: &str, arguments: Value, ) -> Result<CallToolResult>

Call a tool.

On the final lifecycle, a header mismatch, method-not-found, or invalid-params response can indicate that the cached tool schema is stale. The client invalidates tools/list, refreshes it, and retries the rejected round once. These errors are raised before tool execution, so the bounded retry does not replay a completed side effect.

Source

pub async fn call_tool_once( &self, name: &str, arguments: Value, input_responses: Option<InputResponses>, request_state: Option<String>, ) -> Result<RequestOutcome<CallToolResult>>

Send one tools/call attempt without automatically following MRTR input.

Source

pub async fn call_tool_once_task_aware( &self, name: &str, arguments: Value, input_responses: Option<InputResponses>, request_state: Option<String>, ) -> Result<TaskAwareCallToolOutcome>

Send one tools/call attempt and preserve a server-created task.

Unlike call_tool, this does not poll a task or automatically fulfil input requests. Final-protocol callers can use it to retain the exact task handle returned from the ordinary request.

Source

pub async fn call_tool_as_task( &self, name: &str, arguments: Value, ttl_ms: Option<u64>, ) -> Result<CreateTaskResult>

Request direct control of a tool task lifecycle.

Instead of blocking until the tool finishes, the server creates a task and immediately returns a CreateTaskResult carrying the task id. Poll with task_get or block with task_wait; a completed task’s result field carries the CallToolResult the synchronous call would have returned.

On 2025-11-25, ttl_ms is sent in the legacy task-augmentation field. On 2026-07-28, task creation is server-directed: this sends an ordinary request and requires the server to elect a task. A final client cannot request a TTL, so a non-None ttl_ms is rejected on that lifecycle.

Source

pub async fn task_get(&self, task_id: &str) -> Result<TaskObject>

Fetch a task’s current state via tasks/get (SEP-2663).

For completed tasks the returned object carries the terminal CallToolResult in its result field; for failed tasks the JSON-RPC error is in error. Unknown or expired task ids surface as an invalid-params error from the server.

Source

pub async fn task_get_detailed(&self, task_id: &str) -> Result<GetTaskResult>

Fetch the exact final-protocol tasks/get result.

This preserves status-specific payloads, including all outstanding inputRequests. It is available only after selecting the 2026-07-28 lifecycle; legacy callers should use task_get.

Source

pub async fn task_cancel( &self, task_id: &str, reason: Option<String>, ) -> Result<()>

Cancel a task via tasks/cancel (SEP-2663).

Cancellation is cooperative: the acknowledgment is an empty result and the observable status may remain non-terminal for a while after the ack; poll task_get to observe the terminal state. reason is a legacy-only field and is omitted on the final protocol. The ack body is discarded, so legacy peers that return the task object are also tolerated.

Source

pub async fn task_update( &self, task_id: &str, input_responses: InputResponses, ) -> Result<()>

Answer a task’s outstanding input requests via tasks/update (SEP-2663).

Responses are matched to outstanding requests by key. Final-protocol callers read the keys from the inputRequests of an input_required task returned by task_get_detailed.

A partial map is valid and expected: requests left unanswered stay outstanding and the task remains input_required until every one is answered. Keys the server does not currently have outstanding, whether unknown, already answered, or superseded by a later request, are ignored rather than rejected, so replaying a stale update is safe.

The acknowledgment carries no data and is discarded. Poll task_get to observe the resulting state.

Source

pub async fn task_wait(&self, task_id: &str) -> Result<TaskObject>

Poll tasks/get until the task reaches a terminal state.

Honors the server’s suggested polling interval (default 1000 ms, clamped to 50 ms..30 s). On the final protocol it also fulfils input_required requests through the registered client handlers. A task purged after its TTL surfaces as the server’s task-not-found error. Wrap in tokio::time::timeout to bound the overall wait.

Source

pub async fn list_resources(&self) -> Result<ListResourcesResult>

List available resources.

Source

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

Read a resource.

Source

pub async fn read_resource_once( &self, uri: &str, input_responses: Option<InputResponses>, request_state: Option<String>, ) -> Result<RequestOutcome<ReadResourceResult>>

Send one resources/read attempt without automatically following MRTR.

Source

pub async fn listen_subscriptions( &self, notifications: SubscriptionFilter, ) -> Result<SubscriptionHandle>

Open a final-protocol subscriptions/listen notification stream.

The returned handle owns the long-lived request. Use SubscriptionHandle::acknowledged to inspect the subset accepted by the server, SubscriptionHandle::wait to observe graceful server closure, or SubscriptionHandle::cancel to close the stream. Notifications continue to flow through the configured ClientHandler and carry their subscription ID in ServerNotification::Subscription.

Source

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

Subscribe to notifications/resources/updated for one resource (resources/subscribe).

The updates themselves arrive through the notification handler, so a client that subscribes without registering NotificationHandler::on_resource_updated will not see them. Servers that support this advertise resources.subscribe in their capabilities; one that does not will reject the request.

Source

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

Stop receiving updates for a resource (resources/unsubscribe).

Source

pub async fn list_prompts(&self) -> Result<ListPromptsResult>

List available prompts.

Source

pub async fn list_tools_with_cursor( &self, cursor: Option<String>, ) -> Result<ListToolsResult>

List tools with an optional pagination cursor.

Source

pub async fn list_resources_with_cursor( &self, cursor: Option<String>, ) -> Result<ListResourcesResult>

List resources with an optional pagination cursor.

Source

pub async fn list_resource_templates( &self, ) -> Result<ListResourceTemplatesResult>

List resource templates.

Source

pub async fn list_resource_templates_with_cursor( &self, cursor: Option<String>, ) -> Result<ListResourceTemplatesResult>

List resource templates with an optional pagination cursor.

Source

pub async fn list_prompts_with_cursor( &self, cursor: Option<String>, ) -> Result<ListPromptsResult>

List prompts with an optional pagination cursor.

Source

pub async fn list_all_tools(&self) -> Result<Vec<ToolDefinition>>

List all tools, following pagination cursors until exhausted.

Source

pub async fn list_all_resources(&self) -> Result<Vec<ResourceDefinition>>

List all resources, following pagination cursors until exhausted.

Source

pub async fn list_all_resource_templates( &self, ) -> Result<Vec<ResourceTemplateDefinition>>

List all resource templates, following pagination cursors until exhausted.

Source

pub async fn list_all_prompts(&self) -> Result<Vec<PromptDefinition>>

List all prompts, following pagination cursors until exhausted.

Source

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

Call a tool and return the concatenated text content.

Returns the text from all Text items joined together. If the tool result indicates an error (is_error is true), returns an error with the text content as the message.

For more control over the result, use call_tool().

Source

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

Get a prompt.

Source

pub async fn get_prompt_once( &self, name: &str, arguments: HashMap<String, String>, input_responses: Option<InputResponses>, request_state: Option<String>, ) -> Result<RequestOutcome<GetPromptResult>>

Send one prompts/get attempt without automatically following MRTR.

Source

pub async fn ping(&self) -> Result<()>

Ping the server.

Source

pub async fn complete( &self, reference: CompletionReference, argument_name: &str, argument_value: &str, ) -> Result<CompleteResult>

Request completion suggestions from the server.

Source

pub async fn complete_prompt_arg( &self, prompt_name: &str, argument_name: &str, argument_value: &str, ) -> Result<CompleteResult>

Request completion for a prompt argument.

Source

pub async fn complete_resource_uri( &self, resource_uri: &str, argument_name: &str, argument_value: &str, ) -> Result<CompleteResult>

Request completion for a resource URI.

Source

pub async fn request<P: Serialize, R: DeserializeOwned>( &self, method: &str, params: &P, ) -> Result<R>

Send a raw typed request to the server.

Source

pub async fn notify<P: Serialize>(&self, method: &str, params: &P) -> Result<()>

Send a raw typed notification to the server.

Source

pub async fn roots(&self) -> Vec<Root>

Get the current roots.

Source

pub async fn set_roots(&self, roots: Vec<Root>) -> Result<()>

Set roots and notify the server if initialized.

Source

pub async fn add_root(&self, root: Root) -> Result<()>

Add a root and notify the server if initialized.

Source

pub async fn remove_root(&self, uri: &str) -> Result<bool>

Remove a root by URI and notify the server if initialized.

Source

pub async fn list_roots(&self) -> ListRootsResult

Get the roots list result (for responding to server’s roots/list request).

Source

pub async fn shutdown(self) -> Result<()>

Gracefully shut down the client and close the transport.

Trait Implementations§

Source§

impl Drop for McpClient

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

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> 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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

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