Client

Struct Client 

Source
pub struct Client<T: Transport + 'static> { /* private fields */ }
Expand description

JSON-RPC protocol handler for MCP communication MCP client for communicating with servers

The Client struct provides an ergonomic interface for interacting with MCP servers. It handles protocol complexity internally, exposing clean, type-safe methods.

§Type Parameters

  • T - The transport implementation used for communication

§Examples

use turbomcp_client::Client;
use turbomcp_transport::stdio::StdioTransport;

let transport = StdioTransport::new();
let mut client = Client::new(transport);

// Initialize and start using the client
client.initialize().await?;

The core MCP client implementation

Client provides a comprehensive interface for communicating with MCP servers, supporting all protocol features including tools, prompts, resources, sampling, elicitation, and bidirectional communication patterns.

§Clone Pattern

Client<T> is cheaply cloneable via Arc (same pattern as reqwest and AWS SDK). All clones share the same underlying connection and state:

use turbomcp_client::Client;
use turbomcp_transport::stdio::StdioTransport;

let client = Client::new(StdioTransport::new());
client.initialize().await?;

// Cheap clone - shares same connection
let client2 = client.clone();
tokio::spawn(async move {
    client2.list_tools().await.ok();
});

The client must be initialized before use by calling initialize() to perform the MCP handshake and capability negotiation.

§Features

  • Protocol Compliance: Full MCP 2025-06-18 specification support
  • Bidirectional Communication: Server-initiated requests and client responses
  • Plugin Middleware: Extensible request/response processing
  • Handler Registry: Callbacks for server-initiated operations
  • Connection Management: Robust error handling and recovery
  • Type Safety: Compile-time guarantees for MCP message types
  • Cheap Cloning: Arc-based sharing like reqwest/AWS SDK

§Examples

use turbomcp_client::Client;
use turbomcp_transport::stdio::StdioTransport;
use std::collections::HashMap;

// Create and initialize client (no mut needed!)
let client = Client::new(StdioTransport::new());
let init_result = client.initialize().await?;
println!("Connected to: {}", init_result.server_info.name);

// Use MCP operations
let tools = client.list_tools().await?;
let mut args = HashMap::new();
args.insert("input".to_string(), serde_json::json!("test"));
let result = client.call_tool("my_tool", Some(args)).await?;

Implementations§

Source§

impl<T: Transport + 'static> Client<T>

Source

pub fn new(transport: T) -> Self

Create a new client with the specified transport

Creates a new MCP client instance with default capabilities. The client must be initialized before use by calling initialize().

§Arguments
  • transport - The transport implementation to use for communication
§Examples
use turbomcp_client::Client;
use turbomcp_transport::stdio::StdioTransport;

let transport = StdioTransport::new();
let client = Client::new(transport);
Source

pub fn with_capabilities(transport: T, capabilities: ClientCapabilities) -> Self

Create a new client with custom capabilities

§Arguments
  • transport - The transport implementation to use
  • capabilities - The client capabilities to negotiate
§Examples
use turbomcp_client::{Client, ClientCapabilities};
use turbomcp_transport::stdio::StdioTransport;

let capabilities = ClientCapabilities {
    tools: true,
    prompts: true,
    resources: false,
    sampling: false,
    max_concurrent_handlers: 100,
};

let transport = StdioTransport::new();
let client = Client::with_capabilities(transport, capabilities);
Source

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

Shutdown the client and clean up all resources

This method performs a graceful shutdown of the MCP client by:

  1. Stopping the message dispatcher background task
  2. Disconnecting the transport (closes connection, stops background tasks)

CRITICAL: After calling shutdown(), the client can no longer be used.

§Why This Method Exists

The Drop implementation cannot call async methods like transport.disconnect(), which is required for proper cleanup of WebSocket connections and background tasks. Without calling shutdown(), WebSocket reconnection tasks will continue running.

§Best Practices
  • Always call shutdown() before dropping for clean resource cleanup
  • For applications: call in signal handlers (SIGINT, SIGTERM)
  • For tests: call in cleanup/teardown
  • If forgotten, Drop will log warnings and do best-effort cleanup
§Examples
let client = Client::new(StdioTransport::new());
client.initialize().await?;

// Use client...
let _tools = client.list_tools().await?;

// ✅ Clean shutdown
client.shutdown().await?;
Source§

impl<T: Transport + 'static> Client<T>

Source

pub async fn initialize(&self) -> Result<InitializeResult>

Initialize the connection with the MCP server

Performs the initialization handshake with the server, negotiating capabilities and establishing the protocol version. This method must be called before any other operations can be performed.

§Returns

Returns an InitializeResult containing server information and negotiated capabilities.

§Errors

Returns an error if:

  • The transport connection fails
  • The server rejects the initialization request
  • Protocol negotiation fails
§Examples
let mut client = Client::new(StdioTransport::new());

let result = client.initialize().await?;
println!("Server: {} v{}", result.server_info.name, result.server_info.version);
Source

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

Subscribe to resource change notifications

Registers interest in receiving notifications when the specified resource changes. The server will send notifications when the resource is modified, created, or deleted.

§Arguments
  • uri - The URI of the resource to monitor
§Returns

Returns EmptyResult on successful subscription.

§Errors

Returns an error if:

  • The client is not initialized
  • The URI is invalid or empty
  • The server doesn’t support subscriptions
  • The request fails
§Examples
let mut client = Client::new(StdioTransport::new());
client.initialize().await?;

// Subscribe to file changes
client.subscribe("file:///watch/directory").await?;
println!("Subscribed to resource changes");
Source

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

Unsubscribe from resource change notifications

Cancels a previous subscription to resource changes. After unsubscribing, the client will no longer receive notifications for the specified resource.

§Arguments
  • uri - The URI of the resource to stop monitoring
§Returns

Returns EmptyResult on successful unsubscription.

§Errors

Returns an error if:

  • The client is not initialized
  • The URI is invalid or empty
  • No active subscription exists for the URI
  • The request fails
§Examples
let mut client = Client::new(StdioTransport::new());
client.initialize().await?;

// Unsubscribe from file changes
client.unsubscribe("file:///watch/directory").await?;
println!("Unsubscribed from resource changes");
Source

pub fn capabilities(&self) -> &ClientCapabilities

Get the client’s capabilities configuration

Source

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

Initialize all registered plugins

This should be called after registration but before using the client.

Source

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

Cleanup all registered plugins

This should be called when the client is being shut down.

Source§

impl<T: Transport + 'static> Client<T>

Source

pub async fn complete( &self, handler_name: &str, argument_value: &str, ) -> Result<CompletionResponse>

Request completion suggestions from the server

Simple completion interface for basic autocompletion needs. Uses a prompt-based reference with hardcoded “partial” argument name.

§Arguments
  • handler_name - The completion handler name
  • argument_value - The partial value to complete
§Examples
let mut client = Client::new(StdioTransport::new());
client.initialize().await?;

let result = client.complete("complete_path", "/usr/b").await?;
println!("Completions: {:?}", result.completion.values);
Source

pub async fn complete_prompt( &self, prompt_name: &str, argument_name: &str, argument_value: &str, context: Option<CompletionContext>, ) -> Result<CompletionResponse>

Complete a prompt argument with full MCP protocol support

This method provides access to the complete MCP completion protocol, allowing specification of argument names, prompt references, and context.

§Arguments
  • prompt_name - Name of the prompt to complete for
  • argument_name - Name of the argument being completed
  • argument_value - Current value for completion matching
  • context - Optional context with previously resolved arguments
§Examples
let mut client = Client::new(StdioTransport::new());
client.initialize().await?;

// Complete with context
let mut context_args = HashMap::new();
context_args.insert("language".to_string(), "rust".to_string());
let context = CompletionContext { arguments: Some(context_args) };

let completions = client.complete_prompt(
    "code_review",
    "framework",
    "tok",
    Some(context)
).await?;

for completion in completions.completion.values {
    println!("Suggestion: {}", completion);
}
Source

pub async fn complete_resource( &self, resource_uri: &str, argument_name: &str, argument_value: &str, context: Option<CompletionContext>, ) -> Result<CompletionResponse>

Complete a resource template URI with full MCP protocol support

This method provides completion for resource template URIs, allowing servers to suggest values for URI template variables.

§Arguments
  • resource_uri - Resource template URI (e.g., “/files/{path}”)
  • argument_name - Name of the argument being completed
  • argument_value - Current value for completion matching
  • context - Optional context with previously resolved arguments
§Examples
let mut client = Client::new(StdioTransport::new());
client.initialize().await?;

let completions = client.complete_resource(
    "/files/{path}",
    "path",
    "/home/user/doc",
    None
).await?;

for completion in completions.completion.values {
    println!("Path suggestion: {}", completion);
}
Source§

impl<T: Transport + 'static> Client<T>

Source

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

Send a ping request to check server health and connectivity

Sends a ping request to the server to verify the connection is active and the server is responding. This is useful for health checks and connection validation.

§Returns

Returns PingResult on successful ping.

§Errors

Returns an error if:

  • The client is not initialized
  • The server is not responding
  • The connection has failed
§Examples
let mut client = Client::new(StdioTransport::new());
client.initialize().await?;

let result = client.ping().await?;
println!("Server is responding");
Source

pub async fn set_log_level(&self, level: LogLevel) -> Result<SetLevelResult>

Set the logging level for the MCP server

Controls the verbosity of logs sent from the server to the client. Higher log levels provide more detailed information about server operations.

§Arguments
  • level - The logging level to set (Error, Warn, Info, Debug)
§Returns

Returns SetLevelResult confirming the logging level change.

§Errors

Returns an error if:

  • The client is not initialized
  • The server doesn’t support logging configuration
  • The request fails
§Examples
let mut client = Client::new(StdioTransport::new());
client.initialize().await?;

// Set server to debug logging
client.set_log_level(LogLevel::Debug).await?;
println!("Server logging level set to debug");
Source§

impl<T: Transport + 'static> Client<T>

Source

pub fn set_roots_handler(&self, handler: Arc<dyn RootsHandler>)

Register a roots handler for responding to server filesystem root requests

Roots handlers respond to roots/list requests from servers (SERVER->CLIENT). Per MCP 2025-06-18 specification, servers ask clients what filesystem roots they have access to. This is commonly used when servers need to understand their operating boundaries, such as which repositories or project directories they can access.

§Arguments
  • handler - The roots handler implementation
§Examples
use turbomcp_client::Client;
use turbomcp_client::handlers::{RootsHandler, HandlerResult};
use turbomcp_protocol::types::Root;
use turbomcp_transport::stdio::StdioTransport;
use async_trait::async_trait;
use std::sync::Arc;

#[derive(Debug)]
struct MyRootsHandler {
    project_dir: String,
}

#[async_trait]
impl RootsHandler for MyRootsHandler {
    async fn handle_roots_request(&self) -> HandlerResult<Vec<Root>> {
        Ok(vec![Root {
            uri: format!("file://{}", self.project_dir).into(),
            name: Some("My Project".to_string()),
        }])
    }
}

let mut client = Client::new(StdioTransport::new());
client.set_roots_handler(Arc::new(MyRootsHandler {
    project_dir: "/home/user/projects/myproject".to_string(),
}));
Source

pub fn set_elicitation_handler(&self, handler: Arc<dyn ElicitationHandler>)

Register an elicitation handler for processing user input requests

Elicitation handlers are called when the server needs user input during operations. The handler should present the request to the user and collect their response according to the provided schema.

§Arguments
  • handler - The elicitation handler implementation
§Examples
use turbomcp_client::Client;
use turbomcp_client::handlers::{ElicitationHandler, ElicitationRequest, ElicitationResponse, ElicitationAction, HandlerResult};
use turbomcp_transport::stdio::StdioTransport;
use async_trait::async_trait;
use std::sync::Arc;
use serde_json::json;

#[derive(Debug)]
struct MyElicitationHandler;

#[async_trait]
impl ElicitationHandler for MyElicitationHandler {
    async fn handle_elicitation(
        &self,
        request: ElicitationRequest,
    ) -> HandlerResult<ElicitationResponse> {
        let mut content = std::collections::HashMap::new();
        content.insert("user_input".to_string(), json!("example"));
        Ok(ElicitationResponse::accept(content))
    }
}

let mut client = Client::new(StdioTransport::new());
client.set_elicitation_handler(Arc::new(MyElicitationHandler));
Source

pub fn set_log_handler(&self, handler: Arc<dyn LogHandler>)

Register a log handler for processing server log messages

Log handlers receive log messages from the server and can route them to the client’s logging system. This is useful for debugging and maintaining a unified log across client and server.

§Arguments
  • handler - The log handler implementation
§Examples
use turbomcp_client::Client;
use turbomcp_client::handlers::{LogHandler, LoggingNotification, HandlerResult};
use turbomcp_transport::stdio::StdioTransport;
use async_trait::async_trait;
use std::sync::Arc;

#[derive(Debug)]
struct MyLogHandler;

#[async_trait]
impl LogHandler for MyLogHandler {
    async fn handle_log(&self, log: LoggingNotification) -> HandlerResult<()> {
        println!("Server log: {}", log.data);
        Ok(())
    }
}

let mut client = Client::new(StdioTransport::new());
client.set_log_handler(Arc::new(MyLogHandler));
Source

pub fn set_resource_update_handler( &self, handler: Arc<dyn ResourceUpdateHandler>, )

Register a resource update handler for processing resource change notifications

Resource update handlers receive notifications when subscribed resources change on the server. Supports reactive updates to cached data or UI refreshes when server-side resources change.

§Arguments
  • handler - The resource update handler implementation
§Examples
use turbomcp_client::Client;
use turbomcp_client::handlers::{ResourceUpdateHandler, ResourceUpdatedNotification, HandlerResult};
use turbomcp_transport::stdio::StdioTransport;
use async_trait::async_trait;
use std::sync::Arc;

#[derive(Debug)]
struct MyResourceUpdateHandler;

#[async_trait]
impl ResourceUpdateHandler for MyResourceUpdateHandler {
    async fn handle_resource_update(
        &self,
        notification: ResourceUpdatedNotification,
    ) -> HandlerResult<()> {
        println!("Resource updated: {}", notification.uri);
        Ok(())
    }
}

let mut client = Client::new(StdioTransport::new());
client.set_resource_update_handler(Arc::new(MyResourceUpdateHandler));
Source

pub fn set_cancellation_handler(&self, handler: Arc<dyn CancellationHandler>)

Register a cancellation handler for processing cancellation notifications

Per MCP 2025-06-18 specification, cancellation notifications can be sent by the server to indicate that a previously-issued request is being cancelled.

§Arguments
  • handler - The cancellation handler implementation
Source

pub fn set_resource_list_changed_handler( &self, handler: Arc<dyn ResourceListChangedHandler>, )

Register a resource list changed handler

This handler is called when the server’s available resource list changes.

§Arguments
  • handler - The resource list changed handler implementation
Source

pub fn set_prompt_list_changed_handler( &self, handler: Arc<dyn PromptListChangedHandler>, )

Register a prompt list changed handler

This handler is called when the server’s available prompt list changes.

§Arguments
  • handler - The prompt list changed handler implementation
Source

pub fn set_tool_list_changed_handler( &self, handler: Arc<dyn ToolListChangedHandler>, )

Register a tool list changed handler

This handler is called when the server’s available tool list changes.

§Arguments
  • handler - The tool list changed handler implementation
Source

pub fn has_roots_handler(&self) -> bool

Check if a roots handler is registered

Source

pub fn has_elicitation_handler(&self) -> bool

Check if an elicitation handler is registered

Source

pub fn has_log_handler(&self) -> bool

Check if a log handler is registered

Source

pub fn has_resource_update_handler(&self) -> bool

Check if a resource update handler is registered

Source§

impl<T: Transport + 'static> Client<T>

Source

pub async fn register_plugin(&self, plugin: Arc<dyn ClientPlugin>) -> Result<()>

Register a plugin with the client

§Arguments
  • plugin - The plugin to register
§Examples
use turbomcp_client::plugins::{MetricsPlugin, PluginConfig};
use std::sync::Arc;

let metrics_plugin = Arc::new(MetricsPlugin::new(PluginConfig::Metrics));
client.register_plugin(metrics_plugin).await?;
Source

pub async fn has_plugin(&self, name: &str) -> bool

Check if a plugin is registered

§Arguments
  • name - The name of the plugin to check
Source

pub async fn get_plugin(&self, name: &str) -> Option<Arc<dyn ClientPlugin>>

Get plugin data for a specific plugin type

§Arguments
  • name - The name of the plugin
§Examples
use turbomcp_client::plugins::MetricsPlugin;

if let Some(plugin) = client.get_plugin("metrics").await {
    // Use plugin data
}
Source§

impl<T: Transport + 'static> Client<T>

Source

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

List available prompt templates from the server

Retrieves the complete list of prompt templates that the server provides, including all metadata: title, description, and argument schemas. This is the MCP-compliant implementation that provides everything needed for UI generation and dynamic form creation.

§Returns

Returns a vector of Prompt objects containing:

  • name: Programmatic identifier
  • title: Human-readable display name (optional)
  • description: Description of what the prompt does (optional)
  • arguments: Array of argument schemas with validation info (optional)
§Errors

Returns an error if:

  • The client is not initialized
  • The server doesn’t support prompts
  • The request fails
§Examples
let mut client = Client::new(StdioTransport::new());
client.initialize().await?;

let prompts = client.list_prompts().await?;
for prompt in prompts {
    println!("Prompt: {} ({})", prompt.name, prompt.title.unwrap_or("No title".to_string()));
    if let Some(args) = prompt.arguments {
        println!("  Arguments: {:?}", args);
        for arg in args {
            let required = arg.required.unwrap_or(false);
            println!("    - {}: {} (required: {})", arg.name,
                    arg.description.unwrap_or("No description".to_string()), required);
        }
    }
}
Source

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

Get a specific prompt template with argument support

Retrieves a specific prompt template from the server with support for parameter substitution. When arguments are provided, the server will substitute them into the prompt template using {parameter} syntax.

This is the MCP-compliant implementation that supports the full protocol specification.

§Arguments
  • name - The name of the prompt to retrieve
  • arguments - Optional parameters for template substitution
§Returns

Returns GetPromptResult containing the prompt template with parameters substituted.

§Errors

Returns an error if:

  • The client is not initialized
  • The prompt name is empty
  • The prompt doesn’t exist
  • Required arguments are missing
  • Argument types don’t match schema
  • The request fails
§Examples
let mut client = Client::new(StdioTransport::new());
client.initialize().await?;

// Get prompt without arguments (template form)
let template = client.get_prompt("greeting", None).await?;
println!("Template has {} messages", template.messages.len());

// Get prompt with arguments (substituted form)
let mut args = HashMap::new();
args.insert("name".to_string(), serde_json::Value::String("Alice".to_string()));
args.insert("greeting".to_string(), serde_json::Value::String("Hello".to_string()));

let result = client.get_prompt("greeting", Some(args)).await?;
println!("Generated prompt with {} messages", result.messages.len());
Source§

impl<T: Transport + 'static> Client<T>

Source

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

List available resources from the MCP server

Returns a list of resources with their full metadata including URIs, names, descriptions, MIME types, and other attributes provided by the server. Resources represent data or content that can be accessed by the client.

§Returns

Returns a vector of Resource objects containing full metadata that can be read using read_resource().

§Errors

Returns an error if:

  • The client is not initialized
  • The server doesn’t support resources
  • The request fails
§Examples
let mut client = Client::new(StdioTransport::new());
client.initialize().await?;

let resources = client.list_resources().await?;
for resource in resources {
    println!("Resource: {} ({})", resource.name, resource.uri);
    if let Some(desc) = &resource.description {
        println!("  Description: {}", desc);
    }
}
Source

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

Read the content of a specific resource by URI

Retrieves the content of a resource identified by its URI. Resources can contain text, binary data, or structured content.

§Arguments
  • uri - The URI of the resource to read
§Returns

Returns ReadResourceResult containing the resource content and metadata.

§Errors

Returns an error if:

  • The client is not initialized
  • The URI is empty or invalid
  • The resource doesn’t exist
  • Access to the resource is denied
§Examples
let mut client = Client::new(StdioTransport::new());
client.initialize().await?;

let result = client.read_resource("file:///path/to/document.txt").await?;
for content in result.contents {
    println!("Resource content: {:?}", content);
}
Source

pub async fn list_resource_templates(&self) -> Result<Vec<String>>

List available resource templates from the MCP server

Returns a list of resource template URIs that define patterns for generating resource URIs. Templates allow servers to describe families of related resources without listing each individual resource.

§Returns

Returns a vector of resource template URI patterns.

§Errors

Returns an error if:

  • The client is not initialized
  • The server doesn’t support resource templates
  • The request fails
§Examples
let mut client = Client::new(StdioTransport::new());
client.initialize().await?;

let templates = client.list_resource_templates().await?;
for template in templates {
    println!("Resource template: {}", template);
}
Source§

impl<T: Transport + 'static> Client<T>

Source

pub fn set_sampling_handler(&self, handler: Arc<dyn SamplingHandler>)

Set the sampling handler for processing server-initiated sampling requests

Registers a handler that can process LLM sampling requests from the server. When a handler is set, the client will advertise sampling capabilities during initialization, allowing the server to request LLM operations.

§Arguments
  • handler - The handler implementation for sampling requests
§Examples
use turbomcp_client::{Client, sampling::SamplingHandler};
use turbomcp_transport::stdio::StdioTransport;
use turbomcp_protocol::types::{CreateMessageRequest, CreateMessageResult};
use async_trait::async_trait;
use std::sync::Arc;

#[derive(Debug)]
struct ExampleHandler;

#[async_trait]
impl SamplingHandler for ExampleHandler {
    async fn handle_create_message(
        &self,
        _request_id: String,
        _request: CreateMessageRequest,
    ) -> Result<CreateMessageResult, Box<dyn std::error::Error + Send + Sync>> {
        // Handle sampling request (use request_id for tracking/correlation)
        todo!("Implement sampling logic")
    }
}

let mut client = Client::new(StdioTransport::new());
client.set_sampling_handler(Arc::new(ExampleHandler));
Source

pub fn has_sampling_handler(&self) -> bool

Check if sampling is enabled

Returns true if a sampling handler has been configured and sampling capabilities are enabled.

Source

pub fn remove_sampling_handler(&self)

Remove the sampling handler

Disables sampling capabilities and removes the handler. The client will no longer advertise sampling support to servers.

Source§

impl<T: Transport + 'static> Client<T>

Source

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

List all available tools from the MCP server

Returns complete tool definitions with schemas that can be used for form generation, validation, and documentation. Tools represent executable functions provided by the server.

§Returns

Returns a vector of Tool objects with complete metadata including names, descriptions, and input schemas. These schemas can be used to generate user interfaces for tool invocation.

§Examples
let mut client = Client::new(StdioTransport::new());
client.initialize().await?;

let tools = client.list_tools().await?;
for tool in tools {
    println!("Tool: {} - {}", tool.name, tool.description.as_deref().unwrap_or("No description"));
}
Source

pub async fn list_tool_names(&self) -> Result<Vec<String>>

List available tool names from the MCP server

Returns only the tool names for cases where full schemas are not needed. For most use cases, prefer list_tools() which provides complete tool definitions.

§Returns

Returns a vector of tool names available on the server.

§Examples
let mut client = Client::new(StdioTransport::new());
client.initialize().await?;

let tool_names = client.list_tool_names().await?;
for name in tool_names {
    println!("Available tool: {}", name);
}
Source

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

Call a tool on the server

Executes a tool on the server with the provided arguments and returns the complete MCP CallToolResult.

§Arguments
  • name - The name of the tool to call
  • arguments - Optional arguments to pass to the tool
§Returns

Returns the complete CallToolResult with:

  • content: Vec<ContentBlock> - All content blocks (text, image, resource, audio, etc.)
  • is_error: Option<bool> - Whether the tool execution resulted in an error
  • structured_content: Option<serde_json::Value> - Schema-validated structured output
  • _meta: Option<serde_json::Value> - Metadata for client applications (not exposed to LLMs)
§Examples
§Basic Usage
let mut client = Client::new(StdioTransport::new());
client.initialize().await?;

let mut args = HashMap::new();
args.insert("input".to_string(), serde_json::json!("test"));

let result = client.call_tool("my_tool", Some(args)).await?;

// Access all content blocks
for content in &result.content {
    match content {
        Content::Text(text) => println!("Text: {}", text.text),
        Content::Image(image) => println!("Image: {}", image.mime_type),
        _ => {}
    }
}

// Check for errors
if result.is_error.unwrap_or(false) {
    eprintln!("Tool execution failed");
}
§Structured Output (Schema Validation)
let mut client = Client::new(StdioTransport::new());
client.initialize().await?;

let result = client.call_tool("get_weather", None).await?;

// Access schema-validated structured output
if let Some(structured) = result.structured_content {
    let weather: WeatherData = serde_json::from_value(structured)?;
    println!("Temperature: {}°C", weather.temperature);
}
§Metadata Access
let mut client = Client::new(StdioTransport::new());
client.initialize().await?;

let result = client.call_tool("query_database", None).await?;

// Access metadata (tracking IDs, performance metrics, etc.)
if let Some(meta) = result._meta {
    if let Some(query_id) = meta.get("query_id") {
        println!("Query ID: {}", query_id);
    }
}

Trait Implementations§

Source§

impl<T: Transport + 'static> Clone for Client<T>

Clone implementation via Arc (same pattern as reqwest/AWS SDK)

Cloning a Client is cheap (just an Arc clone) and all clones share the same underlying connection and state.

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0§

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

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl<T> Freeze for Client<T>

§

impl<T> !RefUnwindSafe for Client<T>

§

impl<T> Send for Client<T>

§

impl<T> Sync for Client<T>

§

impl<T> Unpin for Client<T>

§

impl<T> !UnwindSafe for Client<T>

Blanket Implementations§

§

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

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

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

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

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

§

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

Mutably borrows from an owned value. Read more
§

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

§

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
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

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
§

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

§

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

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

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

§

type Owned = T

The resulting type after obtaining ownership.
§

fn to_owned(&self) -> T

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

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

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

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

§

type Error = Infallible

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

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

Performs the conversion.
§

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

§

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

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

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