rust-sdk/examples/simple-chat-client/src/config.rs
adam jones eb5a7f7408
feat!: remove SSE transport support (#562)
SSE transport has been removed from the MCP specification in favor of
streamable HTTP. This removes all SSE-specific transport code:

- Remove `transport-sse-client` and `transport-sse-server` features
- Remove `SseClientTransport` and `SseServer` types
- Remove SSE-specific examples (`counter_sse`, `counter_sse_directly`)
- Migrate auth examples from SSE to streamable HTTP
- Update tests to remove SSE transport usage
- Update documentation

BREAKING CHANGE: The following have been removed:
- `transport-sse-client` feature
- `transport-sse-client-reqwest` feature
- `transport-sse-server` feature
- `SseClientTransport` type
- `SseServer` type
- `sse_client` and `sse_server` modules

Users should migrate to streamable HTTP transport which provides
equivalent functionality. See `StreamableHttpClientTransport` and
`StreamableHttpService` for the replacement APIs.

Ref: https://github.com/modelcontextprotocol/rust-sdk/pull/561#issuecomment-3576551699
2025-12-01 20:40:13 -05:00

93 lines
2.7 KiB
Rust

use std::{collections::HashMap, path::Path, process::Stdio};
use anyhow::Result;
use rmcp::{RoleClient, ServiceExt, service::RunningService, transport::ConfigureCommandExt};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
pub struct Config {
pub openai_key: Option<String>,
pub chat_url: Option<String>,
pub mcp: Option<McpConfig>,
pub model_name: Option<String>,
pub proxy: Option<bool>,
pub support_tool: Option<bool>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct McpConfig {
pub server: Vec<McpServerConfig>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct McpServerConfig {
pub name: String,
#[serde(flatten)]
pub transport: McpServerTransportConfig,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(tag = "protocol", rename_all = "lowercase")]
pub enum McpServerTransportConfig {
Streamable {
url: String,
},
Stdio {
command: String,
#[serde(default)]
args: Vec<String>,
#[serde(default)]
envs: HashMap<String, String>,
},
}
impl McpServerTransportConfig {
pub async fn start(&self) -> Result<RunningService<RoleClient, ()>> {
let client = match self {
McpServerTransportConfig::Streamable { url } => {
let transport =
rmcp::transport::StreamableHttpClientTransport::from_uri(url.to_string());
().serve(transport).await?
}
McpServerTransportConfig::Stdio {
command,
args,
envs,
} => {
let transport = rmcp::transport::child_process::TokioChildProcess::new(
tokio::process::Command::new(command).configure(|cmd| {
cmd.args(args)
.envs(envs)
.stderr(Stdio::inherit())
.stdout(Stdio::inherit());
}),
)?;
().serve(transport).await?
}
};
Ok(client)
}
}
impl Config {
pub async fn load(path: impl AsRef<Path>) -> Result<Self> {
let content = tokio::fs::read_to_string(path).await?;
let config: Self = toml::from_str(&content)?;
Ok(config)
}
pub async fn create_mcp_clients(
&self,
) -> Result<HashMap<String, RunningService<RoleClient, ()>>> {
let mut clients = HashMap::new();
if let Some(mcp_config) = &self.mcp {
for server in &mcp_config.server {
let client = server.transport.start().await?;
clients.insert(server.name.clone(), client);
}
}
Ok(clients)
}
}