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:
parent
31da5ff02d
commit
2125698fdc
1 changed files with 733 additions and 12 deletions
89
examples/simple-chat-client/src/config.rs
Normal file
89
examples/simple-chat-client/src/config.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue