docs: add a simple chat client for example (#119)

1. optimize the readme in root
2. add example

Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
This commit is contained in:
jokemanfire 2025-04-10 16:52:25 +08:00 • committed by GitHub
commit 2125698fdc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -0,0 +1,89 @@
use std::{collections::HashMap, path::Path, process::Stdio};
use anyhow::Result;
use rmcp::{RoleClient, ServiceExt, service::RunningService};
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>,
}
#[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 {
Sse {
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::Sse { url } => {
let transport = rmcp::transport::sse::SseTransport::start(url).await?;
().serve(transport).await?
}
McpServerTransportConfig::Stdio {
command,
args,
envs,
} => {
let transport = rmcp::transport::child_process::TokioChildProcess::new(
tokio::process::Command::new(command)
.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)
}
}