Consolidate agent harness course into 19 lessons

This commit is contained in:
Haoran
2026-08-04 02:25:40 +08:00
parent 2ad77cee19
commit b36dbcd84f
168 changed files with 6544 additions and 10400 deletions

187
s16_mcp_plugin/README.ja.md Normal file
View File

@@ -0,0 +1,187 @@
# s16: MCP Tools — 外部ツール、標準プロトコル
[English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md)
[s15](../s15_agent_teams/) → `s16` → [s17](../s17_integrated_harness/) → s18 → s19
> *"外部ツール、標準プロトコル"* — 発見、組み立て、呼び出し。Agent はツールを誰が書いたか知る必要がない。
>
> **Harness 層**: プラグイン — 外部能力を標準プロトコルで接続。
---
## 課題
s01 から s15 まで、Agent の全ツールは手書き — bash、read、write、task、worktree。入力検証、実行ロジック、エラーハンドリング、全て一行ずつ書いた。
今、統合したい外部サービスが 3 つある:社内の Jira APIissue 検索、ticket 作成、独自のデプロイシステムdeploy トリガー、ログ閲覧)、チームの Notion ナレッジベース(ドキュメント検索、ページ作成)。各サービスのためにツールコードを書き直したくない。
標準プロトコルが必要 — 外部サービスがこのプロトコルを実装していれば、サービスが何の言語で書かれていても、Agent は直接そのツールを呼び出せる。
---
## ソリューション
![MCP Architecture](images/mcp-architecture.ja.svg)
MCPModel Context Protocolは、Agent が外部ツールを発見・呼び出しする方法を定義。核心概念:
| 概念 | 目的 |
|------|------|
| MCPClient | Agent 側のクライアント — server に接続、ツールを発見、ツールを呼び出し |
| MCP Server | 外部サービス側 — `tools/list` + `tools/call` を実装 |
| assemble_tool_pool | 組み込みツールと MCP ツールを一つのツールプールに組み立てる |
| mcp\_\_server\_\_tool 命名 | 異なる server 間のツール名衝突を防止 |
s15 の Team runtime を土台にし、idle 時の atomic task claim、安全な task-worktree binding、coordination protocol を引き継ぐ。cron scheduling、background bash の lifecycle、完了後に Lead を自動で起こす通知もそのまま残す。本章では `connect_mcp` ツールを追加し、サービスへの接続、ツール発見、ツールプールへの追加を行う。
task-bound worktree はチームメイトのファイルツールに対するデフォルト作業ディレクトリを変更するだけであり、セキュリティサンドボックスではない。
モデルに公開する `remove_worktree` が受け取るのは `name` だけなので、削除できるのは clean な checkout に限られる。変更を破棄する場合は、ユーザーが Git を手動実行するか、明示的な確認を経て host が下位の強制削除経路を呼び出す。モデル自身が強制削除を選ぶことはできない。
本章はプロセス内の server handler を登録し、発見から呼び出しまでをオフラインで実行する。各 handler はクライアントが必要とする `tools/list``tools/call` を提供する。
---
## 仕組み
### MCPClient発見 + 呼び出し
```python
class MCPClient:
def __init__(self, name: str):
self.name = name
self.tools: list[dict] = []
self._handlers: dict[str, callable] = {}
def register(self, tool_defs, handlers):
"""Simulates tools/list discovery."""
self.tools = tool_defs
self._handlers = handlers
def call_tool(self, tool_name: str, args: dict) -> str:
"""Simulates tools/call."""
handler = self._handlers.get(tool_name)
if not handler:
return f"MCP error: unknown tool '{tool_name}'"
return handler(**args)
```
登録した Python 関数が、`tools/call` から呼ばれる server 側のツール実装になる。
### connect_mcp接続 + 発見
```python
def connect_mcp(name: str) -> str:
if name in mcp_clients:
return f"MCP server '{name}' already connected"
factory = MOCK_SERVERS.get(name)
if not factory:
return f"Unknown server '{name}'. Available: ..."
mcp_client = factory()
mcp_clients[name] = mcp_client
return f"Connected to '{name}'. Discovered: ..."
```
接続後、server が提供するツールが即座に利用可能。
### normalize_mcp_name名前の正規化
```python
_DISALLOWED_CHARS = re.compile(r'[^a-zA-Z0-9_-]')
def normalize_mcp_name(name: str) -> str:
return _DISALLOWED_CHARS.sub('_', name)
```
`[a-zA-Z0-9_-]` 以外の全文字を `_` に置換。server 名やツール名の特殊文字による名前衝突やインジェクション問題を防止。
### assemble_tool_poolツールプールの組み立て
```python
def assemble_tool_pool() -> tuple[list[dict], dict]:
tools = list(BUILTIN_TOOLS)
handlers = dict(BUILTIN_HANDLERS)
for server_name, mcp_client in mcp_clients.items():
safe_server = normalize_mcp_name(server_name)
for tool_def in mcp_client.tools:
safe_tool = normalize_mcp_name(tool_def["name"])
prefixed = f"mcp__{safe_server}__{safe_tool}"
tools.append(...)
handlers[prefixed] = (
lambda *, c=mcp_client, t=tool_def["name"], **kw:
c.call_tool(t, kw))
return tools, handlers
```
プレフィックス `mcp__{server}__{tool}` で server ごとのツールを分離し、名前は `normalize_mcp_name` で正規化する。異なる元の名前が同じプレフィックスになる可能性があるため、`assemble_tool_pool()` は先に登録された handler を暗黙に上書きせず、衝突を拒否する。
MCP ツールの description に `(readOnly)` または `(destructive)` を付け、読み取りと変更の区別をツールメタデータ上で明示する。
### キャッシュなし:ツールプールが変われば、プロンプトも変わる
s10-s15 の agent loop は prompt cache で再シリアライズを回避。s16 はキャッシュを削除:
```python
def agent_loop(messages, context):
tools, handlers = assemble_tool_pool() # 毎回再構築
system = assemble_system_prompt(context) # 毎回再生成
...
if any(b.name == "connect_mcp" ...):
tools, handlers = assemble_tool_pool() # 接続後に再構築
system = assemble_system_prompt(context)
```
`connect_mcp` の後には `mcp__docs__search` などがツールプールへ加わる。古いシリアライズ済みツール一覧を再利用するとモデルから新しいツールが見えないため、接続後にツールプールと system prompt を再構築する。
### MCP ツールは Lead のみ利用可能
`connect_mcp` は Lead のツールであり、`assemble_tool_pool` も Lead の agent loop に使われる。チームメイトはタスク、ファイル、メッセージ、プランの各ツールを保持する。Lead は外部サービスを呼び出して得た仕事を共有 task board に置き、idle のチームメイトが atomic に claim する。
---
## s15 からの変更
| コンポーネント | 変更前 (s15) | 変更後 (s16) |
|--------------|------------|------------|
| ツールソース | 全て手書き builtin | 手書き + MCP 外部ツール動的発見 |
| ツールプール | 固定 BUILTIN_TOOLS | assemble_tool_pool が動的に mcp\_\_ プレフィックスツールを組み立てる |
| 名前の安全性 | なし | normalize_mcp_name 正規化 |
| 新規タイプ | — | MCPClient クラスtools/list + tools/call をシミュレート) |
| 名前空間 | — | mcp\_\_server\_\_tool 衝突防止 |
| ツール説明 | アノテーションなし | (readOnly)/(destructive) アノテーション |
| プロンプトキャッシュ | ありs10 から) | 削除 — ツールプールが動的、キャッシュが陳腐化 |
| 既存 runtime | task、cron、background bash、team、worktree | 全て維持 |
| Lead ツール | cron、background、worktree・チームツール | + connect_mcp と動的に発見した MCP ツール |
| チームメイトツール | タスク、ファイル、メッセージ、プランのツール | 変更なし |
| 拡張方法 | ツール追加のコードを書く | 標準プロトコル、任意言語で server を実装 |
---
## 試してみる
```sh
cd learn-claude-code
python s16_mcp_plugin/code.py
```
以下のプロンプトを試してください:
1. `ドキュメントから worktree のクリーンアップ方針を調べてください。`
2. `現在のプロジェクトをデプロイし、結果を報告してください。`
3. `現在実行できるドキュメント操作とデプロイ操作を教えてください。`
観察ポイントMCP server 接続後、ツール名に `mcp__docs__``mcp__deploy__` プレフィックスが付いているか?両方の server のツールが同時に利用可能かMCP ツールの description に (readOnly)/(destructive) アノテーションが付いているか?
---
## 次の章
Agent は標準プロトコルで外部ツールに接続できるようになった。前 16 章では、各境界を観察できるように仕組みを一つずつ追加してきた。
tools、permissions、hooks、todo、task graph、memory、compact、background work、cron、teams、worktree、MCP は、別々の例ではなく同じ loop に接続されるべきです。
[s17 Integrated Harness](../s17_integrated_harness/) → s01-s16 の仕組みを 1 つの harness に統合。仕組みは多く、loop は 1 つ。
<!-- translation-sync: zh@v4, en@v4, ja@v4 -->

187
s16_mcp_plugin/README.md Normal file
View File

@@ -0,0 +1,187 @@
# s16: MCP Tools — External Tools, Standard Protocol
[English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md)
[s15](../s15_agent_teams/) → `s16` → [s17](../s17_integrated_harness/) → s18 → s19
> *"External tools, standard protocol"* — Discover, assemble, invoke. Agent doesn't need to know who wrote them.
>
> **Harness layer**: Plugins — External capabilities via a standard protocol.
---
## The Problem
From s01 through s15, every tool the agent uses was hand-written — bash, read, write, task, worktree. Input validation, execution logic, error handling — all written line by line.
Now you have 3 external services to integrate: the company's Jira API (query issues, create tickets), an in-house deployment system (trigger deploys, view logs), and the team's Notion knowledge base (search docs, create pages). You don't want to rewrite tool code for every service.
You need a standard protocol — as long as an external service implements it, the agent can call its tools directly, regardless of what language the service is written in.
---
## The Solution
![MCP Architecture](images/mcp-architecture.en.svg)
MCP (Model Context Protocol) defines how agents discover and invoke external tools. Core concepts:
| Concept | Purpose |
|------|------|
| MCPClient | The agent-side client — connects to servers, discovers tools, invokes tools |
| MCP Server | The external service — implements `tools/list` + `tools/call` |
| assemble_tool_pool | Assembles built-in tools and MCP tools into one tool pool |
| mcp\_\_server\_\_tool naming | Prevents tool name collisions across different servers |
Builds on s15's team runtime: atomic idle task claiming, safe task-bound worktrees, and coordination protocols. It also retains cron scheduling, the background bash lifecycle, and completion notifications that automatically wake the Lead. This chapter adds the `connect_mcp` tool, which connects to a service, discovers its tools, and adds them to the tool pool.
A task-bound worktree changes the teammate file tools' default working directory; it is not a security sandbox.
The model-facing `remove_worktree` tool accepts only `name`, so it can remove only a clean checkout. Discarding changes remains a manual Git operation for the user, or a host action that follows explicit confirmation; the model cannot opt into the lower-level force path itself.
The chapter registers in-process server handlers so the full discovery and invocation flow runs offline. Each handler exposes the two operations the client needs: `tools/list` and `tools/call`.
---
## How It Works
### MCPClient: Discovery + Invocation
```python
class MCPClient:
def __init__(self, name: str):
self.name = name
self.tools: list[dict] = []
self._handlers: dict[str, callable] = {}
def register(self, tool_defs, handlers):
"""Simulates tools/list discovery."""
self.tools = tool_defs
self._handlers = handlers
def call_tool(self, tool_name: str, args: dict) -> str:
"""Simulates tools/call."""
handler = self._handlers.get(tool_name)
if not handler:
return f"MCP error: unknown tool '{tool_name}'"
return handler(**args)
```
The registered Python functions provide the server-side tool implementations used by `tools/call`.
### connect_mcp: Connect + Discover
```python
def connect_mcp(name: str) -> str:
if name in mcp_clients:
return f"MCP server '{name}' already connected"
factory = MOCK_SERVERS.get(name)
if not factory:
return f"Unknown server '{name}'. Available: ..."
mcp_client = factory()
mcp_clients[name] = mcp_client
return f"Connected to '{name}'. Discovered: ..."
```
After connecting, the server's tools are immediately available.
### normalize_mcp_name: Name Normalization
```python
_DISALLOWED_CHARS = re.compile(r'[^a-zA-Z0-9_-]')
def normalize_mcp_name(name: str) -> str:
return _DISALLOWED_CHARS.sub('_', name)
```
All non-`[a-zA-Z0-9_-]` characters are replaced with `_`. Prevents special characters in server or tool names from causing naming conflicts or injection issues.
### assemble_tool_pool: Assemble Tool Pool
```python
def assemble_tool_pool() -> tuple[list[dict], dict]:
tools = list(BUILTIN_TOOLS)
handlers = dict(BUILTIN_HANDLERS)
for server_name, mcp_client in mcp_clients.items():
safe_server = normalize_mcp_name(server_name)
for tool_def in mcp_client.tools:
safe_tool = normalize_mcp_name(tool_def["name"])
prefixed = f"mcp__{safe_server}__{safe_tool}"
tools.append(...)
handlers[prefixed] = (
lambda *, c=mcp_client, t=tool_def["name"], **kw:
c.call_tool(t, kw))
return tools, handlers
```
The prefix `mcp__{server}__{tool}` separates tools across servers, and names are normalized through `normalize_mcp_name`. Because different raw names can normalize to the same prefix, `assemble_tool_pool()` rejects a collision instead of silently replacing the earlier handler.
MCP tool descriptions include `(readOnly)` or `(destructive)` labels, making the distinction visible in the tool metadata.
### No Cache: Tool Pool Changes, Prompt Changes Too
s10-s15's agent loop used prompt caching to avoid re-serialization. s16 removes the cache:
```python
def agent_loop(messages, context):
tools, handlers = assemble_tool_pool() # Rebuild every time
system = assemble_system_prompt(context) # Regenerate every time
...
if any(b.name == "connect_mcp" ...):
tools, handlers = assemble_tool_pool() # Rebuild after connection
system = assemble_system_prompt(context)
```
After `connect_mcp`, the tool pool gains entries such as `mcp__docs__search`. Reusing the old serialized tool list would hide those entries from the model, so the loop rebuilds the pool and system prompt after every connection.
### MCP Tools: Lead Only
`connect_mcp` belongs to the Lead, and `assemble_tool_pool` serves the Lead's agent loop. Teammates keep their task, file, message, and plan tools; the Lead invokes external services and puts resulting work on the shared task board, where idle teammates can claim it atomically.
---
## Changes from s15
| Component | Before (s15) | After (s16) |
|------|-----------|-----------|
| Tool source | All hand-written built-in | Hand-written + MCP external tools with dynamic discovery |
| Tool pool | Fixed BUILTIN_TOOLS | assemble_tool_pool dynamically assembles mcp\_\_ prefixed tools |
| Name safety | None | normalize_mcp_name normalization |
| New type | — | MCPClient class (simulates tools/list + tools/call) |
| Namespace | — | mcp\_\_server\_\_tool prevents collisions |
| Tool descriptions | No annotations | (readOnly)/(destructive) annotations |
| Prompt cache | Yes (since s10) | Removed — tool pool is dynamic, cache goes stale |
| Existing runtime | Tasks, cron, background bash, teams, and worktrees | All retained |
| Lead tools | Cron, background, worktree, and team tools | + connect_mcp and dynamically discovered MCP tools |
| Teammate tools | Task, file, message, and plan tools | Unchanged |
| Extension method | Write code to add tools | Standard protocol, implement servers in any language |
---
## Try It Out
```sh
cd learn-claude-code
python s16_mcp_plugin/code.py
```
Try these prompts:
1. `Search the docs for the worktree cleanup policy.`
2. `Deploy the current project and report the result.`
3. `What documentation and deployment actions can you perform?`
What to observe: After connecting to an MCP server, do tool names have `mcp__docs__` or `mcp__deploy__` prefixes? Are both servers' tools available simultaneously? Do MCP tool descriptions include (readOnly)/(destructive) annotations?
---
## What's Next
The Agent can now connect external tools through a standard protocol. The first 16 chapters introduced these mechanisms one at a time so each boundary stayed visible.
Tools, permissions, hooks, todo, task graph, memory, compact, background work, cron, teams, worktrees, and MCP should all attach to the same loop, not live in separate examples.
[s17 Integrated Harness](../s17_integrated_harness/) → Combine the mechanisms from s01-s16 into one harness. Many mechanisms, one loop.
<!-- translation-sync: zh@v4, en@v4, ja@v4 -->

187
s16_mcp_plugin/README.zh.md Normal file
View File

@@ -0,0 +1,187 @@
# s16: MCP Tools — 外接工具,标准协议
[English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md)
[s15](../s15_agent_teams/) → `s16` → [s17](../s17_integrated_harness/) → s18 → s19
> *"外接工具, 标准协议"* — 发现、组装、调用Agent 不需要知道工具是谁写的。
>
> **Harness 层**: 插件 — 外部能力通过标准协议接入。
---
## 问题
s01 到 s15Agent 的所有工具都是手写的,包括 bash、read、write、task 和 worktree。每个工具的输入验证、执行逻辑、错误处理都是你一行行写的。
现在你有 3 个外部服务想接入:公司的 Jira API查 issue、建 ticket、自建的部署系统触发 deploy、看日志、团队的 Notion 知识库(搜文档、建页面)。你不想为每个服务重写一套工具代码。
你需要一个标准协议。外部服务只要实现它Agent 就能直接调用,不管服务用什么语言写的。
---
## 解决方案
![MCP Architecture](images/mcp-architecture.svg)
MCPModel Context Protocol定义了 Agent 如何发现和调用外部工具。核心概念:
| 概念 | 作用 |
|------|------|
| MCPClient | Agent 端的客户端,连接 server、发现工具、调用工具 |
| MCP Server | 外部服务,实现 `tools/list` + `tools/call` |
| assemble_tool_pool | 把内置工具和 MCP 工具组装成一个工具池 |
| mcp\_\_server\_\_tool 命名 | 避免不同 server 的工具名冲突 |
本章建立在 s15 团队运行时之上,沿用 idle 阶段的原子任务认领、安全的 task-worktree 绑定和协调协议,也保留 cron 调度、后台 bash 生命周期,以及任务完成后自动唤醒 Lead 的通知。新增的 `connect_mcp` 工具用于连接服务、发现工具并加入工具池。
task-bound worktree 只会改变队友文件工具的默认工作目录,并不是安全沙箱。
模型可见的 `remove_worktree` 只接受 `name`,因此只能移除状态干净的 checkout。若确实要丢弃改动应由用户手动执行 Git或者由宿主在明确确认后调用底层的强制清理路径不能让模型自行选择。
本章注册进程内 server handler让工具发现和调用流程可以离线运行。每个 handler 都提供客户端需要的 `tools/list``tools/call` 两个操作。
---
## 工作原理
### MCPClient发现 + 调用
```python
class MCPClient:
def __init__(self, name: str):
self.name = name
self.tools: list[dict] = []
self._handlers: dict[str, callable] = {}
def register(self, tool_defs, handlers):
"""Simulates tools/list discovery."""
self.tools = tool_defs
self._handlers = handlers
def call_tool(self, tool_name: str, args: dict) -> str:
"""Simulates tools/call."""
handler = self._handlers.get(tool_name)
if not handler:
return f"MCP error: unknown tool '{tool_name}'"
return handler(**args)
```
注册的 Python 函数提供 `tools/call` 所调用的 server 端工具实现。
### connect_mcp连接 + 发现
```python
def connect_mcp(name: str) -> str:
if name in mcp_clients:
return f"MCP server '{name}' already connected"
factory = MOCK_SERVERS.get(name)
if not factory:
return f"Unknown server '{name}'. Available: ..."
mcp_client = factory()
mcp_clients[name] = mcp_client
return f"Connected to '{name}'. Discovered: ..."
```
连接后server 提供的工具立即可用。
### normalize_mcp_name名称规范化
```python
_DISALLOWED_CHARS = re.compile(r'[^a-zA-Z0-9_-]')
def normalize_mcp_name(name: str) -> str:
return _DISALLOWED_CHARS.sub('_', name)
```
所有非 `[a-zA-Z0-9_-]` 的字符替换为 `_`。防止 server 名或工具名中包含特殊字符导致命名冲突或注入问题。
### assemble_tool_pool组装工具池
```python
def assemble_tool_pool() -> tuple[list[dict], dict]:
tools = list(BUILTIN_TOOLS)
handlers = dict(BUILTIN_HANDLERS)
for server_name, mcp_client in mcp_clients.items():
safe_server = normalize_mcp_name(server_name)
for tool_def in mcp_client.tools:
safe_tool = normalize_mcp_name(tool_def["name"])
prefixed = f"mcp__{safe_server}__{safe_tool}"
tools.append(...)
handlers[prefixed] = (
lambda *, c=mcp_client, t=tool_def["name"], **kw:
c.call_tool(t, kw))
return tools, handlers
```
前缀 `mcp__{server}__{tool}` 用于分隔不同 server 的工具,名称再经过 `normalize_mcp_name` 规范化。不同原始名称仍可能得到同一个前缀,因此 `assemble_tool_pool()` 会拒绝冲突,而不是静默覆盖先注册的 handler。
MCP 工具的 description 带 `(readOnly)``(destructive)` 标注,让只读操作和修改操作在工具元数据中直接可见。
### 无缓存工具池变了prompt 也变
s10-s15 的 agent loop 用 prompt cache 避免重复序列化。s16 去掉了缓存:
```python
def agent_loop(messages, context):
tools, handlers = assemble_tool_pool() # 每次重新构建
system = assemble_system_prompt(context) # 每次重新生成
...
if any(b.name == "connect_mcp" ...):
tools, handlers = assemble_tool_pool() # 连接后重建
system = assemble_system_prompt(context)
```
`connect_mcp` 之后,工具池会新增 `mcp__docs__search` 等条目。继续复用旧的序列化工具列表,模型就看不到这些工具,所以每次连接后都要重建工具池和 system prompt。
### MCP 工具只有 Lead 可用
`connect_mcp` 属于 Lead`assemble_tool_pool` 也服务于 Lead 的 agent loop。Teammate 保留任务、文件、消息和计划工具Lead 调用外部服务后把工作放入共享任务板idle 队友再进行原子认领。
---
## 相对 s15 的变更
| 组件 | 之前 (s15) | 之后 (s16) |
|------|-----------|-----------|
| 工具来源 | 全部手写 builtin | 手写 + MCP 外部工具动态发现 |
| 工具池 | 固定 BUILTIN_TOOLS | assemble_tool_pool 动态组装 mcp\_\_ 前缀工具 |
| 名称安全 | 无 | normalize_mcp_name 规范化 |
| 新类型 | — | MCPClient 类(模拟 tools/list + tools/call |
| 命名空间 | — | mcp\_\_server\_\_tool 避免冲突 |
| 工具描述 | 无标注 | (readOnly)/(destructive) 标注 |
| prompt 缓存 | 有s10 起) | 去掉,因为工具池动态变化后缓存失效 |
| 已有运行时 | task、cron、后台 bash、团队与 worktree | 全部保留 |
| Lead 工具 | cron、后台、worktree 与团队工具 | + connect_mcp 和动态发现的 MCP 工具 |
| Teammate 工具 | 任务、文件、消息与计划工具 | 不变 |
| 扩展方式 | 写代码加工具 | 标准协议,任意语言实现 server |
---
## 试一下
```sh
cd learn-claude-code
python s16_mcp_plugin/code.py
```
试试这些 prompt
1. `查一下文档里的 worktree 清理策略。`
2. `部署当前项目,并告诉我结果。`
3. `你现在可以执行哪些文档和部署操作?`
观察重点:连接 MCP server 后,工具名是否带 `mcp__docs__``mcp__deploy__` 前缀?两个 server 的工具是否同时可用MCP 工具的 description 是否带 (readOnly)/(destructive) 标注?
---
## 接下来
现在 Agent 可以通过标准协议接入外部工具了。前 16 章逐个引入这些机制,让每个边界都能单独观察。
工具、权限、hooks、todo、任务图、记忆、压缩、后台、cron、团队、worktree、MCP 这些机制应该挂在同一个循环上,而不是分散在不同示例里。
[s17 Agent Harness 集成](../s17_integrated_harness/) → 把 s01-s16 的机制合回同一个 harness。机制很多循环一个。
<!-- translation-sync: zh@v4, en@v4, ja@v4 -->

1881
s16_mcp_plugin/code.py Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,112 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 460" font-family="system-ui, -apple-system, sans-serif">
<defs>
<linearGradient id="header" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#1e3a5f"/><stop offset="100%" stop-color="#dc2626"/>
</linearGradient>
<marker id="arrow" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#555"/>
</marker>
<marker id="arrow-rose" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#dc2626"/>
</marker>
<marker id="arrow-rose-left" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M 10 0 L 0 5 L 10 10 z" fill="#dc2626"/>
</marker>
</defs>
<rect width="760" height="460" fill="#fafbfc" rx="8"/>
<!-- Title -->
<rect x="0" y="0" width="760" height="44" fill="url(#header)" rx="8"/>
<rect x="0" y="36" width="760" height="8" fill="url(#header)"/>
<text x="380" y="28" fill="#fff" font-size="15" font-weight="700" text-anchor="middle">MCP Plugin — Standard Protocol + External Tool Integration + Tool Pool Assembly</text>
<!-- Legend -->
<rect x="40" y="56" width="12" height="10" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="58" y="66" fill="#2563eb" font-size="10" font-weight="600">s15 Preserved</text>
<rect x="160" y="56" width="12" height="10" rx="2" fill="#fff1f2" stroke="#dc2626" stroke-width="1"/>
<text x="178" y="66" fill="#dc2626" font-size="10" font-weight="600">s16 New</text>
<!-- ===== Row 1: Lead Loop (s15 preserved) ===== -->
<rect x="20" y="90" width="70" height="40" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="1.5"/>
<text x="55" y="114" fill="#4f46e5" font-size="8" font-weight="600" text-anchor="middle">turn</text>
<line x1="90" y1="110" x2="104" y2="110" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="107" y="90" width="70" height="40" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="142" y="114" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">messages</text>
<line x1="177" y1="110" x2="191" y2="110" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="194" y="86" width="80" height="48" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="234" y="114" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">prompt</text>
<line x1="274" y1="110" x2="288" y2="110" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="291" y="86" width="70" height="48" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="326" y="114" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">LLM</text>
<line x1="361" y1="110" x2="375" y2="110" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="378" y="76" width="356" height="72" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="556" y="94" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL DISPATCH (Lead 16 tools)</text>
<text x="394" y="109" fill="#2563eb" font-size="7.5">bash · read · write · task(4) · send · inbox</text>
<text x="394" y="121" fill="#7c3aed" font-size="7.5" font-weight="700">request_shutdown · request_plan · review_plan</text>
<text x="394" y="133" fill="#b45309" font-size="7.5" font-weight="700">create_worktree · remove_worktree</text>
<text x="394" y="145" fill="#dc2626" font-size="7.5" font-weight="700">★ connect_mcp + dynamic mcp__server__tool tools</text>
<!-- Loop back -->
<path d="M 734 110 L 748 110 L 748 150 L 55 150 L 55 130" fill="none" stroke="#94a3b8" stroke-width="1" marker-end="url(#arrow)" stroke-dasharray="5,4"/>
<!-- ===== Row 2: MCP Architecture (s16 new) ===== -->
<rect x="30" y="172" width="700" height="215" rx="8" fill="#fff1f2" stroke="#dc2626" stroke-width="2"/>
<text x="380" y="194" fill="#991b1b" font-size="11" font-weight="700" text-anchor="middle">MCP Architecture (s16 new: standard protocol + dynamic external tools)</text>
<!-- Agent Side -->
<rect x="50" y="210" width="255" height="140" rx="6" fill="#fff" stroke="#dc2626" stroke-width="1.5"/>
<text x="177" y="230" fill="#991b1b" font-size="10" font-weight="700" text-anchor="middle">Agent Side (MCPClient)</text>
<rect x="65" y="240" width="225" height="24" rx="4" fill="#fef2f2" stroke="#fca5a5" stroke-width="0.5"/>
<text x="177" y="256" fill="#475569" font-size="8" text-anchor="middle">connect_mcp → discover → register tools</text>
<rect x="65" y="272" width="225" height="24" rx="4" fill="#fef2f2" stroke="#fca5a5" stroke-width="0.5"/>
<text x="177" y="288" fill="#475569" font-size="8" text-anchor="middle">assemble_tool_pool assembles builtin + mcp</text>
<rect x="65" y="304" width="225" height="24" rx="4" fill="#fef2f2" stroke="#fca5a5" stroke-width="0.5"/>
<text x="177" y="320" fill="#475569" font-size="8" text-anchor="middle">call_tool("mcp__docs__search", ...)</text>
<!-- Communication arrows -->
<line x1="305" y1="262" x2="435" y2="262" stroke="#dc2626" stroke-width="1.5" marker-end="url(#arrow-rose)"/>
<text x="370" y="256" fill="#dc2626" font-size="7" font-weight="600" text-anchor="middle">tools/list</text>
<line x1="435" y1="296" x2="305" y2="296" stroke="#dc2626" stroke-width="1.5" marker-end="url(#arrow-rose)"/>
<text x="370" y="312" fill="#dc2626" font-size="7" font-weight="600" text-anchor="middle">tools/call + response</text>
<!-- MCP Servers -->
<rect x="438" y="210" width="275" height="140" rx="6" fill="#fff" stroke="#ca8a04" stroke-width="1.5"/>
<text x="575" y="230" fill="#854d0e" font-size="10" font-weight="700" text-anchor="middle">MCP Servers (External Services)</text>
<rect x="453" y="240" width="245" height="28" rx="4" fill="#fefce8" stroke="#facc15" stroke-width="0.5"/>
<text x="575" y="258" fill="#854d0e" font-size="9" font-weight="600" text-anchor="middle">docs server: search · get_version</text>
<rect x="453" y="276" width="245" height="28" rx="4" fill="#fefce8" stroke="#facc15" stroke-width="0.5"/>
<text x="575" y="294" fill="#854d0e" font-size="9" font-weight="600" text-anchor="middle">deploy server: trigger · status</text>
<rect x="453" y="312" width="245" height="28" rx="4" fill="#fefce8" stroke="#facc15" stroke-width="0.5"/>
<text x="575" y="330" fill="#854d0e" font-size="9" font-weight="600" text-anchor="middle">Any language, just needs stdio JSON-RPC</text>
<!-- Naming convention -->
<rect x="50" y="360" width="660" height="20" rx="4" fill="#fef3c7" stroke="#d97706" stroke-width="1"/>
<text x="380" y="374" fill="#92400e" font-size="8" text-anchor="middle">Tool naming: mcp__{server}__{tool} → e.g. mcp__docs__search · mcp__deploy__trigger · prevents name collisions across servers</text>
<!-- ===== Row 3: Bottom notes ===== -->
<rect x="30" y="400" width="700" height="22" rx="4" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="50" y="408" width="12" height="10" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="70" y="418" fill="#475569" font-size="10">s15: atomic claims + task worktrees + protocols</text>
<rect x="420" y="408" width="12" height="10" rx="2" fill="#fff1f2" stroke="#dc2626" stroke-width="1"/>
<text x="440" y="418" fill="#475569" font-size="10">s16: MCP + dynamic tools (Lead 16)</text>
<!-- ===== Final note ===== -->
<rect x="30" y="430" width="700" height="22" rx="4" fill="#fff1f2" stroke="#dc2626" stroke-width="1"/>
<text x="380" y="444" fill="#991b1b" font-size="9" font-weight="600" text-anchor="middle">Next: s17 combines tools, permissions, teams, worktrees, MCP, and more into one while True loop.</text>
</svg>

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@@ -0,0 +1,112 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 460" font-family="system-ui, -apple-system, sans-serif">
<defs>
<linearGradient id="header" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#1e3a5f"/><stop offset="100%" stop-color="#dc2626"/>
</linearGradient>
<marker id="arrow" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#555"/>
</marker>
<marker id="arrow-rose" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#dc2626"/>
</marker>
<marker id="arrow-rose-left" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M 10 0 L 0 5 L 10 10 z" fill="#dc2626"/>
</marker>
</defs>
<rect width="760" height="460" fill="#fafbfc" rx="8"/>
<!-- Title -->
<rect x="0" y="0" width="760" height="44" fill="url(#header)" rx="8"/>
<rect x="0" y="36" width="760" height="8" fill="url(#header)"/>
<text x="380" y="28" fill="#fff" font-size="14" font-weight="700" text-anchor="middle">MCP Plugin — 標準プロトコル + 外部ツール接続 + ツールプール組み立て</text>
<!-- Legend -->
<rect x="40" y="56" width="12" height="10" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="58" y="66" fill="#2563eb" font-size="10" font-weight="600">s15 保持</text>
<rect x="130" y="56" width="12" height="10" rx="2" fill="#fff1f2" stroke="#dc2626" stroke-width="1"/>
<text x="148" y="66" fill="#dc2626" font-size="10" font-weight="600">s16 新規</text>
<!-- ===== Row 1: Lead Loop ===== -->
<rect x="20" y="90" width="70" height="40" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="1.5"/>
<text x="55" y="114" fill="#4f46e5" font-size="8" font-weight="600" text-anchor="middle">turn</text>
<line x1="90" y1="110" x2="104" y2="110" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="107" y="90" width="70" height="40" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="142" y="114" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">messages</text>
<line x1="177" y1="110" x2="191" y2="110" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="194" y="86" width="80" height="48" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="234" y="114" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">prompt</text>
<line x1="274" y1="110" x2="288" y2="110" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="291" y="86" width="70" height="48" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="326" y="114" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">LLM</text>
<line x1="361" y1="110" x2="375" y2="110" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="378" y="76" width="356" height="72" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="556" y="94" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL DISPATCHLead 16 tools</text>
<text x="394" y="109" fill="#2563eb" font-size="7.5">bash · read · write · task(4) · send · inbox</text>
<text x="394" y="121" fill="#7c3aed" font-size="7.5" font-weight="700">request_shutdown · request_plan · review_plan</text>
<text x="394" y="133" fill="#b45309" font-size="7.5" font-weight="700">create_worktree · remove_worktree</text>
<text x="394" y="145" fill="#dc2626" font-size="7.5" font-weight="700">★ connect_mcp + 動的 mcp__server__tool ツール</text>
<!-- Loop back -->
<path d="M 734 110 L 748 110 L 748 150 L 55 150 L 55 130" fill="none" stroke="#94a3b8" stroke-width="1" marker-end="url(#arrow)" stroke-dasharray="5,4"/>
<!-- ===== Row 2: MCP Architecture ===== -->
<rect x="30" y="172" width="700" height="215" rx="8" fill="#fff1f2" stroke="#dc2626" stroke-width="2"/>
<text x="380" y="194" fill="#991b1b" font-size="11" font-weight="700" text-anchor="middle">MCP アーキテクチャs16 新規:標準プロトコル + 外部ツール動的統合)</text>
<!-- Agent Side -->
<rect x="50" y="210" width="255" height="140" rx="6" fill="#fff" stroke="#dc2626" stroke-width="1.5"/>
<text x="177" y="230" fill="#991b1b" font-size="10" font-weight="700" text-anchor="middle">Agent 側MCPClient</text>
<rect x="65" y="240" width="225" height="24" rx="4" fill="#fef2f2" stroke="#fca5a5" stroke-width="0.5"/>
<text x="177" y="256" fill="#475569" font-size="8" text-anchor="middle">connect_mcp → discover → ツール登録</text>
<rect x="65" y="272" width="225" height="24" rx="4" fill="#fef2f2" stroke="#fca5a5" stroke-width="0.5"/>
<text x="177" y="288" fill="#475569" font-size="8" text-anchor="middle">assemble_tool_pool builtin + mcp 組み立て</text>
<rect x="65" y="304" width="225" height="24" rx="4" fill="#fef2f2" stroke="#fca5a5" stroke-width="0.5"/>
<text x="177" y="320" fill="#475569" font-size="8" text-anchor="middle">call_tool("mcp__docs__search", ...)</text>
<!-- Communication arrows -->
<line x1="305" y1="262" x2="435" y2="262" stroke="#dc2626" stroke-width="1.5" marker-end="url(#arrow-rose)"/>
<text x="370" y="256" fill="#dc2626" font-size="7" font-weight="600" text-anchor="middle">tools/list</text>
<line x1="435" y1="296" x2="305" y2="296" stroke="#dc2626" stroke-width="1.5" marker-end="url(#arrow-rose)"/>
<text x="370" y="312" fill="#dc2626" font-size="7" font-weight="600" text-anchor="middle">tools/call + response</text>
<!-- MCP Servers -->
<rect x="438" y="210" width="275" height="140" rx="6" fill="#fff" stroke="#ca8a04" stroke-width="1.5"/>
<text x="575" y="230" fill="#854d0e" font-size="10" font-weight="700" text-anchor="middle">MCP Servers外部サービス</text>
<rect x="453" y="240" width="245" height="28" rx="4" fill="#fefce8" stroke="#facc15" stroke-width="0.5"/>
<text x="575" y="258" fill="#854d0e" font-size="9" font-weight="600" text-anchor="middle">docs server: search · get_version</text>
<rect x="453" y="276" width="245" height="28" rx="4" fill="#fefce8" stroke="#facc15" stroke-width="0.5"/>
<text x="575" y="294" fill="#854d0e" font-size="9" font-weight="600" text-anchor="middle">deploy server: trigger · status</text>
<rect x="453" y="312" width="245" height="28" rx="4" fill="#fefce8" stroke="#facc15" stroke-width="0.5"/>
<text x="575" y="330" fill="#854d0e" font-size="9" font-weight="600" text-anchor="middle">任意言語実装、stdio JSON-RPC のみ必要</text>
<!-- Naming convention -->
<rect x="50" y="360" width="660" height="20" rx="4" fill="#fef3c7" stroke="#d97706" stroke-width="1"/>
<text x="380" y="374" fill="#92400e" font-size="8" text-anchor="middle">ツール命名: mcp__{server}__{tool} → 例: mcp__docs__search · mcp__deploy__trigger · サーバー間の名前衝突を防止</text>
<!-- ===== Row 3: Bottom notes ===== -->
<rect x="30" y="400" width="700" height="22" rx="4" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="50" y="408" width="12" height="10" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="70" y="418" fill="#475569" font-size="10">s15: atomic claim + task worktree + protocols</text>
<rect x="420" y="408" width="12" height="10" rx="2" fill="#fff1f2" stroke="#dc2626" stroke-width="1"/>
<text x="440" y="418" fill="#475569" font-size="10">s16: MCP + dynamic toolsLead 16</text>
<!-- ===== Final note ===== -->
<rect x="30" y="430" width="700" height="22" rx="4" fill="#fff1f2" stroke="#dc2626" stroke-width="1"/>
<text x="380" y="444" fill="#991b1b" font-size="9" font-weight="600" text-anchor="middle">次の s17tools、permissions、teams、worktree、MCP などを 1 つの while True ループに統合。</text>
</svg>

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@@ -0,0 +1,112 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 460" font-family="system-ui, -apple-system, sans-serif">
<defs>
<linearGradient id="header" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#1e3a5f"/><stop offset="100%" stop-color="#dc2626"/>
</linearGradient>
<marker id="arrow" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#555"/>
</marker>
<marker id="arrow-rose" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#dc2626"/>
</marker>
<marker id="arrow-rose-left" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M 10 0 L 0 5 L 10 10 z" fill="#dc2626"/>
</marker>
</defs>
<rect width="760" height="460" fill="#fafbfc" rx="8"/>
<!-- Title -->
<rect x="0" y="0" width="760" height="44" fill="url(#header)" rx="8"/>
<rect x="0" y="36" width="760" height="8" fill="url(#header)"/>
<text x="380" y="28" fill="#fff" font-size="15" font-weight="700" text-anchor="middle">MCP Plugin — 标准协议 + 外部工具接入 + 工具池组装</text>
<!-- Legend -->
<rect x="40" y="56" width="12" height="10" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="58" y="66" fill="#2563eb" font-size="10" font-weight="600">s15 保留</text>
<rect x="140" y="56" width="12" height="10" rx="2" fill="#fff1f2" stroke="#dc2626" stroke-width="1"/>
<text x="158" y="66" fill="#dc2626" font-size="10" font-weight="600">s16 新增</text>
<!-- ===== Row 1: Lead Loop (s15 preserved) ===== -->
<rect x="20" y="90" width="70" height="40" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="1.5"/>
<text x="55" y="114" fill="#4f46e5" font-size="8" font-weight="600" text-anchor="middle">turn</text>
<line x1="90" y1="110" x2="104" y2="110" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="107" y="90" width="70" height="40" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="142" y="114" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">messages</text>
<line x1="177" y1="110" x2="191" y2="110" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="194" y="86" width="80" height="48" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="234" y="114" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">prompt</text>
<line x1="274" y1="110" x2="288" y2="110" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="291" y="86" width="70" height="48" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="326" y="114" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">LLM</text>
<line x1="361" y1="110" x2="375" y2="110" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<rect x="378" y="76" width="356" height="72" rx="8" fill="#f0f4ff" stroke="#2563eb" stroke-width="1.5"/>
<text x="556" y="94" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL DISPATCH (Lead 16 tools)</text>
<text x="394" y="109" fill="#2563eb" font-size="7.5">bash · read · write · task(4) · send · inbox</text>
<text x="394" y="121" fill="#7c3aed" font-size="7.5" font-weight="700">request_shutdown · request_plan · review_plan</text>
<text x="394" y="133" fill="#b45309" font-size="7.5" font-weight="700">create_worktree · remove_worktree</text>
<text x="394" y="145" fill="#dc2626" font-size="7.5" font-weight="700">★ connect_mcp + 动态 mcp__server__tool 工具</text>
<!-- Loop back -->
<path d="M 734 110 L 748 110 L 748 150 L 55 150 L 55 130" fill="none" stroke="#94a3b8" stroke-width="1" marker-end="url(#arrow)" stroke-dasharray="5,4"/>
<!-- ===== Row 2: MCP Architecture (s16 new) ===== -->
<rect x="30" y="172" width="700" height="215" rx="8" fill="#fff1f2" stroke="#dc2626" stroke-width="2"/>
<text x="380" y="194" fill="#991b1b" font-size="11" font-weight="700" text-anchor="middle">MCP 架构s16 新增:标准协议 + 外部工具动态接入)</text>
<!-- Agent Side -->
<rect x="50" y="210" width="255" height="140" rx="6" fill="#fff" stroke="#dc2626" stroke-width="1.5"/>
<text x="177" y="230" fill="#991b1b" font-size="10" font-weight="700" text-anchor="middle">Agent Side (MCPClient)</text>
<rect x="65" y="240" width="225" height="24" rx="4" fill="#fef2f2" stroke="#fca5a5" stroke-width="0.5"/>
<text x="177" y="256" fill="#475569" font-size="8" text-anchor="middle">connect_mcp → discover → 注册工具</text>
<rect x="65" y="272" width="225" height="24" rx="4" fill="#fef2f2" stroke="#fca5a5" stroke-width="0.5"/>
<text x="177" y="288" fill="#475569" font-size="8" text-anchor="middle">assemble_tool_pool 组装 builtin + mcp</text>
<rect x="65" y="304" width="225" height="24" rx="4" fill="#fef2f2" stroke="#fca5a5" stroke-width="0.5"/>
<text x="177" y="320" fill="#475569" font-size="8" text-anchor="middle">call_tool("mcp__docs__search", ...)</text>
<!-- Communication arrows -->
<line x1="305" y1="262" x2="435" y2="262" stroke="#dc2626" stroke-width="1.5" marker-end="url(#arrow-rose)"/>
<text x="370" y="256" fill="#dc2626" font-size="7" font-weight="600" text-anchor="middle">tools/list</text>
<line x1="435" y1="296" x2="305" y2="296" stroke="#dc2626" stroke-width="1.5" marker-end="url(#arrow-rose)"/>
<text x="370" y="312" fill="#dc2626" font-size="7" font-weight="600" text-anchor="middle">tools/call + response</text>
<!-- MCP Servers -->
<rect x="438" y="210" width="275" height="140" rx="6" fill="#fff" stroke="#ca8a04" stroke-width="1.5"/>
<text x="575" y="230" fill="#854d0e" font-size="10" font-weight="700" text-anchor="middle">MCP Servers (外部服务)</text>
<rect x="453" y="240" width="245" height="28" rx="4" fill="#fefce8" stroke="#facc15" stroke-width="0.5"/>
<text x="575" y="258" fill="#854d0e" font-size="9" font-weight="600" text-anchor="middle">docs server: search · get_version</text>
<rect x="453" y="276" width="245" height="28" rx="4" fill="#fefce8" stroke="#facc15" stroke-width="0.5"/>
<text x="575" y="294" fill="#854d0e" font-size="9" font-weight="600" text-anchor="middle">deploy server: trigger · status</text>
<rect x="453" y="312" width="245" height="28" rx="4" fill="#fefce8" stroke="#facc15" stroke-width="0.5"/>
<text x="575" y="330" fill="#854d0e" font-size="9" font-weight="600" text-anchor="middle">任意语言实现,只需 stdio JSON-RPC</text>
<!-- Naming convention -->
<rect x="50" y="360" width="660" height="20" rx="4" fill="#fef3c7" stroke="#d97706" stroke-width="1"/>
<text x="380" y="374" fill="#92400e" font-size="8" text-anchor="middle">工具命名: mcp__{server}__{tool} → 例: mcp__docs__search · mcp__deploy__trigger · 避免不同 server 的工具名冲突</text>
<!-- ===== Row 3: Bottom notes ===== -->
<rect x="30" y="400" width="700" height="22" rx="4" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<rect x="50" y="408" width="12" height="10" rx="2" fill="#f0f4ff" stroke="#2563eb" stroke-width="1"/>
<text x="70" y="418" fill="#475569" font-size="10">s15: 原子认领 + 任务 worktree + 协议</text>
<rect x="420" y="408" width="12" height="10" rx="2" fill="#fff1f2" stroke="#dc2626" stroke-width="1"/>
<text x="440" y="418" fill="#475569" font-size="10">s16: MCP + dynamic tools (Lead 16)</text>
<!-- ===== Final note ===== -->
<rect x="30" y="430" width="700" height="22" rx="4" fill="#fff1f2" stroke="#dc2626" stroke-width="1"/>
<text x="380" y="444" fill="#991b1b" font-size="9" font-weight="600" text-anchor="middle">下一章 s17把工具、权限、团队、worktree、MCP 等机制合回同一个 while True 循环。</text>
</svg>

After

Width:  |  Height:  |  Size: 7.7 KiB