Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

tracking: MCP/ACP 协议与生命周期(5 项)—— 串行 IO + 缺失生命周期对象

Abierto
#190 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
12/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
rust
Área
api, backend

Línea de trabajo

This is a tracking issue with no code of its own; the work is in the child issues #183, #179, #180 (ACP, src/acp/server.rs, run_stdio around lines 1524-1556) and #181, #178 (MCP, src/mcp.rs). Start by reading run_stdio and process_line in src/acp/server.rs to see why the &mut W writer blocks running prompts as separate tasks. Done means each child issue's acceptance checks pass, with the four cluster-level acceptance tests as the final check.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

优先级 P1 · 依赖:无 · 类型:tracking(簇设计入口,不产出代码;子单全部落地后关闭)
记号:正文中的「不变量 #N」指 .dev/AGENTS.md 编号,不是 issue 编号;#150 这类才是 issue。本簇子单头部写 depends-on: #N 表示落地串行(同文件/同契约),不会与语义阻塞混淆。

基线 HEAD = 14bac15a(子单同基线)。本单来自一次全仓审计:先按根因归簇,再拆成可独立验收的子单。

共同根因

两条协议通道都是「能用表面、不能用实际」,而且根因同型:串行 IO + 缺失的生命周期对象。

MCP:#178 旧式 HTTP+SSE transport 完全不可用——spawn_http_sse 读到 endpoint 事件就把流丢掉(src/mcp.rs:544-611),read_sse_response 忽略 _post_url 重新 GET(:1204-1272)等于每次读取另开一个服务端会话;parse_sse_endpoint 返回原始 data、相对路径直接 POST(:1002-1008、:1281-1301)。#181 同文件的另外三处:tools/call 硬编码 10s 读超时且生产调用方无法覆盖(src/mcp.rs:340、388,src/mcp_server.rs:309、crates/recursive-cli/src/cli/builder.rs:500)、服务端发起的 ping/roots/list 被跳过不回复(:1131-1200)、能力字段按 as_bool() 读而规范服务端发对象(:645-653,对比 src/mcp_server.rs:134)。

ACP:run_stdio 串行 await process_line(src/acp/server.rs:1524-1556),而 prompt 在循环内 await runtime.run() 跑完整轮(:1307)→ 取消消息在轮中被积压,下一轮又被 refresh_cancel_token(:1286)换掉令牌;规范形态的无 id 通知被直接丢弃(:1696-1700 的 // Notifications (no id): silently discard)→ 模块头(:36-58)描述的「两阶段协作取消」在链路上不可达(#179)。EOF 也被 Ok(Ok(None)) → sleep(100ms) → continue 变成永不死去的 10 次/秒空转,60s 空闲超时永远不触发(:1524-1535,#183)。会话装配更是空的:AcpPermissionHook 无构造点(src/acp/permission.rs:114-171)、client-fs 工具绑定到 _tool 后丢弃(server.rs:612-636)却打 tool ready、mcp_servers 只存不 spawn(#180)。

子单与依赖

子单 依赖 范围
#183 无 ACP:EOF 即关停;空闲超时按固定 Instant 计算
#179 depends-on: #183 ACP:prompt 任务化 + 常驻读循环;cancel registry 按 sessionId;通知形态 cancel 在早退前分派
#180 depends-on: #179 ACP:每会话装配 registry(client-fs + AcpPermissionHook + spawn mcpServers 并登记 pid)
#181 无 MCP stdio:tools/call 独立可配超时;回服务端请求;能力判定 `object
#178 depends-on: #181 MCP legacy SSE:常驻 reader task + pending: HashMap<Id, oneshot>;Url::join 解析 endpoint

落地思路

  1. E 簇有两条可并行的子链:ACP(#183→#179→#180,全在 src/acp/)与 MCP(#181→#178,全在 src/mcp.rs),互不冲突。
  2. ACP 的难点是并发结构,不是功能:run_stdio 要拆成 (a) 读循环 (b) 每会话 prompt 任务 (c) writer 任务——现在 writer 是 &mut W 传进循环,任务化后必须改成 mpsc<Value> + 单一 writer task,否则借用检查过不去。这是 #179 的真正工作量。
  3. #180 先做 spike:需要确认客户端 capabilities 声明与 agent→client RPC 的路由方式(session/request_permission 要从 prompt 任务里回写),这是唯一需要与 ACP 协议对齐的点;建议先跑通「收到 request_permission 帧」再谈完整装配。
  4. MCP 侧先 #181 再 #178:两者同文件,且 #181 的 per-call 超时与 capability 判定是 #178 的 reader task 分发响应的前提。
  5. 与其它簇无文件重叠,可与其他簇并行。

簇级验收

  1. 本地起最小 SSE 服务端:initialize 成功、同一 sessionId 全程复用、tools/list 可返回;
  2. 长耗时(>10s)MCP 工具成功;{} 能力下 list_resources 可用;服务端 ping 收到回复;
  3. ACP:mock provider 阻塞在流中时,发通知形态 cancel 能中断该轮且 stopReason=cancelled;关闭 stdin 后 run_stdio 返回;
  4. ACP 会话的 tools/list 含 fs 工具,且工具调用时客户端收到 session/request_permission。

边界

不含 ACP 的功能性扩展(如新的 agent 能力);不含 MCP 的认证与协议版本升级(#104 的范围)。#178/#181 只修「不可用」与「不合规」,不改协议版本。

实施顺序、PR 拆分与验收矩阵(补充 · 2026-10-10)

两条可并行的子链(不同文件)

链 顺序 文件
ACP #183 → #179 → #180 src/acp/*
MCP #181 → #178 src/mcp.rs

#179 的真正工作量在并发结构:run_stdio(src/acp/server.rs:1524-1556)串行 await process_line(...),而 process_line 的签名是 (line, writer: &mut W, state: &mut ServerState, sessions: &mut AcpSessionManager, …)——&mut W 使得"prompt 放到独立任务"无法直接做到。因此 #179 必须先把 writer 改成 mpsc::Sender<Value> + 单一 writer task,再任务化 prompt。这一点不写清楚,实现者会卡在借用检查上。

#180 先做一次 spike:需要确认 (a) 客户端 capabilities 的读取位置,(b) session/request_permission 这类 agent→client RPC 在任务化之后怎么回写(同一个 writer 通道),(c) mcpServers 的 spawn 与 pid 登记点。建议 spike 的完成判据就是"能收到一帧 session/request_permission"。

跨簇重叠:无(src/acp/、src/mcp.rs 不被其它簇触碰)→ 本簇可与其他簇并行。

PR 拆分:一子单一 PR;#179 会比较大(读循环 + writer 任务 + cancel registry),建议在 PR 内分三个 commit(结构重构 / 通知形态 cancel / 测试),便于审阅。

簇级验收 → 测试映射:见正文四条;ACP 三条落在 src/acp/server.rs 的 #[cfg(test)](已有 duplex writer 夹具可复用),MCP 两条落在 src/mcp.rs 单测 + 一个新的 loopback e2e。

Lenguaje dominante
Rust
Estrellas
4
Forks
0
Merge medio
5 h 32 min
PR fusionados (30 d)
7

Preparar el entorno

  • Incluye un Dockerfile o un archivo de Docker Compose
  • Sin plantilla de pull request
  • Sin guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de jeffkit/recursive

Todos los issues de jeffkit/recursive

Issues similares

Más issues de Rust

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.