matrixcode_core/mcp/mod.rs
1//! MCP (Model Context Protocol) Integration
2//!
3//! 提供完整的 MCP 协议支持,允许连接任意 MCP 服务器并将其工具映射为内置工具。
4//!
5//! # 架构概览
6//!
7//! ```text
8//! ┌─────────────────────────────────────────────────────────────┐
9//! │ MatrixCode Agent │
10//! │ ┌─────────────────────────────────────────────────────┐ │
11//! │ │ Tool System │ │
12//! │ │ ┌─────────┐ ┌─────────┐ ┌───────────────────────┐ │ │
13//! │ │ │ Built-in│ │ CodeGraph│ │ MCP Tool Wrapper │ │ │
14//! │ │ │ Tools │ │ Tools │ │ (Transparent Proxy) │ │ │
15//! │ │ └─────────┘ └─────────┘ └───────────┬───────────┘ │ │
16//! │ └─────────────────────────────────────│───────────────┘ │
17//! └────────────────────────────────────────│───────────────────┘
18//! │
19//! ┌─────────────────────────────────────────│───────────────────┐
20//! │ MCP Module │ │
21//! │ ┌──────────────┐ ┌──────────────┐ ┌───┴───────┐ │
22//! │ │ Config │ │ Transport │ │ McpClient │ │
23//! │ │ (config.rs) │ │ (transport.rs)│ │ (client.rs)│ │
24//! │ └──────────────┘ └──────────────┘ └─────┬─────┘ │
25//! └───────────────────────────────────────────│─────────────────┘
26//! │ MCP Protocol
27//! ┌───────────────────────────────────────────│─────────────────┐
28//! │ External MCP Servers │ │
29//! │ ┌─────────────┐ ┌─────────────┐ ┌───────┴───┐ │
30//! │ │ Playwright │ │ Filesystem │ │ Other │ │
31//! │ │ MCP Server │ │ MCP Server │ │ MCP │ │
32//! │ └─────────────┘ └─────────────┘ └───────────┘ │
33//! └─────────────────────────────────────────────────────────────┘
34//! ```
35//!
36//! # 快速开始
37//!
38//! ## 1. 配置 MCP 服务器
39//!
40//! 创建 `mcp.toml` 文件:
41//!
42//! ```toml
43//! [servers.playwright]
44//! command = "npx"
45//! args = ["-y", "@playwright/mcp@latest"]
46//!
47//! [servers.filesystem]
48//! command = "npx"
49//! args = ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/files"]
50//! ```
51//!
52//! ## 2. 连接并使用工具
53//!
54//! ```ignore
55//! use matrixcode_core::mcp::{McpConfig, McpToolManager};
56//!
57//! #[tokio::main]
58//! async fn main() -> anyhow::Result<()> {
59//! // 加载配置
60//! let config = McpConfig::from_file("mcp.toml")?;
61//!
62//! // 创建工具管理器
63//! let manager = McpToolManager::new();
64//!
65//! // 连接所有服务器
66//! for (key, server_config) in config.enabled_servers() {
67//! let transport = server_config.to_transport_config()?;
68//! let tools = manager.connect_server(&server_config.get_name(&key), transport).await?;
69//! println!("Connected: {} tools", tools.len());
70//! }
71//!
72//! // 获取所有工具
73//! let tools = manager.get_tools().await;
74//!
75//! // 使用工具...
76//!
77//! // 关闭
78//! manager.shutdown().await;
79//! Ok(())
80//! }
81//! ```
82//!
83//! # 支持的传输方式
84//!
85//! - **Stdio**: 通过子进程 stdin/stdout 通信(推荐)
86//! - **SSE**: 通过 HTTP Server-Sent Events 通信(远程服务器)
87//!
88//! # 内置 MCP 配置
89//!
90//! 模块提供常用 MCP 服务器的预设配置:
91//!
92//! - `playwright_config()`: Playwright 浏览器自动化
93//! - `default_mcp_config()`: 常用配置组合
94
95pub mod types;
96pub mod transport;
97pub mod client;
98pub mod proxy;
99pub mod config;
100pub mod lazy;
101
102// Re-export main types
103pub use types::*;
104pub use transport::{Transport, TransportConfig, StdioTransport, SseTransport};
105pub use client::{McpClient, McpClientBuilder};
106pub use proxy::{McpToolWrapper, McpToolManager, connect_mcp_server, connect_mcp_servers_from_config};
107pub use config::{McpConfig, McpServerConfig, McpSettings, load_mcp_config, find_mcp_config};
108pub use lazy::{McpToolPlaceholder, McpToolRegistry, ServerStatus};
109
110// ============================================================================
111// Convenience Functions
112// ============================================================================
113
114/// 连接 Playwright MCP 服务器
115///
116/// # Example
117///
118/// ```ignore
119/// use matrixcode_core::mcp::connect_playwright;
120///
121/// #[tokio::main]
122/// async fn main() -> anyhow::Result<()> {
123/// let tools = connect_playwright().await?;
124/// println!("Playwright tools: {:?}", tools.iter().map(|t| t.definition().name).collect::<Vec<_>>());
125/// Ok(())
126/// }
127/// ```
128pub async fn connect_playwright() -> anyhow::Result<Vec<Box<dyn crate::tools::Tool>>> {
129 let config = config::playwright_config();
130 let (key, server) = config.enabled_servers()
131 .into_iter()
132 .next()
133 .ok_or_else(|| anyhow::anyhow!("No playwright config found"))?;
134
135 let transport = server.to_transport_config()?;
136 connect_mcp_server(&server.get_name(&key), transport).await
137}
138
139/// 连接配置文件中的所有 MCP 服务器
140///
141/// 从当前目录或用户主目录查找 `mcp.toml` / `mcp.json` 配置文件,
142/// 并连接所有启用的 MCP 服务器。
143///
144/// # Example
145///
146/// ```ignore
147/// use matrixcode_core::mcp::connect_all_from_config;
148/// use std::path::Path;
149///
150/// #[tokio::main]
151/// async fn main() -> anyhow::Result<()> {
152/// let tools = connect_all_from_config(Path::new(".")).await?;
153/// println!("Total tools: {}", tools.len());
154/// Ok(())
155/// }
156/// ```
157pub async fn connect_all_from_config(
158 start_dir: &std::path::Path,
159) -> anyhow::Result<Vec<Box<dyn crate::tools::Tool>>> {
160 let config = load_mcp_config(start_dir);
161 let mut all_tools = Vec::new();
162
163 for (key, server_config) in config.enabled_servers() {
164 match server_config.to_transport_config() {
165 Ok(transport) => {
166 let name = server_config.get_name(&key);
167 tracing::info!("Connecting to MCP server: {}", name);
168
169 match connect_mcp_server(&name, transport).await {
170 Ok(tools) => {
171 tracing::info!("Connected to '{}' with {} tools", name, tools.len());
172 all_tools.extend(tools);
173 }
174 Err(e) => {
175 tracing::error!("Failed to connect to MCP server '{}': {}", name, e);
176 }
177 }
178 }
179 Err(e) => {
180 tracing::error!("Invalid config for server '{}': {}", key, e);
181 }
182 }
183 }
184
185 Ok(all_tools)
186}