Skip to main content
Glama
README.md
# mcp-grok-executor

**An MCP server that turns [Grok CLI](https://x.ai) into the execution agent for Claude Code.**

Claude plans, reviews, and verifies. Grok implements, runs tests, and fixes failures. This server is the bridge: it exposes Grok's headless CLI as a set of MCP tools — including a fully orchestrated *execute → verify → auto-fix* loop — so the advisor model never has to babysit the executor.

```
You ──► Claude Code  (advisor: plan / review / judge evidence)
              │
              │  MCP (stdio)
              ▼
      mcp-grok-executor
              │  grok -p … --always-approve   (subscription OAuth)
              ▼
         Grok CLI  (executor: edit files / run tests / fix)
              │
              ▼
       your project (cwd)
```

## Why

Pairing two models works best with a clear division of labor: a strong reasoning model that owns the design and the acceptance criteria, and a fast execution model that grinds through implementation. Doing that by hand means endless copy-paste. This server makes the loop native to Claude Code:

1. You approve a plan.
2. Claude calls **`run_task`** with a prompt and a `verify_command` (e.g. `npm test`).
3. The server runs Grok, collects `git status` + `diff`, runs your verify command, and — if it fails — automatically sends the failure output back to the *same Grok session*, up to `max_fix_attempts` times.
4. Claude receives a single structured result: every attempt, the diff, the changed files, the verify output. It judges the evidence instead of orchestrating the steps.

## Requirements

- **Node.js ≥ 20**
- **Grok CLI** on your `PATH`, logged in via subscription OAuth:

  ```bash
  grok login
  grok --no-auto-update -p "Say ok."   # sanity check
  ```

  No `XAI_API_KEY` needed — auth comes from `~/.grok/auth.json`.
- **Claude Code** (or any MCP client that speaks stdio).

## Install

```bash
git clone https://github.com/emigrete/mcp-grok-executor.git
cd mcp-grok-executor
npm install
npm run build
```

## Connect to Claude Code

**Globally (recommended)** — available in every project:

```bash
claude mcp add --scope user grok -- node /absolute/path/to/mcp-grok-executor/dist/index.js
```

**Per project** — drop a `.mcp.json` in the project root:

```json
{
  "mcpServers": {
    "grok": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-grok-executor/dist/index.js"]
    }
  }
}
```

If the `grok` binary is not on the `PATH` Claude Code inherits, add `"env": { "GROK_BIN": "/path/to/grok" }`.

## Tools

| Tool | Mutates? | Purpose |
|------|----------|---------|
| `auth_status` | No | Check Grok login (`~/.grok/auth.json`) |
| `review_task` | No | Read-only analysis: Grok runs with write/shell tools disabled |
| `execute_task` | **Yes** | One-shot implementation run (`--always-approve`) |
| `run_task` | **Yes** | **Orchestrated loop**: execute → git evidence → verify → auto-fix |
| `continue_task` | Optional | Follow-up prompt into a previous Grok session |
| `task_status` | No | Poll background jobs, read the live activity log. Job records survive server restarts and are also exposed as MCP resources (`grok://jobs/recent`, `grok://jobs/{id}`) |
| `cancel_task` | No | Cancel a running background job (kills the whole process tree) |

### Common arguments

Every Grok-running tool takes:

- `prompt` *(string, required)* — self-contained task brief for Grok
- `cwd` *(string, required)* — **absolute** path to the target project
- `model`, `max_turns`, `timeout_sec` *(optional)* — per-run overrides
- `background` *(optional bool)* — return a `job_id` immediately; poll with `task_status`

### `run_task` — the orchestrated loop

```
run_task({
  prompt:             "Fix the failing suite. Don't touch the tests.",
  cwd:                "/abs/path/to/project",
  verify_command:     "npm test",        // omitted → git evidence only
  max_fix_attempts:   2,                 // default 2; 0 disables auto-fix
  verify_timeout_sec: 300                // default 300
})
```

Returns structured evidence:

```json
{
  "ok": true,
  "status": "completed",
  "sessionId": "…",
  "totalTokens": 12345,
  "attempts": [
    {
      "type": "execute",
      "exitCode": 0,
      "summary": "…",
      "durationMs": 12314,
      "usage": { "numTurns": 3, "totalTokens": 4200 }
    }
  ],
  "git": {
    "isRepo": true,
    "changedFiles": ["src/foo.js"],
    "statusAfter": " M src/foo.js\n",
    "diff": "diff --git a/src/foo.js …",
    "noChanges": false
  },
  "verify": { "command": "npm test", "ran": true, "exitCode": 0, "output": "…", "attemptsUsed": 1 }
}
```

**`status`** is one of `completed` | `failed` | `needs_advisor`:

- **`completed`** — Grok succeeded and verify passed (or no verify was requested).
- **`failed`** — Grok or verify failed after retries were exhausted.
- **`needs_advisor`** — the executor hit a genuinely ambiguous or destructive decision. Nothing is changed; the result includes a `question` for the advisor. Answer via **`continue_task`** with the returned `session_id` (and your decision in the prompt).

`totalTokens` (and per-attempt `usage`) surface cost so the advisor can see how expensive the loop was.

Loop policy:

- Auto-retry triggers **only** on `verify_command` failure. Each retry continues the *same* Grok session with the failure output and a fixed instruction to fix the underlying issue (never to weaken or delete tests).
- A failed Grok run aborts immediately — there is no verification signal to feed back.
- An empty diff never consumes retries; it is reported as `git.noChanges: true` for the advisor to judge (it may be legitimate).
- A verify timeout counts as a failure and enters the fix loop.
- `ok` is true only when Grok succeeded **and** the final verify passed (or none was requested).

## Watching Grok work live

The server runs Grok with `--output-format streaming-json` and parses the stream as it arrives. Two layers of visibility:

1. **MCP progress notifications** — during any synchronous call, Grok's narration (`[thought] …`, `[grok] …`) streams into the client's progress UI. In Claude Code you watch it think and act in the tool spinner.
2. **Live job log** — every event is appended to the job log in real time. For background jobs, `task_status` returns the growing feed, or just:

   ```bash
   tail -f ~/.cache/mcp-grok-executor/jobs/<job_id>.log
   ```

**ACP transport** — set `MCP_GROK_TRANSPORT=acp` to run `execute_task` / `run_task` (and fix retries) over `grok agent stdio` instead of the CLI stream. Visibility upgrades from narration to **real tool events**: `[tool] run_terminal_command — npm test`, per-file writes with paths, and status updates as tools complete. `review_task`, background jobs, and `continue_task` / recent-session resume still use the CLI transport.

## Sessions

`execute_task` and `run_task` return a `sessionId`. Pass it to `continue_task` for stateful follow-ups ("now update the changelog", "fix the two remaining test failures") — Grok resumes with full context of what it just did.

## Configuration

| Variable | Default | Meaning |
|----------|---------|---------|
| `GROK_BIN` | `grok` | Path to the Grok CLI |
| `GROK_AUTH_PATH` | `~/.grok/auth.json` | Auth file checked by `auth_status` |
| `MCP_GROK_TIMEOUT_SEC` | `600` | Default timeout per Grok run |
| `MCP_GROK_MAX_OUTPUT_CHARS` | `80000` | Truncation budget for inline output |
| `MCP_GROK_MODEL` | (CLI default) | Default `-m` passed to Grok |
| `MCP_GROK_CACHE_DIR` | `~/.cache/mcp-grok-executor` | Job records + logs |
| `MCP_GROK_TRANSPORT` | `cli` | `cli` (default) or `acp` (experimental — real tool events via `grok agent stdio`) |
| `MCP_GROK_REVIEW_TOOLS` | read-only set | Tool allowlist for `review_task` |
| `MCP_GROK_REVIEW_DISALLOWED` | write/shell set | Tools stripped in `review_task` |

## Advisor policy

[`CLAUDE.md`](CLAUDE.md) ships the advisor/executor policy for Claude Code: plan first, delegate after approval, prefer `run_task` with a `verify_command`, always judge the returned evidence. Copy it (or merge it into your own `CLAUDE.md`) in projects where you want the full workflow, and optionally install [`agents/fable-advisor.md`](agents/fable-advisor.md) into `~/.claude/agents/`.

## Development

```bash
npm run typecheck   # tsc --noEmit (includes tests)
npm test            # unit tests (node:test + tsx)
npm run build       # compile to dist/ (tests excluded)
npm run smoke       # build + tests + real grok hello + MCP round-trip
```

The test suite covers the stream parser, the runner (against a fake `grok` binary), git evidence, the shell runner, the orchestrator loop policy, and progress-notification throttling.

## Security notes

- `execute_task` and `run_task` run Grok with `--always-approve` — treat them like giving an autonomous agent full access to `cwd`. Gate them behind manual approval in your MCP client; leave `review_task`/`auth_status` unrestricted.
- Concurrent `run_task` calls on the same `cwd` are rejected by a per-cwd lock (avoids two agents fighting over the same tree).
- `cancel_task` kills the whole process tree of the background job, not just the top-level process.
- `verify_command` is arbitrary shell executed in `cwd` — same trust level as the execution tools. Only pass commands you'd run yourself.
- `review_task` disables Grok's write and shell tools and injects a read-only constraint, but it still runs a model with read access. Spot-check `git status` if in doubt.
- Never add `--debug` / `--debug-file` to the Grok invocation: the Grok debug log prints the OAuth bearer token in plaintext.
- Job logs under `~/.cache/mcp-grok-executor` contain prompts and outputs — don't put secrets in prompts.

## Roadmap

- ACP for `review_task` via restricted profiles (tool visibility without write/shell).
- Interactive `needs_advisor` over MCP elicitation (in-band Q&A instead of return-and-`continue_task`).
- Session/load-based `continue_task` over ACP (resume the same agent session without falling back to CLI).

## License

[MIT](LICENSE)

TDQS

A4.1/5.0

Scored across 7 tools

Disambiguation4/5

Most tools are clearly distinct: auth_status for login, task_status for monitoring, review_task for read-only analysis, execute_task and run_task for mutating work, continue_task for follow-ups, and cancel_task for aborting. The primary ambiguity is between execute_task and run_task, which both delegate implementation to Grok, though the descriptions clarify when to prefer each.

Naming Consistency4/5

All tools use lowercase_with_underscores and are two-word phrases, but there's a slight inconsistency in suffixes: five tools end in '_task' while two end in '_status'. The pattern is otherwise highly predictable, with verb-led names for actions and noun-led names for status queries, so the deviation is minor.

Tool Count5/5

Seven tools is well-scoped for a Grok executor server. Each tool serves a distinct function in the workflow of delegating tasks, monitoring them, and managing sessions, without feeling bloated or sparse.

Completeness4/5

The domain of delegating implementation tasks to Grok is well covered: auth check, read-only review, mutating execution (both one-shot and orchestrated), continuation, status polling, and cancellation. A minor gap is the lack of an explicit tool to retrieve full output of a completed job, though task_status may partially address this.

Maintenance

ActivityStale
ResponsivenessNo issues