mistralrs_mcp/lib.rs
1//! Model Context Protocol (MCP) Client Implementation
2//!
3//! This crate provides a comprehensive client implementation for the Model Context Protocol (MCP),
4//! enabling AI assistants to connect to and interact with external tools and resources through
5//! standardized server interfaces.
6//!
7//! # Overview
8//!
9//! The MCP client supports multiple transport protocols and provides automatic tool discovery,
10//! registration, and execution. It seamlessly integrates with tool calling systems,
11//! allowing MCP tools to be used alongside built-in tools.
12//!
13//! # Features
14//!
15//! - **Multiple Transport Protocols**: HTTP, WebSocket, and Process-based connections
16//! - **Automatic Tool Discovery**: Discovers and registers tools from connected MCP servers
17//! - **Bearer Token Authentication**: Supports authentication for secured MCP servers
18//! - **Concurrent Tool Execution**: Handles multiple tool calls efficiently
19//! - **Resource Access**: Access to MCP server resources like files and data
20//! - **Tool Naming Prefix**: Avoid conflicts with customizable tool name prefixes
21//!
22//! # Transport Protocols
23//!
24//! ## HTTP Transport
25//!
26//! For MCP servers accessible via HTTP endpoints with JSON-RPC over HTTP.
27//! Supports both regular JSON responses and Server-Sent Events (SSE).
28//!
29//! ## WebSocket Transport
30//!
31//! For real-time bidirectional communication with MCP servers over WebSocket.
32//! Ideal for interactive applications requiring low-latency tool calls.
33//!
34//! ## Process Transport
35//!
36//! For local MCP servers running as separate processes, communicating via stdin/stdout
37//! using JSON-RPC messages.
38//!
39//! # Example Usage
40//!
41//! ## Simple Configuration
42//!
43//! ```rust,no_run
44//! use mistralrs_mcp::{McpClientConfig, McpServerConfig, McpServerSource, McpClient};
45//!
46//! #[tokio::main]
47//! async fn main() -> anyhow::Result<()> {
48//! // Simple configuration with minimal settings
49//! // Most fields use sensible defaults (enabled=true, UUID for id/prefix, no timeouts)
50//! let config = McpClientConfig {
51//! servers: vec![
52//! McpServerConfig {
53//! name: "Hugging Face MCP Server".to_string(),
54//! source: McpServerSource::Http {
55//! url: "https://hf.co/mcp".to_string(),
56//! timeout_secs: None,
57//! headers: None,
58//! },
59//! bearer_token: Some("hf_xxx".to_string()),
60//! ..Default::default()
61//! },
62//! ],
63//! ..Default::default()
64//! };
65//!
66//! // Initialize MCP client
67//! let mut client = McpClient::new(config);
68//! client.initialize().await?;
69//!
70//! // Get tool callbacks for integration with model builder
71//! let tool_callbacks = client.get_tool_callbacks_with_tools();
72//! println!("Registered {} MCP tools", tool_callbacks.len());
73//!
74//! Ok(())
75//! }
76//! ```
77//!
78//! ## Advanced Configuration
79//!
80//! ```rust,no_run
81//! use mistralrs_mcp::{McpClientConfig, McpServerConfig, McpServerSource, McpClient};
82//! use std::collections::HashMap;
83//!
84//! #[tokio::main]
85//! async fn main() -> anyhow::Result<()> {
86//! // Configure MCP client with multiple servers and custom settings
87//! let config = McpClientConfig {
88//! servers: vec![
89//! // HTTP server with Bearer token
90//! McpServerConfig {
91//! id: "web_search".to_string(),
92//! name: "Web Search MCP".to_string(),
93//! source: McpServerSource::Http {
94//! url: "https://api.example.com/mcp".to_string(),
95//! timeout_secs: Some(30),
96//! headers: None,
97//! },
98//! enabled: true,
99//! tool_prefix: Some("web".to_string()),
100//! resources: None,
101//! bearer_token: Some("your-api-token".to_string()),
102//! },
103//! // WebSocket server
104//! McpServerConfig {
105//! id: "realtime_data".to_string(),
106//! name: "Real-time Data MCP".to_string(),
107//! source: McpServerSource::WebSocket {
108//! url: "wss://realtime.example.com/mcp".to_string(),
109//! timeout_secs: Some(60),
110//! headers: None,
111//! },
112//! enabled: true,
113//! tool_prefix: Some("rt".to_string()),
114//! resources: None,
115//! bearer_token: Some("ws-token".to_string()),
116//! },
117//! // Process-based server
118//! McpServerConfig {
119//! id: "filesystem".to_string(),
120//! name: "Filesystem MCP".to_string(),
121//! source: McpServerSource::Process {
122//! command: "mcp-server-filesystem".to_string(),
123//! args: vec!["--root".to_string(), "/tmp".to_string()],
124//! work_dir: None,
125//! env: None,
126//! },
127//! enabled: true,
128//! tool_prefix: Some("fs".to_string()),
129//! resources: Some(vec!["file://**".to_string()]),
130//! bearer_token: None,
131//! },
132//! ],
133//! auto_register_tools: true,
134//! tool_timeout_secs: Some(30),
135//! max_concurrent_calls: Some(5),
136//! };
137//!
138//! // Initialize MCP client
139//! let mut client = McpClient::new(config);
140//! client.initialize().await?;
141//!
142//! // Get tool callbacks for integration with model builder
143//! let tool_callbacks = client.get_tool_callbacks_with_tools();
144//! println!("Registered {} MCP tools", tool_callbacks.len());
145//!
146//! Ok(())
147//! }
148//! ```
149
150pub mod client;
151pub mod tools;
152pub mod transport;
153pub mod types;
154
155pub use client::{McpClient, McpServerConnection};
156pub use tools::{CalledFunction, Function, Tool, ToolCallback, ToolCallbackWithTool, ToolType};
157pub use types::McpToolResult;
158
159pub use rust_mcp_schema;
160
161use serde::{Deserialize, Serialize};
162use std::collections::HashMap;
163use uuid::Uuid;
164
165/// Supported MCP server transport sources
166///
167/// Defines the different ways to connect to MCP servers, each optimized for
168/// specific use cases and deployment scenarios.
169#[derive(Debug, Clone, Serialize, Deserialize)]
170#[serde(tag = "type")]
171pub enum McpServerSource {
172 /// HTTP-based MCP server using JSON-RPC over HTTP
173 ///
174 /// Best for: Public APIs, RESTful services, servers behind load balancers
175 /// Features: SSE support, standard HTTP semantics, easy debugging
176 Http {
177 /// Base URL of the MCP server (http:// or https://)
178 url: String,
179 /// Optional timeout in seconds for HTTP requests
180 /// Defaults to no timeout if not specified.
181 timeout_secs: Option<u64>,
182 /// Optional headers to include in requests (e.g., API keys, custom headers)
183 headers: Option<HashMap<String, String>>,
184 },
185 /// Local process-based MCP server using stdin/stdout communication
186 ///
187 /// Best for: Local tools, development servers, sandboxed environments
188 /// Features: Process isolation, no network overhead, easy deployment
189 Process {
190 /// Command to execute (e.g., "mcp-server-filesystem")
191 command: String,
192 /// Arguments to pass to the command
193 args: Vec<String>,
194 /// Optional working directory for the process
195 work_dir: Option<String>,
196 /// Optional environment variables for the process
197 env: Option<HashMap<String, String>>,
198 },
199 /// WebSocket-based MCP server for real-time bidirectional communication
200 ///
201 /// Best for: Interactive applications, real-time data, low-latency requirements
202 /// Features: Persistent connections, server-initiated notifications, minimal overhead
203 WebSocket {
204 /// WebSocket URL (ws:// or wss://)
205 url: String,
206 /// Optional timeout in seconds for connection establishment
207 /// Defaults to no timeout if not specified.
208 timeout_secs: Option<u64>,
209 /// Optional headers for the WebSocket handshake
210 headers: Option<HashMap<String, String>>,
211 },
212}
213
214/// Configuration for MCP client integration
215///
216/// This structure defines how the MCP client should connect to and manage
217/// multiple MCP servers, including authentication, tool registration, and
218/// execution policies.
219#[derive(Debug, Clone, Serialize, Deserialize)]
220pub struct McpClientConfig {
221 /// List of MCP servers to connect to
222 pub servers: Vec<McpServerConfig>,
223 /// Whether to automatically register discovered tools with the model
224 ///
225 /// When enabled, tools from MCP servers are automatically converted to
226 /// the internal Tool format and registered for automatic tool calling.
227 pub auto_register_tools: bool,
228 /// Timeout for individual tool execution in seconds
229 ///
230 /// Controls how long to wait for a tool call to complete before timing out.
231 /// Defaults to no timeout if not specified.
232 pub tool_timeout_secs: Option<u64>,
233 /// Maximum number of concurrent tool calls across all MCP servers
234 ///
235 /// Limits resource usage and prevents overwhelming servers with too many
236 /// simultaneous requests. Defaults to 10 if not specified.
237 pub max_concurrent_calls: Option<usize>,
238}
239
240/// Configuration for an individual MCP server
241///
242/// Defines connection parameters, authentication, and tool management
243/// settings for a single MCP server instance.
244#[derive(Debug, Clone, Serialize, Deserialize)]
245#[serde(default)]
246pub struct McpServerConfig {
247 /// Unique identifier for this server
248 ///
249 /// Used internally to track connections and route tool calls.
250 /// Must be unique across all servers in a single MCP client configuration.
251 /// Defaults to a UUID if not specified.
252 #[serde(default = "generate_uuid")]
253 pub id: String,
254 /// Human-readable name for this server
255 ///
256 /// Used for logging, debugging, and user-facing displays.
257 pub name: String,
258 /// Transport-specific connection configuration
259 pub source: McpServerSource,
260 /// Whether this server should be activated
261 ///
262 /// Disabled servers are ignored during client initialization.
263 /// Defaults to true if not specified.
264 #[serde(default = "default_true")]
265 pub enabled: bool,
266 /// Optional prefix to add to all tool names from this server
267 ///
268 /// Helps prevent naming conflicts when multiple servers provide
269 /// tools with similar names. For example, with prefix "web",
270 /// a tool named "search" becomes "web_search".
271 /// Defaults to a UUID-based prefix if not specified.
272 #[serde(default = "generate_uuid_prefix")]
273 pub tool_prefix: Option<String>,
274 /// Optional resource URI patterns this server provides
275 ///
276 /// Used for resource discovery and subscription.
277 /// Supports glob patterns like "file://**" for filesystem access.
278 pub resources: Option<Vec<String>>,
279 /// Optional Bearer token for authentication
280 ///
281 /// Automatically included as `Authorization: Bearer <token>` header
282 /// for HTTP and WebSocket connections. Process connections typically
283 /// don't require authentication tokens.
284 pub bearer_token: Option<String>,
285}
286
287/// Information about a tool discovered from an MCP server
288#[derive(Debug, Clone)]
289pub struct McpToolInfo {
290 /// Name of the tool as reported by the MCP server
291 pub name: String,
292 /// Optional human-readable description of what the tool does
293 pub description: Option<String>,
294 /// JSON schema describing the tool's input parameters
295 pub input_schema: serde_json::Value,
296 /// ID of the server this tool comes from
297 ///
298 /// Used to route tool calls to the correct MCP server connection.
299 pub server_id: String,
300 /// Display name of the server for logging and debugging
301 pub server_name: String,
302}
303
304impl Default for McpClientConfig {
305 fn default() -> Self {
306 Self {
307 servers: Vec::new(),
308 auto_register_tools: true,
309 tool_timeout_secs: None,
310 max_concurrent_calls: Some(1),
311 }
312 }
313}
314
315fn generate_uuid() -> String {
316 Uuid::new_v4().to_string()
317}
318
319fn default_true() -> bool {
320 true
321}
322
323fn generate_uuid_prefix() -> Option<String> {
324 Some(format!("mcp_{}", Uuid::new_v4().simple()))
325}
326
327impl Default for McpServerConfig {
328 fn default() -> Self {
329 Self {
330 id: generate_uuid(),
331 name: String::new(),
332 source: McpServerSource::Http {
333 url: String::new(),
334 timeout_secs: None,
335 headers: None,
336 },
337 enabled: true,
338 tool_prefix: generate_uuid_prefix(),
339 resources: None,
340 bearer_token: None,
341 }
342 }
343}