pub struct Client<T: Transport> { /* private fields */ }
Expand description
MCP client for connecting to servers.
Implementations§
Source§impl<T: Transport> Client<T>
impl<T: Transport> Client<T>
Sourcepub fn new(transport: T) -> Self
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);
Sourcepub fn with_info(transport: T, client_info: Implementation) -> Self
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);
Sourcepub fn with_options(
transport: T,
client_info: Implementation,
options: ProtocolOptions,
) -> Self
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);
Sourcepub async fn initialize(
&mut self,
capabilities: ClientCapabilities,
) -> Result<InitializeResult>
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
Sourcepub fn get_server_capabilities(&self) -> Option<&ServerCapabilities>
pub fn get_server_capabilities(&self) -> Option<&ServerCapabilities>
Get server capabilities after initialization.
Sourcepub fn get_server_version(&self) -> Option<&Implementation>
pub fn get_server_version(&self) -> Option<&Implementation>
Get server version information after initialization.
Sourcepub fn get_instructions(&self) -> Option<&str>
pub fn get_instructions(&self) -> Option<&str>
Get server instructions after initialization.
Sourcepub async fn set_logging_level(&self, level: LoggingLevel) -> Result<()>
pub async fn set_logging_level(&self, level: LoggingLevel) -> Result<()>
Set the logging level on the server.
Sourcepub async fn list_tools(
&self,
cursor: Option<String>,
) -> Result<ListToolsResult>
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
Sourcepub async fn call_tool(
&self,
name: String,
arguments: Value,
) -> Result<CallToolResult>
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 callarguments
- 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
Sourcepub async fn list_prompts(
&self,
cursor: Option<String>,
) -> Result<ListPromptsResult>
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
Sourcepub async fn get_prompt(
&self,
name: String,
arguments: HashMap<String, String>,
) -> Result<GetPromptResult>
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 retrievearguments
- 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
Sourcepub async fn list_resources(
&self,
cursor: Option<String>,
) -> Result<ListResourcesResult>
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
Sourcepub async fn list_resource_templates(
&self,
cursor: Option<String>,
) -> Result<ListResourceTemplatesResult>
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
Sourcepub async fn read_resource(&self, uri: String) -> Result<ReadResourceResult>
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
Sourcepub async fn subscribe_resource(&self, uri: String) -> Result<()>
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
Sourcepub async fn unsubscribe_resource(&self, uri: String) -> Result<()>
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
Sourcepub async fn complete(&self, params: CompleteRequest) -> Result<CompleteResult>
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
Sourcepub async fn create_message(
&self,
params: CreateMessageRequest,
) -> Result<CreateMessageResult>
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
Sourcepub async fn send_roots_list_changed(&self) -> Result<()>
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
Sourcepub fn authenticate(&self, auth_info: &AuthInfo) -> Result<()>
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
Sourcepub async fn cancel_request(&self, request_id: &RequestId) -> Result<()>
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
Sourcepub async fn send_progress(&self, progress: ProgressNotification) -> Result<()>
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