Skip to content

sudhirkumar-in/mcp-client-rust

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

MCP Client Rust - Model Context Protocol Client

Rust License Status

A comprehensive Rust implementation of the Model Context Protocol (MCP) client. This project provides a robust, type-safe foundation for building AI applications that can interact with MCP-compatible servers.

πŸ“‹ Table of Contents

✨ Features

Core Features

  • βœ… Full MCP Protocol Support - Complete implementation of JSON-RPC 2.0 based MCP
  • βœ… Type-Safe Client - Leverages Rust's type system for compile-time safety
  • βœ… Async/Await - Fully asynchronous using Tokio runtime
  • βœ… Multi-Server Support - Manage multiple MCP server connections simultaneously
  • βœ… Tool Management - Discover, validate, and execute server-exposed tools
  • βœ… Resource Access - Read and manage resources from MCP servers
  • βœ… Prompt Support - Utilize pre-defined LLM prompts from servers

Security Features

  • πŸ”’ Input Validation - Comprehensive input validation and sanitization
  • πŸ”’ Error Isolation - Secure error handling preventing information leakage

Advanced Features

  • πŸ“Š Logging & Debugging - Comprehensive structured logging system
  • πŸ”„ Reconnection Logic - Automatic reconnection with exponential backoff
  • πŸ› οΈ Tool Execution - Execute MCP tools with validation and error handling
  • πŸ“± Streaming Support - Handle streaming responses for long-running operations

πŸ“¦ Prerequisites

System Requirements

  • Rust: 1.70 or later (Install Rust)
  • Operating System: macOS, Linux, or Windows

Verify Installation

# Check Rust installation
rustc --version
cargo --version

πŸš€ Installation

Step 1: Clone the Repository

git clone https://github.com/yourusername/mcp-client-rust.git
cd mcp-client-rust

Step 2: Install Dependencies

# Update Rust toolchain
rustup update

# Build the project
cargo build --release

Step 3: Configure Environment

Create a .env file in the project root:

# Logging
LOG_LEVEL=info
LOG_FILE=./mcp-client.log

# MCP Configuration
MCP_TIMEOUT_SECONDS=30

πŸ’‘ Quick Start

Basic Usage

use mcp_client_rust::client::MCPClient;
use mcp_client_rust::transport::StdioTransport;
use mcp_client_rust::types::ClientInfo;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize MCP client
    let transport = Box::new(StdioTransport::new("./mcp-server", &[])?);
    let client_info = ClientInfo {
        name: "MyClient".to_string(),
        version: "1.0.0".to_string(),
    };

    let mut client = MCPClient::new(transport, client_info);
    client.initialize().await?;

    // List tools
    let tools = client.list_tools().await?;
    for tool in tools {
        println!("Tool: {} - {}", tool.name, tool.description.unwrap_or_default());
    }

    // Call a tool
    let result = client.call_tool(
        "greet",
        serde_json::json!({
            "name": "Alice"
        })
    ).await?;
    
    println!("Result: {:?}", result);

    client.close().await?;
    Ok(())
}

πŸ—οΈ Architecture

Project Structure

mcp-client-rust/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ lib.rs                 # Library entry point
β”‚   β”œβ”€β”€ types.rs               # MCP type definitions
β”‚   β”œβ”€β”€ transport.rs           # Transport layer (Stdio, HTTP/SSE)
β”‚   β”œβ”€β”€ client.rs              # Core MCP client
β”‚   β”œβ”€β”€ tool_manager.rs        # Tool management and validation
β”‚   β”œβ”€β”€ multi_server.rs        # Multi-server connection manager
β”‚   β”œβ”€β”€ security.rs            # Security policies and validation
β”‚   β”œβ”€β”€ logging.rs             # Logging utilities
β”‚   β”œβ”€β”€ validation.rs          # Input validation
β”‚   └── errors.rs              # Error types
β”œβ”€β”€ examples/
β”‚   β”œβ”€β”€ basic_example.rs
β”‚   └── multi_server_example.rs
β”œβ”€β”€ tests/
β”‚   └── integration_tests.rs
β”œβ”€β”€ Cargo.toml
β”œβ”€β”€ README.md
└── .env.example

πŸ“– Usage Examples

Example 1: Connect to Server and List Tools

use mcp_client_rust::client::MCPClient;
use mcp_client_rust::transport::StdioTransport;
use mcp_client_rust::types::ClientInfo;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create transport to connect to the server
    let transport = Box::new(StdioTransport::new(
        "/Users/sudhirkumar/Desktop/sudhir/gitsudhir/mcp-server-rust/target/release/mcp-server-rust",
        &[]
    )?);
    
    let client_info = ClientInfo {
        name: "TestClient".to_string(),
        version: "1.0.0".to_string(),
    };

    let mut client = MCPClient::new(transport, client_info);
    client.initialize().await?;

    // List available tools
    let tools = client.list_tools().await?;
    println!("Available tools:");
    for tool in tools {
        println!("- {} ({})", tool.name, tool.description.unwrap_or_default());
    }

    client.close().await?;
    Ok(())
}

Example 2: Execute a Tool

use mcp_client_rust::client::MCPClient;
use serde_json::json;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = create_client().await?;

    // Execute a greeting tool
    let result = client.call_tool(
        "greet",
        json!({
            "name": "Alice"
        })
    ).await?;

    match &result.content[0] {
        mcp_client_rust::types::ToolResultContent::Text { text } => {
            println!("Greeting result: {}", text);
        }
        _ => println!("Received non-text result"),
    }
    
    client.close().await?;
    Ok(())
}

async fn create_client() -> Result<MCPClient, Box<dyn std::error::Error>> {
    let transport = Box::new(StdioTransport::new(
        "/Users/sudhirkumar/Desktop/sudhir/gitsudhir/mcp-server-rust/target/release/mcp-server-rust",
        &[]
    )?);
    
    let client_info = mcp_client_rust::types::ClientInfo {
        name: "TestClient".to_string(),
        version: "1.0.0".to_string(),
    };

    let mut client = MCPClient::new(transport, client_info);
    client.initialize().await?;
    Ok(client)
}

Example 3: Read a Resource

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = create_client().await?;

    // Read a resource
    let content = client.read_resource("config://app").await?;
    
    for item in content.contents {
        match item {
            mcp_client_rust::types::ContentItem::Text { text } => {
                println!("Content: {}", text);
            }
            mcp_client_rust::types::ContentItem::Blob { blob } => {
                println!("Binary data: {} bytes", blob.len());
            }
        }
    }

    client.close().await?;
    Ok(())
}

πŸ”Œ API Documentation

MCPClient

The main client for interacting with MCP servers.

Methods

impl MCPClient {
    // Initialize connection with server
    pub async fn initialize(&mut self) -> ClientResult<()>

    // List available tools
    pub async fn list_tools(&mut self) -> ClientResult<Vec<Tool>>

    // List available resources
    pub async fn list_resources(&mut self) 
        -> ClientResult<(Vec<Resource>, Vec<ResourceTemplate>)>

    // List available prompts
    pub async fn list_prompts(&mut self) -> ClientResult<Vec<Prompt>>

    // Execute a tool
    pub async fn call_tool(
        &mut self,
        tool_name: &str,
        arguments: Value
    ) -> ClientResult<ToolResult>

    // Read a resource
    pub async fn read_resource(&mut self, uri: &str) 
        -> ClientResult<ResourceContent>

    // Get a prompt with arguments
    pub async fn get_prompt(
        &mut self,
        name: &str,
        arguments: Option<HashMap<String, String>>
    ) -> ClientResult<PromptsResult>

    // Close connection
    pub async fn close(&mut self) -> ClientResult<()>
}

βš™οΈ Configuration

Environment Variables

Create a .env file in the project root:

# Logging Configuration
LOG_LEVEL=info
LOG_FILE=./mcp-client.log

# MCP Configuration
MCP_TIMEOUT_SECONDS=30
MCP_MAX_RETRIES=3

πŸ”’ Security

Best Practices

  1. Validate All Inputs

    use mcp_client_rust::validation::InputValidator;
    
    if !InputValidator::validate_file_path(user_path) {
        return Err("Invalid file path".into());
    }
  2. Comprehensive Logging

    let logger = mcp_client_rust::logging::McpLogger::new(mcp_client_rust::logging::LogLevel::Info)
        .with_file("./mcp-client.log".to_string());
    
    logger.info("Tool execution attempt");
    logger.error("Unauthorized access");

πŸ› Troubleshooting

Server Connection Issues

Problem: Cannot connect to MCP server

Solutions:

// Verify server path exists
let path = "/Users/sudhirkumar/Desktop/sudhir/gitsudhir/mcp-server-rust/target/release/mcp-server-rust";
if !std::path::Path::new(path).exists() {
    eprintln!("Server executable not found at: {}", path);
}

// Check server permissions
#[cfg(unix)]
std::fs::set_permissions(path, std::fs::Permissions::from_mode(0o755))?;

Timeout Issues

Problem: "Request timeout" errors

Solutions:

# Increase timeout
MCP_TIMEOUT_SECONDS=60

πŸ“‹ Building from Source

# Clone repository
git clone https://github.com/yourusername/mcp-client-rust.git
cd mcp-client-rust

# Build debug version
cargo build

# Build release version (optimized)
cargo build --release

# Run tests
cargo test

# Run with logging
RUST_LOG=debug cargo run --example basic_example

πŸ§ͺ Testing

# Run all tests
cargo test

# Run specific test
cargo test test_name

# Run with output
cargo test -- --nocapture

πŸ“š Examples

All examples are located in the examples/ directory:

  1. basic_example - Simple tool execution
  2. multi_server_example - Managing multiple MCP servers

Run any example:

cargo run --example <example_name>

🀝 Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Coding Standards

  • Follow Rust naming conventions
  • Use cargo fmt for formatting
  • Run cargo clippy for linting
  • Add tests for new features
  • Update documentation

πŸ“ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ”— Resources

Official Documentation

Related Projects

πŸ“ž Support

For help and questions:

  1. Check Troubleshooting section
  2. Search existing GitHub Issues
  3. Create a new issue with detailed information

πŸ™ Acknowledgments


Last Updated: 2026-02-13
Version: 0.1.0

Made with ❀️ in Rust

About

A Rust implementation of the Model Context Protocol (MCP) client with built-in Ollama LLM integration, multi-server support, and security features.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages