Skip to content

v0.3.3 — Per-call model override in MCP + CLI

Choose a tag to compare

@AmirShayegh AmirShayegh released this 23 Apr 21:53

Summary

Adds optional `model` to all three review tools so callers can switch models per request instead of relying on the startup-cached config value.

  • MCP: `review_plan`, `review_code`, `review_precommit` each accept `model?: string`
  • CLI: `--model ` on all three subcommands
  • Resolution order: explicit tool-call `model` → `.reviewbridge.json` → built-in default
  • Conflict rule: passing both `session_id` and `model` returns `INVALID_INPUT` — resumed threads are bound to their original model
  • Multi-chunk aware: the override is applied on chunk 1 (`startThread`); chunks 2..N inherit via `resumeThread` without re-asserting the model

Why this matters

When OpenAI ships a new flagship model, it lands in the API tier immediately but lags a few days on the ChatGPT-subscription Codex tier. During that window, `v0.3.0`/`v0.3.1` users on ChatGPT auth hit `MODEL_ERROR: ... not supported when using Codex with a ChatGPT account`. `v0.3.2` shipped a targeted error tip. `v0.3.3` now lets Claude Code (or any caller) act on that tip directly — just pass `model: "gpt-5.4"` on the next call. No config edit, no MCP restart.

Also useful for per-tool model selection in general: cheaper model for precommit, heavier for plan review.

Usage

MCP (Claude Code calls this automatically after reading the error tip):
```
review_code({ diff, model: "gpt-5.4" })
```

CLI:
```bash
git diff HEAD | npx codex-claude-bridge@latest review-code --diff - --model gpt-5.4
npx codex-claude-bridge@latest review-precommit --model gpt-5.4
```

Safety

  • The SDK forwards `--model` to `codex exec` unconditionally whenever set in `ThreadOptions`, including on `resumeThread`. This release strips `model` from the resume-path options entirely, so a thread's original model is preserved across multi-chunk reviews. Omitting the override on resume is correct-by-construction rather than relying on SDK behavior.
  • `model: ""` is rejected at both the MCP (via `z.string().min(1)`) and CLI (via trim-and-coerce-to-undefined) layers.
  • `session_id + model` is rejected at the handler layer before any session-tracker mutation, so invalid input never marks an active session `failed` in SQLite.
  • `classifyError` now receives the resolved model (override or config default) on all failure paths, so error messages report the actually-running model even on chunks 2..N of chunked reviews.

Changes

Change Detail
MCP schemas `model?: string` added to review_plan, review_code, review_precommit (z.string().min(1).optional())
CLI flags `--model ` on all three subcommands; empty-string normalization
Client plumbing New `resumeThreadOpts` helper strips model on resume; `resolvedModel` threaded through `runReview` for error context
Tests 8 new (client-layer override paths, conflict rejection, multi-chunk inheritance for both reviewCode and reviewPrecommit, handler-level forwarding); 487 total
README New `model` row per tool parameter table

Upgrading

```bash
claude mcp remove codex-bridge
claude mcp add codex-bridge -- npx -y codex-claude-bridge@latest
```

The `@latest` pin makes `npx` re-resolve on every launch, so future updates are automatic.