feat: 添加 HTTP 传输连接支持,优化 MCP 客户端管理器

This commit is contained in:
ooodc 2026-05-23 22:57:08 +08:00
parent cbb384a4e6
commit b3fa0bb978
2 changed files with 43 additions and 9 deletions

View File

@ -45,3 +45,4 @@ rmcp = { git = "https://github.com/modelcontextprotocol/rust-sdk", branch = "mai
"reqwest",
] }
schemars = "1.0"
http = "1"

View File

@ -9,7 +9,9 @@ use rmcp::{
RoleClient, ServiceExt,
service::RunningService,
transport::TokioChildProcess,
transport::streamable_http_client::{StreamableHttpClientTransport, StreamableHttpClientTransportConfig},
};
use http::{HeaderName, HeaderValue};
use tokio::process::Command;
use crate::mcp::config::{McpServerConfig, McpTransportConfig};
@ -81,14 +83,8 @@ impl McpClientManager {
McpTransportConfig::Stdio { command, args, env } => {
self.connect_stdio(command, args, env).await?
}
McpTransportConfig::Http { url, headers: _ } => {
// HTTP transport requires additional setup
// For now, we'll return an error for HTTP transport
return Err(anyhow::anyhow!(
"HTTP transport for MCP server '{}' is not yet implemented. URL: {}",
config.name,
url
));
McpTransportConfig::Http { url, headers } => {
self.connect_http(url, headers).await?
}
};
@ -117,7 +113,7 @@ impl McpClientManager {
Ok(server_info)
}
/// Connect via stdio transport
/// Connect via stdio transport (spawn child process)
async fn connect_stdio(
&self,
command: &str,
@ -140,6 +136,43 @@ impl McpClientManager {
Ok(client)
}
/// Connect via HTTP transport (Streamable HTTP)
async fn connect_http(
&self,
url: &str,
headers: &HashMap<String, String>,
) -> anyhow::Result<McpClient> {
// Build custom headers
let custom_headers: HashMap<HeaderName, HeaderValue> = headers
.iter()
.filter_map(|(key, value)| {
// Try to parse header name and value
HeaderName::try_from(key.clone())
.ok()
.and_then(|name| {
HeaderValue::try_from(value.clone())
.ok()
.map(|val| (name, val))
})
})
.collect();
// Create transport config with custom headers
let config = StreamableHttpClientTransportConfig::with_uri(url)
.custom_headers(custom_headers);
// Create transport using reqwest client (default)
let transport = StreamableHttpClientTransport::with_client(
reqwest::Client::default(),
config,
);
// Connect
let client = ().serve(transport).await?;
Ok(client)
}
/// Get a client by server name
pub async fn get_client(&self, name: &str) -> Option<Arc<McpClient>> {
let clients = self.clients.read().await;