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