# Lobster MCP 重构实施方案

## 背景

当前 Lobster 已经具备 MCP Server 配置、真实 discovery、工具缓存、ToolRegistry 注册、调用审计和后台治理入口。但现状仍偏向“发现到 MCP 工具后直接注册为 LLM tool”，在 API Center 这类大工具源接入后会带来三个问题：

1. 工具名不一定符合 LLM provider 规则，例如 OpenAI-compatible 要求 `^[a-zA-Z0-9_-]+$`。
2. 多个 MCP Server 的工具全量暴露会放大 `tools[]`，增加 token、延迟、误选和 400 风险。
3. discovery 刷新和工具列表变化会破坏 prompt cache 稳定性。

本方案目标是把 MCP 改造成“能力池 + 本地治理 + 运行时稳定暴露”的结构。第一阶段只落地 `DIRECT` 模式；`PROXY_ONLY` 作为后续代理模式预留，不在本阶段实现具体代理调用。

## 目标架构

```text
MCP / API Center discovery
  -> AI_MCP_TOOL_CACHE 能力池
  -> 治理字段：enabled / risk / confirm / exposureMode
  -> DIRECT 工具注册到 ToolRegistry
  -> AgentRuntime 按 run 选择稳定 tools[]
  -> ToolExecutorDispatcher 调用真实 MCP remoteToolName
```

### 暴露模式

- `DIRECT`：工具可作为独立 LLM tool 暴露。第一阶段默认模式。
- `PROXY_ONLY`：工具只进入能力池，不直接暴露给 LLM；后续通过 `apicenter_search_apis` / `apicenter_get_api_schema` / `apicenter_call_api` 等代理工具间接调用。
- `HIDDEN`：工具只保留缓存和审计信息，不暴露、不注册。

第一阶段要求：

- 新发现 MCP 工具默认 `DIRECT`。
- `DIRECT` 工具名必须 provider-safe。
- 非 `DIRECT` 工具不得进入 `ToolRegistry`，也不得进入 LLM `tools[]`。
- 存量旧工具名在刷新或注册缓存时自动规范化。

## 第一阶段实施项

### 1. 工具命名规范化

新增 MCP 命名映射组件：

- 输入：`serverId`、`namespace`、`remoteToolName`
- 输出：合法 `localToolName`
- 规则：只保留 `[a-zA-Z0-9_-]`，其它字符归一成 `_`，超长时截断并追加 hash。

示例：

```text
remote: apicenter.get_list
local:  apicenter_get_list
```

真实远端调用仍使用 `remoteToolName`，不改变 MCP/API Center 协议。

### 2. LLM tool name 兜底校验

在 `ToolRegistry.register` 和 `ToolRegistry.toToolSpecs` 增加 provider-safe name 保护：

- 注册非法工具名直接拒绝，防止新代码写入污染。
- 转 LLM `ToolSpec` 时再次过滤非法工具名，防止老内存态导致整轮 LLM 请求 400。

### 3. MCP 工具暴露模式字段

在 `McpToolCache` 增加：

```text
exposureMode: DIRECT | PROXY_ONLY | HIDDEN
```

默认值按代码兜底为 `DIRECT`，避免老数据空值造成行为变化。

### 4. DIRECT 注册策略

`McpToolBridge` 注册前判断：

- `enabled=false`：不注册。
- `exposureMode != DIRECT`：不注册，并从 runtime cache / ToolRegistry 清理。
- `DIRECT`：注册到 `ToolRegistry`，同步 `ToolDefinitionConfig` 治理行。

### 5. 后台治理 API

`AdminMcpToolApi.governance` 增加 `exposureMode` 参数：

- 修改为 `DIRECT`：若 enabled=true，重新注册工具。
- 修改为 `PROXY_ONLY` 或 `HIDDEN`：注销工具，保留缓存。
- 列表接口返回 `exposureMode`。

前端可以后续再补控件；接口先具备能力。

## 第二阶段：run 级工具快照

后续新增 `ToolExposurePlanner`：

- run 开始时生成可用工具快照。
- 同一个 run 内 tools 不随 5 分钟 discovery 刷新抖动。
- trace 中记录本 run 暴露了哪些工具及原因。
- 限制默认工具数量，例如软上限 20，硬上限 40。

这一步用于稳定 prompt cache 和模型行为。

## 第三阶段：PROXY_ONLY 代理模式

API Center 这类大规模 API 源默认改为 `PROXY_ONLY`，只暴露稳定代理工具：

- `apicenter_search_apis`
- `apicenter_get_api_schema`
- `apicenter_call_api`

代理工具负责：

- 搜索 API 能力池。
- 获取具体 API schema。
- 权限校验、确认、审计。
- 调用真实 MCP remote tool。

此时 API Center 有上百个 API，也不会让 LLM `tools[]` 膨胀。

## 验收标准

第一阶段：

- `tools[].function.name` 全部匹配 `^[a-zA-Z0-9_-]+$`。
- `apicenter.get_list` 不再作为 LLM tool name 出现，映射为 `apicenter_get_list`。
- 存量旧缓存刷新或注册后自动迁移本地名。
- `exposureMode=PROXY_ONLY/HIDDEN` 的 MCP 工具不进入 LLM tools。
- MCP 调用仍能通过 `remoteToolName` 调到真实远端工具。

后续阶段：

- API Center 100 个 API 时，默认 LLM tools 数量仍可控。
- 同一个 run 内 tools 快照稳定。
- trace 能查看工具暴露决策。
- prompt cache 不因 discovery 周期刷新频繁 miss。
