# Lobster 与 API Center MCP 集成长期方案

> 更新时间：2026-05-14

本文记录 Lobster 接入 `zm-api-center` MCP 能力的长期方案。结论保持不变：不要把 `zm-api-center` 简单搬进 Lobster，也不要在 Lobster 内重写 API 网关。目标部署形态是两个独立 Tomcat 服务、同一个数据库：API Center 继续作为管理与 HTTP 代理服务独立运行，Lobster 作为 Agent Runtime 独立运行。Lobster 与 API Center 的运行时接入统一使用 HTTP JSON-RPC MCP 协议，不再引入 API Center core 包做类调用，不使用 `direct://`，也不能让 API Center 反向依赖 Lobster runtime。

参考：

- MCP Streamable HTTP transport: https://modelcontextprotocol.io/specification/2025-11-25/basic/transports
- MCP tools: https://modelcontextprotocol.io/specification/2025-06-18/server/tools
- OpenAI Agents SDK MCP guide: https://openai.github.io/openai-agents-js/guides/mcp/

## 1. 相对旧方案的当前变化

旧方案把 Lobster 侧描述为“`McpToolBridge` 仍只注册 `{namespace}.ping` stub，需要新增真实 MCP client”。当前实现已经往前推进，不能再按旧起点理解。

### 1.1 已经完成或部分完成

1. Lobster 已有真实 MCP client 抽象：
   - `com.gzzm.lobster.tool.mcp.McpClient`
   - `HttpApiCenterMcpClient`
   - `direct://` 明确返回 unsupported；生产与 MVP 均只保留 HTTP client
   - `McpClientFactory`
   - `McpToolSpec`
   - `McpCallResult`
   - `McpCallOptions`

2. `McpToolBridge` 已从 stub 方向改为真实 discovery：
   - enabled server -> `McpClient.listTools`
   - 写入 `AI_MCP_TOOL_CACHE`
   - 注册 `namespace.remoteToolName`
   - executor 内部调用 `McpClient.callTool`
   - 写 `AI_MCP_CALL_LOG`

3. Lobster 已有 MCP 管理 API 雏形：
   - `/ai/api/admin/mcp-servers/list`
   - `/ai/api/admin/mcp-servers/{id}/test`
   - `/ai/api/admin/mcp-servers/{id}/discover`
   - `/ai/api/admin/mcp-tools/list`
   - `/ai/api/admin/mcp-tools/{toolKey}/enabled`
   - `/ai/api/admin/mcp-tools/{toolKey}/governance`

4. `AI_MCP_TOOL_CACHE` 已承载本地治理字段：
   - `orgId`
   - `riskLevel`
   - `requireConfirm`
   - `enabled`
   - `schemaHash`
   - `lastDiscoveredAt`
   - `lastErrorCode`
   - `lastErrorMessage`

5. api-center 已开始抽 facade 与 DTO，这些应在现有模块内沉淀为稳定的显式接口，供 api-center HTTP controller 与协议实现复用；Lobster 仍只走 HTTP MCP endpoint：
   - `com.gzzm.apicenter.mcp.api.ApiCenterMcpFacade`
   - `McpRuntimeContext`
   - `McpToolsListRequest`
   - `McpToolsListResult`
   - `McpToolDescriptor`
   - `McpToolCallResult`
   - `McpToolContent`
   - `McpServiceProbeResult`
   - `McpProtocolError`

6. HTTP client 已按 MCP Streamable HTTP 方向修正：
   - `Accept: application/json, text/event-stream`
   - `MCP-Protocol-Version`
   - HTTP 4xx/5xx 不再伪装为空 result
   - 非 JSON 响应不再返回空 Map
   - JSON-RPC `error` 与 HTTP/protocol error 分开处理

7. Lobster 管理台已经开始从“MCP Server”改为“MCP 接入治理”：
   - test/discover
   - 工具缓存展示
   - 本地启停
   - 本地 risk/requireConfirm
   - schemaHash、lastError、lastDiscoveredAt
   - API Center 控制台跳转入口

### 1.2 仍需调整的点

1. Lobster 运行时不依赖 API Center core/api jar，只通过 HTTP MCP 协议交互；HTTP 响应解析到 Lobster 自己的 `McpToolSpec` / `McpCallResult`。当前仓库已不再保留 `com.gzzm.apicenter.mcp.api` 复制源码。

2. `DirectApiCenterMcpClient` 不进入长期方案。当前仓库已移除 direct/core client，`direct://` endpoint 只会明确返回 unsupported，不会触发类调用或反射调用。

3. api-center 不拆新的 Maven 模块，但仍需要更清晰的包边界：
   - `com.gzzm.apicenter.mcp.api`: 纯接口、DTO、错误码
   - `runtime.protocol` / `application` / `domain`: 协议、service、entity/DAO
   - `interfaces` / controller: HTTP controller/WAR 入口

4. `AC_MCPSERVICE` / `AC_MCP_TOOL` 是否做组织字段需要定版。当前长期建议是：
   - api-center 做 consumer/token 隔离和网关日志。
   - Lobster 做 org 隔离、本地治理、Agent Runtime trace。
   - 如果 api-center 未来作为多组织平台暴露控制台，再给 `AC_MCPSERVICE` / `AC_MCP_TOOL` 加 `orgId`。

5. `BuiltinToolRegistrar.syncToGovernanceTable()` 与 MCP discovery 的治理同步边界需要统一：MCP 工具的本地人工治理字段只能在首次发现时给默认值，后续 discovery 不覆盖。

6. 管理台仍需继续收窄职责：Lobster 不做 api-center 的上游 tool editor，只做接入治理和工具缓存治理。

## 2. 长期目标架构

```text
Lobster Agent Runtime
  |
  |-- ToolRegistry
  |-- ToolExecutorDispatcher
  |-- ToolPolicy / pending confirm / Hooks / Audit / Trace
  |
  |-- McpClient
        |-- HttpApiCenterMcpClient
              -> JSON-RPC HTTP
              -> /{systemKey}/mcp-servers/{appId}
              -> future: /ac-mcp/{serverId}
              -> no direct://
              -> no api-center core jar dependency

zm-api-center
  |
  |-- com.gzzm.apicenter.mcp.api
  |     -> pure interfaces and DTOs in the existing WAR module
  |
  |-- runtime.protocol / application / domain
  |     -> McpService / McpTool
  |     -> DAO/service/protocol/facade
  |     -> permissions, rate limits, upstream HTTP proxy, access log
  |
  |-- interfaces / controller
        -> HTTP controllers and WAR packaging
```

固定包依赖方向：

```text
runtime.protocol/application/domain -> com.gzzm.apicenter.mcp.api
interfaces/controller -> runtime.protocol/application
```

禁止：

```text
api-center -> lobster runtime
lobster -> api-center-web/controller
lobster -> api-center entity/DAO/service/core runtime
direct:// pseudo transport
lobster 内重写 API gateway
```

允许：

```text
lobster -> API Center HTTP MCP endpoint
```

Lobster 不通过共享 core 包执行业务调用。这样即使两个 Tomcat 共用数据库，也能保持 API Center 的鉴权、限流、上游代理、访问日志逻辑都发生在 API Center 服务内，部署和版本也能独立演进。

## 3. 边界与职责

### 3.1 API Center 负责

1. MCP 服务发布：
   - `McpService`
   - `McpTool`
   - appId
   - schema
   - endpoint binding

2. 上游 API 代理：
   - HTTP method/path/template
   - request/response mapping
   - upstream timeout
   - payload size guard
   - output cleanup

3. consumer/token：
   - token 解析
   - MCP service 可见性
   - tool 权限
   - rate limit

4. 网关日志：
   - access log
   - requestId
   - upstream target/status/latency
   - mcpServiceId/mcpToolId/toolName

5. MCP protocol facade：
   - `tools/list`
   - `tools/call`
   - `testService`
   - future: `discoverService`

### 3.2 Lobster 负责

1. Agent 接入：
   - `McpServerConfig`
   - endpoint
   - transport type
   - auth token / custom headers
   - connect/read timeout

2. discovery 缓存：
   - `AI_MCP_TOOL_CACHE`
   - localToolName
   - remoteToolName
   - schemaHash
   - lastDiscoveredAt
   - lastErrorCode/lastErrorMessage

3. 工具暴露：
   - `ToolRegistry.register(namespace.remoteToolName)`
   - 不暴露 disabled server/tool
   - 不绕过 `ToolExecutorDispatcher`

4. 本地治理：
   - `enabled`
   - `riskLevel`
   - `requireConfirm`
   - permission mode
   - org isolation

5. Agent Runtime 记录：
   - `ToolExecutionRecord`
   - `AI_MCP_CALL_LOG`
   - runId/threadId/toolCallId/requestId
   - confirm/pending/denied/cancelled trace

## 4. 协议与字段要求

### 4.1 HTTP transport

HTTP client 支持 Streamable HTTP 风格的 JSON-RPC POST。当前 api-center 入口可以继续兼容：

```text
POST /{systemKey}/mcp-servers/{appId}
```

Lobster HTTP client 必须发送：

```text
Content-Type: application/json; charset=UTF-8
Accept: application/json, text/event-stream
MCP-Protocol-Version: 2025-11-25
X-Request-Id: <requestId>
```

MVP 可以先只处理 `Content-Type: application/json` 的单 JSON 响应。若服务端返回 `text/event-stream`，第一版可以明确报 unsupported，不要吞成空工具。

后续新增更标准的内部入口：

```text
POST /ac-mcp/{serverId}
```

`serverId -> systemKey + appId` 由 api-center 配置解析。该入口用于降低 Lobster 管理复杂度，不替代现有兼容路径。

### 4.1.1 不使用 core/direct client

两个 Tomcat、同数据库部署时，仍然使用 `HttpApiCenterMcpClient` 调 API Center HTTP MCP endpoint。同数据库只用于数据关联和日志对齐，不作为跨服务类调用的理由。

约束：

```text
no Class.forName
no Method.invoke
no direct:// endpoint
no api-center core jar runtime dependency
no api-center-web/controller dependency
no api-center -> lobster dependency
```

如果未来出现“同 JVM/同 WAR 嵌入部署”的独立产品形态，可以重新评估 core client，但它不属于当前长期方案和 MVP 范围。

### 4.2 tools/list 字段

api-center 返回的 tool descriptor 应包含：

```text
name
title
description
inputSchema
outputSchema
annotations
schemaHash
```

Lobster 只把远端字段作为 discovery 输入。远端 `annotations` 只能作为展示和默认建议，不能覆盖 Lobster 本地人工治理。

### 4.3 tools/call 字段

api-center 返回的 call result 应包含：

```text
content[]
structuredContent
isError
annotations
mimeType
```

错误语义分层：

```text
HTTP/protocol error
  -> Lobster 报 mcp.http_error / mcp.invalid_response / mcp.remote_error
  -> 不注册为 0 工具成功

tool execution error
  -> JSON-RPC result.isError=true
  -> 转为 ToolResult.errorData
```

## 5. 数据模型长期方案

本轮按新模型直接更新，不保留旧字段兼容。已存在环境需要在部署前重建或迁移 `AI_MCP_CALL_LOG` / `AI_MCP_TOOL_CACHE`，旧的 inline `requestJson` / `responseJson` 字段不再使用。

### 5.1 Lobster

`AI_MCP_SERVER_CONFIG`：

```text
serverId
displayName
transportType
endpoint
authToken
headersJson
connectTimeoutMs
readTimeoutMs
namespace
defaultRisk
enabled
orgId
createTime
updateTime
```

`AI_MCP_TOOL_CACHE`：

```text
toolKey
serverId
namespace
orgId
remoteToolName
localToolName
displayName
description
inputSchemaJson
outputSchemaJson
annotationsJson
riskLevel
requireConfirm
enabled
schemaHash
lastDiscoveredAt
lastCallAt
lastErrorCode
lastErrorMessage
createTime
updateTime
```

`AI_MCP_CALL_LOG`：

```text
callId
serverId
localToolName
remoteToolName
threadId
runId
toolCallId
requestId
userId
orgId
status
durationMs
requestSummary
responseSummary
requestJsonRef
responseJsonRef
errorCode
errorMessage
createTime
```

MCP 调用的请求/响应明细一律写入 ContentStore，`AI_MCP_CALL_LOG` 只保存摘要、状态、索引字段和 `requestJsonRef/responseJsonRef`。上下文、trace 列表和管理台列表只展示有效信息摘要；完整参数和结果按需通过 ref 读取。MCP call log 明细用于排查真实链路，按原始请求和返回写入，不在 `McpToolBridge` 内脱敏。

写入规则：

```text
requestJsonRef
  -> 完整 MCP 调用请求快照：serverId/localToolName/remoteToolName/requestId/threadId/runId/toolCallId/userId/orgId/arguments
  -> endpoint 和 arguments 原样写入

responseJsonRef
  -> 完整 MCP 返回快照：isError/message/content/structuredContent/annotations
  -> 异常时写 exceptionClass/errorMessage
```

`requestSummary` / `responseSummary` 只保留排查所需摘要，例如参数 key、content 条数、是否有 structuredContent、错误码、耗时。若 ContentStore 写入失败，不影响工具执行主链路；`AI_MCP_CALL_LOG` 记录 `mcp.log_ref_failed`，管理台能据此提示“摘要可用，明细缺失”。读取 ref 的接口必须走 admin 权限校验，不把完整请求/响应塞进 LLM 上下文。

### 5.2 API Center

`AC_MCPSERVICE` / `AC_MCP_TOOL` 应补齐 MCP 协议字段：

```text
enabled
title
outputSchema
annotationsJson
schemaHash
riskLevel
requireConfirm
lastDiscoveredAt
lastCallAt
lastErrorCode
lastErrorMessage
version
```

`orgId` 暂不作为 MVP 强制项。若 api-center 后续作为多组织平台开放控制台，再把 `orgId` 加到 `AC_MCPSERVICE` / `AC_MCP_TOOL`，并调整 query、unique key 和权限过滤。

## 6. 实施阶段

### Phase A: api-center 包边界收敛

目标：在不拆 Maven 模块的前提下，让 HTTP controller 与协议/facade 复用同一套包内实现，不把 servlet/controller 泄漏到协议核心，也不使用反射式 direct。

1. 在现有 `zm-api-center` 模块内保留 `com.gzzm.apicenter.mcp.api` 包：
   - `ApiCenterMcpFacade`
   - `McpRuntimeContext`
   - `McpToolsListRequest`
   - `McpToolsListResult`
   - `McpToolDescriptor`
   - `McpToolCallResult`
   - `McpToolContent`
   - `McpServiceProbeResult`
   - `McpProtocolError`

2. 禁止 API 包依赖：
   - `HttpServletRequest`
   - `ObjectMapper`
   - `OkHttp`
   - `GeneralDao`
   - entity annotation
   - api-center entity
   - Lobster runtime class

3. `McpServerProtocolController` 只做 HTTP 组装：
   - servlet request -> `McpRuntimeContext`
   - JSON-RPC body -> facade request
   - facade result -> JSON-RPC response

4. 修正工具更新语义：
   - `tools == null`: 不更新工具
   - `tools == []`: 显式清空工具
   - 删除旧工具前先复制 `toDelete`
   - 不保存仍包含旧工具的 `entity.getTools()`

### Phase B: Lobster MCP client

目标：Lobster 通过统一 `McpClient` 接入，不绕过 Agent Runtime。

1. `HttpApiCenterMcpClient`：
   - JSON-RPC `tools/list`
   - JSON-RPC `tools/call`
   - pagination cursor
   - timeout
   - custom headers
   - token
   - protocol/HTTP/tool error 分层

2. `McpClientFactory`：
   - 只返回 `HttpApiCenterMcpClient`
   - `transportType=null` 或 `STREAMABLE_HTTP` -> HTTP
   - `SSE/STDIO` -> 明确 unsupported
   - endpoint 以 `direct://` 开头 -> 明确 unsupported，不再切到 direct client

### Phase C: discovery 缓存与治理

目标：工具目录可刷新，本地治理不被远端覆盖。

1. `McpToolBridge`：
   - enabled server -> `listTools`
   - upsert `AI_MCP_TOOL_CACHE`
   - register enabled tool
   - missing remote tool -> unregister + mark `not_discovered`

2. 新工具首次发现：
   - 写默认 `riskLevel`
   - 写默认 `requireConfirm`
   - `enabled=true`

3. 已存在工具再次 discovery：
   - 只更新 `displayName/description/inputSchema/outputSchema/annotations/schemaHash/lastDiscoveredAt/lastError`
   - 不覆盖 `enabled/riskLevel/requireConfirm`

4. 管理 API：
   - test
   - discover
   - list cached tools
   - enable/disable tool
   - update risk/requireConfirm

### Phase D: 执行闭环

目标：模型看到的是 Lobster 本地工具；执行统一进入 `ToolExecutorDispatcher`。

1. 注册工具：

```text
ToolRegistry.register(namespace.remoteToolName)
```

2. 执行链路：

```text
model tool call
  -> ToolExecutorDispatcher
  -> ToolPermissionChecker
  -> pending confirm / ToolPolicy
  -> MCP executor
  -> McpClient.callTool
  -> ToolResult.ok/errorData
  -> ToolExecutionRecord
  -> AI_MCP_CALL_LOG
  -> api-center access log
```

3. 关闭 server/tool 后：
   - 不再暴露给模型
   - 执行前校验也必须挡住历史重放

4. request id 对齐：
   - Lobster 生成或传递 `requestId`
   - HTTP client 通过 `X-MCP-Lobster-*` headers 传递 `toolCallId/runId/threadId`
   - api-center access log 与 Lobster trace 可关联

### Phase E: 安全与诊断

目标：达到长期可运维状态。

1. 安全：
   - Origin 校验
   - token scope
   - request/response size limit
   - response sanitization
   - secret redaction
   - admin-only destructive tools

2. 稳定性：
   - connect/read timeout
   - discovery timeout
   - per-call timeout
   - retry policy
   - partial failure handling

3. 诊断：
   - Trace 字段：`exposedTools`、`filteredTools`、`toolPolicyDecision`、`mcpCalls`
   - Run event：`mcp_discovery`、`mcp_call`
   - MCP Tools tab：最近调用状态 `lastCallAt`
   - filtered reason
   - schemaHash drift
   - lastError

当前 MCP 闭环内先补齐 trace/run event/lastCallAt。`PermissionMode`、`READ_ONLY` mode 下写工具过滤、`ASK_WRITE -> pending confirm` 强制路径后移到 Tool Policy 阶段，不作为本轮 MCP 文档验收前置。

本轮的 `toolPolicyDecision` 只记录 MCP 本地治理决策快照，例如 server/tool 是否启用、riskLevel、requireConfirm、过滤原因、执行前拒绝原因；不要求实现完整 org-level `PermissionMode`。

Trace 里只放轻量摘要，避免大字段污染页面和上下文：

```text
exposedTools
  -> toolName/category/serverId/schemaHash/riskLevel/requireConfirm

filteredTools
  -> toolName/category/serverId/reason

toolPolicyDecision
  -> toolName/allowed/reason/source(enabled server, enabled cache, governance row)

mcpCalls
  -> callId/serverId/localToolName/remoteToolName/requestId/threadId/runId/toolCallId/status/durationMs/requestSummary/responseSummary/requestJsonRef/responseJsonRef
```

管理台查看完整流程时，先看 trace 摘要定位 LLM 调用了哪个本地工具，再用 `callId` 打开 MCP call log，按 `requestJsonRef/responseJsonRef` 读取完整请求和返回，最后用同一个 `requestId/runId/toolCallId` 对齐 API Center access log。

后台排查接口：

```text
GET/POST /ai/api/admin/mcp-calls/list
GET/POST /ai/api/admin/mcp-calls/{callId}
GET/POST /ai/api/admin/mcp-calls/{callId}/payload
```

`/ai/api/admin/calls/{callId}/trace` 返回中也应挂载同一 `runId` 下的 `mcpCalls` 摘要，便于从 LLM trace 跳到 MCP 请求/响应明细。

## 7. MVP 范围

本节按 `plan-big-lobster-agent-capability-roadmap-2026-05-13.md` 的 MCP Phase 1 slice 收口：MVP 只承诺 `STREAMABLE_HTTP` 的 `listTools` 和 `callTool`。完整 roadmap MVP 中的 org-level `PermissionMode`、`READ_ONLY` mode、`ASK_WRITE` pending confirm 属于 Tool Policy 阶段，不并入本轮 MCP 交付。

先只做：

```text
STREAMABLE_HTTP / 当前 JSON-RPC HTTP
tools/list
tools/call
HttpApiCenterMcpClient
discovery cache
enabled/risk/requireConfirm
Lobster 管理台 test/discover/tool list/governance
Trace exposedTools/filteredTools/toolPolicyDecision/mcpCalls
Run event mcp_discovery/mcp_call
MCP Tools tab lastCallAt
```

暂缓：

```text
STDIO
SSE 长连接
复杂 MCP session lifecycle
OAuth 动态授权
notifications/tools/list_changed
resumability/redelivery
多 endpoint 自动重连
Core/direct client
```

## 8. 验收标准

1. 在 api-center 配一个 MCP service 和 tool。
2. Lobster 管理台点 discover 后能看到真实工具，不出现 `namespace.ping` stub。
3. 模型可调用 `namespace.toolName`。
4. 执行记录进入 `ToolExecutionRecord`。
5. MCP 调用日志进入 `AI_MCP_CALL_LOG`。
6. api-center access log 与 Lobster trace 可通过 `requestId/runId/toolCallId` 对上。
7. 关闭 Lobster 本地工具后，模型不再看到该工具，历史 tool call 重放执行前也会被挡住。
8. 关闭 MCP server 后，该 server 下所有工具不再暴露。
9. Trace 能看到 `exposedTools`、`filteredTools`、`toolPolicyDecision`、`mcpCalls`。
10. Run event 能记录 `mcp_discovery` 和 `mcp_call`。
11. MCP Tools tab 能展示最近调用状态 `lastCallAt`。
12. HTTP 404/500/HTML/非 JSON 响应时，管理台显示明确错误，不显示 0 工具成功。
13. `direct://` endpoint 不会触发 direct/core client，管理台显示明确 unsupported。

## 9. 与 roadmap MCP 需求的对齐结论

对照 `big-lobster-doc/prd/plan-big-lobster-agent-capability-roadmap-2026-05-13.md`，当前方案满足 MCP Phase 1 主线，但不等同于完整 roadmap MVP；完整 roadmap MVP 还包含 Tool Policy、Hooks、子 Agent、Automation 等后续阶段。

已满足 roadmap Phase 1 / MVP：

```text
enabled MCP server -> discovery
remote tool -> BuiltinToolDefinition
tool call -> ToolExecutorDispatcher
STREAMABLE_HTTP first
SSE/STDIO explicit unsupported
AI_MCP_TOOL_CACHE
AI_MCP_CALL_LOG
test/discover/list/toggle APIs
MCP 管理台基础列表和开关
schemaHash
execution 前再次校验，防历史重放绕过
```

当前方案强于 roadmap 的部分：

```text
outputSchema
requireConfirm
orgId in AI_MCP_TOOL_CACHE
lastCallAt
API Center package boundary cleanup
API Center console jump
HTTP protocol error hardening
requestJsonRef/responseJsonRef ContentStore ref
```

其中 API Center 包边界收敛是长期增强，不应阻塞 MCP Phase 1 slice；不再要求拆出新的 Maven 模块。MCP 验收仍以 `STREAMABLE_HTTP` 路径为准。

本轮 MCP 方案确认补齐：

```text
Trace 的 exposedTools / filteredTools / toolPolicyDecision / mcpCalls
Run event 的 mcp_discovery / mcp_call
MCP Tools tab 的最近调用状态 lastCallAt
requestJsonRef / responseJsonRef 已定版为一律 ContentStore ref，需要补写入和按需读取接口，明细不脱敏
```

本轮暂不处理，后移到 Tool Policy / Hooks 阶段：

```text
PermissionMode / ToolPolicyResolver 的 org-level 数据模型
READ_ONLY mode 下写工具不暴露且不能执行
ASK_WRITE -> pending confirm 强制路径
```

## 10. 当前实现后的下一步优先级

1. 补前端管理台的最近调用、最近错误、schemaHash drift 展示。
2. 继续收窄 api-center 包边界，在现有 WAR 模块内保持清晰的 `mcp.api` / `runtime.protocol` / controller 分层。
3. 后续 Tool Policy 阶段再补 `PermissionMode`、READ_ONLY 模式下写工具过滤、ASK_WRITE -> pending confirm 强制路径。
4. 保持 `McpClientFactory` HTTP-only；`direct://` 只允许明确 unsupported，不能恢复 direct/core client。
