mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-10-28 08:20:49 +08:00
在现有 HTTP 服务挂载 /mcp,让外部 AI 经共享 API Key 调用原分辨率截图、批量键鼠、ATX/WOL 和虚拟介质八个工具。所有调用共用有界 FIFO 和全局限流,复用现有采集管线与硬件控制器。 移除内置模型调用、网页 Agent 面板及旧配置,设置页提供可持续查看的 Key、统一的地址/密钥复制样式。补齐 DEB 的 libudev1 运行依赖。 验证:583 项 Rust 库测试、前端生产构建、ARMv7 设备视觉操作与介质/WOL 实测,以及默认 Release 构建和 DEB 包校验通过。 Refs #319
83 lines
2.3 KiB
Rust
83 lines
2.3 KiB
Rust
use crate::{
|
|
error::{AppError, Result},
|
|
state::AppState,
|
|
};
|
|
use axum::{extract::State, http::header, Json};
|
|
use serde::{Deserialize, Serialize};
|
|
use std::sync::Arc;
|
|
|
|
#[derive(Serialize)]
|
|
pub struct McpConfigResponse {
|
|
pub enabled: bool,
|
|
pub requests_per_second: u32,
|
|
pub api_key_configured: bool,
|
|
pub endpoint: &'static str,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub api_key: Option<String>,
|
|
}
|
|
#[derive(Deserialize)]
|
|
#[serde(deny_unknown_fields)]
|
|
pub struct McpConfigUpdate {
|
|
pub enabled: Option<bool>,
|
|
pub requests_per_second: Option<u32>,
|
|
#[serde(default)]
|
|
pub regenerate_api_key: bool,
|
|
}
|
|
fn response(state: &AppState) -> McpConfigResponse {
|
|
let config = state.config.get();
|
|
McpConfigResponse {
|
|
enabled: config.mcp.enabled,
|
|
requests_per_second: config.mcp.requests_per_second,
|
|
api_key_configured: config.mcp.api_key_hash.is_some(),
|
|
endpoint: "/mcp",
|
|
api_key: config.mcp.api_key.clone(),
|
|
}
|
|
}
|
|
pub async fn mcp_config(
|
|
State(state): State<Arc<AppState>>,
|
|
) -> (
|
|
[(header::HeaderName, &'static str); 1],
|
|
Json<McpConfigResponse>,
|
|
) {
|
|
(
|
|
[(header::CACHE_CONTROL, "no-store")],
|
|
Json(response(&state)),
|
|
)
|
|
}
|
|
pub async fn mcp_update_config(
|
|
State(state): State<Arc<AppState>>,
|
|
Json(req): Json<McpConfigUpdate>,
|
|
) -> Result<(
|
|
[(header::HeaderName, &'static str); 1],
|
|
Json<McpConfigResponse>,
|
|
)> {
|
|
if req
|
|
.requests_per_second
|
|
.is_some_and(|rate| !(1..=100).contains(&rate))
|
|
{
|
|
return Err(AppError::BadRequest(
|
|
"requests_per_second must be between 1 and 100".into(),
|
|
));
|
|
}
|
|
state
|
|
.config
|
|
.update(|config| {
|
|
if let Some(enabled) = req.enabled {
|
|
config.mcp.enabled = enabled;
|
|
}
|
|
if let Some(rate) = req.requests_per_second {
|
|
config.mcp.requests_per_second = rate;
|
|
}
|
|
if req.regenerate_api_key || (config.mcp.enabled && config.mcp.api_key_hash.is_none()) {
|
|
let key = crate::mcp::generate_key();
|
|
config.mcp.api_key_hash = Some(crate::mcp::hash_key(&key));
|
|
config.mcp.api_key = Some(key);
|
|
}
|
|
})
|
|
.await?;
|
|
Ok((
|
|
[(header::CACHE_CONTROL, "no-store")],
|
|
Json(response(&state)),
|
|
))
|
|
}
|