Client

Struct Client 

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

MCP client for connecting to servers.

Implementations§

Source§

impl<T: Transport> Client<T>

Source

pub fn new(transport: T) -> Self

Create a new client with the given transport.

Uses default client information with the name “pmcp-client” and the current crate version.

§Examples
use pmcp::{Client, StdioTransport};

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

pub fn with_info(transport: T, client_info: Implementation) -> Self

Create a new client with custom info.

Allows specifying custom client name and version information that will be sent to the server during initialization.

§Examples
use pmcp::{Client, StdioTransport, Implementation};

let transport = StdioTransport::new();
let client_info = Implementation {
    name: "my-custom-client".to_string(),
    version: "2.1.0".to_string(),
};
let client = Client::with_info(transport, client_info);
Source

pub fn with_options( transport: T, client_info: Implementation, options: ProtocolOptions, ) -> Self

Create a new client with custom protocol options.

§Examples
use pmcp::{Client, StdioTransport, Implementation};
use pmcp::shared::ProtocolOptions;

// Custom options for high-throughput scenarios
let options = ProtocolOptions {
    enforce_strict_capabilities: false,
    debounced_notification_methods: vec![
        "notifications/progress".to_string(),
        "notifications/message".to_string(),
    ],
};

let transport = StdioTransport::new();
let client_info = Implementation {
    name: "high-throughput-client".to_string(),
    version: "1.0.0".to_string(),
};

let client = Client::with_options(transport, client_info, options);
Source

pub async fn initialize( &mut self, capabilities: ClientCapabilities, ) -> Result<InitializeResult>

Initialize the connection with the server.

Performs the MCP initialization handshake, negotiating capabilities and receiving server information. This must be called before using other client methods.

§Examples
use pmcp::{Client, StdioTransport, ClientCapabilities};

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

let capabilities = ClientCapabilities::default();
let server_info = client.initialize(capabilities).await?;

println!("Server: {} v{}",
         server_info.server_info.name,
         server_info.server_info.version);
§Errors

Returns an error if:

  • The client is already initialized
  • The server rejects the initialization
  • Communication with the server fails
Source

pub fn get_server_capabilities(&self) -> Option<&ServerCapabilities>

Get server capabilities after initialization.

Source

pub fn get_server_version(&self) -> Option<&Implementation>

Get server version information after initialization.

Source

pub fn get_instructions(&self) -> Option<&str>

Get server instructions after initialization.

Source

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

Send a ping to the server.

Source

pub async fn set_logging_level(&self, level: LoggingLevel) -> Result<()>

Set the logging level on the server.

Source

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

List available tools.

Retrieves information about all tools available on the server, including their names, descriptions, and input schemas.

§Examples
use pmcp::{Client, StdioTransport, ClientCapabilities};

let transport = StdioTransport::new();
let mut client = Client::new(transport);
client.initialize(ClientCapabilities::default()).await?;

// List all tools
let tools = client.list_tools(None).await?;
for tool in tools.tools {
    println!("Tool: {} - {}",
             tool.name,
             tool.description.unwrap_or_else(|| "No description".to_string()));
}
§Arguments
  • cursor - Optional pagination cursor for retrieving additional results
Source

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

Call a tool.

Invokes a server-provided tool with the specified name and arguments. The server must have declared the tool via the tools capability during initialization.

§Arguments
  • name - The name of the tool to call
  • arguments - JSON value containing the tool’s arguments
§Examples
use pmcp::{Client, StdioTransport, ClientCapabilities};
use serde_json::json;

let transport = StdioTransport::new();
let mut client = Client::new(transport);
client.initialize(ClientCapabilities::default()).await?;

// Call a simple tool with no arguments
let result = client.call_tool(
    "list_files".to_string(),
    json!({})
).await?;

// Call a tool with specific arguments
let search_result = client.call_tool(
    "search".to_string(),
    json!({
        "query": "rust programming",
        "limit": 10
    })
).await?;

// Tools can return structured data
if let Some(content) = result.content.first() {
    match content {
        pmcp::Content::Text { text } => {
            println!("Tool result: {}", text);
        }
        _ => println!("Non-text tool result"),
    }
}
§Errors

Returns an error if:

  • The client is not initialized
  • The server doesn’t support tools
  • The tool name doesn’t exist
  • The arguments are invalid for the tool
  • Network or protocol errors occur
Source

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

List available prompts.

Retrieves information about all prompts available on the server, including their names, descriptions, and required arguments.

§Arguments
  • cursor - Optional cursor for pagination of large prompt lists
§Examples
use pmcp::{Client, StdioTransport, ClientCapabilities};

let transport = StdioTransport::new();
let mut client = Client::new(transport);
client.initialize(ClientCapabilities::default()).await?;

// List all prompts
let prompts = client.list_prompts(None).await?;
for prompt in prompts.prompts {
    println!("Prompt: {} - {}",
             prompt.name,
             prompt.description.unwrap_or_else(|| "No description".to_string()));
     
    // Show required arguments
    if let Some(args) = prompt.arguments {
        for arg in args {
            println!("  - {}: {} (required: {})",
                     arg.name,
                     arg.description.unwrap_or_else(|| "No description".to_string()),
                     arg.required);
        }
    }
}
§Errors

Returns an error if:

  • The client is not initialized
  • The server doesn’t support prompts
  • Network or protocol errors occur
Source

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

Get a prompt.

Retrieves a specific prompt from the server with the provided arguments. The prompt is processed by the server and returned with filled-in content.

§Arguments
  • name - The name of the prompt to retrieve
  • arguments - Key-value pairs for prompt arguments
§Examples
use pmcp::{Client, StdioTransport, ClientCapabilities};
use std::collections::HashMap;

let transport = StdioTransport::new();
let mut client = Client::new(transport);
client.initialize(ClientCapabilities::default()).await?;

// Get a prompt with arguments
let mut args = HashMap::new();
args.insert("language".to_string(), "Rust".to_string());
args.insert("topic".to_string(), "async programming".to_string());

let prompt_result = client.get_prompt(
    "code_review".to_string(),
    args
).await?;

println!("Prompt description: {}",
         prompt_result.description.unwrap_or_else(|| "No description".to_string()));

// Process the prompt messages
for message in prompt_result.messages {
    println!("Role: {}", message.role);
    match &message.content {
        pmcp::Content::Text { text } => {
            println!("Content: {}", text);
        }
        _ => println!("Non-text content"),
    }
}
§Errors

Returns an error if:

  • The client is not initialized
  • The server doesn’t support prompts
  • The prompt name doesn’t exist
  • Required arguments are missing
  • Network or protocol errors occur
Source

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

List available resources.

Retrieves information about all resources available on the server, including their names, descriptions, URIs, and MIME types.

§Arguments
  • cursor - Optional cursor for pagination of large resource lists
§Examples
use pmcp::{Client, StdioTransport, ClientCapabilities};

let transport = StdioTransport::new();
let mut client = Client::new(transport);
client.initialize(ClientCapabilities::default()).await?;

// List all resources
let resources = client.list_resources(None).await?;
for resource in resources.resources {
    println!("Resource: {} ({})", resource.name, resource.uri);
    if let Some(description) = resource.description {
        println!("  Description: {}", description);
    }
    if let Some(mime_type) = resource.mime_type {
        println!("  MIME Type: {}", mime_type);
    }
}
§Errors

Returns an error if:

  • The client is not initialized
  • The server doesn’t support resources
  • Network or protocol errors occur
Source

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

List resource templates.

Retrieves information about all resource templates available on the server. Resource templates define patterns for dynamically generated resources.

§Arguments
  • cursor - Optional cursor for pagination of large template lists
§Examples
use pmcp::{Client, StdioTransport, ClientCapabilities};

let transport = StdioTransport::new();
let mut client = Client::new(transport);
client.initialize(ClientCapabilities::default()).await?;

// List all resource templates
let templates = client.list_resource_templates(None).await?;
for template in templates.resource_templates {
    println!("Template: {} ({})", template.name, template.uri_template);
    if let Some(description) = template.description {
        println!("  Description: {}", description);
    }
}
§Errors

Returns an error if:

  • The client is not initialized
  • The server doesn’t support resource templates
  • Network or protocol errors occur
Source

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

Read a resource.

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

§Arguments
  • uri - The URI of the resource to read
§Examples
use pmcp::{Client, StdioTransport, ClientCapabilities};

let transport = StdioTransport::new();
let mut client = Client::new(transport);
client.initialize(ClientCapabilities::default()).await?;

// Read a text resource
let resource = client.read_resource("file://readme.txt".to_string()).await?;
for content in resource.contents {
    match content {
        pmcp::Content::Text { text } => {
            println!("Text content: {}", text);
        }
        pmcp::Content::Resource { uri, .. } => {
            println!("Resource reference: {}", uri);
        }
        _ => println!("Other content type"),
    }
}
§Errors

Returns an error if:

  • The client is not initialized
  • The server doesn’t support resources
  • The resource URI doesn’t exist
  • Access to the resource is denied
  • Network or protocol errors occur
Source

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

Subscribe to resource updates.

Subscribes to receive notifications when a resource changes. The server will send notifications when the subscribed resource is modified.

§Arguments
  • uri - The URI of the resource to subscribe to
§Examples
use pmcp::{Client, StdioTransport, ClientCapabilities};

let transport = StdioTransport::new();
let mut client = Client::new(transport);
client.initialize(ClientCapabilities::default()).await?;

// Subscribe to a configuration file
client.subscribe_resource("file://config/settings.json".to_string()).await?;

// Now the client will receive notifications when settings.json changes
// Handle notifications in your event loop
§Errors

Returns an error if:

  • The client is not initialized
  • The server doesn’t support resource subscriptions
  • The resource URI doesn’t exist
  • Network or protocol errors occur
Source

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

Unsubscribe from resource updates.

Unsubscribes from notifications for a previously subscribed resource. After unsubscribing, the client will no longer receive change notifications.

§Arguments
  • uri - The URI of the resource to unsubscribe from
§Examples
use pmcp::{Client, StdioTransport, ClientCapabilities};

let transport = StdioTransport::new();
let mut client = Client::new(transport);
client.initialize(ClientCapabilities::default()).await?;

// Subscribe to a resource
client.subscribe_resource("file://config/settings.json".to_string()).await?;

// Later, unsubscribe when no longer needed
client.unsubscribe_resource("file://config/settings.json".to_string()).await?;
§Errors

Returns an error if:

  • The client is not initialized
  • The server doesn’t support resource subscriptions
  • The resource URI was not previously subscribed to
  • Network or protocol errors occur
Source

pub async fn complete(&self, params: CompleteRequest) -> Result<CompleteResult>

Request completion from the server.

Requests auto-completion suggestions from the server for a given context. This is useful for implementing IDE-like features with contextual suggestions.

§Arguments
  • params - The completion request parameters
§Examples
use pmcp::{Client, StdioTransport, ClientCapabilities, CompleteRequest};

let transport = StdioTransport::new();
let mut client = Client::new(transport);
client.initialize(ClientCapabilities::default()).await?;

// Request completion for partial text
let completion_request = CompleteRequest {
    r#ref: pmcp::CompletionReference::Resource {
        uri: "file://code.rs".to_string(),
    },
    argument: pmcp::CompletionArgument {
        name: "function_name".to_string(),
        value: "calc_".to_string(),
    },
};

let completions = client.complete(completion_request).await?;
for completion in completions.completion.values {
    println!("Suggestion: {}", completion);
}
§Errors

Returns an error if:

  • The client is not initialized
  • The server doesn’t support completions
  • The completion context is invalid
  • Network or protocol errors occur
Source

pub async fn create_message( &self, params: CreateMessageRequest, ) -> Result<CreateMessageResult>

Create a message using sampling (for LLM providers).

Requests the server to generate a message using its language model capabilities. This is typically used by servers that provide LLM functionality.

§Examples
use pmcp::{Client, StdioTransport, ClientCapabilities, CreateMessageRequest, SamplingMessage};

let mut capabilities = ClientCapabilities::default();
capabilities.sampling = Some(Default::default());

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

// Create a message with the LLM
let request = CreateMessageRequest {
    messages: vec![
        SamplingMessage {
            role: pmcp::types::Role::User,
            content: pmcp::types::Content::Text {
                text: "Explain how to implement a binary search tree".to_string(),
            },
        },
    ],
    model_preferences: Some(pmcp::types::ModelPreferences {
        hints: Some(vec![
            pmcp::types::ModelHint {
                name: Some("gpt-4".to_string()),
            },
        ]),
        cost_priority: Some(0.5),
        speed_priority: Some(0.3),
        intelligence_priority: Some(0.2),
    }),
    system_prompt: Some("You are a helpful programming assistant".to_string()),
    include_context: pmcp::types::IncludeContext::ThisServerOnly,
    temperature: Some(0.7),
    max_tokens: Some(1000),
    stop_sequences: None,
    metadata: Default::default(),
};

let result = client.create_message(request).await?;
println!("Model: {}", result.model);
println!("Response: {:?}", result.content);
§Errors

Returns an error if:

  • The client is not initialized
  • The server doesn’t support sampling
  • The request parameters are invalid
  • Network or protocol errors occur
Source

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

Send roots list changed notification.

Notifies the server that the client’s root list has changed. This is typically sent when the workspace or project roots are modified.

§Examples
use pmcp::{Client, StdioTransport, ClientCapabilities};

let mut capabilities = ClientCapabilities::default();
// Enable roots list changed capability
capabilities.roots = Some(pmcp::RootsCapabilities {
    list_changed: true,
});

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

// Notify server when project roots change
client.send_roots_list_changed().await?;
§Errors

Returns an error if:

  • The client is not initialized
  • The client doesn’t support roots list changed notifications
  • Network or protocol errors occur
Source

pub fn authenticate(&self, auth_info: &AuthInfo) -> Result<()>

Authenticate with the server.

Performs authentication using the provided authentication information. This should be called after initialization if the server requires authentication.

§Examples
use pmcp::{Client, StdioTransport, AuthInfo, AuthScheme};

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

// Initialize first
client.initialize(pmcp::ClientCapabilities::default()).await?;

// Authenticate with bearer token
let auth = AuthInfo {
    scheme: AuthScheme::Bearer,
    token: Some("your-api-token".to_string()),
    oauth: None,
    params: Default::default(),
};

client.authenticate(&auth)?;
§Errors

Returns an error if:

  • The client is not initialized
  • Authentication fails
  • The server doesn’t support authentication
Source

pub async fn cancel_request(&self, request_id: &RequestId) -> Result<()>

Cancel a request.

Sends a cancellation notification for an active request. This allows graceful termination of long-running operations.

§Arguments
  • request_id - The ID of the request to cancel
§Examples
use pmcp::{Client, StdioTransport, ClientCapabilities, RequestId};
use serde_json::json;

let transport = StdioTransport::new();
let mut client = Client::new(transport);
client.initialize(ClientCapabilities::default()).await?;

// Start a long-running operation
let request_id = RequestId::String("long-operation-123".to_string());

// Later, cancel the request if needed
client.cancel_request(&request_id).await?;
§Errors

Returns an error if:

  • Network or protocol errors occur while sending the cancellation
Source

pub async fn send_progress(&self, progress: ProgressNotification) -> Result<()>

Send a progress notification.

Sends a progress update for a long-running operation. This allows the server or client to track operation progress.

§Arguments
  • progress - The progress notification to send
§Examples
use pmcp::{Client, StdioTransport, ClientCapabilities, ProgressNotification, RequestId};

let transport = StdioTransport::new();
let mut client = Client::new(transport);
client.initialize(ClientCapabilities::default()).await?;

// Send progress update for a file processing operation
let progress = ProgressNotification {
    progress_token: pmcp::ProgressToken::String("file-processing".to_string()),
    progress: 75.0,
    message: Some("Processing files...".to_string()),
};

client.send_progress(progress).await?;
§Errors

Returns an error if:

  • Network or protocol errors occur while sending the notification

Trait Implementations§

Source§

impl<T: Transport> Clone for Client<T>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

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

Performs copy-assignment from source. Read more
Source§

impl<T: Transport> Debug for Client<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. 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§

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<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> 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> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: 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: 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> Same for T

Source§

type Output = T

Should always be Self
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, 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
Source§

impl<T> ErasedDestructor for T
where T: 'static,