# 供水 Agent 的 OpenCode 资产 这里维护服务使用的 Agent 指令、插件和工具。项目查询与受控分析统一通过第一方 MCP,公开网页搜索使用 OpenCode 原生 `websearch`;回答展示、业务写入、记忆和 Skill 管理保留插件接口。管理员通过这些入口管理可复用 Skill 和外部 MCP 连接。 [agent-plugin.json](agent-plugin.json) 是本项目的描述清单,列出各项能力的用途、文件路径和配置来源,方便检索和交接。它是管理索引,不参与运行时加载;字段中的相对路径以 `.opencode/` 为基准,环境变量指定的路径仍遵循服务原有解析规则。 ## 目录与加载入口 | 入口 | 作用 | 实际加载方式 | | --- | --- | --- | | [agents/instruction.md](agents/instruction.md) | 公共数据规则及普通聊天、协作指令 | 配置生成器去除 frontmatter 后,设为 `instruction` Agent 的 system 指令 | | [agents/investigation.md](agents/investigation.md) | 后台调查协调规则 | 叠加公共业务指令,仅可信任务执行会话选择 | | `investigation-reader` | 无独立提示词文件的运行时只读子代理 | 主代理在每次 `subagent` 调用中提供 prompt;配置生成器只设置权限和工具白名单 | | [tjwater-plugin/package.json](tjwater-plugin/package.json) | 插件包名称、版本、描述和导出入口 | OpenCode 显式加载该目录包 | | [tjwater-plugin/index.ts](tjwater-plugin/index.ts) | 插件包入口 | 导出 `plugins/tjwater-tools.ts` 的默认插件 | | [plugins/tjwater-tools.ts](plugins/tjwater-tools.ts) | `tjwater.tools` 插件实现 | 注册业务与待办工具、沙箱、MCP 策略和内部 RPC | | `skills/` | 可复用流程及引用、脚本 | 默认 Skill 根目录,可由 `OPENCODE_SKILLS_ROOT_DIR` 替换 | | [../opencode.json](../opencode.json) | 工具权限和 MCP 连接 | 服务合并部署覆盖配置后校验并交给 OpenCode | | [../agent-models.json](../agent-models.json) | 模型和 provider | 统一生成 OpenCode 模型定义,不在描述清单中重复配置 | [serviceOpencodeConfig](../src/runtime/opencode2-config.ts) 将可信插件包、Agent 指令和 Skill 根目录解析为绝对路径。会话目录位于 `data/session-workspaces/` 时也能加载这些服务资产,并在保留业务数据静态拒绝规则的同时,为受管理的会话文件生成权限规则。插件包名 `tjwater-tools-plugin`、运行时插件 ID `tjwater.tools`、Agent ID `instruction` 各有用途,新增描述时应保留它们的对应关系。 原生插件通过 `Plugin.define({ id, setup })` 注册,额外插件使用 OpenCode 的 `plugins` 配置。参考 [OpenCode 插件文档](https://opencode.ai/v2/docs/build/plugins/)。本项目显式加载可信目录包,新增文件不等于已经注册了业务能力,需检查运行时工具目录。 排查插件状态时需同时核对会话的 Location。仓库根目录会话还会自动扫描 `.opencode/plugins/tjwater-tools.ts`,与显式加载的目录包产生同 ID 重复记录;本次隔离核验中,一个 `tjwater.tools` 正常激活,另一个报 `Duplicate plugin ID: tjwater.tools`。使用独立会话工作目录时仅出现一个正常激活记录,工具发现与调用验证通过。实际聊天使用受管理的会话 `workspace/`,调试时也应在对应目录检查插件和工具。 ## Prompt 组织与角色权限 加载方式由 [opencode2-config.ts](../src/runtime/opencode2-config.ts) 决定:普通聊天使用 `instruction.md`,后台调查使用 `instruction.md` 加 `investigation.md`。只读子代理不加载仓库提示词文件,具体 prompt 由主调查 Agent 在每次调用中编写。 `instruction.md` 集中维护数据来源、限定查询、分析适用范围和消息语义,回答展示与人工补充事实标明仅适用于普通聊天、任务协作。`investigation.md` 补充后台调查的委派、进度、Mermaid、展示、报告和收尾规则,并要求主代理为子任务写明问题、范围、时间窗、预期证据和返回格式。子代理的只读范围由运行时强制,不依赖独立 system prompt。 | 角色 | 产品 MCP | 子代理 | 发布与通信 | | --- | --- | --- | --- | | 项目普通聊天、任务协作 | 25 项查询、10 项受控分析 | 关闭 | 聊天展示、用户事实写入、调查消息,不直接改写正式报告 | | 后台调查主代理 | 25 项查询、10 项受控分析 | 最多 2 个前台只读子任务,仅一层 | 统一发布任务进度、展示、报告与动作提议,只收取和回复绑定运行的消息 | | `investigation-reader` | 仅 25 项查询,可读已有分析结果 | 关闭 | 向父代理返回发现与证据编号,无通信、发布或设备操作权限 | 表中是角色允许的工具类别,不是额外授权。实际调用还需满足产品 MCP 开关、用户项目权限、任务范围及服务端校验;reader 的直接父子关系、运行有效性由宿主核验。只读指不修改业务对象、不发起计算,查询仍可能保存任务证据快照。分析不保存正式方案,也不实际控制设备。 Prompt 负责引导行为,不替代权限检查。维护角色规则时同步核对 [task-agent-policy.ts](task-agent-policy.ts)、[项目 MCP 白名单](../src/runtime/product-mcp-tools.ts) 和服务端工具契约,不通过修改文字扩大权限。更新后需重新加载 Agent/OpenCode 运行时资产;client 模式需同步外部 OpenCode 配置,本次文档修改不代表运行中会话已加载新指令。 ### 提示词职责与收尾规则 | 来源 | 负责的规则 | | --- | --- | | 公共 `instruction.md` | 数据来源、事实与假设、授权工具、查询范围,以及明确限定为普通聊天的展示和等待规则 | | 后台 `investigation.md` | 必要核查如何推进、计算等待、阶段报告、动作提议和唯一的调查停止条件 | | Server 的 `resources/work-order-skills/*/SKILL.md` | 各类事件的判断目标、参数来源、分析适用性与现场闭环要求,按任务上下文读取版本 | | MCP schema 与工具说明 | 合法参数、结果语义及真实能力,不把现场执行前置条件写成候选计算门槛 | | 任务入口消息 | 当前目标和上下文,引用上述规则,不重复编写缺数退出或提案后立即收尾的规则 | `concluded` 表示有依据的有限结论;`final` 表示本轮必要分析已完成或有依据地确认无法继续,两者分别判断。紧急核验建议可先通过 interim 报告和动作草稿提出,之后继续可执行的必要分析。现场确认约束实际处置及闭环,不阻止有明确假设的候选分析。 维护时用下列情形核对各层表述是否一致;这是一组行为验收情形,静态检查通过不等于模型运行已通过验收。 | 情形 | 预期行为 | | --- | --- | | 压力异常,目录首屏未见流量计 | 补齐相关目录覆盖及参数来源核查;无依据不硬填漏量,继续独立隔离及影响分析 | | 已有合理候选,现场尚未确诊 | 可计算候选隔离方案,现场阀门状态列为执行前核验条件 | | 已有现场核验草稿,必要分析仍可执行 | 保存 interim、提议动作后继续分析,不立即发布 final | | 必要计算 queued/running | 发布等待进度,交宿主等待并续跑,读取结果后再判断,不按缺数结束 | | 必要数据经查询无法补齐,或查询接口失败 | 前者若能由用户补齐则提问,回答仍无法补齐时按实际结论选择 outcome;后者按执行异常处理 | ## 当前工具目录 `tjwater.tools` 显式注册 22 个工具;描述清单中的 `plugins[].tool_groups` 按下表列出准确 ID。插件内部 RPC `list`、`mcp`、`check_models` 和 `read_todos` 供宿主使用,不是模型工具。 | 用途 | 插件工具 | | --- | --- | | 回答组织与收尾 | `present_answer`、`final_answer` | | 宿主持久化提问 | 聊天 `ask_user`;后台调查 `ask_task_user` | | 地图、图表与监测展示 | `present_view`(十种受控 command) | | 调查进度、展示与报告 | `publish_task_progress`、`publish_task_presentation`、`publish_task_report`、`publish_execution_plan` | | 人工证据、动作提议与授权申请 | `add_task_human_evidence`、`propose_task_action`、`request_task_data_access` | | 调查讨论写入 | `send_task_message`、`reply_agent_message` | | 完整读写管理接口 | `memory_manager`、`skill_manager` | | 当前会话待办写入 | `todowrite` | 历史曲线先通过 `mcp_tjwater_query_element_history` 查询,再通过 `present_view` 的 open_chart 命令展示。`present_answer` 发布本地界面,不等待浏览器回执;地图/图表动作遵循各自的回执契约。后台 `publish_task_presentation` 记录展示请求,不能把记录成功解释为浏览器已显示。 普通聊天和任务协作声明 `host-question@1` 后,目录提供 `ask_user` 并隐藏原生 question。可信工具桥持久保存问题,工具执行门禁拒绝与提问并行的调用及等待期间的新调用;宿主在工具完成后确认原生轮次 idle。答案通过原会话 Responses 通道继续,不冒充原生工具返回值。后台任务、学习上下文和旧客户端不启用聊天提问工具;业务审批不受此工具替代。后台调查使用 `ask_task_user`,通过 Server 保存问题并产生 human_input_required 通知。固定问答放在右侧调查报告的“补充回答”中,通知打开该报告,提交直接调用任务回答接口;左侧 Agent 保留自由讨论与追问。当前 run 正常结束,任务进入 waiting_human,回答后原任务排队新 generation,答案从任务上下文 questions 分节读取。用户回答不自动写成现场证据。部署前须在项目业务库执行 Server 的 `resources/sql/028_task_questions.sql`。 OpenCode 原生工具包括文件工具 `read`、`glob`、`grep`、`edit`、`write`、`patch`,会话沙箱 `shell`,网页工具 `websearch`、`webfetch`,以及 `skill`、`question` 和受限 `subagent`。保留 `opencode_models`、`opencode_session_move`、`opencode_session_rename`、三个 `opencode_worktree_*` 管理工具及两个 MCP 资源工具;完整 ID 见描述清单的 `native_tools`。这些目录项不代表每种会话都能执行,最终由权限、审批、会话归属及沙箱决定。原生浏览器自动化工具已禁用。 原生 `websearch` 的仓库默认配置为 `websearch.provider = "exa"`;实际搜索引擎以合并后的部署配置为准。无需恢复 `web_search`、Server 搜索接口或 MCP 搜索副本。 任务专用工具 `publish_task_progress` 和 `publish_task_presentation` 也由该插件显式注册,启动工具发现必须包含两者。进度复用 Server artifacts,展示使用 Server 的有序事件流;内部桥只接受后台 task_execution 的可信任务上下文,不接收模型提供的 task/run/用户身份。它们不增加浏览器等待,普通聊天的展示回执保持原有语义。 [task-agent-policy.ts](task-agent-policy.ts) 保留原生 subagent 执行器,增加可信任务用途、 指定只读 Agent、最多两个并发前台子调用及禁止恢复旧子会话的检查。原生直接父子关系 由服务端核验,只有 MCP 项目查询可以使用已核验的父任务身份,其他工具不会继承该身份。 Mermaid 并行分支须对应实际子任务,主 Agent 统一维护整图;图与 todo 不参与调度。 ## 受控调查通信 `mcp_tjwater_list_investigation_tasks`、`mcp_tjwater_get_investigation_task` 和 `mcp_tjwater_read_agent_messages` 通过本地 MCP 提供,OpenCode 原生发现和调用。 插件只注册写入类 `send_task_message`、`reply_agent_message`,使用 `/internal/agent-messages/send|reply`。读取操作没有内部 HTTP 查询路由。 MCP 和写入桥均依据宿主会话核定身份、项目、绑定运行和回复线程;模型不能提供 身份、项目、接收会话 ID、URL 或鉴权头。 通信采用原生消息能力,消息来源保留为 `originalMessage`,不升级为 `userinstruction`。 | 会话 | 工具范围 | | --- | --- | | 当前项目的普通聊天、任务协作 | 列表、详情、发送、读取和回复自己的有效线程 | | 后台 `task_execution` | 仅读取和回复绑定运行的消息 | | `investigation-reader` | 无通信工具 | [agent-message-policy.ts](agent-message-policy.ts) 收紧模型工具目录,配置生成器为两种 主 Agent 设置明确的静态权限;最终身份、项目和运行权限由本地 MCP 与写入桥分别校验,学习、个人 或未绑定会话不能借工具目录获得项目通信权限。普通聊天和协作的子代理规则不变。 先列表再读取详情,使用返回的稳定 UUID `task_id`、`run_id`;收到消息后使用稳定 `message_id` 回复。发送与回复的 UUID `request_id` 是幂等键,重试同一操作复用。 `queued` 表示接受排队,不代表对方读取、处理或调查完成。使用 `mcp_tjwater_read_agent_messages` 明确收取消息,后续分页沿用返回的 opaque cursor。只在确有内容需要答复时回复,不做 自动确认互相触发。消息不保存 human_input、不创建调查新轮次,不自动唤醒空闲主会话。 正式报告、用户事实和任务完成仍使用原有业务流程。 聚焦验证使用 `bun test tests/opencode/agentMessages.test.ts tests/chat/agentMessageCoordinator.test.ts`。 可选原生验证使用 `bun run tests/integration/agent-messages-smoke.ts`:它创建隔离原生数据目录, 仅使用本机确定性 SSE 假模型端点,核验真实工具发现、静态权限、收件箱状态、稳定 ID 去重、 `resume:false` 不唤醒空闲会话,以及显式对话启动后消费消息,不调用付费推理。 ## 管理 Skill 业务处置 Skill 与下述 Agent 本地 Skill 分开维护。爆管、水质投诉和预约跟进流程位于 Server 的 `resources/work-order-skills/`,由 `mcp_tjwater_get_task_context` 的 `handling_skill` 元数据发现,使用 `section="skill"` 读取正文、版本与内容摘要。Server 根据已绑定任务的 workflow 选择流程,沿用任务权限;流程不保存为调查证据。Agent 只保留加载与执行规则,不通过 `skill_manager` 写入或覆盖 Server 业务流程。新增和修改业务流程须发布 Server 资源;Agent 指令变化仍需重启相关运行时。 Skill 是模型按需读取的流程说明,工具负责实际执行。一个 Skill 推荐使用以下结构: ```text skills/ └── supply-data-review/ ├── SKILL.md ├── references/ │ └── field-guide.md └── scripts/ └── summarize.py ``` `SKILL.md` 至少包含名称、用途和适用条件,正文引用的文件路径相对于该 Skill 目录: ```markdown --- name: supply-data-review description: 核对供水数据的时间范围、单位和缺失情况。 --- # 供水数据核对 适用于已通过受控工具取得的数据。 1. 核对查询范围、时间和单位。 2. 将真实缺失与接口错误分别记录。 3. 输出数据结论和未确认事项,保留实际证据来源。 ``` 目录名称决定 OpenCode 的 Skill ID,frontmatter 的 `name` 用于显示。推荐使用唯一的小写名称,避免同名 Skill 被后加载的来源覆盖;完整规则见 [OpenCode Skill 文档](https://opencode.ai/v2/docs/skills/)。 当前 Skill 根目录由 `OPENCODE_SKILLS_ROOT_DIR` 统一指定,供 OpenCode 加载和 Agent 的 SkillStore 使用。描述清单只引用该入口,不维护另一份 Skill 名单。使用绝对路径可减少外部 OpenCode 和 Agent 的启动目录差异。 `skill_manager` 支持列出、写入和删除 Skill,以及维护 pattern、reference 和 script。它通过可信内部工具桥调用 [SkillStore](../src/skills/store.ts),对内容、路径和写入历史进行处理;默认备份位于 `data/backup/skills/`。当前 Skill 存储按部署实例共享,应保存通用方法,避免写入用户凭据、具体会话数据和未经验证的业务结论。 服务当前的指令要求:流程已经验证可复用,且用户明确需要保存时,才通过 `skill_manager` 沉淀。Skill 中的执行步骤不能改变工具权限;引用脚本仍需通过批准的会话沙箱执行,业务 API 仍使用类型化工具。 `skills/` 被 Git 忽略,保存或交付 Skill 时需要单独准备目录和持久化挂载,克隆仓库不包含已有实例的 Skill。修改后重启相关运行时以重新发现;需要后续实现在线刷新时使用原生 Skill reload 接口,当前管理桥不保证即时刷新 OpenCode 目录。 ## 管理 MCP 管理员添加的外部连接配置位于仓库根目录 `opencode.json` 的 `mcp.servers` 中,部署覆盖使用 `OPENCODE_CONFIG_CONTENT`。保留的第一方 `mcp_tjwater` 连接由宿主生成,再由 [query-mcp.ts](query-mcp.ts) 注入原生 MCP;不在外部连接配置中另建同名服务。`agent-plugin.json` 只指向配置和实现来源,不存地址、命令或认证头。 服务名使用 `mcp_` 前缀。添加、修改或禁用连接时,按根目录 README 的 [MCP 配置说明](../README.md#配置外部-mcp) 操作;支持远程 Streamable HTTP 和本地 stdio,详细字段参考 [OpenCode MCP 文档](https://opencode.ai/v2/docs/mcp-servers/)。 密钥通过 `{env:NAME}` 引用 `.local.env` 或部署环境。需要 OAuth 时,由管理员使用同一服务账号和 XDG 数据目录执行认证,不把 TJWater 用户令牌转交给 MCP 服务。修改连接后重启运行时;client 模式需同步外部 OpenCode 的配置与可信插件。 查看会话中实际加载的服务和工具: ```text GET /api/v1/session/:session_id/mcp ``` 该接口校验产品 Bearer、会话归属与个人或项目范围,项目会话额外验证项目头。接口只返回服务名、类型、状态、配置协议和实际工具 ID。`connected` 只表示连接状态,仍需检查工具 ID 是否已出现;响应不包含地址、进程命令或凭据。 管理员配置的外部 MCP 执行策略由 [mcp-policy.ts](mcp-policy.ts) 和 [服务配置校验](../src/runtime/mcp-config.ts) 维护。下表不包含第一方 `mcp_tjwater`,其查询和分析按后文的产品白名单与业务权限校验: | 会话 | 调用规则 | | --- | --- | | 普通聊天、任务协作 | 管理员明确允许的只读工具可自动执行;其他允许审批的调用按本轮选择逐次询问或自动批准 | | 后台任务 | 仅调用精确的只读白名单工具 | | 学习复盘 | 禁用 MCP 调用 | 只读白名单需在 `permissions` 中使用状态接口返回的精确工具名,不能用宽泛的 `mcp_* allow` 替代。Code Mode 和通用资源访问也应用同一策略。本地 stdio MCP 运行于可信宿主进程,不受会话 Shell 沙箱约束,环境过滤不等于 OS 隔离。 聊天输入框的“始终允许”自动处理本轮原生权限询问,包括 Shell、文件修改和 MCP 请求;只回复 `once`,避免切回“请求批准”后继续沿用自动授权。明确拒绝、项目业务权限、后台只读白名单及会话沙箱均继续执行,自动批准不开放被禁止的能力。工具的业务人工审核与向用户提问也不由此模式自动作答。 ## 修改后的检查 更新 Agent、插件或管理入口时,同步修改描述清单和相关说明,保持路径及 ID 对应。插件的运行时代码变更需要类型检查和相关测试: ```bash bun run check bun test tests/frontendAction/callIdPlugin.test.ts tests/runtime/opencode.test.ts ``` MCP 策略变更使用 MCP 相关测试,实际连接联调可选择根目录 README 列出的本地 smoke 脚本。模型配置修改使用 `bun run check:models`。这些命令从仓库根目录运行;仅修改描述或说明时检查路径、JSON 和 `git diff --check` 即可。 运行时确认以 Agent 的启动预热和 `/health` 为准。client 模式要同时更新外部 OpenCode 使用的资产。服务启动、工作区保留和容器挂载参见 [根目录 README](../README.md),代码修改约束见 [AGENTS.md](../AGENTS.md)。 `tools/present_answer.ts` 注册本地交互式回答工具。组件契约来自前端导出的 `../src/chat/answer-ui-catalog.json`,由服务与前端同时校验;注册入口仍是 `plugins/tjwater-tools.ts`。更新后需要重新加载 Agent/OpenCode 的可信插件资产。 发现验证使用 `bun run tests/integration/answer-ui-smoke.ts`,从 Agent 仓库根目录运行。 聊天 UI 的选择规则常驻于 `agents/instruction.md`:对象比较与数值趋势优先使用 `present_answer` 的 Table、Chart,简单问答保留文字。工作台地图操作与用户要求打开的 独立图表使用 `present_view`。工具描述包含可执行校验的最小发布示例;最终组件直接 显式指定 `phase=final`,并由 `final_answer` 的正文锚点及引用列表保留。 本规则不依赖动态 Skill 的读取,也不改变后台调查的发布渠道。 `bun test tests/chat/answer-ui-examples.test.ts` 校验示例是否能通过真实发布契约。 自然问题选择验收使用 `TJWATER_ANSWER_UI_EVAL=1 bun run tests/integration/answer-ui-selection.ts`, 会调用真实模型;隔离环境、范围和可选模型参数见 [根目录 README](../README.md)。 ## 第一方查询与分析 MCP 配置构建器在插件列表末尾添加 `-opencode.browser` 和 `-opencode.browser.*`,禁用原生浏览器插件及其子插件,并拒绝 `browser` / `browser_*` 权限。`present_answer`、地图/图表/SCADA 前端动作、任务展示发布和记忆/技能管理插件继续保留;它们使用各自的业务协议,不依赖原生浏览器自动化工具。 项目查询、受控分析及宿主只读查询通过保留连接 `mcp_tjwater` 统一暴露;插件只配置原生 MCP 连接和权限策略,不注册这些 MCP 工具或自定义查询执行器。公开网页搜索使用 OpenCode 原生 `websearch`,不另设 Server 或 MCP 搜索入口。MCP 实现位于 [query-server.ts](../src/mcp/query-server.ts),连接配置位于 [query-mcp.ts](query-mcp.ts)。 默认提供六个宿主查询:`geocode`、`session_search`、`list_investigation_tasks`、`get_investigation_task`、`read_agent_messages`、`todoread`。Agent 合并 25 项项目查询和 10 项受控分析,目录匹配且上游启用时合计 41 项,原生工具 ID 为 `mcp_tjwater_`。`memory_manager` 和 `skill_manager` 保留完整读写插件能力;发布、动作、发送、地图展示和 `todowrite` 也保留插件形式。 产品目录包含 35 项工具:25 项查询、10 项分析。名单以 [product-mcp-tools.ts](../src/runtime/product-mcp-tools.ts) 为准,`McpQueryClient.prepare()` 对两端工具名做全等检查;升级需先发布 Server,再重启 Agent 和 client 模式下的原生连接。分析权限和适用边界见配套 Server 的 [MCP 分析工具说明](../../next-tjwater-server/docs/mcp-analysis-tools.md),reader 不获得分析能力。 25 项项目查询按以下分组组织;表中省略共同前缀 `mcp_tjwater_`。工具名称以 [product-mcp-tools.ts](../src/runtime/product-mcp-tools.ts) 为准,输入和查询说明来自 Server 实际发现的工具定义,不在描述清单中复制参数契约。 | 查询范围 | 工具名称 | | --- | --- | | 管网与资产 | `get_network_options`、`get_network_schema`、`list_elements`、`query_nearby_elements`、`get_element_properties`、`get_element_gis_properties`、`get_source_gis_properties` | | SCADA 与实测历史 | `list_scada_devices`、`get_scada_device`、`query_scada_readings`、`query_element_history` | | 模型基线 | `get_model_baseline_at_time`、`query_model_baseline_field`、`query_model_baseline_series` | | 分析成果 | `list_analysis_runs`、`get_analysis_run`、`list_analysis_results`、`query_analysis_values`、`query_analysis_series` | | 布点成果 | `list_sensor_placement_runs`、`get_sensor_placement_run` | | 工作台、外围数据和任务证据 | `get_workbench_runtime`、`query_peripheral_data`、`get_task_context`、`get_task_evidence` | 第一方 MCP 的会话边界由 [query-mcp-policy.ts](../src/runtime/query-mcp-policy.ts) 和宿主身份校验执行。下表表示策略上限,工具还必须实际发现、上游启用并通过用户/任务权限检查。 | 会话 | 第一方 MCP 范围 | | --- | --- | | 个人聊天 | `session_search`、`todoread` | | 项目普通聊天、任务协作 | 25 项项目查询、10 项分析及 6 项宿主查询 | | 后台 `task_execution` | 25 项项目查询、10 项分析,以及 `geocode`、`session_search`、`read_agent_messages`、`todoread` | | 已核验的 `investigation-reader` | 仅父任务授权的 25 项项目查询,不含宿主查询 | | 学习复盘 | 禁用 MCP 查询 | 业务凭据和查询上下文由宿主绑定,模型不能指定用户、项目或授权头。工具可发现或允许调用不会扩大用户及任务已有的业务权限;Server MCP 关闭时不回退到旧 HTTP 查询桥。 连接使用 MCP 2026-07-28 Streamable HTTP,独立监听 127.0.0.1 临时端口,启动目录发现前已就绪。宿主写入元数据目录旁的 `mcp-query/connection.json`,仅含公开端点;外部 OpenCode 须共享该路径(`TJWATER_AGENT_MCP_CONNECTION_PATH`)、同一内部密钥及同版本可信插件,Agent 重启后同步重载原生连接。业务 OAuth 密钥及产品 Bearer 仍只在 Agent 宿主。 OpenCode 以 `params._meta["ai.opencode/sessionID"]` 传入会话关联值;它不是认证凭据。服务先验证内部密钥及本机请求,再解析宿主会话与真实父子关系,拒绝浏览器请求、个人项目查询、学习复盘和越权子代理。子代理仅能读取绑定任务的 25 项项目查询。旧查询插件和 `/internal/tools/project-data`、`/internal/operational-task/data-query` 等查询桥已移除;产品 MCP 未启用时项目查询不可用,不回退。 原生聚焦验证:`bun run tests/integration/query-mcp-smoke.ts`;使用隔离目录、样例查询服务和停止推理的 hook,验证原生 `websearch` 调用选定的测试搜索服务,不调用模型或外部搜索。