engineering-bridge

by wudy29 (community) · Claude Desktop, Claude Code, OpenCode, macOS, Windows (Node 22+), Codex, Deepseek Harness

MCP MCP Servers Open Source v1.2.1 · 16.08.2026 активный

Позволяет чату напрямую диспетчеризовать и контролировать локальные Codex / DSH: не нужно вручную переносить промпты и результаты — задачи запускаются прямо из диалога, патчи проверяются/правятся, запись происходит подконтрольно после подтверждения APPLY.

v1.2.1
16.08.2026 current

Установка
git clone https://github.com/wudy29/engineering-bridge.git
cd engineering-bridge
npm install
npm run build
показать оригинал переведено ИИ

Engineering Bridge

打通 Chat 与本地 Codex 与 Deepseek harness:不再搬提示词,Chat 直接调度、监督并验收 Codex 与 Deepseek harness。

稳定版 v1.2.1 CI 许可证: MIT

英文版 · v1.2.1 · V1 稳定版 · 本地运行 · macOS 由维护者持续实测。 这是 V1 稳定版(v1.2.1),但不表示已发布到 npm。v1.2.1 的 Codex 与 DSH Windows npm CLI 启动路径已在 GitHub Actions windows-latest 上验证(Node 22 + 实际 npm 安装的 @openai/codex 与 @deepseek-ai/dsh);更广的 Windows 环境与客户端组合不做全面认证。

以前 / 现在

以前: 你先在 Chat 里讨论需求,再把提示词手工复制到 Codex;Codex 完成一轮后,你又把结果搬回 Chat 继续讨论,然后反复往返。

现在: Chat 直接把任务交给本机 Codex 或 DSH(每个 run_task 可选 executor: "codex" | "dsh",默认 codex),并能继续观察、跟进同一个任务。在同一条原生 Codex 上下文中,Chat 可以让 Codex 继续工作、定向纠正、打断执行,并在审阅后验收结果;不再需要手工搬运提示词和结果。V1 相比旧的一次性 task/result 流程的核心变化,是明确的交互监督流:run_task → waiting_for_supervisor_review → 检查结果/证据 → 用 control_task 发送 continue、steer、interrupt 或 accept。对于受控修改,你仍先审阅完整 diff,并保留是否写入的决定权。

flowchart LR
    A[Chat 描述目标] --> B[Bridge 选择预登记工作区与执行器]
    B -->|executor: codex| C1[本机 Codex:只读检查或生成补丁]
    B -->|executor: dsh| C2[本机 DSH:只读检查或生成补丁]
    C1 --> D[结果回到 Chat]
    C2 --> D
    D --> E[人审阅]
    E -->|精确 APPLY| F[重新校验并受控写入]

状态边界: Bridge 持有控制状态,不持有第二份会话事实。Codex 原生 thread/session 是执行历史的来源;Bridge 只保留继续、定向纠正、打断和验收所需的临时监督/控制状态。DSH 的 headless 接口当前没有可机器恢复的 session seam,因此 DSH 的 continue 是新的执行,task_result 也绝不伪造 thread id。任务监督状态(task/thread/evidence/review)在 Bridge 重启时可按设计丢失;V1 不会把任何执行器会话历史持久化或镜像到 SQLite、数据库或 transcript mirror。

以上全部是本机进程通过 MCP/STDIO 建立的连接。Engineering Bridge 不存在 HTTP 端点或云服务。

它是什么?

Engineering Bridge 是一个在你电脑上运行的小型“工程桥梁”。你在兼容的聊天客户端里说清楚想了解或修改什么,它把任务交给本机 Codex 或 DSH(默认 Codex),在预先登记的项目中检查代码,再把分析结果或补丁带回对话。

它适合希望借助对话理解和审阅代码的人,也适合需要保留明确写入控制的开发者。你不必先会读协议文档,但仍需要完成一次 Node.js、Git、执行器 CLI(Codex 和/或 DSH)和 MCP 客户端配置;仅有普通浏览器聊天无法直接使用它。

为什么需要一座桥?

普通聊天不能天然读取你电脑上的项目,也不能启动本机的 harness,比如 Codex 或者 DeepSeek harness。而 chat 窗口拥有更多的推理能力与内置 skill,Engineering Bridge 在两者之间提供一个本地、预登记且受范围限制的入口,让对话负责理解目标,本机 harness 负责查看、操作真实代码,Bridge 负责传递任务并守住边界。

这里有四个角色:

  • 聊天客户端: 理解你的要求、调用工具,并把结果显示在对话中;它必须支持启动本地 STDIO MCP 服务。
  • Engineering Bridge: 把 workspace_id 映射到可信本机配置中的项目路径,启动并跟踪任务,校验受控补丁。
  • 本机执行器: Codex 通过 codex app-server --stdio 运行;DSH 通过官方 headless 接口运行。两者都只执行只读检查或准备补丁。
  • MCP-STDIO: 客户端与 Bridge 之间的本地协议和进程连接;没有 HTTP 端点或云服务。

今天可以做什么?

  • 只读分析: “概括这个项目的重要目录和主要模块,不要修改文件。”
  • 代码定位: “登录逻辑在哪里实现?请解释调用流程。”
  • 代码审阅: “检查这段实现的可靠性风险,并给出依据,不要编辑文件。”
  • 受控修改: “准备一份补丁来调整超时提示;先展示完整 diff,只有我精确回复 APPLY 后才写入。”

受控写入的原则很简单:先展示 diff,只有精确 APPLY 后才写入。 Bridge 不会自动测试、stage、commit、push 或发布。

为什么通过 Chat 控制本地 Agent?

  • 对话上下文延续。 需求、取舍和此前结果可以继续参与规划,不必在 ChatGPT、终端与 Codex 或 DSH 之间手工搬运。
  • 记忆可以参与规划。 客户端的全局记忆或外部 memory 系统可以提供上下文,但 memory 不是 Bridge 自带的能力。
  • 规划端与执行端各司其职。 Chat 梳理目标;本机执行器(Codex 或 DSH)检查真实工作区并给出证据或补丁;Bridge 限定并校验交接过程。
  • 执行配置保留选择。 Codex 的模型与供应商配置带来选择和灵活性,但不承诺执行成本更低。
  • 人保留最终权限。 你决定补丁是否写入,也决定是否测试、提交、推送或发布。
  • 当前实现 Codex 与 DSH 两个执行器。 run_task、generate_controlled_patch、refine_controlled_patch 都接受可选 executor: "codex" | "dsh"(默认 codex);执行器在每次调用时选择,refine_controlled_patch 不继承父提案的执行器。apply_controlled_patch 没有执行器/模型调用,由 Bridge 自行校验并应用。其他 CLI agent 仍是未来逐个适配的方向,并非当前支持,但原理上皆通。

一个真实案例

本项目曾用 Bridge 生成 CI workflow、Bug Report 模板和 Setup Help 内容。人审阅每份提案并明确执行 APPLY;随后由人运行测试、commit、push 并创建 Release,远端 CI 通过。Bridge 没有 自动发布任何内容。

能力地图

当前可用 当前不会做 Roadmap——不是当前支持
在预登记工作区中进行只读分析、代码定位和审阅;run_task、generate_controlled_patch、refine_controlled_patch 每次调用可选 Codex 或 DSH(默认 Codex) 不自动测试、stage、commit、push 或创建 Release workspace GUI/manager
在 project_root 内用精确 BIND/CREATE 绑定或创建工作区 不是 OS 级读取隔离 其他 CLI agent 逐个适配
写入前生成完整 Git 补丁;managed 工作区经精确 AUTHORIZE 后受控写入 没有 HTTP、UI、账号系统、调用方认证或远程传输 DSH 原生 headless session resume
仅在精确 APPLY 后应用,并重新校验 base HEAD 与仓库状态;支持 unborn 仓库新增 100644 文本文件 不持久化 task/thread/evidence 监督历史;没有自动超时 持久 task/audit 历史
受控补丁提案/应用历史与 managed 工作区目录跨重启保留 — 谨慎探索多 agent 编排
通过 STDIO 提供九个本地 MCP 工具 — —

快速开始

1. 准备

你需要 Node.js 22+、Git、已安装且已认证并能从 PATH 调用的 codex 和/或 dsh CLI(按你使用的 executor)、一个本地项目、能启动本地 STDIO 服务的 MCP 客户端,以及基本终端操作能力。 Controlled writes also require the project to be a clean Git top-level (either with an existing HEAD, or supporting the proposal for new files in an unborn repository), and controlled write permissions must be ready: manual workspaces explicitly enable allow_write in the registry entry, managed workspaces are authorized via exact AUTHORIZE authorization through authorize_workspace_write.

Preparation by executor:

  • Codex: Install and authenticate the codex CLI so it can be invoked from PATH. The Bridge starts Codex with codex app-server --stdio: no shell, approval is never, network disabled.
  • DSH: Install the official npm package @deepseek-ai/dsh; dsh must be invocable from PATH, or the Bridge finds it via the profiles fallback path in DSH_HOME/~/.dsh. If DEEPSEEK_API_KEY is set in the Bridge runtime environment variables, the Bridge forwards it to DSH — this is the only credential environment variable the Bridge forwards; do not write the key into config files (see Section 4). The Bridge starts DSH with dsh --profile headless <command> and pins DSH_PERMISSION_MODE=read-only itself — do not set this variable yourself. DSH_TOOLS_MODE is an optional pass-through; proxy variables are not forwarded.

2. Clone, installation, and build

git clone https://github.com/wudy29/engineering-bridge.git
cd engineering-bridge
npm install
npm run build

The V1 stable version (v1.2.1) has no one-click installer.

3. Registering workspaces

Two ways:

  • Manual registration (authoritative): Fill in the absolute, normalized path of the project in workspaces.json; this file is a trusted local configuration, and MCP callers can only select an ID.
  • Managed registration (onboarding): Configure project_root (the trust boundary of the approved root) in workspaces.json, then bind an existing directory via bind_project (exact BIND), or create and git init a new directory via create_project (exact CREATE). Managed workspaces are read-only by default and persist to <config>.managed-workspaces.json.
[
  {
    "id": "my-project",
    "root": "/absolute/path/to/my-project"
  },
  {
    "kind": "project_root",
    "root": "/absolute/path/to/projects"
  }
]

You must still use the registered workspace_id when calling. On macOS, the Git root check for controlled writes compares aliases like /tmp and /private/tmp by real filesystem path.

4. Configuring STDIO MCP clients

Different clients have different configuration locations and formats; follow your client's documentation to convert the following common fields:

{
  "command": "node",
  "args": [
    "/absolute/path/to/engineering-bridge/dist/src/mcp-stdio.js",
    "/absolute/path/to/engineering-bridge/workspaces.json"
  ],
  "env": {
    "PATH": "/path/that/includes-node-and-your-executor"
  }
}

Use absolute paths. If the client already provides a suitable PATH, you can omit the env override. Do not apply this structure verbatim to clients using other schemas.

When using DSH, if DEEPSEEK_API_KEY is set in the environment variables of the Bridge process at runtime (e.g., shell or launcher environment), the Bridge forwards it to DSH — this is the only credential environment variable the Bridge forwards. Do not write it into the env override here or into any config file — the key must not end up in configuration.

Reconnect the integration and confirm you can see the following nine current V1 tools:

  • run_task
  • task_result
  • control_task
  • bind_project
  • create_project
  • authorize_workspace_write
  • generate_controlled_patch
  • refine_controlled_patch
  • apply_controlled_patch

5. First read-only task

In workspace my-project, list top-level files; if a Git HEAD exists, also report its exact value. Do not modify anything.

A normal run_task is always read-only (optional executor: "codex" | "dsh", default codex), and a successful call returns a task ID. The operation sequence for V1 interactive supervision is: run_task → waiting_for_supervisor_review → check results/evidence → send continue, steer, interrupt, or accept via control_task; this is the core change in V1 compared to the old one-shot task/result flow. Poll task_result: non-interactive tasks return ready: false while queued or running, and finally return output or a safe error. Successful rounds of interactive tasks enter waiting_for_supervisor_review; at that point the result contains status/readiness information, limited evidence, and review_output visible before acceptance. task_result also returns the fixed executor; Codex tasks return the real thread_id when a native thread exists, while DSH tasks never fabricate a thread_id because the headless interface has no machine-recoverable session seam (DSH's continue is a new execution). control_task only accepts task IDs from interactive run_task calls: continue preserves native Codex thread continuity, interrupt only applies to a running interactive task and ends it as failed (if the executor actually produced partial output, task_result returns it as partial_output, with status still failed), and after accept completes, task_result returns the final output or error. Check the workspace yourself:

git -C /absolute/path/to/my-project status --short

For an originally clean Git project, no output means the working tree is still unchanged.

6. First controlled write

Controlled write permissions are ready by workspace origin: manual workspaces set allow_write: true in workspaces.json; managed workspaces call authorize_workspace_write and reply exactly AUTHORIZE (AUTHORIZE only affects managed entries, not manual entries):

[
  {
    "id": "my-project",
    "root": "/absolute/path/to/my-project",
    "allow_write": true
  }
]
  1. Confirm the config root is the Git top-level, and the tracked working tree and index are both clean (either with an existing HEAD, or supporting the proposal for new files in an unborn repository).
  2. Call generate_controlled_patch with the workspace ID and a clearly scoped requirement (optional executor: "codex" | "dsh", default codex). This is a separate controlled patch flow and does not use the interactive run_task supervision stream; generation/refinement is a read-only proposal and can be performed in any registered workspace without write authorization.
  3. Poll the returned patch task ID with task_result until state=completed; the full unified diff is returned in output. If corrections are needed, call refine_controlled_patch with the completed patch task ID and the correction requirement (again optional executor: "codex" | "dsh", default codex); the executor is chosen on each call, and refine_controlled_patch does not inherit the parent proposal's executor. It preserves the original proposal and returns a new complete proposal based on the same base_head. Proposal tasks do not enter waiting_for_supervisor_review, do not produce review_output, and cannot be accepted via control_task.
  4. Outside of task status, operate in the order: generate_controlled_patch → check all paths, the full diff, and the returned base_head → exact APPLY → apply_controlled_patch. For managed workspaces, complete AUTHORIZE before APPLY if needed. After confirming correctness, call apply_controlled_patch with that patch_task_id, and the confirmation value must exactly equal APPLY.
  5. Check the results:

    sh git -C /absolute/path/to/my-project status --short git -C /absolute/path/to/my-project diff --check git -C /absolute/path/to/my-project diff

  6. Run the project tests, then decide whether to stage, commit, push, and publish. The Bridge does not perform any of these operations.

Untracked files in other locations do not by themselves break the requirement of a clean tracked state, but new file targets in a proposal must not exist in HEAD, the index, or the working tree. Unborn repositories (e.g., empty repositories created by create_project) support adding ordinary 100644 text files; the Bridge does not automatically git add or commit.

You can also start the Bridge manually for protocol diagnostics:

node dist/src/mcp-stdio.js /absolute/path/to/workspaces.json
# 或
npm run mcp:stdio -- /absolute/path/to/workspaces.json

This process waits for MCP messages on standard input. It is not an interactive shell and does not connect to a chat client by itself.

Security boundaries

  • Workspaces are read-only by default; controlled writes are ready by origin: manual workspaces set allow_write: true, managed workspaces are authorized via exact AUTHORIZE through authorize_workspace_write.
  • Proposals show the full diff and base HEAD. Only exact APPLY proceeds; before applying, the Bridge re-checks the Git top-level, HEAD, clean tracked working tree and index, and patch validity. Generation/refinement does not require write authorization; write permission is only needed at APPLY.
  • Acceptable patches can modify existing, tracked ordinary text files, or add new ordinary text files with mode 100644 that do not yet exist (unborn repositories only support additions).
  • Bridge отклоняет неподдерживаемые патчи: delete, rename, copy, binary, mode change, executable, symlink, submodule, опасные пути и т.д., а также отклоняет добавление, если цель уже существует.
  • Bridge не выполняет автоматическое тестирование, stage, commit, push или создание Release.
  • Бэкенд Codex — это codex app-server --stdio, без оболочки, approval — never, сеть отключена; DSH запускается через официальный headless-интерфейс, Bridge принудительно устанавливает DSH_PERMISSION_MODE=read-only для каждого процесса DSH, передаёт только явный allowlist (включая DEEPSEEK_API_KEY, DSH_TOOLS_MODE), не передаёт proxy-переменные. Обычные/контролируемые задачи и генерация предложений остаются только для чтения, только шаги применения, точно подтверждённые APPLY после рецензирования, записывают файлы.
  • Состояние контроля задач (task/thread/evidence/review) существует только в текущем процессе; история контролируемых предложений/применений патчей и каталог managed-рабочей области сохраняются между перезапусками (два локальных файла состояния, права 0600). В V1 нет автоматического тайм-аута. Запущенные интерактивные задачи можно явно прервать через control_task(action: "interrupt"); частичный вывод от реального прерывания возвращается как partial_output, обычные сбои не раскрывают повторно stderr или неудачный stdout.
  • Регистрация рабочей области двумя способами: ручная регистрация в workspaces.json (авторитетная) или управляемая регистрация через точный BIND/CREATE в одобренном корневом каталоге project_root; при вызове необходимо указывать зарегистрированный workspace_id.
  • Если доказательства Codex усекаются/вытесняются существующим bound, они помечаются явным маркером ([truncated], пропущенный счётчик changes, evidence-drop) — это означает, что диагностическая информация неполна, это не полная транскрипция.
  • Выполнение только для чтения не является изоляцией чтения файлов на уровне ОС; процессы того же системного пользователя всё ещё могут читать другие файлы, разрешённые операционной системой.
  • Человек должен просматривать полное предложение; имена файлов, упомянутые в запросе, не становятся семантическим allowlist, обеспечиваемым кодом.

Пожалуйста, прочитайте дизайн безопасности, модель угроз и справочник инструментов. Также см. архитектуру, политику безопасности, руководство по внесению вклада и примечания к выпуску.

Устранение неполадок

  • Не видно девять инструментов: переподключите клиент и убедитесь, что его локальная конфигурация STDIO MCP запускает dist/src/mcp-stdio.js.
  • Клиент не находит node, codex или dsh: процесс, запущенный клиентом, может использовать другой PATH, чем терминал; укажите пути, содержащие все эти исполняемые файлы.
  • Ошибки рабочей области или пути: и серверный скрипт, и workspaces.json должны использовать абсолютные пути, root рабочей области должен быть абсолютным нормализованным путём, и используйте зарегистрированный ID.
  • Контролируемая запись отклонена: проверьте права контролируемой записи (ручной allow_write или управляемый AUTHORIZE), верхний уровень Git и чистое tracked-рабочее дерево и индекс; можно выполнить git -C /absolute/path/to/my-project status --short.
  • После ручного запуска выглядит зависшим: это нормально; Bridge ожидает MCP-сообщения через STDIO.
  • Задача не завершается: в V1 нет автоматического тайм-аута; запущенные интерактивные задачи можно явно прервать через control_task(action: "interrupt"). Остальные задачи можно только продолжать опрашивать; перезапуск Bridge по замыслу сбрасывает состояние контроля задач, контролируемые предложения патчей и каталог managed-рабочей области сохраняются.

История проекта

Engineering Bridge — первый открытый проект wudy29 — это эксперимент: сможет ли человек, совершенно не разбирающийся в коде, вместе с ИИ создать настоящий инструмент.

Engineering Bridge был предложен и возглавлен wudy29, завершён в долгосрочном сотрудничестве с ChatGPT-Demu, Codex участвовал в конкретной реализации и проверке.

Особая благодарность Demu. Спасибо, что прошёл со мной путь от идеи до реально существующего открытого проекта и оставил реальный след в нашем мире.

Войдите, чтобы оставить комментарий