ticket: split mcp stdio roadmap

This commit is contained in:
Keisuke Hirata 2026-06-20 14:34:00 +09:00
parent 356d06ef58
commit 75e8103cdd
No known key found for this signature in database
28 changed files with 486 additions and 29 deletions

View File

@ -1,24 +1,25 @@
---
title: 'MCP local stdio integration architecture'
title: 'MCP local stdio integration roadmap'
state: 'active'
created_at: '2026-06-10T07:48:45Z'
updated_at: '2026-06-13T15:30:22Z'
updated_at: '2026-06-20T05:34:00Z'
linked_tickets: ['00001KTR81P9X', '00001KV0SP0TY', '00001KVHR3WRF', '00001KVHR3WRY', '00001KVHR3WS6', '00001KVHR3WSD', '00001KVHR3WSN', '00001KVHR3WSW']
---
## Objective
Add MCP local stdio integration to Yoi without weakening Worker history, prompt-context, scoped tool permission, or Plugin/Feature layering invariants.
MCP should be implemented as a protocol-backed integration layer on top of `pod::feature`. `pod::feature` supplies the contribution/lifecycle API substrate; MCP owns its own enablement, local server trust model, command/env/secret policy, and MCP-specific permissions. MCP is not the Plugin model, and Plugin permission policy is not implemented by feature-layer authority grants.
MCP is a protocol-backed integration layer on top of `pod::feature`. `pod::feature` supplies contribution/lifecycle/dynamic registration substrate; MCP owns its own enablement, local server trust model, command/env/secret policy, and MCP-specific permission decisions. MCP is not the Plugin model, and Plugin permission policy is not implemented by feature-layer authority grants.
## Strategic direction
- Baseline the implementation on MCP specification `2025-11-25`.
- Baseline the initial implementation on MCP specification `2025-11-25`.
- Start with local stdio MCP servers only.
- Treat MCP server metadata, tools, resources, prompts, and results as untrusted content.
- Do not allow MCP resources/prompts to be hidden context injection.
- Do not allow MCP resources/prompts to become hidden context injection.
- They must be explicit tool operations with history records.
- Use the normal Yoi tool registry, PreToolCall permission, history, and bounded result paths.
- Use the normal Yoi ToolRegistry, PreToolCall permission, history, and bounded result paths.
- Do not add private MCP-only bypasses around Worker/tool invariants.
- Keep sampling and elicitation fail-closed initially.
- Keep Streamable HTTP, remote auth, OAuth, and MCP Registry/distribution out of the first slice.
@ -37,28 +38,37 @@ MCP should be implemented as a protocol-backed integration layer on top of `pod:
- MCP enablement, command/env/secret handling, server trust, and MCP-specific permission decisions live in MCP config/implementation.
- MCP dynamic tools/resources/prompts are exposed through the feature API and ordinary Yoi tool paths.
## Work breakdown
## Concrete implementation tickets
1. `00001KTR81P9X` — Extend `pod::feature` API for protocol-backed external providers.
- provider/service lifecycle
- startup discovery and dynamic contribution registration
- bounded refresh semantics
- metadata/result normalization
- no feature-layer authority model for MCP/Plugin permissions
2. `00001KTR82RB7` — Implement MCP `2025-11-25` local stdio server bridge.
- explicit MCP config and trust model
- initialize/capability negotiation
- tools/resources/prompts list/call/read/get
- bounded result serialization
- list-changed diagnostics/refresh behavior
3. `00001KV0SP0TY` — Remove feature-layer HostAuthority model.
- remove authority/grant terminology from `pod::feature`
- keep real permission/trust policy in owning Plugin/MCP/manifest/tool layers
4. Later follow-ups, if needed.
- richer MCP tasks / task-support integration
- remote/HTTP transports
- OAuth / registry / package distribution
- Plugin package/runtime alignment, if an explicit MCP/plugin bridge is later approved
Completed prerequisites:
- `00001KTR81P9X` — Extend `pod::feature` API for external protocol-backed capability providers.
- `00001KV0SP0TY` — Remove feature-layer HostAuthority model.
Concrete MCP implementation sequence:
1. `00001KVHR3WRF` — MCP local stdio server config and trust policy.
- explicit config, command/env/secret redaction, local executable trust boundary, no auto-start.
2. `00001KVHR3WRY` — MCP stdio JSON-RPC lifecycle client.
- subprocess lifecycle, initialize/capability negotiation, diagnostics, shutdown.
3. `00001KVHR3WS6` — MCP tools/list registration into ToolRegistry.
- stable namespacing, schema validation, untrusted metadata normalization, no tools/call yet.
4. `00001KVHR3WSD` — MCP tools/call execution through ordinary Tool path.
- PreToolCall gate before server call, bounded result serialization, history path.
5. `00001KVHR3WSN` — MCP resources/prompts as explicit tool operations.
- resources/list/read and prompts/list/get without hidden context injection.
6. `00001KVHR3WSW` — MCP list_changed notification handling.
- deterministic safe refresh/diagnostic behavior without breaking tool schema or prompt-cache invariants.
The old broad implementation Ticket `00001KTR82RB7` is superseded by this sequence and should not be used as an implementation work item.
## Later follow-ups
- Richer MCP task/task-support integration if ordinary tool-call fallback is insufficient.
- Streamable HTTP transport.
- OAuth / remote auth.
- Registry/package distribution.
- Explicit MCP/Plugin bridge only if separately approved; do not conflate Plugin packages with MCP local server execution.
## Success criteria

View File

@ -1,8 +1,8 @@
---
title: 'Implement MCP 2025-11-25 local stdio server-feature bridge'
state: 'planning'
state: 'closed'
created_at: '2026-06-10T07:48:49Z'
updated_at: '2026-06-13T15:29:21Z'
updated_at: '2026-06-20T05:33:15Z'
assignee: null
readiness: 'blocked'
risk_flags: ['mcp', 'prompt-context', 'permission-scope', 'secrets', 'process-exec', 'feature-api', 'trust-boundary']

View File

@ -0,0 +1,13 @@
Closed as superseded by concrete MCP implementation Tickets.
This Ticket bundled config/trust policy, stdio lifecycle, tools/list registration, tools/call execution, resources/prompts operations, result serialization, and list_changed handling into one broad implementation item. That is too coarse for the current Ticket policy: Tickets should be concrete implementation tasks.
The MCP roadmap now lives in Objective `00001KTR80WMN` (`MCP local stdio integration roadmap`). Concrete follow-up Tickets are:
- `00001KVHR3WRF` — local stdio server config and trust policy;
- `00001KVHR3WRY` — stdio JSON-RPC lifecycle client;
- `00001KVHR3WS6` — server tools registration into ToolRegistry;
- `00001KVHR3WSD` — tools/call execution through ordinary Tool path;
- `00001KVHR3WSN` — resources/prompts as explicit tool operations;
- `00001KVHR3WSW` — list_changed notification handling.
Future MCP work should use those concrete Tickets or similarly scoped follow-ups, not this broad umbrella Ticket.

View File

@ -22,4 +22,34 @@ LocalTicketBackend によって作成されました。
- `00001KSXRQ4G8``00001KT0Z4BK8` は Plugin permission を Plugin layer として扱い、MCP を初期 Plugin packaging/runtime から分離する。
---
<!-- event: state_changed author: hare at: 2026-06-20T05:33:15Z from: planning to: closed reason: closed field: state -->
## State changed
Ticket を closed にしました。
---
<!-- event: close author: hare at: 2026-06-20T05:33:15Z status: closed -->
## 完了
Closed as superseded by concrete MCP implementation Tickets.
This Ticket bundled config/trust policy, stdio lifecycle, tools/list registration, tools/call execution, resources/prompts operations, result serialization, and list_changed handling into one broad implementation item. That is too coarse for the current Ticket policy: Tickets should be concrete implementation tasks.
The MCP roadmap now lives in Objective `00001KTR80WMN` (`MCP local stdio integration roadmap`). Concrete follow-up Tickets are:
- `00001KVHR3WRF` — local stdio server config and trust policy;
- `00001KVHR3WRY` — stdio JSON-RPC lifecycle client;
- `00001KVHR3WS6` — server tools registration into ToolRegistry;
- `00001KVHR3WSD` — tools/call execution through ordinary Tool path;
- `00001KVHR3WSN` — resources/prompts as explicit tool operations;
- `00001KVHR3WSW` — list_changed notification handling.
Future MCP work should use those concrete Tickets or similarly scoped follow-ups, not this broad umbrella Ticket.
---

View File

@ -0,0 +1,13 @@
{
"version": 1,
"relations": [
{
"ticket_id": "00001KVHR3WRF",
"kind": "related",
"target": "00001KTR81P9X",
"note": "MCP implementation builds on the protocol-backed provider feature substrate.",
"author": "yoi ticket",
"at": "2026-06-20T05:33:03Z"
}
]
}

View File

@ -0,0 +1,47 @@
---
title: 'MCP: add local stdio server config and trust policy'
state: 'ready'
created_at: '2026-06-20T05:30:04Z'
updated_at: '2026-06-20T05:33:03Z'
assignee: null
readiness: 'implementation_ready'
risk_flags: ['mcp', 'config', 'trust-boundary', 'secrets', 'process-exec']
---
## Background
MCP integration starts with explicit local stdio server configuration and trust policy. Yoi must not auto-start MCP servers from workspace presence, package discovery, or Plugin packages. A configured MCP local stdio server is a local executable running with the user's OS permissions; Yoi feature authority does not sandbox its OS-level side effects.
This Ticket only defines/parses/validates config and diagnostics. It does not spawn MCP processes or implement JSON-RPC lifecycle.
## Requirements
- Add typed Profile/config support for named local stdio MCP servers.
- Config fields must cover command, args, cwd policy, env policy, and explicit secret/env references as needed.
- No package/workspace presence auto-start.
- Validate command/env/secret config fail-closed.
- Define diagnostic surfaces for config parse/validation errors.
- Redact command/env/secret values where needed; do not write plaintext secrets to logs/model context.
- Document local executable trust boundary.
- Keep MCP config/trust separate from Plugin permissions and `pod::feature` authority.
## Acceptance criteria
- A Profile/config can declare a named local stdio MCP server.
- Invalid command/env/secret config is rejected with bounded diagnostic.
- Secrets are not emitted in plaintext diagnostics/log/model context.
- Config alone does not spawn a process.
- Docs explain that configured local MCP servers are not OS-sandboxed by Yoi feature authority.
- Tests cover valid config, invalid config, secret redaction, and no auto-start.
## Non-goals
- Spawning stdio subprocesses.
- MCP initialize/capability negotiation.
- Tool/resource/prompt registration.
- Streamable HTTP/OAuth/remote MCP.
## Related work
- Objective: `00001KTR80WMN`.
- Supersedes part of broad MCP Ticket `00001KTR82RB7`.

View File

@ -0,0 +1,7 @@
<!-- event: create author: "yoi ticket" at: 2026-06-20T05:30:04Z -->
## 作成
LocalTicketBackend によって作成されました。
---

View File

@ -0,0 +1,21 @@
{
"version": 1,
"relations": [
{
"ticket_id": "00001KVHR3WRY",
"kind": "depends_on",
"target": "00001KVHR3WRF",
"note": "Lifecycle client requires explicit local stdio MCP config/trust policy.",
"author": "yoi ticket",
"at": "2026-06-20T05:33:03Z"
},
{
"ticket_id": "00001KVHR3WRY",
"kind": "related",
"target": "00001KTR81P9X",
"note": "MCP lifecycle uses the protocol-backed provider feature substrate.",
"author": "yoi ticket",
"at": "2026-06-20T05:33:03Z"
}
]
}

View File

@ -0,0 +1,49 @@
---
title: 'MCP: implement stdio JSON-RPC lifecycle client'
state: 'ready'
created_at: '2026-06-20T05:30:04Z'
updated_at: '2026-06-20T05:33:03Z'
assignee: null
readiness: 'implementation_ready'
risk_flags: ['mcp', 'stdio', 'json-rpc', 'process-lifecycle', 'diagnostics']
---
## Background
After MCP local stdio server config exists, Yoi needs a lifecycle client that can start a configured server, speak newline-delimited JSON-RPC over stdio, perform MCP initialize/capability negotiation, and shut down safely.
This Ticket creates the protocol/lifecycle foundation only. It does not expose MCP tools/resources/prompts to the model-visible ToolRegistry.
## Requirements
- Spawn configured local stdio MCP servers from explicit config only.
- Use stdin/stdout newline-delimited JSON-RPC.
- Treat stdout as protocol messages.
- Treat stderr as bounded diagnostics/logging, not automatic protocol failure.
- Implement initialize, capability negotiation, and notifications/initialized.
- Track server name and startup phase in diagnostics.
- Implement graceful shutdown, terminate, and kill fallback.
- Handle process exit/disconnect/startup failure with bounded diagnostics.
- Do not declare sampling or elicitation client capabilities initially.
- Add local mock MCP server tests.
## Acceptance criteria
- Mock local stdio MCP server initializes successfully.
- Initialize failure reports server name and phase.
- stderr is bounded and redacted where needed.
- Shutdown is safe and deterministic.
- Sampling/elicitation are not advertised and fail closed if requested.
- No tools/resources/prompts are registered by this Ticket.
## Non-goals
- tools/list ToolRegistry registration.
- tools/call execution.
- resources/prompts operations.
- Streamable HTTP/OAuth/remote MCP.
## Related work
- Depends on `00001KVHR3WRF`.
- Objective: `00001KTR80WMN`.

View File

@ -0,0 +1,7 @@
<!-- event: create author: "yoi ticket" at: 2026-06-20T05:30:04Z -->
## 作成
LocalTicketBackend によって作成されました。
---

View File

@ -0,0 +1,21 @@
{
"version": 1,
"relations": [
{
"ticket_id": "00001KVHR3WS6",
"kind": "depends_on",
"target": "00001KVHR3WRY",
"note": "Tool registration requires initialized MCP stdio lifecycle.",
"author": "yoi ticket",
"at": "2026-06-20T05:33:03Z"
},
{
"ticket_id": "00001KVHR3WS6",
"kind": "related",
"target": "00001KTR81P9X",
"note": "MCP tool registration uses feature dynamic contribution plumbing.",
"author": "yoi ticket",
"at": "2026-06-20T05:33:03Z"
}
]
}

View File

@ -0,0 +1,45 @@
---
title: 'MCP: register server tools into ToolRegistry'
state: 'ready'
created_at: '2026-06-20T05:30:04Z'
updated_at: '2026-06-20T05:33:03Z'
assignee: null
readiness: 'implementation_ready'
risk_flags: ['mcp', 'tools-list', 'tool-registry', 'schema', 'untrusted-metadata']
---
## Background
Once a configured MCP stdio server can initialize, Yoi should expose discovered MCP tools as ordinary model-visible Yoi tools through the existing ToolRegistry path. Server-provided tool metadata and schemas are untrusted data.
This Ticket only registers tools discovered through `tools/list`. It does not implement `tools/call` execution.
## Requirements
- Call MCP `tools/list` after initialize where supported.
- Handle pagination / bounded listing.
- Normalize MCP tool names into stable namespaced Yoi tool names that include server namespace.
- Validate/normalize tool descriptions and input schemas as untrusted metadata.
- Reject invalid schemas, duplicate names, and collisions fail-closed with diagnostics.
- Register contributions through `pod::feature` / normal ToolRegistry path; no private MCP bypass.
- Do not register resources/prompts in this Ticket.
## 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/call` request is sent during registration.
- Tests cover valid registration, pagination/bounds, invalid schema, duplicate/collision, and untrusted metadata normalization.
## Non-goals
- MCP tool execution.
- Resources/prompts operations.
- list_changed notifications.
## Related work
- Depends on `00001KVHR3WRY`.
- Objective: `00001KTR80WMN`.

View File

@ -0,0 +1,7 @@
<!-- event: create author: "yoi ticket" at: 2026-06-20T05:30:04Z -->
## 作成
LocalTicketBackend によって作成されました。
---

View File

@ -0,0 +1,13 @@
{
"version": 1,
"relations": [
{
"ticket_id": "00001KVHR3WSD",
"kind": "depends_on",
"target": "00001KVHR3WS6",
"note": "tools/call execution requires registered MCP tools.",
"author": "yoi ticket",
"at": "2026-06-20T05:33:03Z"
}
]
}

View File

@ -0,0 +1,43 @@
---
title: 'MCP: execute tools/call through ordinary Tool path'
state: 'ready'
created_at: '2026-06-20T05:30:04Z'
updated_at: '2026-06-20T05:33:03Z'
assignee: null
readiness: 'implementation_ready'
risk_flags: ['mcp', 'tools-call', 'permission', 'history', 'bounded-output']
---
## Background
After MCP tools are registered through ToolRegistry, invoking a Yoi MCP-backed tool should call the server's `tools/call` and return a bounded ordinary Tool result. Permission denial must happen before sending a request to the MCP server.
## Requirements
- Route registered MCP tool invocation to MCP `tools/call`.
- Apply existing PreToolCall / Tool permission path before MCP server call.
- If permission is denied, do not send `tools/call` to the server.
- Distinguish normal result, MCP `isError: true`, and JSON-RPC protocol error.
- Serialize MCP result forms boundedly: `content[]`, `structuredContent`, `isError`, `_meta`, and supported rich content summaries.
- Store result through ordinary Tool result/history path.
- Treat all content as untrusted.
## Acceptance criteria
- MCP mock tool returns normal result through ordinary Yoi Tool result.
- MCP `isError: true` is represented distinctly from JSON-RPC protocol failure.
- Permission denied call is not sent to the MCP server.
- Oversize/rich results are bounded/truncated or rejected according to explicit policy.
- Tool history shows ordinary tool call/result, not hidden context injection.
- Tests cover normal result, `isError`, protocol error, permission denial, and output bounds.
## Non-goals
- resources/read or prompts/get.
- list_changed notifications.
- Sampling/elicitation.
## Related work
- Depends on `00001KVHR3WS6`.
- Objective: `00001KTR80WMN`.

View File

@ -0,0 +1,7 @@
<!-- event: create author: "yoi ticket" at: 2026-06-20T05:30:04Z -->
## 作成
LocalTicketBackend によって作成されました。
---

View File

@ -0,0 +1,13 @@
{
"version": 1,
"relations": [
{
"ticket_id": "00001KVHR3WSN",
"kind": "depends_on",
"target": "00001KVHR3WRY",
"note": "resources/prompts operations require initialized MCP stdio lifecycle.",
"author": "yoi ticket",
"at": "2026-06-20T05:33:03Z"
}
]
}

View File

@ -0,0 +1,43 @@
---
title: 'MCP: expose resources and prompts as explicit tool operations'
state: 'ready'
created_at: '2026-06-20T05:30:04Z'
updated_at: '2026-06-20T05:33:03Z'
assignee: null
readiness: 'implementation_ready'
risk_flags: ['mcp', 'resources', 'prompts', 'prompt-context', 'history', 'untrusted-content']
---
## Background
MCP resources and prompts must not become hidden context injection. They should be exposed as explicit Yoi tool operations whose results are recorded through ordinary Tool result/history paths.
## Requirements
- Expose MCP resources/prompts as explicit namespaced Yoi tool operations: `resources/list`, `resources/read`, `prompts/list`, and `prompts/get`.
- Treat returned content/templates as untrusted tool result data.
- Do not inject resource/prompt content directly into context outside history/tool result.
- Bound result sizes and rich/embedded content serialization.
- Handle pagination/list bounds where applicable.
- Diagnostics identify server/resource/prompt operation without leaking secrets.
## Acceptance criteria
- `resources/list` and `resources/read` can be invoked as explicit tools.
- `prompts/list` and `prompts/get` can be invoked as explicit tools.
- Results are ordinary Tool results and history records.
- No hidden context injection path is introduced.
- Oversize/rich content is bounded.
- Tests cover list/read/get happy paths, untrusted content, bounds, and no hidden injection.
## Non-goals
- MCP tool execution itself.
- list_changed notification refresh.
- Sampling/elicitation.
## Related work
- Depends on `00001KVHR3WRY`.
- Related to `00001KVHR3WSD` for result serialization policy.
- Objective: `00001KTR80WMN`.

View File

@ -0,0 +1,7 @@
<!-- event: create author: "yoi ticket" at: 2026-06-20T05:30:04Z -->
## 作成
LocalTicketBackend によって作成されました。
---

View File

@ -0,0 +1,13 @@
{
"version": 1,
"relations": [
{
"ticket_id": "00001KVHR3WSW",
"kind": "depends_on",
"target": "00001KVHR3WS6",
"note": "tools/list_changed handling requires initial tools/list registration.",
"author": "yoi ticket",
"at": "2026-06-20T05:33:03Z"
}
]
}

View File

@ -0,0 +1,41 @@
---
title: 'MCP: handle list_changed notifications safely'
state: 'ready'
created_at: '2026-06-20T05:30:04Z'
updated_at: '2026-06-20T05:33:03Z'
assignee: null
readiness: 'implementation_ready'
risk_flags: ['mcp', 'notifications', 'tool-schema', 'prompt-cache', 'refresh']
---
## Background
MCP servers can notify that tools/resources/prompts lists changed. Yoi must not silently go stale, but it also must not mutate the model-visible tool schema or context in a way that violates history/prompt-cache invariants during a run.
## Requirements
- Handle MCP list-changed notifications: `notifications/tools/list_changed`, `notifications/resources/list_changed`, and `notifications/prompts/list_changed`.
- Choose and implement a safe refresh policy: next-turn refresh, restart/reinitialize-required diagnostic, or bounded live refresh only if it preserves schema/history invariants.
- Do not mutate current LLM context with hidden resource/prompt content.
- Emit bounded diagnostics when refresh cannot be applied safely.
- Tests with mock server notifications.
## Acceptance criteria
- list_changed does not silently stale forever.
- Current run tool schema consistency is not broken.
- Refresh/diagnostic behavior is deterministic and documented.
- Prompt-context/history invariants are preserved.
- Tests cover tools/resources/prompts list_changed and unsafe refresh fallback.
## Non-goals
- Initial tools/list registration.
- Initial resources/prompts operations.
- Remote MCP transports.
## Related work
- Depends on `00001KVHR3WS6` for tool list registration.
- Related to `00001KVHR3WSN` for resources/prompts lists.
- Objective: `00001KTR80WMN`.

View File

@ -0,0 +1,7 @@
<!-- event: create author: "yoi ticket" at: 2026-06-20T05:30:04Z -->
## 作成
LocalTicketBackend によって作成されました。
---