14 KiB
作成
LocalTicketBackend によって作成されました。
State changed
Ticket を workspace-panel が queued にしました。
Decision
Routing decision: blocked_pending_dependency
Panel Queue により routing 対象として確認したが、00001KVHR3WS6 は 00001KVHR3WRY に depends_on している。MCP tools/list registration は initialized stdio lifecycle を前提にするため、00001KVHR3WRY が closed になるまで実装開始せず queued のまま保持する。
Next:
00001KVHR3WRYが closed になった後、改めて reroute する。
Decision
Routing decision: implementation_ready
Reason:
- Panel Queue により、この Ticket は Orchestrator routing 対象として明示許可された。
- 前回は
00001KVHR3WRYstdio JSON-RPC lifecycle が未完了だったため blocked/queued hold としたが、現在00001KVHR3WRYは closed。 - Ticket body は
tools/listによる registration scope、metadata/schema normalization、ToolRegistry integration、notools/callexecution、no resources/prompts を明確に分離している。 - 現在 inprogress は 0 件、child implementation Pods はなし、matching branch/worktree はなし、Orchestrator worktree は clean。
- Risk domain は mcp / tools-list / ToolRegistry / schema / untrusted metadata だが、Ticket は server metadata を untrusted data として扱い、invalid schema / duplicate / collision を fail-closed、normal ToolRegistry pathを使い、no private MCP bypass / no
tools/callduring registration などの invariants を明示している。bounded context check 後も implementation 前に必要な追加 human decision は見つからなかった。
Evidence checked:
- Ticket
00001KVHR3WS6body / thread / relations / artifacts。 TicketRelationQuery(00001KVHR3WS6): outgoingdepends_on 00001KVHR3WRYis now closed。Incoming00001KVHR3WSD/00001KVHR3WSWare downstream and not blockers。TicketOrchestrationPlanQuery(00001KVHR3WS6): previousblocked_by 00001KVHR3WRYis resolved; accepted plan recorded now。- Workspace state:
- Orchestrator worktree clean at
68a8fc97。 - queued:
00001KVHR3WS6,00001KVHR3WSD,00001KVHR3WSN,00001KVHR3WSW。 - inprogress: 0。
- visible Pods: self + peers only; spawned children 0。
- no matching MCP tool-registration branch/worktree。
- Orchestrator worktree clean at
IntentPacket:
Intent:
- Use the stdio MCP lifecycle client to call
tools/listand register discovered MCP tools as ordinary Yoi model-visible tools through existingpod::feature/ ToolRegistry contribution paths。 - This Ticket implements registration/discovery only. It must not send
tools/call, execute MCP tools, or expose resources/prompts。
Binding decisions / invariants:
- Server-provided tool names, descriptions, schemas, annotations, and metadata are untrusted data。
- Normalize MCP tool names into stable namespaced Yoi tool names that include server namespace and avoid collisions。
- Validate/normalize descriptions and JSON schemas before ToolRegistry registration; invalid schemas/duplicates/collisions fail closed with bounded diagnostics。
- No server metadata may weaken Yoi instructions, scope, permissions, tool permissions, or system/developer instructions。
- Registration must go through normal ToolRegistry /
pod::featuredynamic contribution path; no private MCP bypass。 - Do not send
tools/callduring registration。 - Do not register resources/prompts in this Ticket。
- Preserve lifecycle safety/redaction from
00001KVHR3WRY。
Requirements / acceptance criteria:
- MCP mock server tool appears as model-visible Yoi tool with stable namespaced name。
- Invalid schema is rejected with bounded diagnostic。
- Duplicate/colliding names are rejected fail-closed。
- Server metadata cannot weaken Yoi instructions/scope/permissions。
- No
tools/callrequest is sent during registration。 - Tests cover valid registration, pagination/bounds, invalid schema, duplicate/collision, and untrusted metadata normalization。
Escalate if:
- Existing
pod::featuredynamic contribution API cannot register MCP tools without broader provider-substrate changes。 - Schema normalization requires product decisions beyond safe JSON schema subset / bounded diagnostics。
- ToolRegistry registration would force
tools/callexecution into this Ticket。
Next action:
- Record
queued -> inprogressand commit Ticket records before creating the implementation worktree and spawning Coder。
State changed
Ticket body/thread, relation metadata, closed MCP lifecycle dependency, Orchestrator worktree state, visible Pods, existing branch/worktree, and bounded ToolRegistry/schema context were checked. Dependency 00001KVHR3WRY is closed, no inprogress/capacity blocker exists, and no missing planning decision was found. Accepting this queued Ticket for implementation before worktree/Pod side effects.
Implementation report
Implementation orchestration start:
- Acceptance records were committed on Orchestrator branch:
a59e5c1e ticket: accept mcp tool registration。 - Created implementation worktree
/home/hare/Projects/yoi/.worktree/00001KVHR3WS6-mcp-tool-registrationon branchimpl/00001KVHR3WS6-mcp-tool-registrationata59e5c1e。 - Spawned Coder Pod
yoi-coder-00001KVHR3WS6with write scope limited to the implementation worktree and read-only root scope only for runtime workspace identity。 - Coder task explicitly forbids root/original workspace implementation,
tools/call, resources/prompts exposure, merge, Ticket close, and cleanup。
Next action:
- Wait for Coder implementation report, then inspect branch diff/validation evidence and route to Reviewer。
Implementation report
Coder implementation report received from yoi-coder-00001KVHR3WS6.
Implementation commit:
66fa9d55 mcp: register stdio server tools
Changed areas reported:
crates/mcp:- Added MCP
tools/listprotocol result/tool types。 - Added
list_tools_pageand bounded paginatedlist_tools_bounded。 - Added mock-server coverage for paginated
tools/listand assertion thattools/callis not sent。
- Added MCP
crates/pod:- Added MCP stdio discovery feature module。
- Resolves configured stdio servers, initializes them, calls bounded
tools/list, normalizes discovered tools, and registers them through existing protocol-provider / ToolRegistry contribution paths。 - Namespaces tools as stable names like
Mcp_<server>_<tool>。 - Rejects invalid schemas and duplicate normalized names with bounded diagnostics。
- Ignores untrusted MCP metadata/annotations/instructions for authority purposes。
- Registered tools are discovery-only and return explicit not-implemented error if invoked; no MCP
tools/callexecution is implemented in this Ticket。
package.nix/Cargo.lock: updated for newpod -> mcpdependency and refreshedcargoHash。
Coder validation reported:
cargo test -p mcp list_tools --test stdio_lifecyclecargo test -p pod feature::mcp --libcargo test -p mcpcargo fmt --checkcargo check -p pod -p mcpgit diff --checknix build .#yoi --no-linkafter refreshing stalecargoHash。
Known risks / deferrals reported:
- MCP tool execution remains intentionally unimplemented; registered discovery-only stubs never send
tools/call。 - Resources/prompts and
list_changedhandling are deferred。 - Secret-backed MCP stdio env resolution currently passes no Pod secret store from this integration path; non-secret stdio configs are supported by this Ticket。
Orchestrator evidence checked before review dispatch:
- Implementation worktree is clean。
- HEAD is
66fa9d55。 - Diff from acceptance
a59e5c1e..HEADis one implementation commit touching 9 files, about 852 insertions / 4 deletions。 git diff --check a59e5c1e..HEADproduced no diagnostics。
Next action:
- Dispatch Reviewer for r1 review against Ticket requirements, with focus on ToolRegistry contribution path, schema/name normalization, no
tools/call, discovery-only invocation behavior, metadata authority boundaries, secret-store deferral, and tests。
Plan
Review dispatch:
- Spawned Reviewer Pod
yoi-reviewer-00001KVHR3WS6-r1against implementation branchimpl/00001KVHR3WS6-mcp-tool-registration。 - Review target commit:
66fa9d55 mcp: register stdio server tools。 - Review baseline:
a59e5c1e。 - Reviewer task focuses on normal ToolRegistry contribution path, untrusted metadata/schema/name normalization, no
tools/call, discovery-only invocation behavior, no resources/prompts/list_changed registration, diagnostics bounds, secret-store deferral, and tests。 - Reviewer is instructed not to edit source, commit, merge, close the Ticket, or use TicketReview directly; it will report verdict/evidence back to Orchestrator。
Review: request changes
Verdict: request_changes
確認範囲:
- Ticket contract / Orchestrator IntentPacket。
- Diff:
a59e5c1e..66fa9d55。 - 主な対象:
crates/pod/src/feature/mcp.rs,crates/pod/src/controller.rs,crates/pod/src/feature.rs,crates/mcp/src/stdio.rs,crates/mcp/tests/stdio_lifecycle.rs,crates/mcp/tests/fixtures/mock_server.rs,crates/pod/Cargo.toml,Cargo.lock,package.nix。 tools/call, resources/prompts registration,list_changed/listChangedhandlingを確認。
Blocking issue:
- Duplicate/colliding MCP tool names が fail-closed で reject されていない。
- Path:
crates/pod/src/feature/mcp.rs normalize_listed_toolsは最初の normalized name を登録し、後続 duplicate は diagnostic を出して skip するだけ。- Test
duplicate_names_after_normalization_are_diagnostic_onlyはこの挙動を期待している。 - Ticket / IntentPacket は invalid schemas / duplicates / collisions を fail-closed with bounded diagnostics と要求している。
- Server-controlled ordering で衝突する片方が model-visible tool として勝つため、normalized tool identity に対して fail-closed ではない。
- Path:
Required fix:
- Duplicate/colliding normalized names は、少なくとも該当 normalized identity の tool を model-visible にしないこと。
- より安全には、その server contribution/tool set 全体を reject/diagnostic-only にすること。
- Test を更新し、colliding normalized name が model-visible tool として登録されないことを確認する。
Non-blocking concerns / follow-ups:
- Acceptance criteria の run-stable schema behavior について、active-run refresh/list_changed mutation は見当たらないが、明示テストはない。可能なら追加するとよい。
- Secret-backed stdio env は integration path が
resolve_stdio_server(..., None)のため bounded diagnostic で fail し、silent support claim はしていない。これは今回の deferral と整合。
Positive findings:
tools/listは initialize 後にMcpStdioClient::list_tools_bounded経由で呼ばれる。- Pagination / tool-count bounds がある。
tools/callexecution path は追加されていない。model-visible stub は not-implemented error を返す。- Resources/prompts は登録されていない。
- Registration は既存
pod::featureprotocol-provider contribution path を通って Worker/ToolRegistry に入る。 - Server
instructions, annotations,_meta, output schema は authority として使われていない。 - Lifecycle redaction/shutdown behavior は保持されている。
- Nix/Cargo dependency updates は minimal/consistent。
Reviewer validation:
cargo fmt --check: passed。git diff --check a59e5c1e..HEAD: passed。cargo test -p mcp list_tools --test stdio_lifecycle: passed。cargo test -p pod feature::mcp --lib: passed。cargo test -p mcp: passed。cargo check -p pod -p mcp: passed。nix build .#yoi --no-link: passed。
Worktree status at review end: clean。
Implementation report
Coder r1-fix report received from yoi-coder-00001KVHR3WS6.
New fix commit:
0080c5b3 mcp: reject colliding tool names
Branch commits now:
0080c5b3 mcp: reject colliding tool names66fa9d55 mcp: register stdio server tools
Fix summary:
- Changed duplicate/collision handling in
crates/pod/src/feature/mcp.rsto fail closed for the normalized tool identity。 - Implementation now normalizes all valid candidate tools first, counts namespaced normalized names, emits bounded duplicate diagnostics, and registers only candidates whose normalized name appears exactly once。
- Server-controlled ordering can no longer cause the first colliding definition to become model-visible。
- Updated test to prove
Mcp_demo_search_filesis not model-visible when produced by two colliding MCP tool names, while unrelated validMcp_demo_uniquestill registers。
Coder validation reported as passing:
cargo fmt --checkgit diff --check a59e5c1e..HEADcargo test -p mcp list_tools --test stdio_lifecyclecargo test -p pod feature::mcp --libcargo test -p mcpcargo check -p pod -p mcpnix build .#yoi --no-link
Remaining deferrals unchanged:
- MCP
tools/callexecution remains intentionally unimplemented。 - Resources/prompts and
list_changedhandling remain out of scope。
Orchestrator evidence checked before r2 review:
- Implementation worktree is clean。
- HEAD is
0080c5b3。 - Fix diff from
66fa9d55..HEADtouches onlycrates/pod/src/feature/mcp.rs, about 43 insertions / 17 deletions。 - Overall
git diff --check a59e5c1e..HEADproduced no diagnostics。
Next action:
- Route back to Reviewer for r2 verification of duplicate/collision fail-closed behavior and final acceptance criteria。