use axum::{Json, extract::State, response::IntoResponse};
use http::Uri;
use log::{debug, error};
use tracing::instrument;
use uuid::Uuid;
use crate::AppError;
use crate::model::{
AddRouteParams, HttpResult, McpConfig, McpProtocolPath, McpServerConfig, McpType,
};
use crate::model::{AppState, McpRouterPath};
use crate::server::task::integrate_server_with_axum;
use serde_json::json;
#[instrument]
#[utoipa::path(
post,
path = "/mcp/sse/add",
tag = "mcp-sse",
request_body = AddRouteParams,
responses(
(status = 200, description = "注册成功。data 内含 mcp_id 与接入路径:SSE 协议返回 sse_path/message_path,Streamable HTTP 协议返回 stream_path",
body = Object,
example = json!({
"code": "0000",
"message": "成功",
"data": {
"mcp_id": "018f6a2b3c4d5e6f7a8b9c0d1e2f3a4b",
"sse_path": "/mcp/sse/proxy/018f6a2b3c4d5e6f7a8b9c0d1e2f3a4b/sse",
"message_path": "/mcp/sse/proxy/018f6a2b3c4d5e6f7a8b9c0d1e2f3a4b/message",
"mcp_type": "OneShot"
},
"tid": null,
"success": true
}))
)
)]
pub async fn add_route_handler(
State(state): State<AppState>,
uri: Uri,
Json(params): Json<AddRouteParams>,
) -> Result<impl IntoResponse, AppError> {
let request_path = uri.path().to_string();
debug!("Request path: {}", request_path);
debug!("Full URI: {:?}", uri);
let mcp_protocol = McpRouterPath::from_uri_prefix_protocol(&request_path);
if let Some(mcp_protocol) = mcp_protocol {
let mcp_id = Uuid::now_v7().to_string().replace("-", "");
let mcp_router_path = McpRouterPath::new(mcp_id, mcp_protocol)
.map_err(|e| AppError::mcp_server_error(e.to_string()))?;
let mcp_plugin_json = params.mcp_json_config;
let mcp_server_config = McpServerConfig::try_from(mcp_plugin_json.clone())
.map_err(|e| AppError::mcp_server_error(format!("解析 MCP 配置失败: {e}")))?;
let mcp_type = params.mcp_type.unwrap_or(McpType::default());
debug!("Client protocol: {:?}", mcp_router_path.mcp_protocol);
let full_mcp_config = McpConfig {
mcp_id: mcp_router_path.mcp_id.clone(),
client_protocol: mcp_router_path.mcp_protocol.clone(),
mcp_type: mcp_type.clone(),
mcp_json_config: Some(mcp_plugin_json),
server_config: Some(mcp_server_config.clone()),
};
let _ = integrate_server_with_axum(
mcp_server_config.clone(),
mcp_router_path.clone(),
full_mcp_config,
)
.await
.map_err(|e| {
error!("Failed to start MCP service: {e}");
AppError::mcp_server_error(e.to_string())
})?;
let mcp_protocol = mcp_router_path.mcp_protocol_path.clone();
let data = match mcp_protocol {
McpProtocolPath::SsePath(sse_path) => {
let data = json!({
"mcp_id": mcp_router_path.mcp_id,
"sse_path": sse_path.sse_path,
"message_path": sse_path.message_path,
"mcp_type": mcp_type
});
data
}
McpProtocolPath::StreamPath(stream_path) => {
let data = json!({
"mcp_id": mcp_router_path.mcp_id,
"stream_path": stream_path.stream_path,
"mcp_type": mcp_type
});
data
}
};
Ok(HttpResult::success(data, None))
} else {
return Err(AppError::invalid_parameter("无效的请求路径"));
}
}