mcp_stdio_proxy/client/support/
args.rs

1//! CLI 参数定义
2//!
3//! 定义所有命令行参数结构体
4
5use clap::Parser;
6use std::collections::HashMap;
7use std::path::PathBuf;
8
9/// 通用日志配置参数
10///
11/// 用于多个命令之间共享日志配置
12#[derive(Parser, Debug, Clone)]
13pub struct LoggingArgs {
14    /// 启用详细诊断模式,输出连接和工具调用的详细时间信息(默认启用)
15    #[arg(long, default_value = "false", help = "启用详细诊断模式,追踪连接生命周期和超时问题(默认启用)")]
16    pub diagnostic: bool,
17
18    /// 日志输出目录(自动生成文件名)
19    #[arg(long, help = "日志输出目录,将自动生成日志文件名")]
20    pub log_dir: Option<PathBuf>,
21
22    /// 日志文件完整路径(手动指定)
23    #[arg(long, conflicts_with = "log_dir", help = "日志文件完整路径")]
24    pub log_file: Option<PathBuf>,
25
26    /// OTLP 追踪端点(如 http://localhost:4317)
27    /// 
28    /// 启用 diagnostic 模式时,可配置此参数将追踪数据发送到 Jaeger 等 OTLP 兼容的后端。
29    /// 支持 gRPC (端口 4317) 和 HTTP (端口 4318) 协议。
30    #[arg(
31        long,
32        env = "OTEL_EXPORTER_OTLP_ENDPOINT",
33        help = "OTLP 追踪端点 (如 http://localhost:4317)"
34    )]
35    pub otlp_endpoint: Option<String>,
36
37    /// 追踪服务名称(用于 Jaeger 等追踪后端标识)
38    #[arg(
39        long,
40        default_value = "mcp-proxy",
41        help = "追踪服务名称(用于 Jaeger 等追踪后端标识)"
42    )]
43    pub service_name: String,
44}
45
46
47/// MCP-Proxy CLI 主命令结构
48#[derive(Parser, Debug)]
49#[command(name = "mcp-proxy")]
50#[command(version = env!("CARGO_PKG_VERSION"))]
51#[command(about = "MCP 协议转换代理工具", long_about = None)]
52pub struct Cli {
53    #[command(subcommand)]
54    pub command: Option<Commands>,
55
56    /// 直接URL模式(向后兼容)
57    #[arg(value_name = "URL", help = "MCP 服务的 URL 地址(直接模式)")]
58    pub url: Option<String>,
59
60    /// 全局详细输出
61    #[arg(short, long, global = true)]
62    pub verbose: bool,
63
64    /// 全局静默模式
65    #[arg(short, long, global = true)]
66    pub quiet: bool,
67}
68
69#[derive(clap::Subcommand, Debug)]
70pub enum Commands {
71    /// 协议转换模式 - 将 URL 转换为 stdio
72    Convert(ConvertArgs),
73
74    /// 检查服务状态
75    Check(CheckArgs),
76
77    /// 协议检测
78    Detect(DetectArgs),
79
80    /// 代理模式 - 将 stdio MCP 服务代理为 HTTP/SSE 服务
81    Proxy(crate::client::proxy_server::ProxyArgs),
82}
83
84/// 协议转换参数
85#[derive(Parser, Debug, Clone)]
86pub struct ConvertArgs {
87    /// MCP 服务的 URL 地址(可选,与 --config/--config-file 二选一)
88    #[arg(value_name = "URL", help = "MCP 服务的 URL 地址")]
89    pub url: Option<String>,
90
91    /// MCP 服务配置 JSON
92    #[arg(long, conflicts_with = "config_file", help = "MCP 服务配置 JSON")]
93    pub config: Option<String>,
94
95    /// MCP 服务配置文件路径
96    #[arg(long, conflicts_with = "config", help = "MCP 服务配置文件路径")]
97    pub config_file: Option<PathBuf>,
98
99    /// MCP 服务名称(多服务配置时必需)
100    #[arg(short, long, help = "MCP 服务名称(多服务配置时必需)")]
101    pub name: Option<String>,
102
103    /// 指定远程服务协议类型(不指定则自动检测)
104    #[arg(long, value_enum, help = "指定远程服务协议类型(不指定则自动检测)")]
105    pub protocol: Option<crate::client::proxy_server::ProxyProtocol>,
106
107    /// 认证 header (如: "Bearer token")
108    #[arg(short, long, help = "认证 header")]
109    pub auth: Option<String>,
110
111    /// 自定义 HTTP headers
112    #[arg(short = 'H', long, value_parser = parse_key_val, help = "自定义 HTTP headers (KEY=VALUE 格式)")]
113    pub header: Vec<(String, String)>,
114
115    /// 重试次数
116    #[arg(long, default_value = "0", help = "重试次数,0 表示无限重试")]
117    pub retries: u32,
118
119    /// 工具白名单(逗号分隔),只允许指定的工具
120    #[arg(long, value_delimiter = ',', help = "工具白名单(逗号分隔),只允许指定的工具")]
121    pub allow_tools: Option<Vec<String>>,
122
123    /// 工具黑名单(逗号分隔),排除指定的工具
124    #[arg(long, value_delimiter = ',', help = "工具黑名单(逗号分隔),排除指定的工具")]
125    pub deny_tools: Option<Vec<String>>,
126
127    /// 客户端 ping 间隔(秒),0 表示禁用
128    #[arg(long, default_value = "30", help = "客户端 ping 间隔(秒),0 表示禁用")]
129    pub ping_interval: u64,
130
131    /// 客户端 ping 超时(秒)
132    #[arg(long, default_value = "10", help = "客户端 ping 超时(秒),超时则认为连接断开")]
133    pub ping_timeout: u64,
134
135    /// 日志配置(使用通用结构)
136    #[command(flatten)]
137    pub logging: LoggingArgs,
138}
139
140/// 检查参数
141#[derive(Parser, Debug)]
142pub struct CheckArgs {
143    /// 要检查的 MCP 服务 URL
144    #[arg(value_name = "URL")]
145    pub url: String,
146
147    /// 认证 header
148    #[arg(short, long)]
149    pub auth: Option<String>,
150
151    /// 超时时间
152    #[arg(long, default_value = "10")]
153    pub timeout: u64,
154}
155
156/// 协议检测参数
157#[derive(Parser, Debug)]
158pub struct DetectArgs {
159    /// 要检测的 MCP 服务 URL
160    #[arg(value_name = "URL")]
161    pub url: String,
162
163    /// 认证 header
164    #[arg(short, long)]
165    pub auth: Option<String>,
166}
167
168/// 解析 KEY=VALUE 格式的辅助函数
169pub fn parse_key_val(s: &str) -> Result<(String, String), String> {
170    let pos = s.find('=')
171        .ok_or_else(|| format!("无效的 KEY=VALUE 格式: {}", s))?;
172    Ok((s[..pos].to_string(), s[pos + 1..].to_string()))
173}