mcp-protocol-client

Crates.iomcp-protocol-client
lib.rsmcp-protocol-client
version0.2.0
created_at2025-06-12 16:00:38.292149+00
updated_at2025-07-31 01:23:19.391748+00
descriptionโ›” DEPRECATED: Use mcp-protocol-sdk v0.4.0+ instead. This crate is consolidated into the main SDK.
homepagehttps://modelcontextprotocol.io
repositoryhttps://github.com/mcp-rust/mcp-protocol-client
max_upload_size
id1709952
size75,584
Rishi Randhawa (Rishirandhawa)

documentation

https://docs.rs/mcp-protocol-client

README

MCP Protocol Client

Crates.io Documentation License: MIT

Client library for the Model Context Protocol (MCP)

This crate provides a high-level, ergonomic API for building MCP clients in Rust. It handles connection management, capability negotiation, and transport abstraction, allowing you to focus on using MCP servers' capabilities.

โœจ Features

  • ๐Ÿฆ€ Pure Rust - Zero-cost abstractions with memory safety
  • ๐ŸŽฏ Type-Safe - Compile-time guarantees using mcp-protocol-types
  • ๐Ÿš€ Async/Await - Built on Tokio for high performance
  • ๐Ÿ”Œ Multiple Transports - STDIO, HTTP, WebSocket support
  • ๐Ÿ› ๏ธ Complete MCP Support - Tools, resources, prompts, logging
  • ๐Ÿ“ฆ Lightweight - Minimal dependencies for fast builds
  • ๐Ÿงช Well Tested - Comprehensive test suite
  • ๐Ÿ“– Great Documentation - Examples and guides

๐Ÿš€ Quick Start

Add to your Cargo.toml:

[dependencies]
mcp-protocol-client = "0.1.0"
mcp-protocol-types = "0.1.0"
tokio = { version = "1.0", features = ["full"] }
serde_json = "1.0"

Basic Client Example

use mcp_protocol_client::{Client, ClientBuilder};
use mcp_protocol_types::*;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create and connect client
    let mut client = ClientBuilder::new("my-client", "1.0.0")
        .build();

    // Connect via STDIO transport
    client.connect_stdio().await?;
    
    // Initialize connection
    let init_result = client.initialize().await?;
    println!("Connected to: {}", init_result.server_info.name);
    
    // List available tools
    let tools = client.list_tools().await?;
    for tool in tools {
        println!("Available tool: {} - {}", tool.name, 
                 tool.description.unwrap_or_default());
    }
    
    // Call a tool
    let result = client.call_tool("my-tool", json!({
        "param": "value"
    })).await?;
    
    println!("Tool result: {:?}", result);
    
    Ok(())
}

๐Ÿ—๏ธ Architecture

The client library provides a layered architecture:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚           Your Application                   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚         MCP Protocol Client                 โ”‚ โ† This crate
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚         MCP Protocol Types                  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚           Transport Layer                   โ”‚ (STDIO, HTTP, WebSocket)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ“‹ Core Concepts

Client Builder

The ClientBuilder provides a fluent API for configuring your client:

use mcp_protocol_client::ClientBuilder;

let client = ClientBuilder::new("my-client", "1.0.0")
    .with_description("An awesome MCP client")
    .with_timeout(Duration::from_secs(30))
    .with_retry_policy(RetryPolicy::exponential())
    .build();

Connection Management

Connect to servers using different transports:

// STDIO transport (for local servers)
client.connect_stdio().await?;

// HTTP transport (for remote servers)
client.connect_http("http://localhost:8080/mcp").await?;

// WebSocket transport (for real-time communication)
client.connect_websocket("ws://localhost:8080/mcp").await?;

Server Interaction

Use the client to interact with MCP servers:

// Initialize connection and exchange capabilities
let init_result = client.initialize().await?;

// List available tools
let tools = client.list_tools().await?;

// Call a tool
let result = client.call_tool("calculate", json!({
    "expression": "2 + 2"
})).await?;

// List resources
let resources = client.list_resources().await?;

// Read a resource
let content = client.read_resource("file://config.json").await?;

// Get prompt templates
let prompts = client.list_prompts().await?;

// Get a prompt with arguments
let prompt = client.get_prompt("generate-code", Some(json!({
    "language": "rust",
    "description": "HTTP client"
}))).await?;

๐Ÿ”ง Feature Flags

Feature Description Default
stdio STDIO transport support โœ…
http HTTP transport support โŒ
websocket WebSocket transport support โŒ

๐Ÿ“Š Usage Patterns

Tool Discovery and Execution

// Discover what tools are available
let tools = client.list_tools().await?;

// Find a specific tool
let calc_tool = tools.iter()
    .find(|t| t.name == "calculate")
    .ok_or("Calculator tool not found")?;

// Examine tool schema
println!("Tool input schema: {:#}", calc_tool.input_schema);

// Call the tool with proper parameters
let result = client.call_tool("calculate", json!({
    "expression": "sqrt(16) + 2 * 3"
})).await?;

Resource Access

// List available resources
let resources = client.list_resources().await?;

// Read configuration files
let config = client.read_resource("config://database").await?;

// Process resource content
match config.contents.first() {
    Some(content) => {
        if content.mime_type.as_deref() == Some("application/json") {
            let json: serde_json::Value = serde_json::from_str(&content.text)?;
            println!("Database config: {:#}", json);
        }
    }
    None => println!("No content found"),
}

Error Handling

use mcp_protocol_client::{ClientError, ClientResult};

async fn handle_tool_call() -> ClientResult<()> {
    match client.call_tool("risky-operation", json!({})).await {
        Ok(result) => {
            println!("Success: {:?}", result);
        }
        Err(ClientError::ToolNotFound(name)) => {
            eprintln!("Tool '{}' not available on server", name);
        }
        Err(ClientError::InvalidParams(msg)) => {
            eprintln!("Invalid parameters: {}", msg);
        }
        Err(ClientError::Transport(e)) => {
            eprintln!("Connection error: {}", e);
            // Attempt reconnection
            client.reconnect().await?;
        }
        Err(e) => {
            eprintln!("Unexpected error: {}", e);
        }
    }
    
    Ok(())
}

๐Ÿงช Testing

use mcp_protocol_client::testing::MockServer;

#[tokio::test]
async fn test_client_tool_call() {
    let mut mock_server = MockServer::new();
    
    // Configure mock responses
    mock_server.expect_tool_call("echo")
        .with_params(json!({"message": "hello"}))
        .returning(json!({"response": "hello"}));
    
    let mut client = ClientBuilder::new("test-client", "1.0.0")
        .build();
    
    client.connect_mock(mock_server).await?;
    client.initialize().await?;
    
    let result = client.call_tool("echo", json!({
        "message": "hello"
    })).await?;
    
    assert_eq!(result.content[0].text, "hello");
}

๐Ÿ› ๏ธ Development

# Build the crate
cargo build

# Run tests
cargo test

# Run with all features
cargo check --all-features

# Generate documentation
cargo doc --open

๐Ÿ”— Related Crates

๐Ÿค Contributing

This crate is part of the MCP Rust ecosystem. Contributions are welcome!

Guidelines

  • API Design - Keep the API simple and ergonomic
  • Performance - Optimize for low latency and memory usage
  • Documentation - All public APIs need examples
  • Testing - Comprehensive test coverage required

๐Ÿ“‹ Protocol Compliance

โœ… MCP 2024-11-05 Specification

This library implements the complete MCP client specification:

  • JSON-RPC 2.0 protocol handling
  • Capability negotiation and initialization
  • Tool discovery and execution
  • Resource access and content retrieval
  • Prompt template processing
  • Logging and debugging support
  • Error handling and recovery

๐Ÿ“„ License

Licensed under the MIT License.

๐Ÿ™ Acknowledgments

  • Anthropic - For creating the MCP specification
  • Tokio Team - For the excellent async runtime
  • Rust Community - For the amazing ecosystem

Lightweight MCP client library for Rust ๐Ÿฆ€

Commit count: 0

cargo fmt