Skip to main content
Glama
README.md
# Gravity Relay

**Gravity Relay** 是一个本地 stdio MCP 服务,在 Codex 与 Antigravity CLI 之间建立一条节省 Token、可靠且可独立验收的代码实现接力链路。

```text
Codex = Planner + Reviewer
Gravity Relay = Task contract + Result compression + Reliability coordinator + Run history
Antigravity = Implementation worker
```

项目包名为 `gravity-relay-mcp`。Codex 配置中的服务键继续使用 `antigravity`,无需修改现有配置。

## Token 优化后的工作流

```text
Codex 只描述任务,不重复固定约束
  -> antigravity_execute
  -> Antigravity 修改 workspace
  -> MCP 返回分级 review manifest
  -> Codex 只检查高风险文件与行号
  -> 有明确问题才用 run_id 续跑(最多两次)
  -> 只有诊断不足才 antigravity_get_result
```

服务级 `instructions` 已内置以上策略,Codex 连接后会自动读取。

## 日常使用

不需要每次提到 Gravity Relay、MCP 或具体工具名。直接描述代码任务即可:

```text
修复用户列表空状态问题,并补充相关测试。
```

连接成功后,Codex 会读取服务的 `instructions`,自行选择紧凑计划、委派、Review 和返修流程。

如果某次不希望委派:

```text
这次由 Codex 自己修改,不调用 Antigravity。
```

如果希望每个项目都稳定自动委派,可以在目标项目的 `AGENTS.md` 中加入:

```md
# Gravity Relay delegation

对于要求实现、修复、重构或补充测试的代码任务:

1. Codex 只读取足够的信息,形成最多 8 条的简短计划。
2. 调用 antigravity_execute 交给 Antigravity 实现。
3. 返回后先检查 changed_files、diff_stat 和相关 diff hunks。
4. 发现明确缺陷时调用 antigravity_continue,最多两次。
5. Codex 负责最终验收。

以下任务不要委派:
- 只回答问题、解释代码或分析原因。
- 用户明确要求 Codex 自己修改。
- 明显只需修改一两行的简单任务。
```

如需对所有本地项目生效,可将同一规则放在:

```text
C:\Users\<用户名>\.codex\AGENTS.md
```

## 执行模式与安全边界 (Execution Modes & Trust Boundary)

Gravity Relay 支持显式执行模式,同时完全向下兼容旧版布尔字段:

| 模式 / 参数 | 说明 | CLI 映射行为 |
| :--- | :--- | :--- |
| `execution_mode: "safe"` (推荐安全模式) | 沙箱限制模式,需交互确认权限 | 启用 `--sandbox`,不传 `--dangerously-skip-permissions` |
| `execution_mode: "trusted"` (受信任模式) | 自动批准所有工具与子 Agent 操作 | 启用 `--dangerously-skip-permissions`,不启用 `--sandbox` |
| `sandbox: true` (向后兼容) | 启用沙箱限制 | 映射为 Safe 模式 |
| `skip_permissions: true` (向后兼容) | 在受信任的工作区自动批准权限 | 映射为 Trusted 模式 |

建议新调用显式选择 `safe` 或 `trusted`。为保持旧调用兼容,省略 `execution_mode` 且两个旧布尔字段均为 `false` 时,仍沿用原来的 `accept-edits` 行为:不启用沙箱,也不自动跳过命令审批。

### 冲突校验 (Option Validation)
当传入冲突或矛盾的参数组合时,Relay 会立即返回 `CONFLICTING_OPTIONS` 错误并拒绝执行:
- 禁止在 `execution_mode: "safe"` 时指定 `skip_permissions: true`。
- 禁止在 `execution_mode: "trusted"` 时指定 `sandbox: true`。
- 禁止同时传入 `sandbox: true` 和 `skip_permissions: true`。

### 信任边界与命令白名单限制说明 (Security Limitations)
> [!IMPORTANT]
> **关于内部命令白名单限制的诚实说明**:
> Gravity Relay 是调用上游 Antigravity CLI (`agy`) 的外部宿主协调器。当使用 Trusted 模式(或 `skip_permissions: true`)传递 `--dangerously-skip-permissions` 时,上游 `agy` CLI 会在内部直接自动批准所有工具调用与命令执行,不提供外部交互拦截点。因此,**在跳过权限模式下,Relay 无法在内部强行实施细粒度命令白名单**。请仅在完全受信任的本地仓库和工作区中启用 Trusted 模式。

### 工作区路径边界与允许根目录 (Allowed Roots Confinement)
Relay 严格校验 `workspace` 路径:
1. 必须为绝对路径,且必须指向存在的文件系统目录。
2. 禁止指定操作系统文件系统根目录(如 `C:\` 或 `/`)以防意外污染系统盘。
3. **可选规范允许根目录 (`GRAVITY_RELAY_ALLOWED_ROOTS`)**:
   可通过环境变量配置允许的工作区根目录列表(分号或逗号分隔):
   ```powershell
   $env:GRAVITY_RELAY_ALLOWED_ROOTS = "E:\nexp;E:\projects;D:\workspace"
   ```
   配置后,任何处于允许根目录之外的工作区路径将被拒绝并返回 `INVALID_WORKSPACE`。

## 认证预检与健康缓存 (Auth Preflight & Health Caching)

为了避免反复启动进程导致的开销以及交互式登录挂起超时,Relay 引入了轻量级认证健康管理:

1. **探测防重与并发去重 (In-flight Probe Deduplication)**:多个并发请求共享同一个在途探测 Promise,避免同时派生多个认证探测子进程。
2. **短期健康缓存 (TTL 60s)**:成功的认证探测状态会被缓存 60 秒,连续的任务执行与返修请求可直接复用,避免重复探测开销。
3. **成功后刷新**:正式任务成功本身会刷新认证健康时间,长任务结束后的 `run_id` 续跑无需立即重复探测。
4. **区分 Keyring 超时与交互式登录**:
   - **交互式登录需求 (`LOGIN_REQUIRED`)**:检测到需要浏览器 OAuth 授权或输入授权码时,Relay 立即快速失败 (Fail-Fast),避免任务长时间挂起 60 秒超时,并提示用户在终端运行 `agy auth` 登录。
   - **Keyring/凭据锁超时 (`KEYRING_TIMEOUT` / `AUTH_TIMEOUT`)**:识别为瞬态错误,预检内部具有有界退避重试(1 次);若重试后依然超时,Relay **绝不盲目启动完整任务**,直接以 `AUTH_TIMEOUT` 状态快速失败。

## 精准机器可读错误分类 (Error Classification)

执行失败时,Relay 将结果精确归一化为标准化机器可读 `status`:

- `SUCCESS`:任务成功完成且返回了合规的结构化报告。
- `PERMISSION_DENIED`:权限策略拒绝或用户在提示中拒绝了工具调用。
- `KEYRING_TIMEOUT`:系统 Keyring、Keychain 或 Secret Service 响应超时。
- `AUTH_TIMEOUT`:认证服务瞬态请求超时。
- `LOGIN_REQUIRED`:未登录或凭据失效,需交互式登录。
- `EXECUTION_TIMEOUT`:任务执行超过预设的超时时间。
- `SPAWN_ERROR`:可执行文件缺失 (ENOENT) 或无法生成子进程。
- `STREAM_ERROR`:与 CLI 通信流损坏或 NDJSON 解析异常。
- `INVALID_REPORT`:CLI 退出码为 0 但未返回有效的结构化 `WorkerReport`。
- `INVALID_JSON` / `INVALID_ENVELOPE`:CLI 输出不符合 JSON/Envelope 格式契约。
- `CONFLICTING_OPTIONS`:传入了矛盾或不安全的参数配置。
- `INVALID_WORKSPACE`:工作区路径非法或超出允许根目录范围。
- `MUTATION_ABORTED`:检测到工作区在失败尝试中已产生实际文件变更,已中止重试以保护工作区现场。
- `MCP_ERROR`:MCP 协议层未预期异常。

## 有界策略恢复与变更防重护栏 (Bounded Recovery & Mutation Guard)

Relay 采用策略驱动的自动化恢复:

1. **瞬态错误有界重试**:仅对 `KEYRING_TIMEOUT` / `AUTH_TIMEOUT` 进行指数退避重试(最多重试 1 次,共 2 次尝试)。
2. **禁止重试交互登录与确定性错误**:`LOGIN_REQUIRED`、`PERMISSION_DENIED`、`EXECUTION_TIMEOUT` 等直接快速失败,绝不盲目重试。
3. **工作区变更防重护栏 (`MUTATION_ABORTED`)**:
   在重试前,Relay 会检查工作区真实文件快照。如果上一次失败尝试已经在工作区中产生了文件修改、新增或删除,**Relay 会立即中止重试并返回 `status: "MUTATION_ABORTED"`**,保留现场并将观测到的变更返回给 Codex 评审,防止盲目重试导致代码被重复修改或产生冲突标记。

## 串行化 Worker 调度协调与 Stream 协议分析 (Worker Coordination & Stream Protocol Analysis)

### 为什么不采用持久化 stream-json 守护进程?(Technical Analysis)
上游 `agy` CLI (1.1.23) 提供了 `--input-format stream-json --output-format stream-json`,允许从 stdin 读取 NDJSON 并连续执行 turns。然而,经过对协议与生产环境的深度验证,**在多任务、多工作区 MCP Relay 场景下保持单一持久化 `stream-json` 进程在技术上是不合适且不可靠的**:
1. **工作区路径绑定 (Workspace Pinning)**:`agy` 进程在启动时必须绑定单个 `cwd` 工作区,无法通过 stdin 的单个 NDJSON turn 动态切换工作区路径。
2. **结构化 Schema 约束限制**:CLI 的 `--json-schema` 参数在 `stream-json` 模式下仅对最终回合有效,无法保证多轮交互中的单回合强类型契约。
3. **僵尸进程与凭据超期风险**:Codex 评审与返修之间可能存在数分钟至数小时的人工等待间隔。长时间保持后台 `stream-json` 进程容易产生孤儿进程泄漏、文件锁占用以及 Keyring 凭据会话静默失效。

### 生产级最佳实践方案:串行协调器 + 会话续接
Relay 采用了目前最健壮的**串行化 Worker 协调器 (`WorkerCoordinator`)** + **会话标识续接 (`--conversation <id>`)**:
- 对并发传入的 delegation 请求进行有序排队排他执行,彻底杜绝多进程竞争 Keyring 与 Git 锁的问题。
- 返修时通过 `--conversation <id>` 精确恢复上下文,保证多工作区并发隔离与进程生命周期安全。

## 工具定义

公开工具 Schema 只展示高频字段。旧版的 `plan`、`acceptance_criteria`、`constraints`、`model`、`effort`、`agent`、`timeout_minutes`、`sandbox` 和 `skip_permissions` 仍可传入,但不再占用日常工具说明上下文。

## 服务端 Profile 与固定约束

Profile 把 workspace、权限、模型、超时和项目约束放在服务端。可通过 MCP 环境变量配置:

```text
GRAVITY_RELAY_PROFILES={"trusted-code":{"workspace":"E:\\projects\\app","execution_mode":"trusted","timeout_minutes":30,"constraints":["Do not run build commands"]}}
GRAVITY_RELAY_DEFAULT_PROFILE=trusted-code
```

也可以将同一 JSON 保存为文件,并设置:

```text
GRAVITY_RELAY_PROFILE_FILE=E:\scripts\mcp-server\profiles.json
```

Profile 配置在 MCP 进程内缓存;修改后重启 MCP/Codex 连接即可生效。

全局固定约束支持 JSON 数组或每行一条:

```text
GRAVITY_RELAY_FIXED_CONSTRAINTS=["Preserve public contracts","Do not run build commands"]
```

有默认 Profile 后,Codex 日常调用只需发送 `task`;没有默认 Profile 时,再传 `profile` 或 `workspace`。

### `antigravity_execute`

启动新实现任务。成功时只返回紧凑 review packet:

```json
{ "task": "修复用户列表空状态", "profile": "trusted-code" }
```

```json
{
  "ok": true,
  "run_id": "...",
  "status": "SUCCESS",
  "summary": "完成了什么",
  "changes": {
    "count": 1,
    "files": ["src/a.ts"],
    "risk": "medium",
    "review": [{ "file": "src/a.ts", "lines": "10-28", "risk": "medium", "reason": "Implementation change" }]
  },
  "tests": { "passed": 1, "failed": 0, "not_run": 0 }
}
```

### `antigravity_continue`

优先通过 `run_id` 发送聚焦的 Review 意见。服务端自动恢复 workspace、conversation、Profile 和执行策略:

```json
{ "run_id": "...", "feedback": "空数组时仍然抛异常" }
```

旧版 `conversation_id + workspace` 调用仍然兼容。

### `antigravity_get_result`

通过 `run_id` 按需读取已保存信息(包括正常完成与早期失败的完整记录):
- `summary`:读取紧凑结果,适合新任务恢复上下文。
- `errors`:只读错误、stderr 尾部和 response 尾部。
- `full`:读取有字符上限的完整记录;只在其他诊断不足时使用。

```json
{
  "run_id": "...",
  "detail": "errors",
  "max_chars": 12000
}
```

## 真实变更观测

执行前后,MCP 会读取 Git tracked/untracked 文件变化,并生成最多 8 个按风险排序的 Review Target,包括文件、变更行范围、风险和原因。默认结果只返回最多 12 个文件;完整记录仍保存在本地。非 Git 目录会回退到 Antigravity 的文件报告。

## 完整运行记录与早期失败追踪

默认存放于:

```text
E:\scripts\mcp-server\.gravity-relay\runs\<run_id>.json
```

可通过环境变量改变数据目录:

```powershell
$env:GRAVITY_RELAY_DATA_DIR = "D:\mcp-data\gravity-relay"
```

无论是正常执行、策略冲突拒绝、路径非法还是预检认证失败,Relay 均会生成一致的运行诊断文件,便于 Codex 或开发者随时通过 `antigravity_get_result` 回溯。

## 前置条件与配置

- Node.js 20+
- Antigravity CLI (`agy`)

Windows 默认位置会自动识别:
`%LOCALAPPDATA%\agy\bin\agy.exe`

自定义 CLI 路径:
`$env:AGY_BIN = "D:\path\to\agy.exe"`

可选限制允许的工作区根目录:
`$env:GRAVITY_RELAY_ALLOWED_ROOTS = "E:\projects;D:\projects"`

## 安装与开发运行

```powershell
npm install
npm run dev
```

### Codex MCP 配置示例

```toml
[mcp_servers.antigravity]
command = "C:\\Program Files\\nodejs\\npx.cmd"
args = ["tsx", "E:\\scripts\\mcp-server\\src\\index.ts"]
cwd = "E:\\scripts\\mcp-server"
startup_timeout_sec = 20
tool_timeout_sec = 7200
```

保存后重启 Codex。现有旧连接不会热加载修改后的工具定义。

默认不跳过 Antigravity 内部权限。只有完全信任目标 workspace 和任务内容时,才选择 `execution_mode: "trusted"` 或将 `skip_permissions` 设为 `true`。