MCP 配置与策略由 Node 控制面管理,React 设置页提供 connector、凭据绑定、项目工具覆盖和健康状态入口。Worker 使用官方 MCP SDK 执行连接和工具调用。当前运行架构见架构说明。
connector 定义、启用策略、include/exclude、确认策略和凭据引用由控制面投影为工作区的 mcp-runtime.json。快照保存引用;环境变量和 managed credential 在所属 Worker 内按 connector 解析,不把整个 Worker 凭据环境传给 stdio 子进程。
stdio 使用普通工具环境白名单及 connector 自身绑定。受信任的内置网络工具可使用专门的代理/CA 配置。HTTP/SSE 使用受控 fetch、绑定 header 和 endpoint 网络策略。
allowedTools 未指定时,初始化所有配置的 connector。显式空列表或仅包含非 MCP 工具时跳过 discovery。
允许 mcp__foo__bar 时,在解析 env/header 凭据前选出匹配 connector;只连接该范围内的服务。初始化和 listTools 属于 connector 协议操作,因此会读取该服务的工具目录;只有完整工具名在能力列表中且通过 managed include/exclude 策略的工具才会注册到 Harness。其他 connector 不解析凭据、不启动进程、不连接网络。
Worker 工具能力不会覆盖控制面禁止的工具,也不会跳过现有用户确认策略。能力限制同时作用于工具发现和模型可见工具集。
AgentMcpTools 拥有每个 Worker 的 SDK clients,支持 stdio、Streamable HTTP、SSE 和 Unix socket。发现阶段共享有界期限;初始化、工具目录或凭据错误记录为 connector diagnostics。Worker 关闭会清理已打开 clients。
工具请求使用 connector 的请求期限和 operation 取消信号。需要确认的工具通过 InteractionBridge 请求浏览器授权;拒绝不会发起实际工具调用。用户交互等待不计入 operation 无进展期限。
回归覆盖 SDK 连接与工具调用、stdio 环境隔离、HTTP 网络策略、确认拒绝、发现预算、能力范围、凭据解析和关闭。只允许一个工具的真实 stdio fixture 同时配置其他 stdio/HTTP connector,验证它们不被启动或解析凭据。
测试不能替代全部真实第三方 connector、OAuth 服务和传输组合的端到端验收。新增 connector 应结合自身认证和网络要求验证。
以下保留早期管理子系统的设计细节,包含当时的 adapter、配置格式和 API 示例,供追溯设计用途;不代表当前运行架构或可直接执行的接口。当前实现以前文和源码为准。
状态:Draft for implementation
适用基线:编写时的代码基线,Node 控制面 + React 设置页 + 旧会话运行时 +
pi-mcp-adapter@2.18.0目标:将现有“读取 MCP JSON 并显示开关”的功能改造成由 Pi-Science 控制面统一管理配置、全局启用策略、项目级工具覆盖、认证引用、运行时投影、健康状态和工具授权的 MCP Connector 子系统。
本改造不重写 MCP 协议运行时。pi-mcp-adapter 继续负责 MCP 连接、懒加载、工具发现、资源暴露、输出保护和实际工具调用;OAuth 在第一阶段仍由 adapter 承担,最终由 Pi-Science 控制面提供设置页授权与 token 生命周期管理。Pi-Science Node 控制面成为 MCP 配置与策略的唯一权威,并向每个 旧会话运行时 runtime 投影一份隔离、无明文密钥的有效配置。
改造后的职责边界如下:
flowchart LR
UI[设置页 / Connectors] --> API[Node MCP API]
API --> SVC[McpConnectorService]
SVC --> DB[(state.sqlite)]
SVC --> CRED[CredentialStore]
SVC --> PROBE[MCP Probe]
SVC --> PROJ[McpRuntimeProjection]
PROJ --> SNAP[隔离配置快照]
SNAP --> WRAP[Pi-Science MCP Extension]
WRAP --> ADAPTER[pi-mcp-adapter]
ADAPTER --> STDIO[stdio / socket MCP]
ADAPTER --> HTTP[Streamable HTTP / SSE MCP]
核心决策:
- Connector、启用状态和默认工具权限均为用户级全局配置;所有工作区使用同一集合。
- 配置、启用、认证、运行状态和工具权限分别建模。
- 项目运行时只接受控制面生成的 programmatic MCP 配置,不再让 adapter 隐式合并环境中的多个 MCP 文件。
- 现有
.mcp.json、.pi/mcp.json和用户级配置只作为兼容导入源,不再作为最终运行时权威。 - 第一阶段继续使用
pi-mcp-adapter的单一mcpproxy tool,避免大量 MCP tool schema 占用上下文;默认不开启directTools。 - 与 Claude Science 一致,不把 Project/Workspace 作为 MCP 设置作用域;待 Specialist Agent 获得稳定数据库身份后扩展 agent assignment。
apps/server/src/catalog/mcp-config.ts 按以下优先级寻找第一个可解析文件:
config.json中的mcp_config_path<workspace>/.mcp.json<workspace>/.pi/mcp.json~/.config/mcp/mcp.json<PI_SCIENCE_HOME>/mcp.json
找到一个文件后即停止,不进行多层合并。解析失败会被当作“继续寻找下一个文件”,最终可能静默返回空配置。
frontend/src/components/settings/MCPTab.tsx 当前支持:
- 显示 MCP server 列表;
- 显示静态 transport、auth、data egress 和工具数量;
- 全局启用/停用;
- 展示静态健康检查结果。
不支持:
- 添加、编辑、删除 MCP;
- Remote 与 local command 分流;
- 项目级绑定;
- OAuth/credential 管理;
- 真实 MCP handshake 和
tools/list; - 工具级 Allow/Ask/Deny;
- 连接、重连、断开;
- 配置导入预览和冲突处理。
运行时通过 pi-mcp-adapter@2.18.0 加载 MCP。该 adapter 自己合并以下配置:
~/.config/mcp/mcp.json~/.agents/mcp.json~/.agents/mcp/mcp.json<Pi agent dir>/mcp.json.mcp.json.pi/mcp.json
adapter 还自行维护:
- lazy/eager/keep-alive 生命周期;
- OAuth 和 OS credential store;
- metadata cache;
- MCP 状态事件;
- proxy/direct tool;
- per-server
disabled、includeTools、excludeTools、approveTools; - MCP Apps、resources、prompts、sampling 和 elicitation。
Node 控制面只读取第一个配置文件,adapter 会合并六层配置。设置页看到的 Connector 集合不一定等于 Agent 实际可调用的集合。
PUT /api/settings/mcp/:server_id 只更新 <PI_SCIENCE_HOME>/config.json 的 mcp_servers 数组;adapter 不读取这个字段,而是读取 MCP definition 中的 disabled 或 .pi/mcp.json override。因此 UI 可能显示 disabled,但 Agent 仍可调用该 MCP。
当前 probeMcpHealth 只检查:
- stdio command 是否在 PATH;
- URL 是否可解析且通过出站 URL 校验;
required_env是否存在。
它不会连接 MCP、执行 initialize 或列出工具,无法区分 needs-auth、协议不兼容、握手失败和工具发现失败。
缺失文件与 malformed JSON 都被同一 catch 忽略。用户无法判断“没有配置”和“配置损坏”。
设置页、用户手工 JSON、adapter 的 /mcp enable|disable 命令都可能表达不同状态,缺少冲突和审计模型。
- 设置页可以添加 Remote URL、Local command 和 Unix socket MCP。
- Connector 配置和启用状态在用户级全局注册;项目只提供工具权限覆盖。
- Node 控制面成为规范状态与公开 API 的唯一写入者。
- runtime 使用控制面生成的隔离配置,UI 状态与实际运行配置一致。
- 支持真实 connect/probe、工具发现、错误分类和工具缓存。
- 支持全局工具默认、项目级 Allow/Ask/Deny 覆盖,以及全局 Allow all 策略。
- 密钥不写入 Connector 表、runtime 配置快照、日志或浏览器响应。
- 支持现有 MCP 文件的预览、显式导入、冲突检测和渐进迁移。
- 配置变化能够安全刷新当前 workspace 的 runtime;繁忙 runtime 延迟重启,不中断当前 turn。
- 保留
pi-mcp-adapter的上下文节省、输出保护、MCP Apps 和协议兼容能力。
- 不接入 Claude Connectors Directory;这是 claude.ai 专有数据源。后续如需市场能力,应定义 Pi-Science 自有 registry/provider 接口。
- 不在本期实现 Organization/Admin 下发。
- 不在本期实现 per-Agent attachment,也不实现项目级 Connector 启用状态。项目级工具覆盖对该项目内所有会话和 subagent 生效。
- 不自行实现 MCP transport、sampling、elicitation、Apps renderer 或 output guard。
- 不允许浏览器直接连接 MCP server。
- 不支持在 UI 中保存任意明文 Authorization header;认证必须使用 Credential 引用、环境变量引用、OAuth 或受控 helper。
- 不自动导入其他工具的配置,不自动执行导入配置里的 command。
保留 Settings 一级导航中的 MCP 标签,但将页面从表格改成 master-detail Connector 管理页。
桌面布局:
┌──────────────────────────────────────────────────────────────┐
│ Search connectors… [All ▾] [Add connector ▾]│
├──────────────────────────────────────────────────────────────┤
│ Project enabled │
│ ● paper-search Ready [on] │
│ ● local-memory Connected [on] │
│ │
│ Available │
│ ○ context7 Not connected [off] │
│ │
│ Imported / compatibility │
│ ! legacy-github Import required │
└──────────────────────────────────────────────────────────────┘
过滤器:
- All
- Enabled in this project
- Connected/Ready
- Needs authentication
- Local
- Remote
- Imported
Add 菜单:
- Remote URL
- Local command
- Unix socket
- Import existing config
Remote 基础字段:
- Name/ID
- Display name
- URL
Remote 高级字段:
- Auth:Auto / None / OAuth / Bearer credential / Custom headers
- OAuth Client ID、scope、redirect URI(需要时)
- Transport:Auto/Streamable HTTP/SSE legacy
- Lifecycle:Lazy(默认)/Eager/Keep alive/Lazy keep alive
- Timeout、idle timeout
- Include tools、exclude tools
- Expose resources
- Description、terms URL、privacy URL
Local command 基础字段:
- Name/ID
- Display name
- Command line
Local 高级字段:
- Environment bindings
- Working directory
- Lifecycle、timeout、idle timeout
- Include/exclude tools
- Description
命令行在前端解析为 command + args,并显示解析预览。服务端重新校验,绝不能把整条字符串交给 shell。
详情页分为:
- Overview:source、transport、endpoint/command 摘要、全局启用状态。
- Connection:Configured/Checking/Ready/Needs auth/Error/Disabled。
- Tools:工具名、描述、只读提示、Allow/Ask/Deny。
- Default agent access:全局启用开关、include/exclude、Allow all。
- Security:credential 来源、data egress、terms/privacy、最近 probe 时间。
- Actions:Probe、Reconnect、Edit、Disconnect credential、Remove。
“Disable”“Disconnect”“Remove”必须是三个动作:
- Disable:全局关闭 Connector,不再投影到任何工作区。
- Disconnect:删除/撤销认证,不删除配置。
- Remove:删除全局 Connector;内置 Connector 不可删除。
UI 不再用单个 health 字符串表达所有状态:
type McpConfigState = "valid" | "invalid";
type McpAuthState = "not-required" | "configured" | "needs-auth" | "expired" | "error";
type McpRuntimeState = "unknown" | "checking" | "ready" | "connecting" | "connected" | "error" | "disabled";显示优先级:invalid > disabled > needs-auth > error > connecting/checking > connected/ready > unknown。
Connector 是全局、单用户资源:
type McpConnectorSource = "builtin" | "custom" | "imported";
type McpTransport = "stdio" | "streamable_http" | "sse" | "socket";
interface McpConnector {
connector_id: string;
name: string; // URL-safe stable id
display_name: string;
description: string;
source: McpConnectorSource;
transport: McpTransport;
endpoint_url: string | null;
command: string | null;
args: string[];
socket_path: string | null;
runtime_config: McpRuntimeConfig;
credential_ref: string | null;
revision: number;
created_at: number;
updated_at: number;
}runtime_config 只保存非敏感字段,例如 cwd、lifecycle、timeout、headers 的环境/credential 引用、OAuth metadata、include/exclude 和资源开关。
interface McpConnectorSettings {
connector_id: string;
enabled: boolean;
include_tools: string[];
exclude_tools: string[];
approval_mode: "ask" | "custom" | "allow_all";
revision: number;
created_at: number;
updated_at: number;
}全局设置是 runtime effective config 的入口。启用后自动进入所有工作区的派生快照;Workspace 不是 MCP 权限边界。
interface McpToolGrant {
connector_id: string;
tool_name: string;
decision: "allow" | "ask" | "deny";
updated_at: number;
}
interface McpProjectToolGrant extends McpToolGrant {
project_id: string;
}McpToolGrant 是全局默认,McpProjectToolGrant 是当前 workspace 所属项目的覆盖。项目覆盖可以改变全局 allow/ask,但全局 deny 是不可提升的安全边界。allow_all 是 connector settings 级显式状态,不使用工具名 * 冒充普通 grant。
interface McpToolCacheEntry {
connector_id: string;
config_revision: number;
tools: McpToolSummary[];
resources: McpResourceSummary[];
server_info: Record<string, unknown> | null;
fetched_at: number;
expires_at: number;
}缓存 key 必须包含会影响服务器身份的配置 fingerprint,至少包括 transport、URL origin/path、command/args/socket 和认证类型,但不能包含密钥值。
0002_mcp_connectors.sql 建立初始结构;0003_global_mcp_settings.sql 将项目绑定迁移为全局设置并记录冲突;0004_project_mcp_tool_grants.sql 建立独立的项目级工具覆盖表。三个 migration 均注册到 apps/server/src/storage/sqlite/migrations.ts。
建议 schema:
CREATE TABLE mcp_connectors (
connector_id TEXT PRIMARY KEY,
name TEXT NOT NULL UNIQUE COLLATE NOCASE,
display_name TEXT NOT NULL,
description TEXT NOT NULL DEFAULT '',
source TEXT NOT NULL CHECK (source IN ('builtin', 'custom', 'imported')),
transport TEXT NOT NULL CHECK (transport IN ('stdio', 'streamable_http', 'sse', 'socket')),
endpoint_url TEXT,
command TEXT,
args_json TEXT NOT NULL DEFAULT '[]' CHECK (json_valid(args_json)),
socket_path TEXT,
runtime_config_json TEXT NOT NULL DEFAULT '{}' CHECK (json_valid(runtime_config_json)),
credential_ref TEXT,
enabled INTEGER NOT NULL DEFAULT 0 CHECK (enabled IN (0, 1)),
include_tools_json TEXT NOT NULL DEFAULT '[]' CHECK (json_valid(include_tools_json)),
exclude_tools_json TEXT NOT NULL DEFAULT '[]' CHECK (json_valid(exclude_tools_json)),
approval_mode TEXT NOT NULL DEFAULT 'ask' CHECK (approval_mode IN ('ask', 'custom', 'allow_all')),
settings_revision INTEGER NOT NULL DEFAULT 1,
revision INTEGER NOT NULL DEFAULT 1,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
CHECK (
(transport = 'stdio' AND command IS NOT NULL AND endpoint_url IS NULL AND socket_path IS NULL) OR
(transport IN ('streamable_http', 'sse') AND endpoint_url IS NOT NULL AND command IS NULL AND socket_path IS NULL) OR
(transport = 'socket' AND socket_path IS NOT NULL AND endpoint_url IS NULL AND command IS NULL)
)
) STRICT;
CREATE TABLE mcp_global_tool_grants (
connector_id TEXT NOT NULL,
tool_name TEXT NOT NULL,
decision TEXT NOT NULL CHECK (decision IN ('allow', 'ask', 'deny')),
updated_at INTEGER NOT NULL,
PRIMARY KEY (connector_id, tool_name),
FOREIGN KEY (connector_id) REFERENCES mcp_connectors(connector_id) ON DELETE CASCADE
) STRICT;
CREATE TABLE mcp_project_tool_grants (
project_id TEXT NOT NULL,
connector_id TEXT NOT NULL,
tool_name TEXT NOT NULL,
decision TEXT NOT NULL CHECK (decision IN ('allow', 'ask', 'deny')),
updated_at INTEGER NOT NULL,
PRIMARY KEY (project_id, connector_id, tool_name),
FOREIGN KEY (project_id) REFERENCES projects(project_id) ON DELETE CASCADE,
FOREIGN KEY (connector_id) REFERENCES mcp_connectors(connector_id) ON DELETE CASCADE
) STRICT;
CREATE TABLE mcp_tool_cache (
connector_id TEXT PRIMARY KEY,
config_revision INTEGER NOT NULL,
fingerprint TEXT NOT NULL,
tools_json TEXT NOT NULL CHECK (json_valid(tools_json)),
resources_json TEXT NOT NULL DEFAULT '[]' CHECK (json_valid(resources_json)),
server_info_json TEXT CHECK (server_info_json IS NULL OR json_valid(server_info_json)),
fetched_at INTEGER NOT NULL,
expires_at INTEGER NOT NULL,
FOREIGN KEY (connector_id) REFERENCES mcp_connectors(connector_id) ON DELETE CASCADE
) STRICT;credential_ref 暂不建立 SQLite FK,因为当前 CredentialStore 使用独立的原子 JSON 存储。Service 层必须在写入、删除和 runtime projection 时验证引用。
新增目录:
apps/server/src/mcp/
├── connector-types.ts
├── connector-repository.ts
├── connector-service.ts
├── connector-validation.ts
├── legacy-config-import.ts
├── mcp-probe-service.ts
├── mcp-runtime-projection.ts
├── mcp-status-registry.ts # 第二阶段
└── mcp-oauth-service.ts # 第二阶段
只负责 SQLite CRUD 和事务性约束:
createConnectorupdateConnector(expectedRevision)deleteConnectorlistConnectorsgetConnectorgetGlobalSettingssetGlobalToolGrant/clearGlobalToolGrantsetProjectToolGrant/clearProjectToolGrantlistMigrationConflictsreplaceToolCache
所有 update 使用 revision 乐观锁。冲突返回 409 revision_conflict,避免两个设置页相互覆盖。
负责:
- workspace → stable project_id 解析(仅用于项目级工具覆盖);
- DTO 校验和错误分类;
- credential_ref 验证;
- 全局 Connector/settings 与项目级 tool grant 协调;
- import preview/commit;
- runtime projection invalidation;
- 配置变化后的 runtime reload;
- 删除前引用检查;
- 审计事件。
必须注入到 ServerModules,不能在 route 内自行 new repository/service。
名称约束:
- 1–64 字符;
^[a-z0-9][a-z0-9-]*[a-z0-9]$,单字符允许;- 大小写不敏感唯一;
- 禁止控制字符和路径分隔符。
Remote URL:
- 必须是绝对
http(s)URL; - 禁止 URL 内嵌用户名/密码;
- 创建时调用现有
validateConnectorOutboundUrl; - 私网访问单独使用
allow_private_mcp,不要复用模型 provider 的allow_private_providers; - HTTP 默认不允许私网,用户必须在 Connector 安全区显式开启;
- redirect 每一跳重新验证,敏感 header 不跨 origin。
stdio:
command与args分开;- 禁止通过
shell: true启动; - command 不以
-开头; - cwd 必须是 workspace 内路径,或者为空并使用 workspace root;
- 环境变量 key 必须匹配
^[A-Za-z_][A-Za-z0-9_]*$; - secret 使用 credential/environment 引用,不允许写入 runtime_config_json。
socket:
- 路径必须是绝对路径或
~路径; - 保存前规范化;
- 默认要求 socket 位于当前用户拥有的目录;
- UI 明确提示 socket 连接可能共享工具状态和文件权限。
共享 DTO 和 Zod schema 新增到 packages/contracts/src/mcp.ts,由 packages/contracts/src/index.ts 导出。前端不得再在 settings-types.ts 手写另一份 McpServer。
| 方法 | 路径 | 说明 |
|---|---|---|
GET |
/api/mcp/connectors |
全局 Connector + settings/status |
POST |
/api/mcp/connectors |
创建 Connector,可选同时全局启用 |
GET |
/api/mcp/connectors/:id |
详情、全局设置和工具缓存 |
PATCH |
/api/mcp/connectors/:id |
更新配置,要求 revision |
DELETE |
/api/mcp/connectors/:id |
删除自定义 Connector;内置返回 403 |
PUT |
/api/mcp/connectors/:id/settings |
全局启停和默认工具策略 |
POST |
/api/mcp/connectors/:id/probe |
有界真实握手 + tools/list |
GET |
/api/mcp/connectors/:id/tools[?cwd=] |
工具缓存和 effective 权限;带 cwd 时返回项目覆盖 |
PUT |
/api/mcp/connectors/:id/tools/:tool[?cwd=] |
无 cwd 写全局默认,带 cwd 写项目覆盖 |
DELETE |
/api/mcp/connectors/:id/tools/:tool[?cwd=] |
清除对应作用域的 grant,恢复继承 |
POST |
/api/mcp/connectors/:id/disconnect |
删除/撤销认证 |
写 API 使用 JSON body,不使用 ?enabled=true 表达 mutation。
全局 settings 请求示例:
{
"enabled": true,
"include_tools": ["search_*"],
"exclude_tools": ["delete_*"],
"approval_mode": "custom",
"revision": 3
}列表响应示例:
{
"connectors": [
{
"connector_id": "mcp_01...",
"name": "paper-search",
"display_name": "Paper Search",
"source": "custom",
"transport": "stdio",
"settings": { "enabled": true, "approval_mode": "ask", "revision": 2 },
"config_state": "valid",
"auth_state": "not-required",
"runtime_state": "ready",
"tool_count": 8,
"error": null
}
]
}| 方法 | 路径 | 说明 |
|---|---|---|
POST |
/api/mcp/import/preview?cwd= |
扫描受支持配置,返回来源、冲突、敏感字段提示 |
POST |
/api/mcp/import/commit?cwd= |
只导入用户明确选中的项目 |
preview 不能启动 command、连接远端或执行 !command secret helper。
| 方法 | 路径 | 说明 |
|---|---|---|
POST |
/api/mcp/connectors/:id/oauth/start |
discovery + PKCE,返回 authorize_url |
GET |
/api/mcp/oauth/callback |
校验 state/issuer,交换 token |
GET |
/api/mcp/connectors/:id/oauth/status |
仅返回 metadata |
DELETE |
/api/mcp/connectors/:id/oauth |
删除 token,尽力调用 revoke |
浏览器响应中不得返回 access token、refresh token、client secret 或 headers helper 输出。
/api/mcp/catalog:第一阶段改为调用新 Service,返回旧 DTO 投影并标注 deprecated。/api/settings/mcp:改为新 Service 的 compatibility projection。PUT /api/settings/mcp/:server_id:内部转换成全局 connector settings mutation,不再要求cwd。- 两个版本后删除旧 route 和前端调用。
Probe 分两级:
preflight:当前probeMcpHealth的安全校验,不启动服务器。connect:使用 MCP SDK 执行 initialize、tools/list、可选resources/list,然后关闭临时连接。
设置页的 Probe 按钮执行 connect probe。列表自动刷新只读取 cache,不自动启动本地 command 或触发 OAuth。
- connect timeout:15 秒;
- tools/resources 总分页最多 50 页;
- metadata 总大小最多 2 MiB;
- stderr 最多保留 16 KiB,并做 secret redaction;
- probe 子进程在成功、失败、超时和客户端断开时都必须 terminate;
- 不执行任何 tool;
- 不跟随跨 origin credential redirect;
- 每个 connector 同时只允许一个 probe;
- 全局并发默认 4。
错误必须分类为稳定 code:
invalid_config
command_not_found
spawn_failed
timeout
network_blocked
tls_error
protocol_error
auth_required
auth_expired
tool_list_failed
server_closed
unknown
禁止前端依赖自由文本匹配。
pi-mcp-adapter 已发布 pi-mcp-adapter/status/v1 snapshot。Pi-Science wrapper extension 订阅该事件,只转发以下非敏感字段:
- runtime/session identity;
- connector name;
- connected/cached/failed/needs-auth/not-connected/disabled;
- tool/resource count;
- failure age。
Node McpStatusRegistry 以内存 TTL 保存,不写 SQLite。runtime 停止或 90 秒未更新后回落为 unknown。不得转发 URL、headers、client、tool input schema 或 credential。
如果继续让默认 pi-mcp-adapter 扫描 .mcp.json 等文件:
- 设置页无法证明运行时实际使用了哪个 definition;
- 全局启用状态无法成为强约束;
- import 后会产生重复或同名覆盖;
- UI disable 仍可能被另一个配置层覆盖;
- 运行时可能执行用户未在 Pi-Science 中启用的 MCP command。
因此生产运行时必须使用 adapter 的 programmatic config 模式。该模式是完整隔离快照,不读取或写入 ambient MCP 文件。
新增:
apps/server/src/runtime/pi/extensions/pi-science-mcp.ts
职责:
- 从当前 workspace 的
.pi-science/mcp-runtime.json读取控制面生成的快照; - 校验 version、project_id 和 schema;
- 调用
createMcpAdapter({ config }); - 订阅 adapter status event;
- 不暴露 adapter 的
/mcp setup和文件写入路径作为规范配置入口。
概念代码:
import { createMcpAdapter } from "pi-mcp-adapter";
import { readFileSync } from "node:fs";
const snapshot = parseSnapshot(readFileSync(join(workspace, ".pi-science/mcp-runtime.json"), "utf8"));
export default createMcpAdapter({ config: { mcpServers: snapshot.mcpServers } });实际实现必须避免模块加载时跨 runtime 共享 snapshot:若 旧会话运行时 extension 模块会被 Host 缓存,应在 extension factory 初始化时按当前 runtime env 读取,并添加多 runtime characterization test。
McpRuntimeProjection 输入:
- workspace project_id(写入快照标识,并用于出站审计归属);
- globally enabled connectors;
- connector revisions;
- global tool grants 和当前项目的 tool grant overrides;
- credential runtime values;
- application MCP defaults。
输出:
interface McpRuntimeSnapshot {
version: 1;
project_id: string;
generated_at: number;
mcpServers: Record<string, McpServer>;
}推荐 adapter settings:
{
"toolPrefix": "server",
"directTools": false,
"scriptMode": true,
"hostConfigDiscovery": "off",
"outputGuard": true,
"showStatusIcon": false,
"mcpFooterStatus": "off",
"authRequiredMessage": "Connector ${server} requires authentication. Open Settings → MCP."
}每个 Connector 的全局设置和项目工具覆盖投影规则:
enabled=false:不写入 snapshot;- include/exclude:写入 adapter
includeTools/excludeTools; approval_mode=ask/custom:approveTools: true;approval_mode=allow_all:approveTools: false,如果存在显式 Ask 覆盖则只对这些精确工具名启用审批;- 显式 Deny 工具合并进入
excludeTools;显式 Allow 工具写入精确的__piScienceAllowedTools,项目覆盖优先于全局 allow/ask,但不能提升全局 Deny; - lifecycle 默认 lazy;
directTools默认 false,只有产品明确允许的 Connector 才能开启。
快照禁止包含 secret。认证值通过不可预测的 runtime 环境变量或当前 runtime 专属的 0600 secret file 注入。
建议沿用模型资源投影思路:
PI_RUNTIME_MCP_CREDENTIAL_<random> = <secret>
adapter definition 只包含:
{
"headers": {
"Authorization": "Bearer ${PI_RUNTIME_MCP_CREDENTIAL_X7Q2}"
}
}变量名随机生成,不使用 connector name,避免可预测枚举。runtime descriptor、API 和日志只能出现变量名,不能出现值。
OAuth refresh 需要长会话更新时,改用 runtime 专属 credential helper/file;helper 只能读取本 runtime 被分配的 credential,不能接受任意 credential id。
Connector、全局 settings 或项目 tool grant mutation 成功后:
- 提交 SQLite/credential 更新;
- 失效 projection cache;
- 调用
nodeSessionService.reloadConfiguration(); - 空闲 runtime 立即重建;
- busy runtime 设置
restartPending,当前 turn 结束后重建; - 重建失败时保留数据库新状态,但 API 返回
runtime_reload_failed和受影响 session;UI 显示“Saved, runtime reload pending/failed”; - 不因 reload 失败回滚已完成的 OAuth 或 Connector 数据库写入。
本期不实现 adapter 内部 hot reload,以避免动态工具注册、prompt cache 和并发调用的竞态。
扩展 credential metadata:
owner_kind?: "provider" | "mcp";
owner_id?: string;旧 owner_provider_id 保留兼容读取,迁移后新写入使用通用 owner 字段。Connector API 只能引用 owner_kind=mcp 且 owner_id 匹配自身,或用户显式选择的共享 credential。
Credential 种类至少支持:
- bearer token;
- API key/header value;
- OAuth token bundle;
- environment variable reference;
- external/keyring reference。
- Authorization Code + PKCE;
- state 单次使用、10 分钟过期,并绑定 connector_id、user/session、redirect URI;
- pin MCP resource URL 和 authorization server URL;授权中途发生变化则拒绝回调;
- 校验 issuer;
- 动态客户端注册可选;无 registration endpoint 时要求用户填写 client ID;
- access/refresh/client secret 只进入 CredentialStore;
- URL origin 或 OAuth server 修改时自动失效旧 grant;
- refresh 使用单飞锁;
invalid_grant转为 needs-auth;短暂网络失败不得删除 refresh token;- callback 页面只显示成功/失败,不输出 code、token、state;
- 日志统一 redaction。
若 OAuth Service 未在首个 PR 实现:
- 可以导入
auth: oauthdefinition; - Settings 显示“需要在会话中完成认证”;
- runtime 继续由 adapter 使用 OS keyring 执行 OAuth;
- UI 不伪装成已连接;
- 第二阶段接管 OAuth 前,不迁移或删除 adapter keyring credential。
复用并扩展 adapter 的标准路径概念,但只做读取和 preview:
- 当前 workspace
.mcp.json - 当前 workspace
.pi/mcp.json ~/.config/mcp/mcp.json~/.agents/mcp.json~/.agents/mcp/mcp.json- 当前
mcp_config_path
不自动扫描 Cursor、Claude、Codex 等 host-specific 配置;用户从 Import 页面显式选择后才扫描。
每项返回:
- source path 和 precedence;
- server name;
- transport;
- 是否包含疑似明文 secret;
- 是否包含
!command; - 是否与现有 Connector 同名;
- 是否引用 workspace 外 cwd/socket;
- 是否支持无损导入;
- normalized diff。
明文 headers/token/env secret 不能直接复制到 connector runtime_config。commit 时创建 Credential 或要求改为 environment reference。
阶段 A:新页面同时展示 canonical Connector 和 legacy import banner,runtime 仍使用旧 adapter 文件发现。
阶段 B:canonical runtime projection 默认开启;已导入项目只使用 snapshot。未导入项目继续旧路径,并显示 compatibility mode。
阶段 C:新项目只使用 canonical mode;旧路径需要显式 PI_SCIENCE_LEGACY_MCP_CONFIG=1。
阶段 D:删除旧 resolveMcpConfig 生产调用和 mcp_servers 设置字段,保留独立 CLI import 工具。
每个阶段必须记录 live caller 和移除条件,符合仓库兼容代码规则。
建议目录:
frontend/src/lib/mcp/
├── mcp-api.ts
├── mcp-queries.ts
├── mcp-mutations.ts
└── mcp-view-model.ts
frontend/src/components/settings/mcp/
├── McpConnectorsPage.tsx
├── McpConnectorRow.tsx
├── McpConnectorDetail.tsx
├── McpConnectorForm.tsx
├── McpToolsPanel.tsx
├── McpImportDialog.tsx
└── McpStatusBadge.tsx
实现要求:
- 使用 TanStack Query,不再用组件本地 state 手工模拟 catalog cache;
- mutation 使用 optimistic update,但 revision conflict 必须回滚并重新获取;
- query key 必须包含 canonical cwd/project identity;
- URL/command/credential 字段不写 localStorage;
- Add/Edit 有 unsaved guard;
- 删除、断开、Allow all 使用确认对话框;
- 列表错误、空状态、partial status、reload pending 分开展示;
- 移动端使用列表 → 详情导航,不压缩成五列表格;
- 视觉仅使用
docs/ui/deepseek-harness-reference.md中的 token;新增视觉值先登记; - i18n 同时补齐英文和简体中文。
添加 local command 时必须展示:该程序以当前用户身份运行,并可访问项目文件和继承的非敏感 runtime 环境。
添加 remote Connector 时必须展示:调用可能向目标服务发送 prompt、文件内容、序列、结构或其他项目数据。
扩展现有 egress-audit.jsonl:
note:
| "mcp_probe"
| "mcp_connect"
| "mcp_oauth_discovery"
| "mcp_oauth_token"
| "mcp_tool_call"只记录 connector id、origin、时间、project id、操作类型和 approved;不记录 path/query、请求体、tool args/result 或 secret。
Remote HTTP/SSE 的握手、SSE 消息和工具请求都经过控制面出站 guard,并记录 metadata-only audit;stdio/socket 程序自行发起的网络请求仍无法由 transport wrapper 拦截,必须标明 runtime call audit unavailable。
- 所有错误经过
redactMcpError; - redaction 覆盖 URL userinfo、Authorization、Bearer、API key、env secret、OAuth code/state;
- stdout/stderr 不直接返回前端;
- config import preview 不回显 secret,只显示
configured: true; - headers helper 的输出从不落盘、不展示;
- tool schema 视为不可信输入,限制深度、节点数和字节数。
- Connector update:revision optimistic lock。
- Global settings 使用独立的 settings revision;项目 tool grant 是按
(project_id, connector_id, tool_name)幂等 upsert,不伪造 Connector revision。 - Probe:按 connector serialized,全局 semaphore=4。
- OAuth refresh:按 credential single-flight。
- Runtime projection:按 workspace/project 生成原子快照;全局变更 fan-out 到所有已知 workspace,项目 tool grant 只更新所属 workspace。
- Import commit:SQLite batch;Credential 创建失败时回滚 Connector 创建,已创建 secret 必须补偿删除。
- Remove:Connector、project tool grant、global tool grant 和 tool cache 由 FK cascade;删除项目时 project tool grant 由 FK cascade 清理。
- runtime reload 失败不回滚规范配置,返回 partial success。
- SQLite disabled 模式下 MCP 写 API 返回
503 canonical_state_unavailable;不要新建第二套文件写实现。
- Connector create/update/settings/tool grant/project override schema;
- secret 字段不出现在 public DTO;
- invalid union 和 transport exclusivity;
- stable error code。
- migrations 0002–0004;
- CRUD、cascade、revision conflict;
- project tool grant deletion cascade;
- legacy scope conflict records and fail-closed defaults;
- connector deletion引用冲突;
- cache revision/fingerprint。
- workspace containment 和 stable project identity;
- remote SSRF、redirect、userinfo;
- stdio 不经过 shell;
- malformed command/env;
- private MCP opt-in;
- import preview 不执行 command/helper;
- raw secret 不进入 DB/API/log;
- legacy route projection;
- busy runtime 变更进入 restartPending;
- reload partial failure。
提供测试 MCP fixtures:
- 正常 stdio;
- 正常 Streamable HTTP;
- SSE legacy;
- auth required;
- initialize error;
- tools pagination;
- oversized schema;
- hanging server;
- 子进程退出;
- stderr 包含 secret;
- redirect 到 private address。
- 只包含全局 enabled connectors,并合并当前项目的 tool grant overrides;
- ambient
.mcp.json不会进入 programmatic config; - include/exclude/approval 映射正确;
- snapshot 不含 credential value;
- 多个 旧会话运行时 runtime 不共享错误项目的 snapshot;
- runtime restart 后 adapter tool catalog 与 API effective config 一致。
- 列表、搜索、过滤、空态和错误态;
- Remote/Local/Socket 表单;
- Advanced 渐进披露;
- optimistic global settings toggle 回滚;
- project override and inherit/reset;
- revision conflict;
- Probe/Connect/Disconnect/Remove;
- per-tool permission;
- keyboard、focus trap、screen reader label;
- mobile navigation;
- 中英文文案。
每个里程碑至少运行:
pnpm typecheck
pnpm --filter @pi-science/contracts test
pnpm --filter @pi-science/server test
pnpm --filter frontend test
pnpm build设置页视觉变更还需按仓库规则由视觉验证阶段独占运行 visual/accessibility 套件。
交付:
- 固化 Node resolver 与 adapter resolver 当前差异的测试;
- 证明
mcp_servers不影响 adapter 的回归测试; - 临时修正旧 toggle:写
.pi/mcp.jsondisabled override,或明确禁用该 UI,避免继续产生错误安全感; - 增加 malformed config diagnostics。
完成标准:设置页开关与当前 runtime 行为至少一致。
交付:
- migrations 0002–0004;
- repository/service/contracts/routes;
- Connector list/add/edit/remove;
- global connector settings;
- legacy import preview/commit;
- preflight health;
- 旧 API compatibility projection。
完成标准:用户可在 UI 创建 Remote/Local/Socket Connector,并全局启停;规范状态落 SQLite。
交付:
pi-science-mcp.tswrapper;- programmatic config;
- secret projection;
- runtime reload;
- ambient config 隔离;
- effective config diagnostics。
完成标准:Agent 可调用的 Connector 集合严格等于全局 enabled connectors;工具调用权限再叠加当前项目的 tool grant overrides。
交付:
- MCP connect probe;
- tool/resource cache;
- 工具详情;
- Allow/Ask/Deny/Allow all;
- global default 与 project override/inherit;
- adapter policy projection;
- 有界子进程和 HTTP 测试 fixtures。
完成标准:设置页可真实发现工具,权限变更在 runtime restart 后生效。
交付:
- OAuth start/callback/refresh/disconnect;
- CredentialStore owner 泛化;
- URL/AS pinning;
- adapter status bridge;
- runtime status registry;
- metadata-only egress/call audit。
完成标准:用户可以在设置页完成 OAuth,连接状态与 adapter runtime 状态一致。
交付:
- 新项目默认 canonical mode;
- 删除生产环境
resolveMcpConfig调用; - 删除
SettingsData.mcp_servers和mcp_config_path写入; - 删除旧
MCPTab/McpRow; - 保留独立 import CLI 和有期限的 legacy feature flag;
- 更新中英文 architecture 文档。
完成标准:只有 MCP Service 和 Runtime Projection 可以改变 Agent 的 MCP 可用集合。
packages/contracts/src/mcp.ts new
packages/contracts/src/index.ts export
apps/server/src/storage/sqlite/migrations/0002_mcp_connectors.sql new
apps/server/src/storage/sqlite/migrations/0003_global_mcp_settings.sql update
apps/server/src/storage/sqlite/migrations/0004_project_mcp_tool_grants.sql new
apps/server/src/storage/sqlite/migrations.ts update
apps/server/src/storage/sqlite/repositories/mcp-repository.ts new
apps/server/src/mcp/* new
apps/server/src/http/routes/mcp-routes.ts new
apps/server/src/http/runtime-boundaries.ts update
apps/server/src/app/server-modules.ts inject service
apps/server/src/app/app.ts register routes
apps/server/src/model-resources/credential-store.ts owner generalization
apps/server/src/runtime/pi/pi-runtime-launch.ts add wrapper/projection
apps/server/src/runtime/pi/extensions/pi-science-mcp.ts new
apps/server/src/security/mcp-health.ts split preflight/connect
apps/server/src/security/egress-audit.ts event types
frontend/src/lib/mcp/* new
frontend/src/components/settings/mcp/* new
frontend/src/components/settings/MCPTab.tsx replace/remove
frontend/src/components/settings/McpRow.tsx remove after migration
frontend/src/i18n/locales/en.json update
frontend/src/i18n/locales/zh-Hans.json update
docs/architecture.md update at M2/M5
docs/architecture.zh-CN.md update at M2/M5
- 设置页列出的有效 Connector 集合与新建 runtime 实际加载集合完全一致。
- 全局关闭 Connector 后,新 turn 无法再调用;繁忙 turn 不被强制中断。
- 新建 Remote、Local command、Socket Connector 均可通过 UI 完成。
- Remote URL 经过 SSRF/redirect 校验;local command 不经 shell。
- Connector 全局关闭时,所有工作区 Agent 均不可访问。
- Probe 能区分 ready、auth required、protocol error、timeout 和 command not found。
- Tools 页面展示真实
tools/list结果,并能配置 Allow/Ask/Deny。 - Credential 不出现在 SQLite Connector 表、API、runtime snapshot、日志和 egress audit。
- 修改 MCP URL 或 OAuth server 会使旧 grant 失效。
- legacy 配置导入前有 preview,导入不会自动执行 command/helper 或复制明文 secret。
- ambient
.mcp.json无法绕过全局启用状态注入 runtime。 - 多 workspace、多 session 使用同一全局配置,运行快照不会过期或分叉。
- 内置 Connector 删除返回明确 403;自定义 Connector 删除后从全部工作区快照移除。
- 旧 API 在迁移期有明确兼容投影和删除条件。
- typecheck、unit、integration、build、视觉和 accessibility 验证通过。
本轮按 Claude Science 的作用域和出站策略实现以下决定:
- Connector 注册、启用状态和默认工具权限是用户级全局配置;不实现项目级 Connector enablement。
- 工具权限可以按项目覆盖全局 allow/ask;全局 deny 是不可提升的安全边界;清除项目 grant 后恢复继承。
- Remote HTTP/SSE 默认拒绝私网;每次实际请求、OAuth discovery、动态注册和 token/refresh 请求都经过同一出站 guard。
- Local command 的 cwd 必须位于 workspace 内,命令不经 shell;本轮不引入 stdio 子进程的 OS sandbox,第三方 stdio/socket 程序自行发起的网络访问仍不受 transport wrapper 控制。
- 当前设置页支持 API Key、Bearer、Header 和环境变量引用;OAuth PKCE、callback 与 refresh 生命周期仍是后续独立阶段,不在 UI 中伪装成可用能力。
- 旧 project binding 迁移遇到分歧时记录 conflict,并将受影响的连接器禁用或重置为 Ask,交由用户显式复核。
custom和ask投影approveTools: true,显式 allow(包括项目覆盖)才写入__piScienceAllowedTools;allow_all只对显式 Ask 工具启用精确审批。未缓存的新工具不会因为缓存缺失而获得额外授权,通配符不会扩展 grant。- 凭证送达通道已于 2026-09-07 实现。设置页可将密钥保存在独立的 mode-0600
CredentialStore,或只保存来源环境变量名;可投递到 stdio 环境变量、HTTP Header 或带Bearer前缀的 Authorization Header。SQLite 与 workspace runtime 快照只保存 credential reference,Pi 扩展在进程内解析实际值。literal env/header 仍被拒绝,缺失引用会明确报错并阻止连接器运行。 - 探针和适配器 stdio 子进程只继承基本系统变量、审计目录和显式绑定。托管绑定按原值传递,不执行适配器的
!command或${VAR}二次解释。 - HTTP/SSE 的真实请求经过共同的出站策略及审计,包括握手、SSE 消息发送、工具请求以及 OAuth discovery/dynamic registration/token/refresh。默认拒绝私网,并在实际建连 DNS lookup 再次检查地址;显式
allow_private保留本地服务支持。拒绝重定向和跨源请求以防凭证外泄,因此跨源 OAuth 服务目前不能使用,需配置同源认证或环境变量 Authorization。 - 内置 paper-search 的 HTTP 请求也接入同一策略。任意第三方 stdio/socket 程序仍属于受信任的本地代码;本轮明确不做其 OS sandbox,故其自行发起的网络访问不能由 MCP transport 包装器拦截。
scripts/patch-mcp-adapter.mjs在 fetch-pi 安装后应用可重复的适配器补丁;遇到未知源代码布局报错。运行时检查 transport、project-audit、OAuth 和 tool-approval 补丁标记,缺失时拒绝加载。适配器入口由启动器按选定 CLI 的安装目录解析并通过绝对路径传递,移除扩展中的六层相对路径依赖。- 无 UI 时 ask 继续拒绝调用;无人值守任务应逐项授权,不自动降级为 allow_all。测试覆盖真实适配器的无 UI 拒绝和 UI select 审批分支;尚未执行真实浏览器端到端审批验收。
- SQLite 关闭时,旧设置接口第一次 toggle 以全部已配置服务作为默认启用集合。
验证包含 API/快照、全局/项目 grant 覆盖与迁移冲突、无缓存工具授权、真实 stdio 握手及环境隔离、真实适配器 HTTP/OAuth 拦截、重定向/跨源拦截和连接阶段 DNS rebinding 回归测试;stdio OS sandbox 留待后续变更。
该实现采用 Claude Science 的“连接器定义与凭据分离”方案:Connector 详情页负责选择凭据来源与投递方式,密钥本身不进入连接器 JSON、SQLite、浏览器响应或 workspace 快照。
managed:密钥只写入 Pi-Science 用户级credentials.json(0600),API 后续只返回状态和 metadata,不回传 secret。environment:只记录环境变量名,运行时从 Pi-Science 进程环境读取值。environmentdelivery:将值注入 stdio MCP 子进程的指定环境变量。headerdelivery:将值注入指定 HTTP Header。bearerdelivery:固定注入Authorization: Bearer <token>。- 内置连接器提供目标名称建议,例如 OpenAlex 的
OPENALEX_API_KEY、NCBI 的NCBI_API_KEY和 openFDA 的OPENFDA_API_KEY;这些凭据均为可选,是否必需由上游服务决定。 - 凭据带有
owner_kind=mcp/owner_id=<connector_id>,只能通过所属 Connector 的认证 API 管理;删除自定义 Connector 时同步清理其自有凭据。 - 更新认证绑定不会清空工具发现缓存;内置 Connector 目录升级也会保留用户绑定。
本阶段不实现 OAuth 授权码 + PKCE、callback、refresh token 单飞刷新或 OS keychain。这些能力应按 11.2 的完整安全要求一次性实现,不能把静态 Bearer Token 表单标记为 OAuth。
内置连接器支持独立的 enabled_by_default 种子策略:该值只在首次创建时生效,后续升级不会覆盖用户已经保存的启停选择。paper-search 保持默认开启;新增科学数据连接器默认关闭,以避免一次性把大量工具加入所有会话。
首批连接器使用官方公开 API 独立实现,不依赖 Claude 托管 MCP 端点,也不复制来源不明的第三方 MCP 实现:
| Connector | 数据源 | 首批工具数 |
|---|---|---|
literature-graph |
OpenAlex | 3 |
clinical-trials |
ClinicalTrials.gov | 2 |
structures-interactions |
RCSB PDB、AlphaFold DB | 3 |
genes-ontologies |
MyGene.info、EBI OLS、Reactome | 3 |
genomes |
Ensembl REST、VEP | 3 |
cellguide |
CELLxGENE CellGuide | 2 |
所有 15 个工具均为只读、默认 Ask、严格 JSON Schema(拒绝未知字段),经共享出站安全策略访问固定的公开 origin,并返回来源、检索时间、有效请求参数和结构化记录。网络请求使用超时、有限重试和响应大小上限;CellGuide 的版本化元数据在 server 进程内缓存一小时。受限授权资源(包括 KEGG、CADD、PanglaoDB 和 Sanger Cell Model Passports)不在本批范围内。
第二批继续按领域默认关闭,增加 20 个只读工具:
| Connector | 数据源 | 工具数 |
|---|---|---|
protein-annotation |
InterPro、STRING v12 | 3 |
omics-archives |
NCBI GEO、PRIDE Archive、MGnify | 3 |
chemistry |
PubChem、ChEBI | 3 |
regulation |
ENCODE、JASPAR | 3 |
biomart |
Ensembl BioMart | 2 |
drug-regulatory |
openFDA Labels、Drugs@FDA | 3 |
human-genetics |
NHGRI-EBI GWAS Catalog | 3 |
STRING 使用固定 v12 服务并遵守一秒请求间隔。BioMart 使用不会发生版本归档重定向的 Ensembl 官方 Asia mirror;ENCODE 详情通过同源搜索精确定位 accession,不放宽全局的重定向阻断。openFDA 不暴露原始查询语法,只允许受控字段并转义用户输入。GWAS Catalog 搜索使用 v2 API;详情读取使用相同 Catalog 的稳定记录端点,以规避 v2 详情端点当前的高延迟。
第三批增加 4 个默认关闭的连接器和 11 个只读工具:
| Connector | 数据源 | 工具数 |
|---|---|---|
protein-records |
UniProtKB | 3 |
nucleotide-archives |
NCBI GenBank、ENA | 3 |
target-discovery |
Open Targets Platform GraphQL | 2 |
chembl |
ChEMBL Data Web Services | 3 |
UniProt 搜索支持 review 状态、物种、排序和 cursor,详情与 FASTA 输出均压缩或限长。GenBank 搜索通过 NCBI ESearch → ESummary,记录读取支持格式、区间与链方向;NCBI 请求使用共享节流并支持 NCBI_API_KEY。Open Targets 只发送代码内固定的 GraphQL document,用户输入始终作为 variables,不允许注入任意 GraphQL。ChEMBL 活性检索必须显式指定 molecule 或 target,并对分页、pChEMBL 范围和返回字段设置边界。Synapse、Benchling 和 10x 等需要账号、租户或私有工作区上下文的连接器不作为零配置内置项加入。
现有连接器覆盖补全新增 35 个工具,总工具数提升到 85。Paper Search 加入 bioRxiv/medRxiv 日期区间检索和 Europe PMC 开放全文限长读取;Literature Graph 加入 OpenAlex references 和 author search;Clinical Trials 加入 eligibility search 和 endpoint extraction;Structures & Interactions 加入 EMDB、IntAct、Complex Portal;Genes & Ontologies 加入 OLS 详情和 QuickGO;Genomes 加入 UCSC track 搜索与有界区间读取;CellGuide 加入 marker、来源和组织查询;Protein Annotation 加入 Human Protein Atlas;Omics Archives 加入 BioStudies ArrayExpress 与 MetaboLights;Chemistry 加入 BindingDB 与 Rhea;Regulation 加入 UniBind;BioMart 增加 attribute/filter introspection;Drug Regulatory 增加精确 Drugs@FDA application 读取;Human Genetics 增加 FinnGen PheWAS;Open Targets 增加 disease/drug 详情;ChEMBL 增加 mechanism 查询。
所有新增 schema 使用 strict object,并限制自由字符串、分页、基因组区间和最大返回条数。Rhea 和 Open Targets 仅发送代码内固定查询,模型输入不能提供任意 SPARQL/GraphQL。UCSC track 目录改用官方 /search 端点,而不是下载超过 15 MB 的完整 track tree。Claude Science 旧实现使用的 eQTL Catalogue v2 API 在本次验证时已返回 HTTP 410,因此没有加入失效工具;KEGG、CADD、PanglaoDB 和 Sanger 模型仍遵循上游许可限制,不纳入零配置内置能力。