From 13ce49599f0ad45a372e43a9ed7b45ca4e2fd2c9 Mon Sep 17 00:00:00 2001 From: kdletters <61648117+kdletters@users.noreply.github.com> Date: Fri, 2 Oct 2026 14:55:27 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20AGC=20MCP=20=E9=80=9A?= =?UTF-8?q?=E7=9F=A5=E8=AF=B7=E6=B1=82=E8=A2=AB=E6=8B=92=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=20cc=20=E6=89=A7=E8=A1=8C=E5=99=A8=E9=9B=B6=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - direct_tools_mcp:HTTP 入口对没有 id 的 JSON-RPC 通知(notifications/initialized)返回 202 空体,不再按错误回 400 - 之前 Claude Code 的 MCP 握手被 400 打断,把 agc 服务器标记为 failed,模型请求里一个工具都没有(实测 tools=0,修复后 tools=60) --- .../src-tauri/src/agent/direct_tools_mcp.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tools_mcp.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tools_mcp.rs index 95feedd00..99f4c3506 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tools_mcp.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tools_mcp.rs @@ -2,6 +2,7 @@ use super::*; use axum::extract::DefaultBodyLimit; use axum::extract::State as AxumState; use axum::http::{HeaderMap, StatusCode}; +use axum::response::IntoResponse; use axum::routing::post; use axum::Json; use axum::Router; @@ -2090,7 +2091,7 @@ async fn handle_external_mcp_http_request( AxumState(state): AxumState, headers: HeaderMap, Json(request): Json, -) -> Result, StatusCode> { +) -> Result { if !external_mcp_authorized(&headers, &state.token) { return Err(StatusCode::UNAUTHORIZED); } @@ -2107,6 +2108,13 @@ async fn handle_external_mcp_http_request( .in_flight .try_acquire() .map_err(|_| StatusCode::TOO_MANY_REQUESTS)?; + // JSON-RPC 通知(没有 `id`)没有响应体:MCP 客户端在 `initialize` 之后一定会发 + // `notifications/initialized`,按错误回 400 会被判成握手失败,整个服务器就被标记 + // 成 `failed`、一个工具都不广告(真实案例:2026-10-02 的 cc DirectProject 因此 + // 拿到 0 个工具)。规范要求的应答是 202 Accepted(空体)。 + if request.get("id").is_none() { + return Ok(StatusCode::ACCEPTED.into_response()); + } let response = EXTERNAL_MCP_BRIDGE_URL .scope( state.bridge_url.clone(), @@ -2114,7 +2122,7 @@ async fn handle_external_mcp_http_request( ) .await .ok_or(StatusCode::BAD_REQUEST)?; - Ok(Json(response)) + Ok(Json(response).into_response()) } pub(crate) async fn start_external_mcp_loopback(