Skip to main content
Glama

llm-cli-gateway

CI Security OpenSSF Scorecard npm License: MIT

"Without consultation, plans are frustrated, but with many counselors they succeed." — Proverbs 15:22 (LSB)

Secure local control plane for AI coding agents.

llm-cli-gateway lets supported MCP clients operate Claude Code, Codex, Gemini/Antigravity, Grok Build, Mistral Vibe, Cognition Devin, Cursor Agent, and configured HTTP API providers through one user-owned gateway while preserving native CLI sessions, local credentials, durable async jobs, validation receipts, and review workflows.

Why developers try it: use the client you are already in to delegate work to local coding agents, scope remote execution to registered workspaces, gate risky actions, survive disconnects, and collect auditable review evidence without turning those agents into a generic chat proxy.

Current signals: CI and security workflows pass on main, OpenSSF Scorecard is published, OpenSSF Best Practices is passing, releases use Sigstore signing, and the package is MIT licensed.

Quick Start

npm install -g llm-cli-gateway

Or use directly with npx from an MCP client:

{
  "mcpServers": {
    "llm-gateway": {
      "command": "npx",
      "args": ["-y", "llm-cli-gateway"]
    }
  }
}

Related MCP server: MCP-AI-Gateway

What It Provides Today

llm-cli-gateway is a single-user MCP control plane for operating AI coding agents from supported local or remote clients. It is more than a thin CLI wrapper:

  • Runs registered provider CLIs and configured HTTP API providers through consistent sync and async MCP tools.

  • Persists long-running jobs, supports restart-safe result collection, deduplication, cancellation, and sync-to-async deferral.

  • Tracks sessions, real CLI resume paths, structured response metadata, and cache telemetry.

  • Supports cache-aware promptParts, including explicit Claude cache_control when opted in.

  • Can run supported provider requests inside gateway-managed git worktrees for isolated multi-agent review and implementation loops when using the local file-backed session manager. PostgreSQL-backed sessions reject this filesystem-local feature before creation. Grok, Devin, and Mistral require an explicit provider-native sessionId for a gateway worktree; fresh, createNewSession, and resumeLatest-only worktree requests fail closed because they cannot durably reselect it. Materialization suppresses repository, system, and global Git hooks, configured clean, smudge, and process checkout filters, sparse checkout, and lazy object fetching. Filter-dependent content such as Git LFS remains in its repository representation instead of executing host commands.

  • Ships personal-appliance setup surfaces: HTTP transport with bearer-token auth, doctor --json, setup UI artifacts, provider setup snippets, Docker fallback, and checked release bundles.

  • Remote web connectors use MCP OAuth discovery and authorization-code setup with static client or shared-secret gates. Client secrets are generated locally, stored only as hashes, and printed only by explicit copy-once commands.

  • Provider CLI requests can select registered workspaces by alias via workspace; every HTTP/tunnel request must use a registered alias, session workspace, or [workspaces].default before provider execution. Local unrestricted filesystem access is the stdio transport.

Workflow Assets

The repo ships agent-ready workflow skills under .agents/skills for async orchestration, session continuity, multi-LLM review, implement-review-fix loops, retrospective evidence walks, secure approval-gated dispatch, and Personal Agent Config Kit operations. Nine caller-facing skills are bundled in the published npm package: async-job-orchestration, multi-llm-review, session-workflow, secure-orchestration, implement-review-fix, retrospective-walk, public-demo-session, least-cost-routing, and personal-agent-config-kit. Machine-readable DAG-TOML plans live under docs/plans and setup/install-plan.dag.toml for workflows that need deterministic sequencing and verification gates.

Skill packs can be updated outside the core npm release by placing skill directories in local, operator-controlled paths. The gateway loads bundled skills first, then [skills].paths, then LLM_GATEWAY_SKILLS_PATH, then ~/.llm-cli-gateway/skills when it exists; later roots override earlier skills by name. Each skill is a directory containing SKILL.md. A root may also carry skill-pack.json to pin expected SKILL.md hashes:

[skills]
paths = ["/opt/llm-cli-gateway/skills"]
export LLM_GATEWAY_SKILLS_PATH="/opt/team-skill-pack:/opt/incident-skill-pack"
{
  "name": "team-pack",
  "version": "1.0.0",
  "skills": [
    {
      "name": "incident-retrospective",
      "sha256": "<sha256 of incident-retrospective/SKILL.md>"
    }
  ]
}

The loader is intentionally local-only: it never fetches remote Markdown at startup. To update a pack, install or replace files through your package manager or deployment system, then restart the gateway so the advertised skills://... resources refresh.

The next documentation focus is provider-specific skill and DAG-TOML pairs for each outbound CLI and API-provider family: Claude, Codex, Gemini/Antigravity, Grok, Mistral Vibe, Devin, Cursor Agent, OpenAI-compatible endpoints, Anthropic Messages, and xAI Responses. The implementation plan is tracked in docs/plans/provider-workflow-assets.dag.toml, with each provider asset expected to cover install/login checks or token-env checks, session behavior, approval modes, cache/telemetry surfaces, failure modes, and a smoke-test gate.

Trust & Supply Chain

OpenSSF Best Practices Releases: Sigstore signed

  • CI runs build, lint, format, tests, package checks, and npm audit.

  • Security CI runs actionlint, zizmor, shellcheck, typos, osv-scanner, gitleaks, and lychee.

  • GitHub release installer artifacts are checksummed and signed with Sigstore keyless signing.

  • npm releases use a generated prod-only shrinkwrap and release security audit; GitHub Actions Trusted Publishing exchanges the job's OIDC identity for short-lived npm publish credentials.

  • The npm package intentionally ships a generated, prod-only npm-shrinkwrap.json so registry installs resolve the audited release tree. Release gates regenerate it from package-lock.json, compare for parity, and run a registry-fidelity consumer install before publishing.

  • Socket behavioural alerts are documented in socket.yml and under "Security Considerations" below. shellAccess and shrinkwrap are reviewed package capabilities/configuration for this CLI appliance, not hidden install behaviour.

Personal MCP Appliance

The personal-appliance contract keeps that surface intentionally narrow: one trusted user runs the gateway on a machine or volume they own, connects one MCP endpoint, and lets supported clients operate local coding agents through workspace-scoped, approval-gated, auditable requests.

The product contract is documented in docs/personal-mcp/PRODUCT_CONTRACT.md. It defines the single-user scope, security posture, target support matrix, and provider-support verification gates. Public setup guides must not claim ChatGPT, Claude web, Claude Desktop, Codex, Gemini CLI, Gemini web, or Grok inbound support until the corresponding provider/client path has been verified.

This project does not provide hosted multi-tenant credential custody. Provider credentials stay on the user's machine or user-owned deployment volume.

For a single developer who works on several workstations and repositories, the Personal Agent Config Kit guide explains the Git-synchronised personal baseline, repository overlays, immutable context stamps, and workstation-safe provider continuity model. The baseline directory is confined to a non-symlinked descendant of the local home directory, and every publish or sync revalidates its configured origin fetch and push URLs against the HTTPS/SSH-only policy. The Kit is intentionally local-caller-only; Kit provider execution and recovery of an unadmitted attempt require healthy durable SQLite or PostgreSQL async-job admission. Kit mode supports Claude, Codex, and Mistral; every other provider fails closed while it is enabled. Kit scope never inherits the gateway process cwd: Claude and Mistral require a registered workspace selection or configured default, while Codex can also use an explicit absolute workingDir. Relative Kit workingDir values are rejected before filesystem or Git inspection. It disables cross-model validation tools while enabled and is not an HTTP/OAuth configuration or remote execution feature.

For a retention-pinned non-Kit Claude MCP request configuration, follow the local-only same-host recovery procedure. It accepts no SQL or arbitrary-path override. A valid recovery invocation emits JSON and exits 0 after success or 2 for a safe refusal; invalid usage or unavailable durable storage exits 1.

Release-readiness history is tracked in docs/personal-mcp/RELEASE_READINESS.md. Dogfooding evidence (which target LLMs guided setup, what unsafe suggestions were captured, and which findings were deferred from the initial personal-appliance rollout) is in docs/personal-mcp/DOGFOODING_RESULTS.md.

Current personal-appliance artifacts include:

  • Streamable HTTP startup: LLM_GATEWAY_AUTH_TOKEN=<token> npm run start:http

  • Machine-readable diagnostics: npm run doctor

  • Go bootstrapper: installer/ with setup, doctor --json, start, stop, status, repair, upgrade, uninstall, print-client-config, and verified bundle download commands.

  • Release packaging: on the public mirror, the release workflow builds Linux binaries on GitHub-hosted ubuntu-latest and builds Windows/macOS binaries on their GitHub-hosted platform runners. The private upstream uses its internal self-hosted Linux runner. Each release publishes checksummed platform bundles with the gateway, production dependencies, and a managed Node runtime; see installer/packaging/README.md.

  • Docker Compose fallback: docker/personal.compose.yml + docker/Dockerfile.personal for users who already manage containers.

  • Local setup UI artifact: setup/ui/index.html

  • Provider setup snippets: setup/providers/

  • Cross-validation tools: review_changes, validate_with_models, second_opinion, compare_answers, red_team_review, consensus_check, ask_model, synthesize_validation, job_status, job_result, and validation_receipt (plus the validation-receipt://{validationId} resource). review_changes and durable receipts require a SQLite or PostgreSQL validation-run store and are absent in Personal Agent Config Kit mode.

Install / Upgrade / Uninstall (single binary)

Windows PowerShell:

$Version = '<version>'
$Base = "https://github.com/verivus-oss/llm-cli-gateway/releases/download/v$Version"
$InstallDir = Join-Path (Join-Path $env:LOCALAPPDATA 'Programs') 'llm-cli-gateway'
$ExeName = "llm-cli-gateway-$Version-windows-amd64.exe"
$BundleName = "llm-cli-gateway-bundle-$Version-windows-amd64.tar.gz"
$Exe = Join-Path $InstallDir 'llm-cli-gateway.exe'
$Checksums = Join-Path $InstallDir 'SHA256SUMS'
$ChecksumBundle = Join-Path $InstallDir 'SHA256SUMS.sigstore.json'
New-Item -ItemType Directory -Force $InstallDir | Out-Null
Invoke-WebRequest -UseBasicParsing "$Base/$ExeName" -OutFile $Exe
Invoke-WebRequest -UseBasicParsing "$Base/SHA256SUMS" -OutFile $Checksums
Invoke-WebRequest -UseBasicParsing "$Base/SHA256SUMS.sigstore.json" -OutFile $ChecksumBundle
cosign verify-blob $Checksums --bundle $ChecksumBundle --certificate-identity "https://github.com/verivus-oss/llm-cli-gateway/.github/workflows/release-installer.yml@refs/tags/v$Version" --certificate-oidc-issuer "https://token.actions.githubusercontent.com"
if ($LASTEXITCODE -ne 0) { throw "Sigstore verification failed for SHA256SUMS" }
function Get-ReleaseSha256($Name) {
  $line = Select-String -Path $Checksums -Pattern "^[a-fA-F0-9]{64}\s+$([regex]::Escape($Name))$" | Select-Object -First 1
  if (-not $line) { throw "No SHA256SUMS entry found for $Name" }
  return (($line.Line -split "\s+")[0]).ToLowerInvariant()
}
if ((Get-FileHash $Exe -Algorithm SHA256).Hash.ToLowerInvariant() -ne (Get-ReleaseSha256 $ExeName)) { throw "Checksum mismatch for $ExeName" }
$env:RVWR_GATEWAY_BUNDLE_URL = "$Base/$BundleName"
$env:RVWR_GATEWAY_BUNDLE_SHA256 = Get-ReleaseSha256 $BundleName
& $Exe setup
& $Exe stop
& $Exe install-bundle
& $Exe start
& $Exe status
& $Exe doctor

The Windows installer keeps a stable llm-cli-gateway.exe command in %LOCALAPPDATA%\Programs\llm-cli-gateway and adds that directory to the user PATH. Do not script against release-versioned exe names after install.

# After downloading the binary that matches your OS/arch from a release:
cosign verify-blob SHA256SUMS --bundle SHA256SUMS.sigstore.json \
  --certificate-identity "https://github.com/verivus-oss/llm-cli-gateway/.github/workflows/release-installer.yml@refs/tags/v<version>" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com"
sha256sum --check SHA256SUMS            # verify before run (or `shasum -a 256 --check` on macOS)
chmod +x llm-cli-gateway-<ver>-<os>-<arch>
./llm-cli-gateway-<ver>-<os>-<arch> setup
./llm-cli-gateway-<ver>-<os>-<arch> install-bundle    # uses the platform bundle URL/SHA256
./llm-cli-gateway-<ver>-<os>-<arch> start
./llm-cli-gateway-<ver>-<os>-<arch> doctor

# Upgrade: replace the binary, set the new bundle env vars, run upgrade.
./llm-cli-gateway-<new>-<os>-<arch> upgrade

# Uninstall: dry-run first, then run with --yes.
./llm-cli-gateway-<ver>-<os>-<arch> uninstall
./llm-cli-gateway-<ver>-<os>-<arch> uninstall --yes

Docker fallback:

LLM_GATEWAY_AUTH_TOKEN=$(openssl rand -hex 32) \
  docker compose -f docker/personal.compose.yml up -d
docker compose -f docker/personal.compose.yml run --rm doctor

Features

Core Capabilities

  • Multi-LLM Orchestration: Unified interface for Claude Code, Codex, Gemini, Grok, Mistral (Vibe), Devin, and Cursor Agent CLIs

  • Session Management: Track gateway session metadata and provider-specific continuity with persistent storage

  • Gateway-owned worktrees: Run supported sync or async provider requests inside a managed git worktree with the local file-backed session manager. Same-session reuse requires same-host durable ownership plus a matching live Git registration and gateway branch; manager-level named path collisions fail closed. PostgreSQL-backed sessions reject worktrees before creation because a different database-connected host cannot safely own filesystem cleanup. Grok, Devin, and Mistral require an explicit provider-native sessionId; fresh, createNewSession, and resumeLatest-only worktree requests fail closed. A worktree requires a registered workspace selected explicitly, through caller-owned session metadata, or by the configured default; it never inherits process cwd or combines with workingDir, addDir, or includeDirs. Materialization suppresses repository, system, and global Git hooks, configured clean, smudge, and process checkout filters, sparse checkout, and lazy object fetching. Filter-dependent content such as Git LFS remains in its repository representation instead of executing host commands. Session deletion and TTL eviction hide a durably owned worktree session while cleanup runs. If Git removal fails, the file-backed store retains a durable cleanup-pending tombstone, blocks reuse, and retries cleanup when that store is registered on the owning host. The record is finalized only after verified Git removal.

  • Token Optimization: opt-in prompt/response compaction via optimizePrompt / optimizeResponse, both defaulting to false. The 44% / 37% figures are v1.0.0 measurements on a specific corpus, not a guarantee: src/optimizer.ts is a deterministic phrase-stripper, and nothing measures a ratio at runtime.

  • Correlation ID Tracking: Full request tracing across all LLM interactions

  • Cross-Tool Collaboration: LLMs can use each other via MCP (validated through dogfooding)

Observability

  • Durable Flight Recorder: Provider requests and responses follow [persistence].backend: SQLite writes to ~/.llm-cli-gateway/logs.db by default, while PostgreSQL writes them to the configured database with the other durable subsystems. A PostgreSQL failure leaves the recorder unavailable or degraded and is reported generically on health surfaces; it never falls back to SQLite. Existing rows are not migrated or dual-read when the backend changes. Records include correlation IDs, duration, and token usage where the provider emits it (today: claude on stream-json/json, codex, and the API providers; grok, gemini, mistral, devin and cursor emit no usage on their CLI wire). Two exclusions are worth knowing: cross-LLM validation seats write no flight-recorder row at all, so llm_request_result cannot read one back by correlation ID, and repository-review seats are additionally excluded by design so review evidence is not retained in a non-expiring table. The retry_count and circuit_breaker_state columns are constants on the async path, which is the production path; retry and circuit breaking apply only to the direct-execute fallback. Read history through llm_request_list and llm_request_result so per-principal ownership checks remain in force. For human browsing of a SQLite deployment: datasette ~/.llm-cli-gateway/logs.db

  • Structured Metadata: Tool responses include machine-readable structuredContent (model, cli, correlationId, sessionId, durationMs, token counts)

  • Cache observability resources: cache-state://global, cache-state://session/{id}, and cache-state://prefix/{hash} MCP resources return aggregate cache hit/miss/savings — tokens and hashes only, no prompt text. session_get includes a cacheState block when the session has prior requests.

  • Provider capability inventory: provider_tool_capabilities and provider-tools://catalog expose the gateway request fields, supported/degraded provider controls, local skill/tool discovery, and safe config-surface hints for Claude Code, Codex CLI, Gemini/Antigravity, Grok CLI/API, Mistral Vibe, Cognition Devin, and Cursor Agent. doctor --json includes a compact provider_capabilities summary for setup assistants.

Cache-aware operation

Every *_request and *_request_async tool except devin_request / devin_request_async and cursor_request / cursor_request_async accepts an optional promptParts field that structures the prompt for better cache hit rates (the Devin and Cursor headless paths take a plain prompt only). The gateway concatenates the parts in canonical order (system → tools → context → task) so that the stable prefix bytes precede the volatile task tail unchanged across calls, letting each provider's automatic prompt-caching land on the same content hash each time.

{
  "promptParts": {
    "system": "You are a helpful code reviewer.",
    "tools": "You have access to Read, Grep, Bash.",
    "context": "<long stable context block — file dumps, etc.>",
    "task": "Review the changes in src/foo.ts for security issues."
  }
}

prompt and promptParts are mutually exclusive — pass exactly one.

Per-CLI capability matrix (prefix discipline is automatic via promptParts for all providers except Devin and Cursor, which have no promptParts surface; explicit levers are provider-specific):

CLI

Prefix discipline

Explicit lever(s)

claude

yes

promptParts.cacheControl + outputFormat: "stream-json" (Anthropic cache_control breakpoints on stable blocks; ttl="1h" forced)

codex

yes

none (OpenAI implicit)

gemini

yes

none (implicit server-side)

grok

yes

compactionMode / compactionDetail (context compaction: `summary

mistral

yes

none (implicit)

devin

no

plain prompt only

cursor

no

plain prompt only

Claude example (explicit cacheControl)

claude_request({
  promptParts: {
    system: "You are a helpful code reviewer.",
    context: "<long stable file dump>",
    task: "Review the diff.",
    cacheControl: { system: true, context: true }, // task is never marked
  },
  outputFormat: "stream-json",
});

Gateway emits the stream-json stdin path with cache_control: {type:"ephemeral", ttl:"1h"} on marked blocks only.

Grok example (compaction)

grok_request({
  promptParts: { system: "...", context: "...", task: "..." },
  compactionMode: "segments",
  compactionDetail: "balanced",
});

Emits --compaction-mode segments --compaction-detail balanced.

See docs/personal-mcp/PROVIDER_CACHE_SURFACES.md for full surfaces, telemetry differences (e.g. Grok -p vs ACP), exact stream-json payload shapes, and cross-LLM review notes.

Opt-in flags (all default off) live under [cache_awareness] in ~/.llm-cli-gateway/config.toml.

Reliability & Performance

  • Retry Logic: Exponential backoff with circuit breaker for transient failures

  • Atomic File Writes: Process-specific temp files with fsync for data integrity

  • Host-protection backpressure: bounded HTTP session lifecycle (max sessions + idle reaper), global and per-provider job-execution limits with a bounded FIFO queue, and a configurable per-job output cap (default 50MB). See Host-protection limits.

  • NVM Path Caching: Eliminates I/O overhead on every request

  • Long-Running Jobs: Non-time-bound async execution via *_request_async + polling tools

Security & Quality

  • Comprehensive Testing: 1,700+ tests covering unit, integration, and regression scenarios with real CLI execution

  • Input Validation: Zod schemas prevent injection attacks

  • No Secret Leakage: Generic session descriptions only (file permissions 0o600)

  • No ReDoS: Bounded regex patterns prevent catastrophic backtracking

  • Type Safety: Strict TypeScript with comprehensive error handling

  • Supply-chain hardening: a dedicated .github/workflows/security.yml runs actionlint, zizmor, shellcheck, typos, osv-scanner, gitleaks, and lychee on every push and PR (see SECURITY.md for the threat model)

Provider capability surface

Every provider is reachable through the same request, session, job, and validation machinery, but the underlying CLIs differ in what they natively expose. The table records what actually shipped per provider; discover the live surface at runtime with provider_tool_capabilities, list_models, and the provider-acp://<provider> / provider-tools://<provider> resources.

Provider

CLI request tools

Native ACP

Live model discovery

Admin surface

Claude Code (claude)

claude_request / _async

None (CLI-first; no ACP entrypoint at its tracked version)

model aliases, reasoning-effort levels, fallback model

read-only via provider_admin_list / provider_admin_run

OpenAI Codex (codex)

codex_request / _async, codex_fork_session

None (codex-cli advertises mcp-server / app-server transports, not native ACP)

codex debug models

read-only via provider_admin_list / provider_admin_run

Gemini / Antigravity (gemini, agy)

gemini_request / _async

None (agy exposes no ACP entrypoint; legacy Gemini CLI ACP evidence does not transfer)

agy models

read-only via provider_admin_list / provider_admin_run

xAI Grok (grok)

grok_request (sync transport: "acp") / _async

Native via grok agent stdio

grok models + ~/.grok/config.toml

read-only via provider_admin_list / provider_admin_run

Mistral Vibe (mistral)

mistral_request (sync transport: "acp") / _async

Native via vibe-acp

Vibe config plus the VIBE_ACTIVE_MODEL active model and agent profiles

read-only via provider_admin_list / provider_admin_run

Cognition Devin (devin)

devin_request (sync transport: "acp", agentType: summarizer|review) / _async

Native via devin acp

--model / DEVIN_MODEL

read-only via provider_admin_list / provider_admin_run

Cursor Agent (cursor)

cursor_request (sync transport: "acp") / _async

Native via cursor-agent acp (companion-owned)

model aliases

read-only via provider_admin_list / provider_admin_run

  • Native ACP is reported honestly. grok, mistral, devin, and cursor expose a native ACP entrypoint, so provider-acp://<provider> carries the negotiated initialize capability set and the derived session-method availability, and the sync *_request accepts transport: "acp" (fails closed unless [acp] and the provider's runtime_enabled gate are set). ACP routing is sync-only: the *_request_async variants always run the CLI transport and do not accept transport: "acp" (nor Devin's agentType); async ACP parity is a later phase. ACP workspace selection is gateway-owned: an explicit ACP workspace must be a registered alias. A fresh remote ACP request uses that alias or [workspaces].default; a remote resume is fixed to its recorded canonical alias and cwd, and a different or unbound workspace is rejected. Local ACP may omit workspace; each unscoped process then gets a fresh private 0o700 neutral directory that is removed after the process exits, never a shared predictable temp path. claude, codex, and gemini have no native ACP entrypoint at their target CLI versions; their provider-acp:// records report native: false with no methods and no adapter-as-native masquerade, and they expose no transport: "acp" selector.

  • Managed approval is Claude-only today. approvalStrategy:"mcp_managed" is executable only by the Claude CLI adapter, which launches Claude with a request-scoped generated MCP configuration and --strict-mcp-config. It permits only provisioned, gateway-owned MCP definitions and rejects dynamic npx, ambient-PATH, and Codex-config overrides. Codex, Gemini, Grok, Mistral, Devin, and Cursor reject mcp_managed before launching a provider because their current adapters cannot isolate ambient MCP configuration. For those adapters, use approvalStrategy:"legacy"; approvalPolicy has no effect.

  • ACP has its own permission bridge. approvalStrategy:"mcp_managed" and any approvalPolicy are rejected when transport:"acp" is selected. Use the Claude CLI transport for managed approval. ACP host services fail closed, gated by the tool-call category the agent declares: write is denied unless allow_write_host_services is set, execute unless allow_terminal_host_services is set, and any other category is denied outright, including fetch and every unrecognised kind, so a new upstream tool kind cannot be auto-approved by default. Approval is expressed only by selecting an agent-offered single-use allow option; an agent that offers only a persistent allow_always grant is denied, so ACP never maps a raw CLI bypass input to a standing permission grant. Note the boundary is this category gate: it constrains what the agent may ask the gateway to do, not what the agent does in its own process.

  • Resources are generated from the provider registry for every CLI provider: models://<provider>, sessions://<provider>, provider-acp://<provider>, provider-tools://<provider>, and provider-subcommands://<provider>.

  • Model discovery is live and account-aware: the discovery listed above reaches models://<provider> and list_models, degrading to static registry facts when a live probe is unavailable (a resource read never spawns a CLI).

  • Admin surfaces are discovery-driven and output-redacted. provider_admin_list and provider_admin_run are read-only for every provider. State-mutating admin operations are exposed only through provider_admin_mutate, gated behind [admin] allow_mutating_cli_admin_ops, the remote cli:admin scope, an approval gate, and an audit record. Mutating ACP session operations are likewise gated behind [acp] allow_mutating_session_ops.

  • Validation commands work across every provider: review_changes, validate_with_models, second_opinion, compare_answers, red_team_review, consensus_check, ask_model, and synthesize_validation, with canonically hashed immutable receipts via validation_receipt and the validation-receipt://{validationId} resource. review_changes captures a complete, hashed Git artifact and starts repository-bound read-only reviewers.

Prerequisites

Node.js >= 24.4.0 is required (engines.node in package.json). The SQLite backend uses Node's built-in node:sqlite module, so there is no native binding to compile and no install scripts run. The 24.4 floor is where allowBareNamedParameters defaults to true, which the SQLite persistence layer relies on.

Running the source-tree release audit also requires Bash and flock from util-linux. This prerequisite was verified against commit 242e7669565ecc7c71183f5f7133791a1384ca7c. Release automation runs the audit on Ubuntu. On macOS, install a compatible flock before running npm run security:audit or the full npm run check gate.

Before using this gateway, you need to install the CLI tools you want to use:

Claude Code CLI

# Installation instructions for Claude Code
# Visit: https://docs.anthropic.com/claude-code
npm install -g @anthropic-ai/claude-code

Codex CLI

npm install -g @openai/codex
codex login

Gemini (Google Antigravity CLI)

The Gemini provider runs through Google Antigravity CLI (agy).

curl -fsSL https://antigravity.google/cli/install.sh | bash
# Docs: https://antigravity.google/docs

Grok Build CLI (xAI)

curl -fsSL https://x.ai/cli/install.sh | bash
grok login   # OAuth flow; for headless auth, set XAI_API_KEY
# Docs: https://docs.x.ai/build/overview

Mistral Vibe CLI

# Pick one — the gateway's cli_upgrade auto-detects which one you used.
curl -LsSf https://mistral.ai/vibe/install.sh | bash
pip install mistral-vibe
uv tool install mistral-vibe
brew install mistral-vibe

vibe --setup
# Complete the API-key setup locally. Do not paste the key into a chat.
# Current Vibe defaults session logging to enabled. If an older config disabled it,
# edit ~/.vibe/config.toml and set:
# [session_logging]
# enabled = true

Vibe-specific notes:

  • Model selection is via the VIBE_ACTIVE_MODEL environment variable — Vibe has no --model flag. The gateway discovers ~/.vibe/config.toml / VIBE_MODELS, injects VIBE_ACTIVE_MODEL only when a model is explicitly requested or Vibe config needs recovery, and retries once after a model-not-found failure with refreshed discovery.

  • permissionMode is the Vibe --agent name. Builtins are default | plan | accept-edits | auto-approve; Vibe also accepts install-gated builtins (e.g. lean) and custom agents from ~/.vibe/agents. Requests pass the selected name through for Vibe to validate. mcp_managed is not available for Vibe.

  • Tool controls use Vibe's native flags. The gateway emits one --enabled-tools <tool> flag per allowedTools entry and one --disabled-tools <tool> flag per disallowedTools entry. Vibe applies disabled tools after enabled-tool filtering.

  • Usage telemetry is best-effort. Vibe does not emit token or cost data in programmatic stdout. When the gateway knows Vibe's native session UUID, it reads ~/.vibe/logs/session/session_<...>/meta.json for usage and cost. A missing, malformed, or not-yet-known session log leaves those fields empty.

  • No self-update: cli_upgrade --cli mistral detects whether you used pip / uv / brew and dispatches the matching upgrade command. Running vibe update is not a thing.

Installation

As an MCP server (npm)

npm install -g llm-cli-gateway

Or use directly with npx:

{
  "mcpServers": {
    "llm-gateway": {
      "command": "npx",
      "args": ["-y", "llm-cli-gateway"]
    }
  }
}

From source

git clone https://github.com/verivus-oss/llm-cli-gateway.git
cd llm-cli-gateway
npm install
npm run build

Usage

As an MCP Server

For clients that already support local stdio MCP servers, add a configuration like:

{
  "mcpServers": {
    "llm-cli-gateway": {
      "command": "node",
      "args": ["/path/to/llm-cli-gateway/dist/index.js"]
    }
  }
}

Stdio is the recommended path for unrestricted machine-local development access. HTTP MCP, including localhost HTTP and tunneled HTTPS, is treated as remote-capable for provider execution: provider tools must resolve a registered workspace alias, a session workspace, or [workspaces].default before spawning a CLI. Remote clients should pass relative workingDir, addDir, and include-directory values inside the selected workspace, and may resume only gateway-tracked sessions they own. Raw native provider session IDs are local-only. Disabling auth or using a no-auth connector path is not a filesystem bypass.

For a local CLI request with no resolved workingDir, registered workspace, or gateway-managed worktree, the child runs in a fresh private 0o700 temporary directory that is removed after the process exits. It never inherits the gateway repository cwd or its provider-native instruction context. The gateway canonicalizes the temp root and rejects or relocates it when any ancestor contains .git, AGENTS.md, AGENTS.override.md, Agents.md, AGENT.md, CLAUDE.md, Claude.md, CLAUDE.local.md, .claude/CLAUDE.md, .claude/rules/, .cursor/rules/, .cursorrules, GEMINI.md, or .vibe/config.toml, including through a symlinked or custom TMPDIR beneath that context. The list covers entries a provider discovers by walking up from its cwd. User-scope configuration such as ~/.claude/settings.json is deliberately absent: it loads on every invocation regardless of cwd, so relocating the workspace would not isolate it. Provider-native resumeLatest operations that use a cwd-scoped latest-session pointer therefore require an explicit workingDir, workspace, or configured default workspace and fail closed when none is available. Use explicit target selection whenever several repositories are active at once.

CLI request schemas accept prompts up to 100,000 characters, but operating systems also impose byte limits on individual argv elements. Codex new and resume requests stream the exact prompt over stdin. codex_fork_session remains argv-bound and rejects an oversized UTF-8 prompt before spawn as non-retryable input_too_large. Other providers whose current CLI contracts require an argv prompt use the same admission rule. Every other caller-controlled argv value is checked on its final encoded form too, including serialized agent/schema JSON, joined tool lists, instruction overrides, paths, model names, and native session IDs. The final spawn boundary checks every argv element plus the aggregate resolved command line against a conservative platform-specific byte budget and a 2,048-element cap. The aggregate byte budget excludes the environment but reserves headroom for it; on Windows, pre-resolution admission assumes the smaller npm .cmd/.bat wrapper limit until command resolution proves a native executable. Native session and resume flags on non-Kit requests are included before workspace, session, provider-artifact handoff, or durable job side effects. Claude Kit projects its eventual argv before materializing its compiled context artifact or allocating a durable Kit session. An embedded NUL byte in the command or any argv element is rejected before spawn as non-retryable invalid_input. Caller-facing results, long-lived job memory, durable job args, and async flight rows use a fixed invalid-argv marker; the optional duplicate durable payload is suppressed. None retains the rejected vector or Node's value-echoing native error. Native E2BIG, including an environment-driven failure, is normalized without retaining the native spawnargs. The gateway never truncates instructions or other values to make them fit. For stdin-backed requests, a clean provider exit is accepted only after the complete payload write callback succeeds. A closed or still-pending pipe becomes a fixed, non-sensitive incomplete-delivery failure; timeout, cancellation, and provider nonzero exits remain authoritative.

This generic stdio example is not provider-support verification for the Personal MCP Appliance. Client-specific setup guides for ChatGPT, Claude web, Claude Desktop, Codex, Gemini CLI, Gemini web, and Grok remain gated by the provider-support matrix in docs/personal-mcp/PRODUCT_CONTRACT.md.

Available Tools

Cross-LLM Validation Tools

The personal-appliance surface exposes simplified validation tools for non-developer clients. These tools start provider CLI jobs through the durable async job manager and return normalized provider status plus raw job references.

  • validate_with_models: ask two or more providers to independently validate a question.

  • review_changes: capture one complete Git review artifact, fence repository content as untrusted data, and start read-only independent reviewers. See Repository change review.

  • second_opinion: ask one provider to review an answer.

  • red_team_review: challenge a plan, answer, or document for risks and failure modes.

  • consensus_check: check whether providers agree with a claim.

  • ask_model: ask one provider through the simplified surface.

  • synthesize_validation: run an explicit judge model after provider results have been collected. General validation requires the caller's question and terminal normalized results. A review_changes run instead reloads its exact owned durable results from validationId; caller-supplied question/results are ignored.

  • list_available_models: list the models each provider CLI exposes through the simplified surface.

  • job_status and job_result: poll and collect validation job outputs.

  • validation_receipt: retrieve the canonically hashed immutable receipt of a terminal cross-LLM validation run by validationId (returns minted | pending | verification_failed | expired_unminted | not_found, own-or-not-found). verification_failed means a stored receipt exists but disagrees with its durable run, which is a defect to investigate; expired_unminted only ever means absence. format: "markdown" renders a human-readable report; includeRawResponses inlines complete provider answer text when the linked job still exposes identity-verified output. Registered only when the attached job store provides the durable validation-run store capability (sqlite and postgres).

The same receipt is also exposed as the validation-receipt://{validationId} MCP resource (same durable gate and own-or-not-found owner scoping).

The validation report preserves per-provider disagreement. Optional judge synthesis is explicit about which provider produced the judge job.

Repository change review

review_changes accepts an absolute local workingDir or a registered workspace, then resolves scope: "auto" | "uncommitted" | "branch" | "commit". It can take an explicit Git base, literal repository-relative paths, stance: "standard" | "adversarial", reviewer models, an optional judgeModel, trustCursorWorkspace, and fail-closed artifact/prompt byte ceilings.

Cursor refuses to review a directory it does not trust, so a cursor seat is granted --trust only when the reviewed directory is a registered [[workspaces.repos]] path whose providers include cursor (a gateway worktree beneath one counts, and the nearest enclosing registration decides). On any other directory the cursor seat is skipped with an actionable reason, and the rest of the roster still runs. trustCursorWorkspace: true accepts the grant for one durable review run. The consent applies to Cursor seats in that run's reviewer roster and to its planned Cursor judge when synthesize_validation launches it later. It is bound to the run owner, repository, and planned judge, so another principal or review run cannot replay it. That is a real decision rather than a formality: a trusted folder is also where cursor loads project rules and AGENTS.md, so the repository under review gains some influence over its own reviewer, which the fenced review prompt otherwise forbids. The artifact keeps committed, staged, unstaged, and regular non-ignored untracked file evidence separate. It forces tracked diffs to remain readable even when in-tree attributes mark them as non-diffable. The review-evidence.v2 artifact exposes committedPatch, stagedPatch, and unstagedPatch independently; each segment carries its sorted path inventory, encoding, exact byte length, SHA-256 identity, and content. This prevents an index change and its worktree-only reversal from canceling out. The artifact is collision-fenced, byte-counted, SHA-256 identified, race-checked, and never truncated. In auto mode, a diverged branch is reviewed from its merge base with working-tree evidence included. Otherwise, a dirty tree selects uncommitted changes, while a clean tree falls back to the last commit (HEAD^..HEAD) without working-tree evidence. Unsafe untracked file types or a repository mutation during capture cause a refusal.

The tool starts asynchronous provider jobs and returns a validationId, exact artifact and prompt identities, file inventory, and one rawJobReference per reviewer. Poll those references with validation job_status and collect them with validation job_result, not the similarly named llm_job_* tools. If a judge was requested, wait for every reviewer to become terminal, then call synthesize_validation with the validationId and the same workingDir or workspace selector. Continue collecting results for progress and human visibility, but do not pass them as review evidence: for a review_changes run, the gateway ignores caller-supplied question and providerResults, reloads the exact owned durable linked terminal jobs, and reconstructs requested but unavailable seats as skipped. General validation synthesis still requires a caller-supplied question and terminal normalized results.

The review surface is registered only with durable SQLite or PostgreSQL job and validation-run storage. Each CLI review job retains the exact fenced prompt in its expiry-bound payload_json; its persisted argv contains only a hash marker. The non-expiring flight recorder does not receive repository-review prompts. Configured HTTP/API reviewer seats require explicit allowApiUpload:true because the complete artifact leaves the local CLI boundary. Remote HTTP/OAuth workspace reviews reject API reviewer uploads even with that flag. Treat the durable job store as sensitive. Its retention is unbounded by default, and an operator can set [persistence.retention].jobs when a bounded record is required. When judgeModel is an HTTP/API provider, review_changes binds that explicit consent, the judge provider, the resolved repository, and the caller identity to the durable validationId. The later synthesize_validation call must provide that id and the same repository selector. The stored judge, repository, owner, and upload consent are authoritative. The gateway atomically claims the planned judge once, so concurrent or repeated synthesis cannot start a second judge. A follow-up argument cannot grant or override upload consent.

LLM Request Tools

claude_request

Execute a Claude Code request with optional session management.

Parameters:

  • prompt (string, optional*): The prompt to send (1-100,000 chars). *Exactly one of prompt or promptParts is required (mutually exclusive)

  • model (string, optional): Model name or alias (use list_models for available values; supports latest)

  • outputFormat (string, optional): Output format (text|json|stream-json), default: stream-json — the gateway parses NDJSON usage events for token/cost observability; override to text only when you want unparsed stdout

  • sessionId (string, optional): Specific session ID to use. Under mcp_managed, native continuation is a high-risk input because it can inherit an unverified provider posture; it requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1, but does not select a full-permission profile.

  • continueSession (boolean, optional): Continue the active session. It has the same managed-approval requirement as sessionId. Because Claude --continue selects by cwd, it requires workingDir or a registered workspace selected explicitly, through caller-owned session metadata, or by the configured default. That workspace may optionally supply a gateway worktree. The request fails closed when no selection supplies a stable cwd.

  • createNewSession (boolean, optional): Always create a new session

  • forkSession (boolean, optional): Fork the resumed session instead of appending to it. Under mcp_managed, it is a high-risk native-fork input that requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1, but stays bounded.

  • allowedTools (string[], optional): Restrict Claude tools to this allow-list. A non-empty allow-list is a high-risk managed input because it can change the tool posture.

  • disallowedTools (string[], optional): Explicitly deny listed Claude tools

  • permissionMode (string, optional): Claude permission mode (default|acceptEdits|plan|auto|dontAsk|bypassPermissions); preferred over dangerouslySkipPermissions. bypassPermissions is a direct full-permission request under mcp_managed.

  • dangerouslySkipPermissions (boolean, optional): Deprecated, maps to permissionMode: "bypassPermissions"; permissionMode wins when both are set. It is a direct full-permission request under mcp_managed.

  • agent (string, optional): Named sub-agent to run as. A non-empty value is a high-risk managed input because it can change tool and permission posture.

  • agents (string, optional): Inline agent definitions JSON. A non-empty value is a high-risk managed input for the same reason.

  • systemPrompt / appendSystemPrompt (string, optional): Replace or extend the system prompt. A non-empty value is a high-risk managed input.

  • systemPromptFile / appendSystemPromptFile (string, optional): Replace or extend the system prompt from a file. A non-empty file path is a high-risk managed input.

  • safeMode (boolean, optional): Start Claude with local customizations disabled, including CLAUDE.md, skills, plugins, hooks, MCP, commands, and agents. true is a high-risk managed input.

  • bare (boolean, optional): Start Claude in minimal mode, skipping local customization discovery. true is a high-risk managed input.

  • debugFile (string, optional): Write Claude debug output to a file. A non-empty path is a high-risk managed input.

  • maxBudgetUsd (number, optional): Budget cap in USD for the request

  • maxTurns (integer, optional): Agent-loop turn cap

  • effort (string, optional): Reasoning effort (low|medium|high|xhigh|max)

  • fallbackModel (string, optional): Auto-fallback model when the default is overloaded

  • jsonSchema (string, optional): JSON Schema literal constraining structured output

  • addDir (string[], optional): Additional workspace directories. A non-empty value is a high-risk managed input.

  • noSessionPersistence (boolean, optional): Ephemeral session (not persisted to disk)

  • settingSources / settings / tools (optional): Setting sources to load, settings JSON path/literal, built-in tool restriction. Non-empty setting sources, settings, or tool selections are high-risk managed inputs.

  • pluginDir / pluginUrl (string[], optional): Load Claude plugins from local directories or URLs. Non-empty values are high-risk managed inputs.

  • excludeDynamicSystemPromptSections (boolean, optional): Trim dynamic system prompt sections

  • approvalStrategy (string, optional): "legacy" (default) or "mcp_managed". Managed mode uses acceptEdits by default and forces strictMcpConfig:true, so Claude uses only the gateway-generated MCP configuration. A direct full-permission request requires all of an explicit caller request, an approval-manager approval, and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1. Other high-risk inputs require the approval and operator setting too, but remain bounded and do not themselves select full permission.

  • approvalPolicy (string, optional): "strict", "balanced", or "permissive"

  • mcpServers (string[], optional): Names of MCP servers to expose to Claude (default: none). Legacy requests resolve names from the local registry or Codex MCP config; unknown names are reported as unavailable. Under mcp_managed, Claude uses only the generated configuration and only registry entries explicitly provisioned as gateway-owned local commands are eligible. Dynamic npx launchers, ambient-PATH commands, and Codex-config overrides are rejected. Configure and deploy the managed entries in the gateway environment.

  • strictMcpConfig (boolean, optional): In legacy mode this defaults to false; set true to require only the generated MCP config and fail if requested servers are unavailable. Under mcp_managed, the gateway forces it to true and a caller-supplied false cannot weaken that boundary.

  • optimizePrompt (boolean, optional): Optimize prompt for token efficiency (44% reduction), default: false

  • optimizeResponse (boolean, optional): Optimize response for token efficiency (37% reduction), default: false

  • correlationId (string, optional): Request trace ID (auto-generated if omitted)

  • idleTimeoutMs (integer, optional): Kill a stuck process after output inactivity; 30,000 to 3,600,000 ms. Idle enforcement applies only when outputFormat is stream-json; it is ignored for text/json, which produce no output until the run completes

  • worktree (boolean|object, optional): Run inside a gateway-owned git worktree (slice Ī»). A worktree requires a registered workspace selected explicitly, through caller-owned session metadata, or by the configured default; it never inherits process cwd or combines with workingDir, addDir, or includeDirs. Materialization suppresses repository, system, and global Git hooks and configured clean, smudge, and process checkout filters, so filter-dependent content such as Git LFS remains in its repository representation instead of executing host commands. Requesting a worktree is a high-risk managed input that requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1, but remains bounded.

  • promptParts (object, optional): Cache-aware structured prompt { system?, tools?, context?, task }; mutually exclusive with prompt

  • forceRefresh (boolean, optional): Bypass dedup and force a fresh CLI run, default: false

Workspace boundary: stdio callers may use machine-local paths directly. HTTP/tunnel callers must pass workspace or rely on a configured default/session workspace; path fields are then validated relative to that workspace. [workspaces].allow_unregistered_working_dir is an inert legacy key: it is still accepted so old configs keep loading, but nothing reads it at either value, and setting it now logs a warning at startup. It never allowed arbitrary HTTP working directories or additional directories.

Response extras:

  • approval: Approval decision record when approvalStrategy="mcp_managed"

  • mcpServers: Requested/enabled/missing MCP servers for this call

Example:

{
  "prompt": "Write a Python function to calculate fibonacci numbers",
  "model": "sonnet",
  "continueSession": true,
  "optimizePrompt": true,
  "optimizeResponse": true
}
codex_request

Execute a Codex request with optional session tracking.

Parameters:

  • prompt (string, optional*): The prompt to send (1-100,000 chars). *Exactly one of prompt or promptParts is required (mutually exclusive)

  • model (string, optional): Model name or alias (use list_models for available values; supports latest, recommended: gpt-5.5)

  • fullAuto (boolean, optional): Deprecated — expands to --sandbox workspace-write only (current Codex no longer accepts approval-policy flags); prefer sandboxMode

  • sandboxMode (string, optional): Codex sandbox (read-only|workspace-write|danger-full-access).

  • dangerouslyBypassApprovalsAndSandbox (boolean, optional): Request Codex's full approvals-and-sandbox bypass.

  • dangerouslyBypassHookTrust (boolean, optional): Request Codex hook-trust bypass.

  • approvalStrategy (string, optional): "legacy" is the only executable strategy. "mcp_managed" is rejected before Codex launches because the adapter cannot isolate ambient MCP configuration.

  • approvalPolicy (string, optional): Has no effect for Codex because mcp_managed is unavailable.

  • mcpServers (string[], optional): Metadata only. It does not configure or isolate Codex MCP servers.

  • sessionId (string, optional): Session identifier for tracking.

  • resumeLatest (boolean, optional): Resume a previous Codex session (codex exec resume --last). Do not rely on which session --last selects or on the resumed working directory (#258): --last is cwd-filtered upstream and the child is still spawned with the gateway-resolved cwd. Verify the target, or start a fresh session when it must be certain. Ignored if sessionId is set.

  • createNewSession (boolean, optional): Always create a new session

  • forceRefresh (boolean, optional): Bypass dedup and force a fresh CLI run, default: false

  • outputFormat (string, optional): text (default) or json (--json JSONL events for token usage extraction)

  • outputSchema (string|object, optional): Codex --output-schema, path or inline JSON Schema.

  • workingDir (string, optional): Working root for this session (-C/--cd; new sessions only). Personal Agent Config Kit mode requires an absolute path.

  • addDir (string[], optional): Additional writable workspace directories (one --add-dir per entry; new sessions only).

  • ephemeral (boolean, optional): Codex --ephemeral (no session persistence)

  • images (string[], optional): Image attachments (one -i <path> per entry).

  • profile (string, optional): Codex --profile <name> (new sessions only; ignored with a logged warning on resume).

  • configOverrides (object, optional): Codex -c key=value overrides. Local callers only; remote HTTP/OAuth requests are rejected.

  • enable / disable (string[], optional): Codex --enable / --disable feature overrides. They are -c features.* equivalents and are also local-only.

  • ignoreRules / ignoreUserConfig (boolean, optional): Codex --ignore-rules / --ignore-user-config.

  • outputLastMessage (string, optional): Codex --output-last-message <path>.

  • oss (boolean, optional): Codex --oss, selecting the open-source provider.

  • localProvider (string, optional): Codex --local-provider <name>.

  • worktree (boolean|object, optional): Run inside a gateway-owned git worktree (slice Ī»). A worktree requires a registered workspace selected explicitly, through caller-owned session metadata, or by the configured default; it never inherits process cwd or combines with workingDir, addDir, or includeDirs. Materialization suppresses repository, system, and global Git hooks and configured clean, smudge, and process checkout filters, so filter-dependent content such as Git LFS remains in its repository representation instead of executing host commands.

  • promptParts (object, optional): Cache-aware structured prompt { system?, tools?, context?, task }; mutually exclusive with prompt

  • optimizePrompt (boolean, optional): Optimize prompt for token efficiency, default: false

  • optimizeResponse (boolean, optional): Optimize response for token efficiency, default: false

  • correlationId (string, optional): Request trace ID (auto-generated if omitted)

  • idleTimeoutMs (integer, optional): Kill a stuck Codex process after output inactivity; 30,000 to 3,600,000 ms

Response extras:

  • mcpServers: Requested MCP-server metadata for this call

Example:

{
  "prompt": "Create a REST API endpoint",
  "model": "gpt-5.5",
  "sandboxMode": "workspace-write",
  "optimizePrompt": true
}
codex_fork_session

Fork an existing Codex session into a new branch (codex fork <SESSION_ID|--last> <prompt>), preserving the original session's history while the fork diverges. Unlike Codex new and resume requests, this command remains argv-bound and rejects oversized UTF-8 prompts as non-retryable input_too_large.

Parameters:

  • prompt (string, required): Prompt text for the forked session (1-100,000 chars)

  • sessionId (string, optional): Codex session UUID to fork from (mutually exclusive with forkLast).

  • forkLast (boolean, optional): Fork the most recent Codex session instead of naming one.

  • model (string, optional): Model name or alias (e.g. gpt-5.5, latest)

  • sandboxMode (string, optional): Codex sandbox (read-only|workspace-write|danger-full-access).

  • approvalStrategy (string, optional): "legacy" is the only executable strategy. "mcp_managed" is rejected before Codex launches because the adapter cannot isolate ambient MCP configuration.

  • approvalPolicy (string, optional): Has no effect for Codex because mcp_managed is unavailable.

  • correlationId (string, optional): Request trace ID (auto-generated if omitted)

  • idleTimeoutMs (number, optional): Idle timeout in ms (30s-1h, omit for CLI default)

gemini_request

Execute a Google Antigravity CLI (agy) request with session support.

Parameters:

  • prompt (string, optional*): The prompt to send (1-100,000 chars). *Exactly one of prompt or promptParts is required (mutually exclusive)

  • model (string, optional): Model name or alias (use list_models for available values; supports latest, pro, flash)

  • sessionId (string, optional): Session ID to resume.

  • resumeLatest (boolean, optional): Resume the latest session automatically.

  • createNewSession (boolean, optional): Always create a new session

  • approvalMode (string, optional): Antigravity approval mode in legacy mode: default leaves agy prompted, auto_edit emits --mode accept-edits, plan emits --mode plan, and yolo emits --dangerously-skip-permissions.

  • approvalStrategy (string, optional): "legacy" is the only executable strategy. "mcp_managed" is rejected before Antigravity launches because the adapter cannot isolate ambient MCP configuration.

  • approvalPolicy (string, optional): Has no effect for Antigravity because mcp_managed is unavailable.

  • includeDirs (string[], optional): Additional workspace directories (passed as --add-dir).

  • project (string, optional): Select the Antigravity project for this session (--project <ID>); mutually exclusive with newProject.

  • newProject (boolean, optional): Create a new Antigravity project for this session (--new-project); mutually exclusive with project.

  • sandbox (boolean, optional): Run Antigravity in sandbox mode (--sandbox)

  • workingDir (string, optional): Local Antigravity process working directory. Stdio/local callers may pass local paths directly; remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. includeDirs adds read paths but does not select cwd.

  • workspace (string, optional): Registered gateway workspace alias that selects the Antigravity process cwd for remote HTTP/OAuth callers.

  • outputFormat (string, optional): text (default), json, or stream-json. The async job recorder launches the transcript-capable stream-json wire independently of the requested presentation.

  • mcpServers (string[], optional): Metadata only. Antigravity manages its own MCP configuration; this field does not create an allowlist.

  • allowedTools, policyFiles, adminPolicyFiles, attachments (string[], optional) and skipTrust (boolean, optional): Unsupported by Antigravity CLI. Non-empty values, or skipTrust: true, are rejected with an explanatory error.

  • yolo (boolean, optional): Auto-approve all; equivalent to approvalMode: "yolo". Emits --dangerously-skip-permissions in legacy mode.

  • worktree (boolean|object, optional): Run inside a gateway-owned git worktree (slice Ī»). A worktree requires a registered workspace selected explicitly, through caller-owned session metadata, or by the configured default; it never inherits process cwd or combines with workingDir, addDir, or includeDirs. Materialization suppresses repository, system, and global Git hooks and configured clean, smudge, and process checkout filters, so filter-dependent content such as Git LFS remains in its repository representation instead of executing host commands.

  • promptParts (object, optional): Cache-aware structured prompt { system?, tools?, context?, task }; mutually exclusive with prompt

  • optimizePrompt (boolean, optional): Optimize prompt for token efficiency, default: false

  • optimizeResponse (boolean, optional): Optimize response for token efficiency, default: false

  • correlationId (string, optional): Request trace ID (auto-generated if omitted)

  • idleTimeoutMs (integer, optional): Total-runtime bound, not an idle timer: this provider emits no output until it exits, so the process is killed after this duration even while healthy. 30,000 to 3,600,000 ms, default 3,600,000 ms

  • forceRefresh (boolean, optional): Bypass dedup and force a fresh CLI run, default: false

Response extras:

  • mcpServers: Requested MCP-server metadata for this call

Example:

{
  "prompt": "Explain quantum computing",
  "model": "latest",
  "resumeLatest": true,
  "optimizePrompt": true
}
grok_request

Execute a Grok CLI (xAI) request with session support.

Parameters:

  • prompt (string, optional*): The prompt to send (1-100,000 chars). *Exactly one of prompt or promptParts is required (mutually exclusive)

  • model (string, optional): Model name or alias (e.g. grok-4.6, grok-4.5). Prefer live discovery via list_models or models://grok: the legacy grok-build id was removed upstream and now hard-fails with Invalid params: "unknown model id".

  • transport (string, optional): "cli" (default) runs the Grok CLI; "acp" routes through Grok's native grok agent stdio transport when [acp].enabled and the provider's runtime_enabled are set (fails closed otherwise). Both transports reject approvalStrategy:"mcp_managed"; approvalPolicy has no effect. Sync-only: grok_request_async always runs the CLI transport and does not accept transport

  • outputFormat (string, optional): "plain" (default), "json", or "streaming-json"

  • sessionId (string, optional): Session ID to resume (--resume <id>).

  • resumeLatest (boolean, optional): Resume the most recent session in the current cwd (--continue).

  • createNewSession (boolean, optional): Always create a new session

  • alwaysApprove (boolean, optional): Auto-approve all tool executions (--always-approve) in legacy mode.

  • permissionMode (string, optional): default|acceptEdits|auto|dontAsk|bypassPermissions|plan.

  • effort (string, optional): low|medium|high|xhigh|max

  • reasoningEffort (string, optional): Reasoning effort for reasoning models

  • approvalStrategy (string, optional): "legacy" is the only executable strategy. "mcp_managed" is rejected before Grok launches because the adapter cannot isolate ambient MCP configuration.

  • approvalPolicy (string, optional): Has no effect for Grok because mcp_managed is unavailable.

  • mcpServers (string[], optional): Metadata only. Grok manages its own MCP configuration via grok mcp; this field does not create an allowlist.

  • allowedTools (string[], optional): Allowed built-in tools (passed as --tools comma list).

  • disallowedTools (string[], optional): Disallowed built-in tools (passed as --disallowed-tools comma list)

  • maxTurns (integer, optional): Agent-loop iteration cap (--max-turns)

  • workingDir (string, optional): Working directory for this invocation (--cwd)

  • sandbox (string, optional): Sandbox profile for filesystem/network access (--sandbox, freeform; also via GROK_SANDBOX).

  • rules (string, optional): Extra rules appended to the system prompt (--rules; supports @file prefix).

  • systemPromptOverride (string, optional): Replace the agent's system prompt entirely.

  • allow / deny (string[], optional): Permission allow/deny rules (one --allow/--deny per entry).

  • compactionMode (string, optional): summary (default) |transcript|segments

  • compactionDetail (string, optional): none|minimal|balanced|verbose (segments mode only)

  • agent (string, optional): Agent name or definition file path.

  • agents (string|object, optional): Inline subagent definitions JSON.

  • disableWebSearch (boolean, optional): Disable web search and remote retrieval tools

  • todoGate (boolean, optional): Enable runtime turn-end TodoGate (session-scoped)

  • verbatim (boolean, optional): Send the prompt exactly as given (also skips gateway prompt optimisation)

  • promptFile / promptJson / single (optional): Single-turn prompt from a file / JSON blocks / literal.

  • experimentalMemory / noMemory (boolean, optional): Enable/disable cross-session memory.

  • noAltScreen / noPlan / noSubagents (boolean, optional): Disable alt screen / plan mode / subagent spawning

  • oauth (boolean, optional): Use OAuth during authentication.

  • restoreCode (boolean, optional): Check out the original session commit when resuming.

  • leaderSocket (string, optional): Custom leader socket path (--leader-socket, Grok 0.2.32+; default ~/.grok/leader.sock) targeting an isolated leader process, for example a local or branch Grok build.

  • nativeWorktree (boolean|string, optional): Grok's own --worktree flag (true means bare, string means named); distinct from the gateway worktree option.

  • worktreeRef (string, optional): Branch/tag/commit to base the native worktree on (--worktree-ref); requires nativeWorktree.

  • forkSession (boolean, optional): Fork the resumed session into a new branch instead of appending to it.

  • jsonSchema (string|object, optional): JSON Schema (string or object) constraining structured output (--json-schema)

  • worktree (boolean|object, optional): Run inside a gateway-owned git worktree (slice Ī»). Grok requires an explicit provider-native sessionId; fresh, createNewSession, and resumeLatest-only worktree requests are rejected because they cannot durably reselect the worktree. A worktree requires a registered workspace selected explicitly, through caller-owned session metadata, or by the configured default; it never inherits process cwd or combines with workingDir, addDir, or includeDirs. Materialization suppresses repository, system, and global Git hooks and configured clean, smudge, and process checkout filters, so filter-dependent content such as Git LFS remains in its repository representation instead of executing host commands.

  • promptParts (object, optional): Cache-aware structured prompt { system?, tools?, context?, task }; mutually exclusive with prompt

  • optimizePrompt (boolean, optional): Optimize prompt for token efficiency, default: false

  • optimizeResponse (boolean, optional): Optimize response for token efficiency, default: false

  • correlationId (string, optional): Request trace ID (auto-generated if omitted)

  • idleTimeoutMs (integer, optional): Kill a stuck process after output inactivity; 30,000 to 3,600,000 ms

  • forceRefresh (boolean, optional): Bypass dedup and force a fresh CLI run, default: false

Example:

{
  "prompt": "Summarize the latest commit message in 1 sentence",
  "model": "grok-4.6",
  "effort": "low"
}

Durable job results & automatic dedup

Every async job is persisted to a job store as it transitions through running → completed/failed/canceled. This makes the gateway a durable collection layer:

  • Re-issuing a request is safe. Identical *_request / *_request_async calls within the dedup window (default 1 hour) short-circuit onto the existing running or completed job — the caller gets back the same job ID instead of starting a duplicate run. This directly fixes the "agent times out polling, re-issues, and the whole job starts over" failure mode.

  • llm_job_status and llm_job_result work across gateway restarts. Job rows are retained until an operator configures a bound; callers can collect results long after the in-memory cache has evicted them.

  • A job is marked orphaned only when its owning gateway instance is provably gone, never because another instance restarted. Each instance holds a periodic heartbeat lease and stamps every job it owns; the recovery sweep orphans a queued/running job only when that job's own lease has expired. On a shared store (backend = "postgres") this means a fresh instance never orphans another live instance's in-flight jobs. The captured partial output of a genuinely orphaned job remains readable, and a stale-then-reviving owner that later finishes self-heals to the correct terminal state (issue #139).

  • Pass forceRefresh: true on any request tool to bypass dedup and force a fresh CLI run.

Persistence configuration

The durable backend is configured by ~/.llm-cli-gateway/config.toml (override with LLM_GATEWAY_CONFIG=/path/to/config.toml). Example:

[persistence]
backend = "sqlite"                          # "sqlite" | "memory" | "postgres" | "none"
path = "~/.llm-cli-gateway/logs.db"         # for sqlite
# dsn = "postgresql://user:pw@host/db"      # for postgres
# retentionDays = 30                       # optional legacy JOB-store bound; omitted means unbounded
dedupWindowMs = 3600000
acknowledgeEphemeral = false                # required to enable async tools with memory backend

# One retention policy, over every subsystem. Every destructive bound is OFF
# unless you write a number, because deleting prompt, response, or transcript
# history is destructive and no upgrade should do it for you. Unknown keys are
# refused rather than silently applying no bound.
# `llm-cli-gateway doctor --json` -> .storage.retention reports what each bound
# would delete BEFORE you set it.
[persistence.retention]
# jobs = 30                                 # overrides retentionDays above
# requests = 90                             # flight-recorder transcripts, incl. bodies
# wedgedValidationRuns = 30                 # validation runs nothing can ever finalize
# sweepIntervalMs = 3600000                 # how often the sweeper ticks

# Issue #139 durable orphan-recovery lease (defaults shown). Each instance
# advances a per-job lease on every heartbeat; the sweep orphans a job only
# after its own lease expires, so a fresh instance never orphans another live
# instance's jobs on a shared store. Validated: leaseTtl >= 2*heartbeat and
# httpJobGrace >= leaseTtl.
instanceHeartbeatMs = 15000                 # heartbeat cadence
instanceLeaseTtlMs = 90000                  # per-job lease TTL (6x heartbeat)
httpJobGraceMs = 300000                     # extra grace for no-pid http jobs (5 min)
orphanSweepIntervalMs = 30000               # reaper cadence
instanceGcMs = 3600000                      # gateway_instances GC horizon
# ownsOrphanRecovery = false                # DEPRECATED (#139): superseded by the lease; parsed + warned, no longer used

# Optional, postgres only. One credential per class of work, for a deployment
# that has provisioned the RBAC in docs/plans/postgres-security-hardening.md.
# `app` is not a key here: the runtime credential is [persistence].dsn above.
# `migrate` is not a key either, and must not be held by a running gateway.
# A role left out degrades onto `app`, which llm_process_health reports as
# `persistence.roles.degraded` rather than implying separation is in force.
# [persistence.roles]
# reader = "postgresql://llmgw_reader@host/db"       # transcript read-back
# analytics = "postgresql://llmgw_analytics@host/db" # aggregates, no body text
# retention = "postgresql://llmgw_retention@host/db" # job expiry

Backends:

  • sqlite (default) — durable, file-backed. Safe for single-instance deployments.

  • postgres: PostgreSQL is authoritative for every backend-governed durable subsystem, including async jobs, dedup, orphan recovery, HTTP jobs, validation state, session metadata, and the flight recorder. File-backed operator records such as approvals, admin audit, and the workspace registry are not SQLite/PostgreSQL engine choices. Use this for multi-instance or service deployments. Requires the optional peer dependency pg to be installed alongside the gateway.

  • memory — in-process Map. Lost on gateway exit. Requires acknowledgeEphemeral = true to be loaded. Suitable for tests and ephemeral CI gateways.

  • none — no store. *_request_async, llm_job_status, llm_job_result, and llm_job_cancel are NOT registered on the gateway. This is a structural invariant: agents that try to call async tools against a gateway with backend = "none" get a clean "tool not found" at connect time instead of silent in-memory loss after the 1-hour TTL. Use llm_process_health to inspect the resolved persistence state programmatically.

backend = "postgres" is the whole engine decision. The configured dsn must be a PostgreSQL URL. The gateway does not infer deployment topology, resolve the host, restrict PostgreSQL to a local target, or render a DSN-derived target on diagnostics. If migration, connection, or an operation fails, the affected PostgreSQL subsystem fails closed and the gateway does not open SQLite as a fallback. Health surfaces identify the selected engine and report PostgreSQL failures generically.

Changing engines does not move data. Existing SQLite and PostgreSQL rows stay where they are: there is no automatic migration, dual-write, or cross-engine read. Plan and execute any data move separately before cutover if old history must remain available through the gateway.

backend = "none" and LLM_GATEWAY_LOGS_DB=none are different switches. The first disables async job persistence; the second disables request history. Setting the backend to "none" leaves the flight recorder writing, and disabling the recorder leaves the job store alone. Both are stated at startup in the Storage: block on stderr. llm_process_health reports the selected engine, recorder state, role configuration, and deprecated-input decisions without rendering the configured PostgreSQL target.

DATABASE_URL is deprecated and never overrides [persistence]. When it is the only selector, it acts as a deprecated alias for backend = "postgres" plus dsn, so sessions, jobs, validation state, and request history stay on one engine. Against an explicit backend, or against a dsn it disagrees with, it is ignored with a reason: the gateway does not abort, because the outcome is fully determined and is the one the config file describes.

For PostgreSQL, apply the schema with a schema-owner or dedicated migration role before starting a DML-only gateway role:

DATABASE_URL='postgresql://<user>:<password>@<host>/<database>' npm run migrate

The runner serializes migration work with an advisory lock and records a SHA-256 of each migration in schema_migrations.checksum_sha256. On later runs, a malformed or mismatched recorded checksum stops the runner before it calculates or applies pending migrations. A NULL checksum is an explicit legacy row from before checksum recording. It is allowed with a warning but is never backfilled, because current source files cannot prove what SQL ran historically. Do not edit released migration files or populate ledger checksums manually. The runner preserves the historical 002/003 SQL and applies compatibility only while one of those legacy versions remains pending; forward migration 018 repairs an already-recorded legacy session/view layout. Release checks reject a source edit to a published migration file.

Legacy environment variables (deprecated; emit a warning at startup):

  • LLM_GATEWAY_LOGS_DB / LLM_GATEWAY_JOBS_DB: when no backend is explicitly configured, none selects backend = "none" and any other value selects backend = "sqlite" with that path. An explicit [persistence].backend wins. LLM_GATEWAY_LOGS_DB still independently disables the recorder on every backend and paths it when the selected recorder engine is SQLite.

  • LLM_GATEWAY_JOB_RETENTION_DAYS — overrides retentionDays.

  • LLM_GATEWAY_DEDUP_WINDOW_MS — overrides dedupWindowMs.

  • LLM_GATEWAY_ACKNOWLEDGE_EPHEMERAL — 1/true/yes sets acknowledgeEphemeral = true.

Host-protection limits ([http] and [limits])

The gateway bounds HTTP session growth and async/sync job execution so a burst of clients or requests cannot drive unbounded memory, process, CPU, or provider-request growth. All keys live in the same ~/.llm-cli-gateway/config.toml; defaults are conservative but chosen not to surprise local stdio development.

[http]                              # HTTP MCP transport session lifecycle
max_sessions = 100                  # max concurrent live sessions; excess initialize returns HTTP 429
session_idle_ttl_ms = 1800000       # 30 min: reap a session idle longer than this (no client DELETE needed)
session_reaper_interval_ms = 60000  # 1 min: how often the idle reaper sweeps

[limits]                            # async + sync job-execution backpressure (per gateway process)
max_running_jobs = 32               # global concurrent running jobs (process CLI + HTTP API)
max_running_jobs_per_provider = 16  # per-provider concurrent running jobs
max_queued_jobs = 128               # bounded wait queue; a full queue rejects new work
queue_timeout_ms = 120000           # 2 min: max time a job waits in the queue before failing
completed_job_memory_ttl_ms = 3600000  # 1 h: in-memory retention for finished jobs (durable rows kept separately)
max_job_output_bytes = 52428800     # 50 MB: per-job stdout+stderr cap

Failure modes (all deterministic and safe to retry):

  • HTTP session cap reached: the initialize request returns 429 with Retry-After: 5 and a structured { error, code: "session_capacity", retryable: true } body. No new session is created.

  • Idle HTTP session: the reaper closes it (transport + gateway server) once idle past session_idle_ttl_ms, independent of the client sending DELETE. A session with an in-flight request is never reaped mid-request.

  • Job limiter saturated: when the running limit is reached and the queue is full, *_request / *_request_async and the direct-sync fallback return a retryable saturated error (structuredContent.errorCategory = "saturated", retryable: true). Nothing is spawned. When the queue has room the job waits (FIFO, per-provider fair) up to queue_timeout_ms, then fails with the same category.

  • Sync direct execution: the SYNC_DEADLINE_MS=0 and storeless/backend="none" paths acquire the same process permit before spawning, so no execution bypasses the limiter.

  • Output overflow: a job whose combined stdout+stderr exceeds max_job_output_bytes is failed (exit code 126), its process terminated, its completion persisted, and its run slot released.

  • In-memory vs durable retention: completed_job_memory_ttl_ms only ages finished jobs out of the in-memory map. The durable job store is unbounded by default and can be bounded with [persistence.retention].jobs or the legacy [persistence].retentionDays, so results stay readable via llm_job_result / llm_request_result after in-memory eviction.

Live counters are exposed on GET /healthz (unauthenticated, HTTP transport) and via the llm_process_health tool backpressure block: session current/max/oldest-age/idle-TTL/saturation, running and queued job counts globally and per provider, limiter saturation counters, configured TTL/output caps, and parent-process RSS/heap. These surfaces report counts, ages, and bytes only, never prompt text, response content, tokens, session IDs, bearer/OAuth tokens, API keys, or machine secrets.

For production user services, pair the in-process limits above with systemd's outer guardrails so an unexpected bug, provider CLI leak, or evaluation burst cannot consume the host:

systemctl --user edit llm-cli-gateway.service
[Service]
MemoryMax=2G
TasksMax=512

Choose values for your workload: MemoryMax should cover the gateway process, the configured max_running_jobs provider children, and normal output buffering; TasksMax should exceed the process/thread count implied by max_running_jobs plus the HTTP server and SQLite work, but still be far below host exhaustion. If systemd terminates the service at those limits, durable jobs can be inspected after restart and llm_process_health.backpressure should be used to tune [http], [limits], MemoryMax, and TasksMax together.

Per-project isolation

By default, gateway state is global per user, not per project. With no overrides, every Claude Code window across every repo spawns its own gateway subprocess but they all read and write the same state:

  • ~/.llm-cli-gateway/logs.db when [persistence].backend = "sqlite" (async jobs + flight recorder). With backend = "postgres", those rows live in the configured database instead. All destructive retention bounds default to OFF. [persistence.retention].jobs prunes complete job records, [persistence.retention].requests prunes the flight recorder's requests and gateway_metadata tables, and [persistence.retention].wedgedValidationRuns prunes validation runs that can never be finalized with their validation_run_jobs links. An operator must opt in to each bound. validation_receipts is immutable by design and is never pruned; a finalized run is never pruned either, so no receipt is ever orphaned.

    Deleting rows frees SQLite pages but never bytes, so the file does not shrink. llm-cli-gateway storage compact --yes returns the space, with the gateway stopped, because a VACUUM holds an exclusive lock for the length of a full rewrite. doctor --json -> .storage.retention reports the resolved bounds, what a sweep would delete, and how many bytes a compaction would return. See docs/plans/durable-state-lifecycle.dag.toml.

  • ~/.llm-cli-gateway/sessions.json (gateway session metadata when using the default file session backend)

  • ~/.llm-cli-gateway/config.toml (resolved config)

When [persistence].backend = "postgres" selects the PostgreSQL session manager, the session metadata lives in PostgreSQL instead of sessions.json. This is usually what you want: session_list from repo A can show sessions from repo B, an async job started in window A can be polled from window B, and the 1-hour dedup window catches re-issues across windows. Gateway-managed worktrees are the exception: they are filesystem-local and therefore fail closed with PostgreSQL session storage. SQLite WAL mode protects the default job/flight-recorder database, while the file session manager uses locked atomic writes.

Per-project durable-job isolation

If unrelated repositories should not share async jobs, flight-recorder rows, or deduplication, point each project at its own persistence config. In .claude/settings.local.json for the project:

{
  "mcpServers": {
    "llm-gateway": {
      "env": {
        "LLM_GATEWAY_CONFIG": "${workspaceFolder}/.gateway/config.toml"
      }
    }
  }
}

…and put a per-project config.toml in the repo:

[persistence]
backend = "sqlite"
path = "/srv/repos/.../my-repo/.gateway/logs.db"

Now every gateway subprocess spawned for this repo's Claude Code window reads its own config and writes its durable jobs, flight-recorder rows, and deduplication state to its own SQLite file. Other repos keep using the global default. This [persistence] override does not move the default file-backed sessions.json, so it does not isolate session lists. llm_process_health.persistence.sources.configFile lets an agent confirm which persistence config it is actually running under.

Agent-executable spec (DAG-TOML)

If you want an LLM agent to perform this setup deterministically — rather than reading the prose above and guessing — copy the following DAG-TOML into the repo (e.g. docs/planning/per-project-gateway-isolation.toml) and point your agent at it. The schema is agent-assurance template_kind = "implementation-dag". The agent MUST execute units in layer order, must not skip the verification unit, and must treat any failed gate as blocking.

[meta]
schema_version    = "1.0.0"
template_kind     = "implementation-dag"
docs              = "https://github.com/verivus-oss/agent-assurance/blob/main/SPEC.md"
confidentiality   = "public"
title             = "Per-project llm-cli-gateway durable-job isolation"
spec              = "https://github.com/verivus-oss/llm-cli-gateway#per-project-durable-job-isolation"
created           = "YYYY-MM-DD"
total_units       = 5
tier1_units       = ["U01","U02","U03","U04","U05"]
tier2_units       = []
tier3_units       = []

# ============================================================================
# [policy.agent] — persona for the agent performing the configuration.
# ============================================================================

[policy.agent]
name                 = "Gateway Persistence Isolator"
role                 = "Configuration Engineer"
purpose              = "Configure the llm-cli-gateway MCP server so its SQLite durable state is scoped to THIS repository instead of the per-user default at ~/.llm-cli-gateway/. The default file-backed session metadata remains shared."
validation_type      = "Structural + Runtime Verification"
workflow_initiator   = false
description          = "Writes a repo-local config.toml, registers an LLM_GATEWAY_CONFIG override in .claude/settings.local.json, restarts the MCP server, and confirms via llm_process_health that the gateway is now reading the repo-local config and writing to the repo-local SQLite path."

[policy.agent.orchestration]
consumes_events      = ["PerProjectIsolationRequested"]
produces_events      = ["PerProjectDurableJobIsolationComplete"]

[policy.agent.responsibilities]
items = [
  "Create the repo-local gateway data directory and add it to .gitignore.",
  "Write a config.toml that pins backend=sqlite to a repo-local path.",
  "Register the LLM_GATEWAY_CONFIG env override in .claude/settings.local.json (NOT .mcp.json — that file is committed and shared).",
  "Trigger an MCP server reconnect.",
  "Verify via llm_process_health that the resolved configFile and dbPath are the repo-local values.",
]

# ============================================================================
# [policy.instance] — concrete paths the agent fills in for THIS repo.
# Agent MUST replace <REPO_ABS_PATH> with the absolute path to the repo
# before emitting any artefact. Relative paths in config.toml MUST be
# expanded to absolute — the gateway does not re-resolve them per cwd.
# ============================================================================

[policy.instance]
repo_abs_path                  = "<REPO_ABS_PATH>"           # e.g. /srv/repos/me/my-project
gateway_data_dir_relative      = ".gateway"                  # repo-relative directory
config_toml_relative           = ".gateway/config.toml"
sqlite_db_relative             = ".gateway/logs.db"
claude_local_settings_relative = ".claude/settings.local.json"
gitignore_relative             = ".gitignore"
mcp_server_name                = "llm-gateway"               # must match the entry in .mcp.json

# ============================================================================
# [policy.gates] — blocking checks. Any failure stops the workflow.
# ============================================================================

[policy.gates]
gate_repo_abs_path_resolved    = "policy.instance.repo_abs_path must NOT be the literal string '<REPO_ABS_PATH>' when U01 starts."
gate_config_is_committed       = "policy.instance.config_toml_relative MAY be committed. policy.instance.claude_local_settings_relative MUST NOT be committed (it is per-developer). Agent MUST verify .gitignore covers .claude/settings.local.json if absent."
gate_no_legacy_env_leak        = "Agent MUST grep the shell init files for LLM_GATEWAY_LOGS_DB / LLM_GATEWAY_JOBS_DB. An explicit [persistence].backend wins for job persistence, but LLM_GATEWAY_LOGS_DB still disables the recorder on every backend and paths it when SQLite is selected. Both variables remain deprecated. The agent reports either as a finding and asks the operator to unset it before proceeding."
gate_health_confirms_isolation = "U05 MUST observe llm_process_health.persistence.sources.configFile == policy.instance.repo_abs_path + '/' + policy.instance.config_toml_relative AND llm_process_health.persistence.path == policy.instance.repo_abs_path + '/' + policy.instance.sqlite_db_relative. Anything else means the override did not take effect."

# ============================================================================
# [policy.evidence] — what each unit must emit so the work is auditable.
# ============================================================================

[policy.evidence]
per_unit_required_fields = [
  "unit_id",                  # U01..U05
  "status",                   # "completed" | "failed"
  "artefact_paths",           # files written / modified
  "stdout_tail",              # last 20 lines of any command output
  "verification_quote",       # for U05, the verbatim llm_process_health.persistence block
]
findings_required_fields = [
  "gate_id",                  # which gate failed
  "observed",
  "expected",
  "remediation",
]

# ============================================================================
# Units. Execute in layer order. U01..U03 modify the working tree; U04
# triggers a reconnect; U05 is the verification gate that decides success.
# ============================================================================

[units.U01]
name           = "create-repo-local-data-dir"
summary        = "mkdir -p <repo>/.gateway and append /.gateway/ to .gitignore (creating .gitignore if missing). The gateway will write logs.db, logs.db-wal, logs.db-shm here — none should be committed."
layer          = 0
tier           = 1
status         = "pending"
depends_on     = []
blocks         = ["U02"]
estimated_loc  = 5
files_modify   = [".gitignore"]
produces       = ["ART:gateway-data-dir"]
consumes       = []

[units.U02]
name           = "write-config-toml"
summary        = "Write <repo>/.gateway/config.toml with [persistence] backend='sqlite' and path=<absolute-path-to-repo>/.gateway/logs.db. Path MUST be absolute. Do NOT use ~ — the gateway expands ~ but [persistence].path is read literally if not prefixed with ~/, and Claude Code may launch the gateway with a HOME that surprises you."
layer          = 1
tier           = 1
status         = "pending"
depends_on     = ["U01"]
blocks         = ["U03"]
estimated_loc  = 10
files_modify   = [".gateway/config.toml"]
produces       = ["ART:gateway-config"]
consumes       = ["ART:gateway-data-dir"]

[units.U03]
name           = "register-llm-gateway-config-env-in-claude-local-settings"
summary        = "Add (or merge) an mcpServers.<mcp_server_name>.env entry in .claude/settings.local.json that sets LLM_GATEWAY_CONFIG to the absolute path of .gateway/config.toml. Do NOT modify .mcp.json — that file is committed and the path would be wrong for every other developer. If .claude/settings.local.json already has an mcpServers.<mcp_server_name> entry, the agent MUST merge into the existing env map (preserving other keys), not overwrite the whole entry."
layer          = 2
tier           = 1
status         = "pending"
depends_on     = ["U02"]
blocks         = ["U04"]
estimated_loc  = 20
files_modify   = [".claude/settings.local.json"]
produces       = ["ART:claude-local-settings"]
consumes       = ["ART:gateway-config"]

[units.U04]
name           = "trigger-mcp-reconnect"
summary        = "Ask the operator to run /mcp in Claude Code (or restart Claude Code) so the gateway subprocess is re-spawned under the new env. The agent cannot do this itself — MCP server lifecycle is owned by the host."
layer          = 3
tier           = 1
status         = "pending"
depends_on     = ["U03"]
blocks         = ["U05"]
estimated_loc  = 0
files_modify   = []
produces       = ["OUT:mcp-reconnected"]
consumes       = ["ART:claude-local-settings"]

[units.U05]
name           = "verify-via-llm-process-health"
summary        = "Call llm_process_health and assert the returned persistence block satisfies policy.gates.gate_health_confirms_isolation. Quote the verbatim persistence block in evidence. If the assertion fails, the agent MUST NOT mark the workflow complete — it must emit a finding under policy.evidence.findings_required_fields, naming the observed vs. expected configFile/path, and stop."
layer          = 4
tier           = 1
status         = "pending"
depends_on     = ["U04"]
blocks         = []
estimated_loc  = 5
files_modify   = []
produces       = ["ART:durable-isolation-verification","OUT:per-project-durable-isolation-complete"]
consumes       = ["OUT:mcp-reconnected"]

Why this matters for agents: the gateway has multiple configuration surfaces (TOML file, env-var overrides, two different MCP settings files) and one easy mistake, editing the committed .mcp.json instead of the local-only .claude/settings.local.json, will silently break the per-project persistence scope for every other developer on the repo. The DAG above encodes the correct sequence, the verification gate, and the failure modes explicitly so an agent can execute it without inference. It deliberately does not claim to isolate the default file-backed session store.

mistral_request

Run a Mistral Vibe agentic coding request. Like grok_request in shape, but with Vibe's specific surface:

  • model (string, optional): Vibe model alias (for example mistral-medium-3.5 or latest). The resolved value is injected via the VIBE_ACTIVE_MODEL environment variable; omit it to let the gateway discover Vibe config and avoid stale hardcoded defaults.

  • transport (string, optional): "cli" (default) runs the Vibe CLI; "acp" routes through Vibe's native vibe-acp transport when [acp].enabled and the provider's runtime_enabled are set (fails closed otherwise). Both transports reject approvalStrategy:"mcp_managed"; approvalPolicy has no effect. Sync-only: mistral_request_async always runs the CLI transport and does not accept transport

  • permissionMode: the Vibe --agent name: builtins default | plan | accept-edits | auto-approve, or any install-gated/custom agent. Requests emit the supplied name in legacy mode.

  • allowedTools (string[], optional): One --enabled-tools <tool> flag per entry.

  • disallowedTools (string[], optional): One --disabled-tools <tool> flag per entry, applied after the enabled-tool filter.

  • outputFormat (string, optional): Vibe 2.x values are "text", "json", or "streaming"; legacy aliases "plain" and "stream-json" are accepted and normalized before spawn.

  • sessionId / resumeLatest / createNewSession: standard session controls. Current Vibe defaults session logging to enabled; if an older config has [session_logging] enabled = false, doctor --json surfaces an actionable next-action.

  • trust (boolean, optional): Emit --trust so Vibe trusts the cwd for this invocation only (not persisted; skips the interactive trust prompt).

  • maxTurns (integer, optional): Agent-loop iteration cap (--max-turns, programmatic mode only)

  • maxPrice (number, optional): Interrupt when cumulative cost crosses this USD cap (--max-price, programmatic mode only)

  • maxTokens (integer, optional): Cap cumulative prompt + completion tokens (--max-tokens, programmatic mode only)

  • workingDir (string, optional): Change to this directory before running (--workdir)

  • addDir (string[], optional): Additional writable workspace directories (one --add-dir per entry).

  • approvalStrategy (string, optional): "legacy" is the only executable strategy. "mcp_managed" is rejected before Vibe launches because the adapter cannot isolate ambient MCP configuration.

  • approvalPolicy (string, optional): Has no effect for Vibe because mcp_managed is unavailable.

  • mcpServers (string[], optional): Metadata only. Vibe reads its MCP configuration from VIBE_HOME config; this field does not create an allowlist.

  • worktree (boolean|object, optional): Run inside a gateway-owned git worktree (slice Ī»). Mistral requires an explicit provider-native sessionId; fresh, createNewSession, and resumeLatest-only worktree requests are rejected because they cannot durably reselect the worktree. A worktree requires a registered workspace selected explicitly, through caller-owned session metadata, or by the configured default; it never inherits process cwd or combines with workingDir, addDir, or includeDirs. Materialization suppresses repository, system, and global Git hooks and configured clean, smudge, and process checkout filters, so filter-dependent content such as Git LFS remains in its repository representation instead of executing host commands.

  • promptParts (object, optional): Cache-aware structured prompt { system?, tools?, context?, task }; mutually exclusive with prompt

  • optimizePrompt / optimizeResponse (boolean, optional): Token-efficiency optimisation, default: false

  • correlationId (string, optional): Request trace ID (auto-generated if omitted)

  • idleTimeoutMs (integer, optional): Total-runtime bound, not an idle timer: this provider emits no output until it exits, so the process is killed after this duration even while healthy. 30,000 to 3,600,000 ms, default 3,600,000 ms

  • forceRefresh (boolean, optional): Bypass dedup and force a fresh CLI run, default: false

devin_request

Run a Cognition Devin CLI request synchronously (headless print mode, devin -p). Auto-defers to a pollable job past the sync deadline when async jobs are enabled.

Parameters:

  • prompt (string, optional*): Prompt text for Devin CLI (1-100,000 chars). Required in practice; promptFile is additive

  • model (string, optional): Model name or alias (e.g. opus, latest)

  • transport (string, optional): "cli" (default) runs the Devin CLI; "acp" routes through Devin's native devin acp transport when [acp].enabled and the provider's runtime_enabled are set (fails closed otherwise). Both transports reject approvalStrategy:"mcp_managed"; approvalPolicy has no effect. Sync-only: devin_request_async always runs the CLI transport and accepts neither transport nor agentType

  • agentType (string, optional): ACP agent variant for transport: "acp" (devin acp --agent-type): "summarizer" (no tools, text summary) or "review" (read-only plus shell code-review); ignored for the CLI transport

  • permissionMode (string, optional): Devin CLI permission mode (--permission-mode): auto (auto-approves read-only tools), accept-edits (also auto-approves workspace edits), smart (also auto-runs actions a fast model judges safe), dangerous (auto-approves all). Omit to use Devin's headless default

  • approvalStrategy (string, optional): "legacy" is the only executable strategy. "mcp_managed" is rejected before Devin launches because the adapter cannot isolate ambient MCP configuration.

  • approvalPolicy (string, optional): Has no effect for Devin because mcp_managed is unavailable.

  • promptFile (string, optional): Load the initial prompt from a file (--prompt-file)

  • sessionId (string, optional): Devin session ID to resume (--resume <id>). The gw-* id minted for a brand-new session is not resumable via sessionId; continue with resumeLatest: true

  • resumeLatest (boolean, optional): Resume the most recent Devin session in the selected cwd (--continue). Requires workingDir, workspace, or a configured default workspace.

  • createNewSession (boolean, optional): Force a new session

  • workingDir (string, optional): Local Devin process cwd. CLI transport only.

  • workspace (string, optional): Registered gateway workspace alias that selects the Devin process cwd.

  • worktree (boolean|object, optional): Run the Devin CLI request inside a gateway-owned Git worktree. Devin requires an explicit provider-native sessionId; fresh, createNewSession, and resumeLatest-only worktree requests are rejected because they cannot durably reselect the worktree. A worktree requires a registered workspace selected explicitly, through caller-owned session metadata, or by the configured default; it never inherits process cwd or combines with workingDir, addDir, or includeDirs. Materialization suppresses repository, system, and global Git hooks and configured clean, smudge, and process checkout filters, so filter-dependent content such as Git LFS remains in its repository representation instead of executing host commands.

  • optimizePrompt / optimizeResponse (boolean, optional): Token-efficiency optimisation, default: false

  • correlationId (string, optional): Request trace ID (auto-generated if omitted)

  • idleTimeoutMs (integer, optional): Total-runtime bound, not an idle timer: this provider emits no output until it exits, so the process is killed after this duration even while healthy. 30,000 to 3,600,000 ms, default 3,600,000 ms

  • forceRefresh (boolean, optional): Bypass dedup and force a fresh CLI run, default: false

cursor_request

Run a Cursor Agent request synchronously. The default CLI transport uses headless print mode (cursor-agent --print) and auto-defers to a pollable job past the sync deadline when async jobs are enabled. Set transport: "acp" to use Cursor's native cursor-agent acp transport when [acp].enabled, [acp.providers.cursor].enabled, and [acp.providers.cursor].runtime_enabled are enabled. ACP accepts prompt, model, a gateway-owned ACP sessionId, and a registered gateway workspace alias. Both Cursor transports reject approvalStrategy:"mcp_managed"; approvalPolicy has no effect on CLI and is rejected on ACP.

Parameters:

  • prompt (string, required): Prompt text for Cursor Agent CLI (1-100,000 chars)

  • model (string, optional): Model name or alias (for example gpt-5, sonnet-4-thinking, or latest)

  • mode (string, optional): Cursor mode, "plan" or "ask" (--mode)

  • outputFormat (string, optional): "text" (default), "json", or "stream-json"

  • transport (string, optional): "cli" (default) or "acp"; ACP fails closed unless its global and Cursor provider gates are enabled. ACP accepts only prompt, model, sessionId, and a registered workspace; non-default Cursor CLI controls (mode, non-text outputFormat, workingDir, non-empty addDir, force, autoReview, sandbox, trust, resumeLatest, createNewSession, optimization or compression, idleTimeoutMs, and forceRefresh) are rejected. Sync-only: cursor_request_async always runs the CLI transport and does not accept transport

  • force (boolean, optional): Emit --force for non-interactive operation.

  • autoReview (boolean, optional): Emit --auto-review.

  • sandbox (string, optional): "enabled" or "disabled" (--sandbox).

  • trust (boolean, optional): Emit --trust for this invocation.

  • workspace (string, optional): On transport: "cli", a Cursor workspace path or name (--workspace); remote HTTP/OAuth callers must pass a registered workspace alias, while local stdio callers may pass paths. An unregistered relative local value is preserved verbatim as a provider-native saved-workspace name and is never resolved against the gateway process cwd; pass an absolute path to select a local directory cwd. On transport: "acp", it must be a registered gateway workspace alias. A fresh remote ACP request uses the supplied alias or [workspaces].default; a remote ACP resume stays bound to its recorded canonical alias and cwd

  • workingDir (string, optional): Local Cursor Agent process working directory, CLI transport only. Distinct from workspace, which is Cursor's own selector; passing an absolute workspace path that disagrees with workingDir is rejected rather than silently ranked. Rejected on transport: "acp", which resolves its own scope, rather than being accepted and discarded.

  • addDir (string[], optional): Additional workspace roots (one --add-dir per entry); remote HTTP/OAuth callers must use registered workspace roots.

  • sessionId (string, optional): On transport: "cli", a Cursor chat/session ID to resume (--resume <id>). The gw-* id minted for a brand-new gateway session is not resumable through the CLI transport; continue with resumeLatest: true. On transport: "acp", pass the gateway-owned ACP session ID returned by an earlier ACP call; Cursor-native and CLI session IDs are rejected

  • resumeLatest (boolean, optional): CLI only: resume the most recent Cursor chat (--continue). true is rejected on ACP.

  • createNewSession (boolean, optional): CLI only: force a new session. true is rejected on ACP.

  • approvalStrategy (string, optional): "legacy" is the only executable CLI strategy. "mcp_managed" is rejected before Cursor launches; ACP has its own permission bridge and also rejects it.

  • approvalPolicy (string, optional): Has no effect on CLI because mcp_managed is unavailable. ACP rejects it because ACP uses its own permission bridge.

  • optimizePrompt / optimizeResponse (boolean, optional): Token-efficiency optimisation, default: false

  • correlationId (string, optional): Request trace ID (auto-generated if omitted)

  • idleTimeoutMs (integer, optional): Total-runtime bound, not an idle timer: this provider emits no output until it exits, so the process is killed after this duration even while healthy. 30,000 to 3,600,000 ms, default 3,600,000 ms. This holds for the default text invocation; with outputFormat: "stream-json" Cursor streams incrementally, so the same timer behaves as a genuine idle window

  • forceRefresh (boolean, optional): Bypass dedup and force a fresh CLI run, default: false

claude_request_async / codex_request_async / gemini_request_async / grok_request_async / mistral_request_async / devin_request_async / cursor_request_async

Start a long-running Claude, Codex, Gemini, Grok, Mistral, Devin, or Cursor request without waiting for completion in the same MCP call.

Use this flow when analysis/runtime can exceed client tool-call limits:

  1. Start job with *_request_async

  2. Poll with llm_job_status

  3. Read output with llm_job_result

  4. Optionally stop with llm_job_cancel

Async request tools accept the same strategy fields as their sync variants:

  • claude_request_async supports approvalStrategy:"legacy" (default) or "mcp_managed", and approvalPolicy:"strict"|"balanced"|"permissive". Managed mode forces strictMcpConfig:true and launches Claude with only the generated MCP config.

  • Every other *_request_async tool supports only executable approvalStrategy:"legacy". It rejects mcp_managed before provider launch because ambient MCP configuration cannot be isolated; approvalPolicy has no effect.

  • mcpServers configures the Claude generated config only. For the other CLI adapters it is metadata only and does not create an MCP allowlist.

llm_job_status

Return lifecycle status (queued, running, completed, failed, canceled, orphaned), metadata, and bounded normalized progress for an async job. afterProgressSeq returns events with a greater sequence number and progressLimit selects up to 64 events in forward sequence order. Continue with nextAfterSeq; highWaterSeq (and its compatibility alias lastSeq) reports the highest sequence observed for the job, while hasMore reports whether another retained page is immediately available. The progress snapshot reports capability (structured, activity_only, or lifecycle_only), lastActivityAt, cursor/high-water metadata, droppedCount, and events with a phase, kind, timestamp, safe message, and source. Claude stream-JSON, Codex JSONL, Grok streaming-JSON, Gemini stream-JSON, Mistral streaming, and Cursor stream-JSON expose structured activity. Codex validation and repository review calls do not request JSONL and therefore report activity_only. HTTP/API jobs report lifecycle_only; other process output modes expose only privacy-safe activity/lifecycle signals. Raw reasoning, provider-supplied tool names, tool arguments, paths, provider IDs, and output text are not copied into progress messages. Tool-start activity uses the fixed message Using a provider tool.

llm_job_watch

Wait up to 30 seconds for new normalized progress on an owned async job. Pass the response's nextAfterSeq as afterProgressSeq; the response uses the same snapshot shape as llm_job_status. When the MCP request carries a progress token, the gateway emits notifications/progress only while that watch call is active. The tool rechecks owner access throughout the wait and returns the same own-or-not-found result as other job tools.

llm_job_result

Return captured stdout/stderr for an async job. By default it returns a display-oriented result, with maxChars limiting each stdout and stderr stream to 1,000 through 2,000,000 characters per call (200,000 by default).

For complete, resumable retrieval of a large provider stream, set rawOutput:true. The response's result includes independent stdoutOffsetChars, stdoutTotalChars, and stdoutNextOffsetChars fields, plus matching stderr* fields. Start both offsets at zero, then pass each non-null next offset back as stdoutOffsetChars or stderrOffsetChars until that stream's next offset is null. Raw pages are not display-parsed or compressed. On the local stdio surface, pages concatenate in stream order to the captured stdout or stderr stream. Remote callers use the same offset protocol, but provider-session-ID ranges are redacted before pages are returned, including an ID that crosses a page boundary. Treat remote rawOutput:true as resumable, sanitized output, not byte-for-byte captured provider output.

Non-zero offsets are rejected in default display mode. Display mode can parse a streaming provider format, reconstruct a Codex reply, or compress text, so a slice of the captured stream cannot safely resume or concatenate the displayed result. Use rawOutput:true whenever an application must resume output collection.

Every non-Kit CLI job records the exact launched argv, the resolved cwd scope, the repository HEAD when available, bounded SHA-256 instruction-file evidence, the capture grammar, and whether the transcript was captured whole, captured to the stated 50 MiB aggregate ceiling, or not captured. Claude, Codex, Gemini, Grok, Mistral, and Cursor are launched with their richest transcript-capable wires. Devin is launched with a gateway-owned ATIF export path; the regular, non-symlink export is copied into the durable job row after process exit and the source is then removed. Local stdio callers can page the native transcript in raw mode. Remote HTTP/OAuth callers cannot retrieve raw job results, native transcripts, instruction paths, or replay context.

llm_job_cancel

Cancel a running async job.

approval_list

List recent Claude MCP-managed approval decisions recorded by the gateway.

Parameters:

  • limit (number, optional): Max records (1-500), default: 50

  • cli (string, optional): Filter by "claude", "codex", "gemini", "grok", "mistral", "devin", or "cursor"

Approval records are persisted to ~/.llm-cli-gateway/approvals.jsonl.

llm_request_result

Read back any persisted request — sync or async — by its correlation ID. Every response echoes its ID in structuredContent.correlationId; pass it here to recover the persisted prompt/response after the inline result is gone. Reads the flight recorder, so it works independently of async-job persistence (returns "not found" when flight recording is disabled).

Parameters:

  • correlationId (string, required): Correlation ID from a prior request

  • maxChars (number, optional): Max chars of the persisted response to return (1,000-2,000,000)

  • includePrompt (boolean, optional): Include the full persisted prompt text, default: false

  • includeJobRecord (boolean, optional): Include the linked raw provider capture and replay context for local stdio callers, default: false. Remote callers receive neither transcripts nor host paths.

llm_request_list

List recent persisted requests newest-first without a correlation ID, which is how you find one. Every other flight-recorder read is keyed by an id handed out inline to the caller that made the request, so an agent that did not make the call (or whose context was compacted since) starts here. Returns metadata only: pass a returned correlationId to llm_request_result for the bodies, or a returned asyncJobId to llm_job_status. A caller only ever sees its own requests. An empty list is not proof nothing ran, and it does not mean the work left no record: cross-LLM validation seats write no row here, but they write validation_runs and validation_run_jobs, and each of those links a job row holding the launched argv and the provider output (read it with validation_receipt, then llm_job_result). Flight recording can also be disabled. Jobs and requests are both unbounded by default; an operator can configure their bounds independently.

Parameters:

  • limit (number, optional): Max rows, 1-200, default: 25

  • since (string, optional): ISO-8601 lower bound, e.g. 2026-08-21T00:00:00Z

  • cli (string, optional): Restrict to one provider as recorded

  • sessionId (string, optional): Restrict to one gateway session id

llm_process_health

Report gateway process health: async-job manager state, the resolved durable persistence configuration, and flight-recorder health on that configured engine. With backend = "postgres", the recorder reports the opaque postgresql target and generic PostgreSQL failures, and never falls back to SQLite. Its warning also states that rows left in the previous engine were not migrated. The explicit LLM_GATEWAY_LOGS_DB=none recorder-off switch remains separate, as do the intentionally ephemeral memory and disabled none job-store modes.

upstream_contracts

Return the gateway's declared provider CLI contracts, optionally probing the installed binaries for drift.

Parameters:

  • cli (string, optional): Filter (claude|codex|gemini|grok|mistral|devin|cursor)

  • probeInstalled (boolean, optional, default false): Run local --help probes and compare advertised flags against the declared contract — strongly recommended after any provider CLI upgrade. The probe reports missingFlags, extraFlags, acknowledgedExtraFlags (known upstream-only flags filtered from extraFlags), discoveredFlags, and stale-marker warnings.

Session Management Tools

session_create

Create a new session for a specific CLI.

Parameters:

  • cli (string, required): CLI to create session for ("claude", "codex", "gemini", "grok", "mistral", "devin", "cursor")

  • description (string, optional): Description for the session

  • setAsActive (boolean, optional): Set as active session, default: true

Example:

{
  "cli": "claude",
  "description": "Code review session",
  "setAsActive": true
}
session_list

List all sessions, optionally filtered by CLI.

Parameters:

  • cli (string, optional): Filter by CLI ("claude", "codex", "gemini", "grok", "mistral", "devin", "cursor")

Response includes:

  • Total session count

  • Session details (ID, CLI, description, timestamps, active status)

  • Active session IDs for each CLI

session_set_active

Set the active session for a specific CLI.

Parameters:

  • cli (string, required): CLI to set active session for

  • sessionId (string, required): Session ID to activate (or null to clear)

session_get

Retrieve details for a specific session.

Parameters:

  • sessionId (string, required): Session ID to retrieve

session_delete

Delete a specific session.

Parameters:

  • sessionId (string, required): Session ID to delete

session_clear_all

Clear all sessions, optionally for a specific CLI.

Parameters:

  • cli (string, optional): Clear sessions for specific CLI only

Utility Tools

list_models

List available models for each CLI.

Parameters:

  • cli (string, optional): Specific provider to list models for ("claude", "codex", "gemini", "grok", "mistral", "devin", "cursor", or an enabled API provider name). When one or more [providers.<name>] API providers are enabled, the unfiltered response also carries an apiProviders array (each entry tagged providerKind: "api"); see API providers (HTTP).

Response includes:

  • Model names and descriptions

  • Best use cases for each model

  • CLI-specific information

  • defaultModel and defaultModelSource when a default is explicitly configured

  • modelMetadata with source/confidence (fallback, config, env, observed)

  • aliases and warnings when configured or when discovery degrades gracefully

The registry treats explicit configuration as authoritative. Bundled fallback models are low-confidence hints, and Gemini models observed in local session history are merged as low-confidence entries only; they do not become the default model.

Model registry environment overrides:

# Explicit defaults
CLAUDE_DEFAULT_MODEL=haiku
CODEX_DEFAULT_MODEL=<codex-model-id>
GEMINI_DEFAULT_MODEL=gemini-2.5-flash

# Additional models: comma/newline list, JSON array, or JSON object of model->description
GEMINI_MODELS='{"gemini-team-default":"Team-approved Gemini model"}'

# Aliases
GEMINI_MODEL_ALIASES='team=gemini-team-default'
LLM_GATEWAY_MODEL_ALIASES='codex.fast=gpt-5.3-codex-spark,gemini.fast=gemini-team-default'

# Deterministic config/discovery paths
CODEX_CONFIG_PATH=/path/to/config.toml
CLAUDE_SETTINGS_PATH=/path/to/settings.json
CLAUDE_SETTINGS_LOCAL_PATH=/path/to/settings.local.json
GEMINI_SETTINGS_PATH=/path/to/settings.json
GEMINI_HISTORY_ROOT=/path/to/.gemini/tmp

# Disable local model-history discovery
LLM_GATEWAY_DISABLE_MODEL_DISCOVERY=1
provider_tool_capabilities

Report the provider tool and feature capability catalog. Use this before orchestrating provider-specific requests so callers can distinguish supported controls, provider-owned configuration, ignored parity fields, and unsupported inputs.

Parameters:

  • cli (string, optional): Provider filter ("claude", "codex", "gemini", "grok", "mistral", "devin", "cursor", "grok_api", or an enabled API provider name)

  • includeSkills (boolean, default true): Include bounded local skill discovery

  • includeProviderTools (boolean, default true): Include provider-native tools extracted from discovered skills

  • includeUnsupported (boolean, default true): Include explicit unsupported/degraded input records

  • includePaths (boolean, default false): Include raw local filesystem paths in discovery output

  • refresh (boolean, default false): Bypass the short-lived capability cache

The response schema is provider-tool-capabilities.v2. Capability discovery is read-only and bounded; raw local paths are redacted unless includePaths is explicitly true, and secret-bearing auth files are not read.

Equivalent MCP resources:

  • provider-tools://catalog: full provider catalog

  • provider-tools://claude

  • provider-tools://codex

  • provider-tools://gemini

  • provider-tools://grok

  • provider-tools://grok_api

  • provider-tools://mistral

  • provider-tools://devin

  • provider-tools://cursor

  • provider-tools://<api-provider> for each enabled [providers.<name>] API provider

doctor --json also emits a compact provider_capabilities block with the same schema version, per-provider request tool names, supported feature names, unsupported input names, config-surface counts, discovery counts, and resource URIs. This block is intended for setup assistants that need a concise capability summary without local skill bodies or raw paths. When API providers are enabled, doctor --json additionally emits an api_providers health block; see API providers (HTTP).

cli_versions

Report installed CLI versions.

Parameters:

  • cli (string, optional): Specific CLI to inspect ("claude", "codex", "gemini", "grok", "mistral", "devin", "cursor")

cli_upgrade

Plan or run an upgrade for one CLI.

Parameters:

  • cli (string, required): CLI to upgrade ("claude", "codex", "gemini", "grok", "mistral", "devin", "cursor")

  • target (string, optional): Package tag/version/target, default: latest

  • dryRun (boolean, optional): Return the upgrade plan without running it, default: true

  • timeoutMs (number, optional): Upgrade timeout when dryRun=false

Upgrade strategies:

  • Claude latest: claude update

  • Claude explicit target: claude install <target>

  • Codex latest: codex update

  • Codex explicit target: npm install -g @openai/codex@<target>

  • Gemini latest: agy update (Antigravity self-update; explicit version targets are unsupported)

  • Grok latest: grok update

  • Grok explicit target: grok update --version <target>

  • Mistral (Vibe): dispatches to the detected installer (pip/uv/brew); errors with guidance when none is detected (Vibe ships no self-update command)

  • Devin latest: devin update (self-update; explicit version targets are unsupported)

  • Cursor latest: cursor-agent update (self-update; explicit version targets are unsupported)

Example dry run:

{
  "cli": "gemini",
  "target": "latest",
  "dryRun": true
}

API providers (HTTP)

In addition to the spawnable CLI tools, the gateway can route requests to first-class HTTP/API providers (OpenRouter and other OpenAI-compatible endpoints, the Anthropic Messages API, and the xAI Responses API). These use Node's built-in HTTP client (node:https, or node:http for loopback endpoints) rather than spawning a CLI, and they run through the same request/job/validation/flight-recorder machinery as the CLI tools, so they reach parity for sessions, async jobs, dedup, retries, usage/cost capture, and cross-LLM validation.

Configuring a provider

API providers are declared as [providers.<name>] blocks in ~/.llm-cli-gateway/config.toml (override with LLM_GATEWAY_CONFIG). The <name> becomes the provider's identity across every tool and resource and must not collide with a spawnable CLI name (claude, codex, gemini, grok, mistral, devin, cursor); a collision is rejected with a warning and the provider is disabled.

# OpenRouter (OpenAI-compatible). The key is read from the named env var at
# request time and is never written to config, logs, the flight recorder, or
# the dedup key.
[providers.openrouter]
kind = "openai-compatible"                 # "openai-compatible" | "anthropic" | "xai-responses"
base_url = "https://openrouter.ai/api/v1"
api_key_env = "OPENROUTER_API_KEY"         # env var NAME, not the key itself
default_model = "x-ai/grok-2"
models = ["x-ai/grok-2", "anthropic/claude-sonnet-4.6"]   # optional allowlist: an explicit model must be listed (omit model to use default_model)
usage_include = true                       # OpenRouter token/cost reporting (usage:{include:true})

# Keyless-local: an openai-compatible provider on a loopback base_url (Ollama,
# llama.cpp) is enabled with no api_key_env at all.
[providers.ollama]
kind = "openai-compatible"
base_url = "http://127.0.0.1:11434/v1"
default_model = "qwen2.5"

A provider is enabled when its api_key_env resolves to a non-empty value, OR it is a keyless-local openai-compatible provider on a loopback base_url. base_url must use https unless it targets localhost/loopback. A schema-invalid single [providers.<name>] block disables only itself (with a warning) and leaves the other providers untouched; a TOML syntax error anywhere in the file is different, it makes the whole config fall back to defaults.

The pre-existing [providers.xai] block keeps its dedicated grok_api_request tool and xAI identity. It is also exposed through the generic surface like any other enabled provider, so a configured xAI key registers both grok_api_request and the generic api_xai_request (and the xai entry appears in apiProviders, models://xai, etc.).

Request tools

For each enabled provider, the gateway registers api_<name>_request (and api_<name>_request_async when async jobs are enabled). They accept the same shape as the CLI request tools:

  • prompt (or the cache-aware promptParts { system?, tools?, context?, task }, mutually exclusive), optional system

  • model (omit to use default_model; an explicit value is rejected if outside a configured models allowlist), maxOutputTokens, temperature, topP

  • reasoningEffort (none|low|medium|high): forwarded only by the xai-responses adapter; accepted but ignored by the other kinds

  • timeoutMs, optimizePrompt, optimizeResponse, forceRefresh, correlationId

  • sessionId / createNewSession for continuity on the synchronous api_<name>_request (see below); on the async variant they are currently inert

Responses (and the 50 MB output cap, dedup window, cancellation, retention) behave exactly as for the CLI tools, and HTTP requests are logged to the flight recorder with status/usage/cost like everything else.

Continuity

Continuity is capability-typed per provider kind and never stores conversation content in the session record (the gateway's no-transcript-in-sessions invariant holds):

  • xai-responses uses real server-side continuation: the gateway persists the provider's previous_response_id in session metadata and threads it back on resume, self-healing on a stale-handle 404.

  • openai-compatible and anthropic are stateless-resend: the session tracks active/owner state for principal isolation, but the caller resends prior context (no server-side conversation handle exists).

Discovery surfaces

Enabled API providers appear, alongside the CLI providers, across the discovery surfaces. The model, capability, doctor, and resource surfaces below omit their API field entirely when no API providers are enabled, so their output is byte-identical to before; llm_process_health is the exception (it always carries an apiProviders array that is simply empty when none are enabled):

  • list_models / list_available_models: an apiProviders array tagged providerKind: "api" with defaultModel and the optional allowlist, omitted entirely when no API providers are enabled.

  • llm_process_health: an always-present outboundProviders.apiProviders array (empty when none are enabled) carrying the same projection plus each provider's circuit-breaker state.

  • provider_tool_capabilities: per-api-kind capability metadata. Model + sampling + (for xai-responses) reasoning + continuity are supported; allow/deny tool lists, MCP servers, local skills, and workspace/worktree controls are not (those are CLI-only).

  • doctor --json: an api_providers health block (kind, base_url, default_model, models, the key env var name, whether the key is present, and login guidance), omitted entirely when none are enabled. The optional flag doctor --json --probe-api-providers adds a per-provider endpoint-reachability result (a bare GET, treating any HTTP response as reachable). The probe is opt-in and off by default: a normal doctor run opens no socket and spends no tokens (reachable stays null).

  • MCP resources: models://<provider> for every enabled provider and sessions://<provider> for continuity-tracked kinds, plus provider-tools://<provider>. The provider-subcommands:// resources stay CLI-only (API providers have no subcommands).

The API key value is never emitted on any of these surfaces (only the env var name and a presence boolean). Because base_url is config-supplied and may legally carry URL userinfo, the diagnostic surfaces (doctor, login guidance) redact any embedded credentials before displaying it; the actual request path and the reachability probe still use the original configured URL.

Security note

The resolved API key is excluded from payloadJson, the dedup key, logs, and the flight recorder. For ordinary non-Kit async jobs, the request prompt is persisted in plaintext in the async job store (SQLite at [persistence].path, default ~/.llm-cli-gateway/logs.db, or Postgres rows under backend = "postgres") and is not covered by secret redaction. This mirrors the CLI tools, whose prompt is persisted in argsJson whenever it is passed as a command argument rather than streamed over stdin. review_changes deliberately retains the complete fenced CLI prompt in expiry-bound payloadJson, stores only a hash marker in argsJson, and does not copy that prompt into the flight recorder. Personal Agent Config Kit durable rows use a separate privacy boundary: they do not persist compiled instructions or request arguments, and they withhold provider output and errors while retaining only the recovery and integrity state the Kit needs. Treat the job store as sensitive at rest. See Security Considerations and the Personal Agent Config Kit guide.

Session Management

How It Works

  1. Gateway metadata, not transcripts: Session records track ownership, timestamps, active pointers, and provider metadata. They do not store a conversation transcript.

  2. Storage backend: The session manager follows [persistence].backend in config.toml: sqlite/none keep ~/.llm-cli-gateway/sessions.json, postgres selects the PostgreSQL session manager. DATABASE_URL is a DEPRECATED override retained for compatibility; it warns once and is refused outright when it disagrees with an explicit [persistence].dsn. Note the PostgreSQL session store has no TTL eviction, where the file store reaps at 30 days; see the 3.1.0 notes.

  3. Provider-native continuity: A gateway session ID is tracking metadata, not automatically a provider-native resume ID. Native behavior remains provider-specific: claude_request with continueSession:true uses Claude's latest conversation in a stable selected working directory and fails closed without workingDir or a registered workspace selected explicitly, through caller-owned session metadata, or by the configured default. That workspace may optionally supply a gateway worktree. codex_request needs a real Codex UUID for sessionId, or resumeLatest:true, which resumes a previous session. Do not rely on which session --last selects or on the resumed working directory (under review).

  4. Caller isolation: HTTP/OAuth callers can retrieve or reuse only sessions they own. Their session projection hides local paths and native provider identifiers.

  5. Personal Kit: With Personal Agent Config Kit enabled, Claude, Codex, and Mistral use a separate, context-bound active-session pointer and retain a native continuation handle only in the current gateway process. See the Personal Agent Config Kit guide.

Session Workflow

// 1. Create a gateway tracking record when you need one.
// This ID is not automatically a native provider resume ID.
await callTool("session_create", {
  cli: "claude",
  description: "Debugging session",
  setAsActive: true,
});

// 2. Use the provider's documented native continuity control.
await callTool("claude_request", {
  prompt: "What's the bug in this code?",
  continueSession: true, // Claude's latest conversation in this working directory
});

await callTool("codex_request", {
  prompt: "Review the proposed fix.",
  resumeLatest: true, // or pass a real Codex UUID as sessionId
});

// 3. Inspect or remove gateway tracking records.
await callTool("session_list", { cli: "claude" });
await callTool("session_delete", {
  sessionId: "session-id-to-delete",
});

session_delete removes gateway tracking from caller-visible session surfaces. For file-backed sessions, it also runs cleanup for associated gateway-owned lifecycle resources, such as a managed worktree. A durably owned worktree session remains as a hidden cleanup-pending tombstone until Git removal is verified; failed removal is retried when that store is registered on the owning host. It does not delete a provider's own stored conversation.

Configuration

Environment Variables

  • DEBUG: Enable debug logging (set to any value)

    DEBUG=1 node dist/index.js
  • LLM_GATEWAY_APPROVAL_POLICY: Default approval policy for a Claude mcp_managed request when it does not pass approvalPolicy (strict, balanced, permissive). It has no effect on non-Claude adapters because they reject mcp_managed before launch.

    LLM_GATEWAY_APPROVAL_POLICY=strict node dist/index.js
  • LLM_GATEWAY_APPROVAL_ALLOW_BYPASS: Applies only to Claude approvalStrategy:"mcp_managed". A direct bypassPermissions request, or an unverified execution posture such as settings, instruction overrides, plugins, additional directories, worktrees, or native continuation, is denied by default regardless of approval score. Ordinary managed Claude requests use --permission-mode acceptEdits.

    Set this to 1/true only to allow an explicit caller request through Claude's normal approval decision. The environment setting alone never escalates an ordinary managed Claude request. This setting does not enable mcp_managed on Codex, Gemini, Grok, Mistral, Devin, or Cursor: those adapters reject it before provider launch.

    LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1 node dist/index.js
  • LLM_GATEWAY_TRUSTED_PRINCIPAL_HEADER: Name of an HTTP header carrying the authenticated user identity asserted by a trusted front door (any identity-aware reverse proxy / IdP). When set, the gateway adopts that header value as the request's ownership principal — but only for requests authenticated with the gateway's own static bearer token (i.e. the trusted upstream proxy), never from an arbitrary remote client. Off by default; IdP-agnostic. Lets a proxy-fronted multi-user deployment carry per-user identity into the gateway.

    LLM_GATEWAY_TRUSTED_PRINCIPAL_HEADER=x-gateway-principal node dist/index.js
  • LLM_GATEWAY_OAUTH_REQUIRE_CONSENT / LLM_GATEWAY_OAUTH_CONSENT_SECRET: Opt-in human-consent gate for the built-in OAuth server. When enabled (REQUIRE_CONSENT=1, or implied by setting CONSENT_SECRET), /oauth/authorize renders an operator approval page (CSRF-protected) and issues an authorization code only after the dedicated consent password is entered — instead of auto-issuing. CONSENT_SECRET is the plaintext password (hashed in memory; or persist a consent_secret_hash in [http.oauth]). Off by default; remote OAuth refuses to enable consent without a secret to verify.

    LLM_GATEWAY_OAUTH_REQUIRE_CONSENT=1 LLM_GATEWAY_OAUTH_CONSENT_SECRET='choose-a-strong-code' node dist/index.js
  • LLM_GATEWAY_CONFIG: Path to the gateway TOML config (default: ~/.llm-cli-gateway/config.toml). See Persistence configuration above for the [persistence] schema.

  • LLM_GATEWAY_SKILLS_PATH: Extra local skill-pack roots to load at startup, separated by the host path delimiter (: on Linux/macOS, ; on Windows). These paths are appended after [skills].paths; ~/.llm-cli-gateway/skills still loads last when present.

  • LLM_GATEWAY_LOGS_DB: Deprecated. When no backend is explicitly configured, selects backend = "sqlite" with this path (or backend = "none" when set to none). An explicit backend wins for job persistence. The variable still independently disables the recorder on every backend and paths it when SQLite is selected. Emits a deprecation warning at startup; migrate to config.toml.

    # Custom path
    LLM_GATEWAY_LOGS_DB=/var/log/gateway/logs.db node dist/index.js
    # Disable the recorder; with no explicit backend, also disable async persistence
    LLM_GATEWAY_LOGS_DB=none node dist/index.js
  • LLM_GATEWAY_REDACT_LOGGED_SECRETS: Redact recognisable secrets (provider/cloud/VCS keys, bearer tokens, JWTs, PEM private keys, key=value secret assignments) from the prompt/system/response copies written to the flight-recorder log. Enabled by default; set to 0/false/off/no to store content verbatim. Only the audit log is affected — live sync responses and async llm_job_result output are never altered.

    # Opt out of flight-recorder secret redaction
    LLM_GATEWAY_REDACT_LOGGED_SECRETS=0 node dist/index.js

CLI-Specific Settings

Each CLI can be configured through its own configuration files:

  • Claude Code: ~/.claude/settings.json

  • Codex: ~/.codex/config.toml

  • Gemini / Antigravity (agy): ~/.gemini/settings.json

Development

Project Structure

llm-cli-gateway/
ā”œā”€ā”€ src/
│   ā”œā”€ā”€ index.ts              # Main MCP server and tool definitions
│   ā”œā”€ā”€ executor.ts           # CLI execution with timeout support
│   ā”œā”€ā”€ session-manager.ts    # Session management logic
│   └── __tests__/
│       ā”œā”€ā”€ executor.test.ts  # Unit tests for executor
│       └── integration.test.ts # Integration tests
ā”œā”€ā”€ dist/                     # Compiled JavaScript
ā”œā”€ā”€ package.json
ā”œā”€ā”€ tsconfig.json
└── vitest.config.ts

Running Tests

# Run all tests
npm test

# Run unit tests only
npm run test:unit

# Run integration tests only
npm run test:integration

# Watch mode
npm run test:watch

Building

npm run build

Starting the Server

npm start

Error Handling

The gateway provides detailed error messages for common issues:

CLI Not Found

Error executing claude CLI:
spawn claude ENOENT

The 'claude' command was not found. Please ensure claude CLI is installed and in your PATH.

External Timeout / Legacy Timeout Option

Error executing codex CLI: Command timed out
Process timed out after 120000ms

Invalid Parameters

Prompt cannot be empty
Prompt too long (max 100k chars)

Logging

Logs are written to stderr (stdout is reserved for MCP protocol):

[INFO] 2026-01-24T05:00:00.000Z - Starting llm-cli-gateway MCP server
[INFO] 2026-01-24T05:00:01.000Z - claude_request invoked with model=sonnet, prompt length=150
[INFO] 2026-01-24T05:00:05.000Z - claude_request completed successfully in 4523ms, response length=2048
[ERROR] 2026-01-24T05:00:10.000Z - codex CLI execution failed: spawn codex ENOENT

Enable debug logging:

DEBUG=1 node dist/index.js

Troubleshooting

CLIs Not Found

Make sure the CLIs are installed and in your PATH:

which claude
which codex
which agy

The gateway extends PATH to include common locations:

  • ~/.local/bin

  • /usr/local/bin

  • /usr/bin

  • All ~/.nvm/versions/node/*/bin directories

Permission Errors

If you encounter permission errors, ensure the CLI tools have proper permissions:

chmod +x $(which claude)
chmod +x $(which codex)
chmod +x $(which agy)

Session Storage Issues

These file checks apply only to the default file session manager. When [persistence].backend = "postgres" selects PostgreSQL session storage, sessions.json is not authoritative. Do not delete or edit session storage while gateway processes, provider children, or Personal Agent Config Kit attempts are active.

  1. Check file permissions after stopping local gateway processes:

ls -la ~/.llm-cli-gateway/
  1. Use session_delete or session_clear_all for intentional gateway-record cleanup. Do not manually edit the file as a normal recovery method.

  2. If a file-backed store is unreadable, inspect a copy only after the gateway is stopped:

cat ~/.llm-cli-gateway/sessions.json

For a stuck Personal Agent Config Kit attempt, do not reset sessions.json; follow the local-only recovery procedure in the Personal Agent Config Kit guide.

Performance

Timeouts

The gateway does not enforce a default execution timeout for LLM CLI requests.

If your MCP client/runtime enforces per-tool-call deadlines, use async tools (*_request_async + llm_job_status/llm_job_result) so long-running jobs can complete outside a single call window.

Concurrent Requests

The gateway supports concurrent requests across different CLIs. Each request spawns a separate process.

Security Considerations

  • Input Validation: All prompts are validated (min 1 char, max 100k chars)

  • API-provider keys: For [providers.<name>] HTTP providers, the gateway reads the key from the named environment variable at request time only. The resolved key is excluded from the persisted payloadJson, the dedup key, logs, and the flight recorder, and is never surfaced on the discovery/diagnostic surfaces (which report only the env var name and a presence boolean). base_url userinfo is redacted on the diagnostic surfaces. See API providers (HTTP).

  • Prompt persistence at rest: Ordinary non-Kit async job rows store the request prompt in plaintext (HTTP payloadJson, and CLI argsJson whenever the prompt is passed as a command argument rather than streamed over stdin); this is not covered by secret redaction. review_changes is explicit about its different CLI layout: the complete fenced prompt is retained in expiry-bound payloadJson, persisted argv contains only its hash marker, and the prompt is not copied into the flight recorder. Personal Agent Config Kit durable rows do not persist compiled instructions or request arguments and withhold provider output and errors, retaining only privacy-safe recovery and integrity state. The SQLite job-store file (default ~/.llm-cli-gateway/logs.db, configurable via [persistence].path) is chmoded to 0o600 on non-Windows hosts; the Postgres backend stores the corresponding fields in database rows. Treat either backend as sensitive and scope/rotate it like any prompt log. Set [persistence].backend = "none" to disable the async job store entirely (the *_request_async / llm_job_* tools are then not registered). See the Personal Agent Config Kit guide for its narrower durable-record boundary.

  • Command Execution: Uses spawn with separate arguments (not shell execution)

  • No Eval: No dynamic code evaluation in our source (see "Socket alerts" below for the transitive ajv codegen case)

  • Sandboxing: Consider running in containers for production use

  • npm publish control: npm releases are gated by the generated prod-only shrinkwrap, release security audit, packed-consumer checks, and GitHub Actions Trusted Publishing with short-lived OIDC-derived npm publish credentials

  • Release signing: GitHub release installer artifacts are signed with Sigstore keyless signing; verify SHA256SUMS.sigstore.json before trusting the checksum file

Socket alerts — context for reviewers

If you're vetting llm-cli-gateway through Socket or a similar supply-chain scanner, you'll see behavioural alerts and some dependency-ownership alerts. They are accurate descriptions of what the package does and what it depends on. The reviewed shellAccess and shrinkwrap entries are configured in socket.yml for repository/PR policy surfaces, but Socket's public package page may still display them for the published npm artifact; the rationale remains documented here and in the package.

The currently flagged surfaces are not new in 2.6.x: the 2.3.0, 2.4.0, 2.5.0, and 2.6.3 npm tarballs all include npm-shrinkwrap.json, and all include the same dist/executor.js child-process spawn surface used to run provider CLIs. The socket.yml policy for 2.4.0, 2.5.0, 2.6.0, and 2.6.3 is materially the same for shellAccess; this README now adds the missing shrinkwrap disclosure as well.

Alert

Where

Why it's bounded

Network access

src/http-transport.ts opens an HTTP MCP transport when started via npm run start:http. src/endpoint-exposure.ts issues a HEAD probe to verify configured public/tunnel URLs. Socket also flagged dist/upstream-contracts.js in v1.17.2 from descriptive text, not a network call.

The transport binds to 127.0.0.1 by default and requires LLM_GATEWAY_AUTH_TOKEN to be set. The default stdio MCP entry point (npm start) opens no sockets. src/upstream-contracts.ts stores provider CLI metadata and imports no HTTP client APIs.

Shell access

src/executor.ts uses child_process.spawn(cmd, args, …) to invoke the underlying LLM CLIs.

spawn is called with an argument array and never shell: true, so there is no shell interpolation path for caller input. The command name is never taken from caller input either: it is derived from the provider registry via providerCommandName(cli) for a CLI_TYPES member, or from a gateway-computed upgrade plan in src/cli-updater.ts (npm/pip/uv/brew). No MCP tool accepts a binary name. Note this is a property of every call site rather than a membership check inside src/executor.ts, which takes command as a string and does not filter it.

Published shrinkwrap

The npm artifact includes npm-shrinkwrap.json; package.json#files includes it and scripts/make-prod-shrinkwrap.mjs generates it from package-lock.json.

This is a CLI/application package. npm documents the shrinkwrap use case for applications, daemons, and command-line tools published through the registry. Our shrinkwrap is a prod-only projection, not a committed full dev lockfile: scripts/release-security-audit.sh verifies parity with the audited lockfile, and scripts/verify-registry-install.sh proves fresh registry consumers receive no better-sqlite3/prebuild-install/tar-fs/tar-stream production chain.

Uses eval

None in our source. Transitive: @modelcontextprotocol/sdk → ajv@8 uses new Function(...) in ajv/dist/compile/index.js to compile JSON Schema validators.

This is ajv's standard codegen path. Only known schemas (defined in our source and the MCP SDK) flow into it; no caller-supplied data ever reaches the compiled function body.

SQLite adapter isolation

The SQLite backend uses Node's built-in node:sqlite module (no native binding, no install scripts) through a single adapter, src/sqlite-driver.ts.

node:sqlite is touched by exactly one production module (the adapter); every other module talks to SQLite through its typed surface. We never call any db.pragma() helper (it does not exist on node:sqlite); SQLite setup uses fixed literal db.exec("PRAGMA ...") statements. npm run security:audit fails the release if production code references node:sqlite outside the adapter or reintroduces a .pragma() call.

Dependency ownership

A handful of small transitive packages (e.g. media-typer via @modelcontextprotocol/sdk) trip Socket's "unstable ownership" or "obfuscated code" heuristics.

These are pinned, well-known micro-deps in the Node ecosystem with no known issues. We pin direct override versions of content-type and type-is in package.json#overrides. As of 2.0.0 the prod graph carries no native module (better-sqlite3 moved to devDependencies; node:sqlite is built into Node), eliminating the entire prebuild-install/tar-fs/tar-stream install-time chain. Our earlier direct dependency on toml@3.0.0 was replaced with smol-toml.

See socket.yml for the same context in machine-readable form.

Contributing

  1. Fork the repository

  2. Create a feature branch

  3. Make your changes

  4. Run tests: npm test

  5. Build: npm run build

  6. Submit a pull request

License

MIT. See LICENSE for details.

Support

For issues and questions:

  • Open an issue on GitHub

  • Check existing issues and documentation

  • Review CLI-specific documentation for CLI-related problems

Changelog

See CHANGELOG.md for detailed release history.

Available Tools

65 tools
approval_listA
Read-onlyIdempotent

List recent MCP-managed approval decisions recorded by the gateway (approvalStrategy: mcp_managed).

ParametersJSON Schema
NameRequiredDescriptionDefault
cliNoOptional CLI filter (any gateway CLI provider, derived from CLI_TYPES)
limitNoMax number of approval records

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful scoping context about MCP-managed approvals and recency, but it does not describe the return shape, ordering, or any limits on how 'recent' is defined. This is comparable to the calibration example where annotations cover safety but return/pagination details are absent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, information-dense sentence. It front-loads the action and resource, then adds the critical scoping qualifier without any filler or redundant phrasing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list tool, the description, complete parameter schema, and annotations together are nearly sufficient. The only gap is the vague term 'recent' and the absence of any return-format description, but the description's phrasing adequately implies a list result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and both parameters ('cli' and 'limit') already have meaningful descriptions in the schema. The tool description adds no additional parameter-level detail, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List'), a clear resource ('MCP-managed approval decisions recorded by the gateway'), and an explicit scope ('approvalStrategy: mcp_managed'). This clearly distinguishes it from the many sibling tools, which deal with validation, configuration, sessions, or model requests rather than approval decision history.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context for when to use the tool: when an agent needs to see recent gateway-recorded approvals for the MCP-managed strategy. It does not explicitly name alternatives or state when not to use it, but the domain is specific enough that an agent can select it appropriately.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ask_modelA
Destructive

Ask one provider CLI a question through the simplified validation surface (starts a validation job).

ParametersJSON Schema
NameRequiredDescriptionDefault
modelNoProvider to ask.claude
selectNoOptional least-cost routing: fill the provider target(s) from the LCR selector instead of the explicit list. 'cheapest' picks the single cheapest eligible provider; 'cheapest_per_tier' picks the cheapest in each quality tier. Requires [least_cost].enabled=true; fails closed (no default-list fallback) when disabled or nothing is eligible.
questionYesQuestion for one provider.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses a key behavioral trait beyond the annotations: the call 'starts a validation job' rather than returning a direct synchronous answer. This aligns with openWorldHint=true and explains the side-effecting nature. However, with destructiveHint=true, it does not clarify what consequences follow (resource consumption, state written, job lifecycle), leaving the most surprising annotation unexplained.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with zero filler. The action verb leads, and the two most decision-relevant qualifications ('simplified validation surface' and 'starts a validation job') immediately follow. Every element earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the burden of explaining what the caller gets back, but it stops at 'starts a validation job' without mentioning the job reference, receipt, or how to retrieve results. Sibling names (job_status, job_result, validation_receipt) hint at the workflow, but the description itself leaves the follow-up loop open for a tool marked destructive and open-world.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including a rich explanation of the select parameter with its 'fails closed' behavior, so the baseline of 3 applies. The tool description itself adds no parameter-level meaning, but the schema already carries the full load.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb+resource ('Ask one provider CLI a question') and adds a differentiating scope ('simplified validation surface... starts a validation job'). This clearly separates it from direct provider-request siblings (claude_request, codex_request) which don't go through the validation surface, and from multi-model siblings (compare_answers, consensus_check) which involve more than one provider.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'simplified validation surface' gives implied context that this is the lightweight path for single-provider questions inside validation workflows. However, it never names alternatives or states when not to use it — e.g., when to use validate_with_models, second_opinion, or the direct provider request tools instead. The select parameter description adds routing detail but only for the LCR sub-option, not for tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

claude_requestA
Destructive

Run a Claude Code CLI request synchronously (when async jobs are enabled, auto-defers to a pollable job past the sync deadline; otherwise runs to completion). Requires exactly one of prompt or promptParts.

ParametersJSON Schema
NameRequiredDescriptionDefault
bareNoClaude --bare: minimal mode (skip hooks, LSP, plugin sync, attribution, auto-memory, keychain reads, CLAUDE.md auto-discovery). Under mcp_managed, this repository-rule suppression requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1.
nameNoClaude --name: display name for this session (shown in pickers/titles).
agentNoClaude --agent: dispatch to a named single sub-agent.
debugNoClaude -d/--debug: enable debug mode. true emits a bare --debug; a string emits --debug <filter> (e.g. "api,hooks"). Debug output goes to stderr only.
modelNoModel name or alias (e.g. sonnet, claude-sonnet-4-5-20250929, latest)
toolsNoClaude --tools: restrict the available built-in tool set (distinct from allowedTools permission gating). Pass [""] to disable all tools.
addDirNoClaude --add-dir: additional directories the CLI is allowed to read/write beyond the process cwd. Each entry is emitted as its own --add-dir instance. Under mcp_managed, non-empty addDir requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1. Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
agentsNoClaude --agents: inline JSON map of agent name → { description, prompt, tools?, model? }.
effortNoClaude --effort: low|medium|high|xhigh|max.
promptNoPrompt text for Claude (mutually exclusive with promptParts)
maxTurnsNoClaude --max-turns: cap on agent loop iterations.
safeModeNoClaude --safe-mode: start with all customizations (CLAUDE.md, skills, plugins, hooks, MCP, commands, agents) disabled for troubleshooting. Under mcp_managed, this repository-rule suppression requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1.
settingsNoClaude --settings: path to a settings JSON file or a JSON literal of additional settings. Powerful: settings can define hooks/permissions/model; passed verbatim.
worktreeNoSlice Ī»: run this request inside a dedicated git worktree owned by the gateway. `true` creates a fresh worktree at `<repoRoot>/.worktrees/<uuid>` branched from HEAD. `{ name?, ref? }` lets the caller supply a sanitized name and/or a git ref (default: HEAD). When the request carries a sessionId and the session already has a worktree, reuse requires same-host ownership metadata and a matching live Git registration. Named path collisions never reuse manager state. Gateway-managed worktrees require the local file-backed session manager and fail closed with PostgreSQL sessions. The Grok, Devin, and Mistral adapters require an explicit provider-native sessionId; fresh, createNewSession, and resumeLatest-only worktree requests fail closed because they cannot durably reselect the worktree. The request must select a registered workspace explicitly, through caller-owned session metadata, or through the configured default. Worktrees never fall back to the gateway process cwd and cannot be combined with local workingDir, addDir, or includeDirs paths. The gateway spawns the child CLI with `cwd: <worktree-path>`; no `-w`/`--worktree` flag is ever emitted to the underlying CLI. On worktree materialization, the gateway suppresses repository, system, and global Git hooks and configured clean, smudge, and process checkout filters, sparse checkout, and lazy object fetching. Filter-dependent content such as Git LFS remains in its repository representation instead of executing host commands. On session_delete or TTL eviction the gateway hides the session and runs `git worktree remove --force`. Failed removal retains a durable cleanup-pending tombstone which blocks reuse and is retried when the file store is registered on the owning host. The tombstone is finalized only after verified Git removal. Successful responses are prefixed with `[gateway] worktree=<absolute-path>\n` so callers can use the path. For Claude approvalStrategy:mcp_managed, requesting or reusing a worktree requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1. Other adapters reject mcp_managed before launch. NOTE: callers should `.gitignore` the `.worktrees/` directory in their repo (the gateway does NOT auto-gitignore; see slice Ī» spec Q4).
debugFileNoClaude --debug-file: write debug logs to a specific file path (enables debug mode).
pluginDirNoClaude --plugin-dir: load a plugin from a directory or .zip for this session only. One --plugin-dir instance per entry.
pluginUrlNoClaude --plugin-url: load a plugin .zip from a URL for this session only. One --plugin-url instance per entry.
sessionIdNoOn a fresh request this id is emitted as Claude --session-id <uuid> (must be a valid UUID that does not already exist). Resume the latest cwd conversation with continueSession:true. gw-* ids are not valid Claude --session-id values.
workspaceNoRegistered workspace alias for remote HTTP/OAuth provider calls. Do not use this field, workspace_list, or workspace_register_existing_repo as a fallback for stdio/local provider path access; pass workingDir/addDir/includeDirs directly instead.
jsonSchemaNoClaude --json-schema: JSON Schema literal (NOT a path) constraining structured output. Object values are JSON.stringify-d; string values are passed verbatim. Use with outputFormat='json'. Set outputFormat:json so the gateway treats the reply as structured output (skips response optimization and warning injection); the default output format is not json, so pass it explicitly.
mcpServersNoMCP servers exposed to Claude
workingDirNoClaude process working directory. The gateway launches Claude in this directory. Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
forkSessionNoClaude --fork-session: branch from an existing session into a fresh fork.
promptPartsNoCache-aware structured prompt: { system?, tools?, context?, task, cacheControl? }. Use for repeated calls that share a stable prefix — `system`/`tools`/`context` are the stable head; `task` is the volatile tail (never marked). Set `cacheControl: { system?: boolean, tools?: boolean, context?: boolean }` to opt into explicit Anthropic prefix caching via `--input-format stream-json` (slice Īŗ). Requires `outputFormat: 'stream-json'` and hard-codes `ttl='1h'` (Anthropic rejects 5m blocks after Claude Code's 1h-marked session-wrap content). Mutually exclusive with `prompt`. The stable prefix hash is logged to the flight recorder for cache_state aggregates.
allowedToolsNoAllowed tools (['Bash(git:*)','Edit','Write'])
forceRefreshNoBypass dedup and force a fresh CLI run even if a recent identical request exists
maxBudgetUsdNoClaude --max-budget-usd: spend cap for this request in USD.
outputFormatNoOutput format (text|json|stream-json). DEFAULT: stream-json; the gateway parses NDJSON usage events to extract input/output/cache_read/cache_creation tokens + cost + model, persists them to the flight recorder for cache_state aggregates, and still returns the assistant text. Override to 'text' only when you truly want unparsed stdout (loses observability).stream-json
systemPromptNoClaude --system-prompt: replace the system prompt entirely. Mutually exclusive with appendSystemPrompt. Under mcp_managed, an override requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1.
correlationIdNoRequest trace ID (auto if omitted)
fallbackModelNoClaude --fallback-model: model name to auto-fallback to when the default model is overloaded (effective only with --print, which the gateway always uses).
idleTimeoutMsNoIdle timeout in ms (min 30s, max 1h, omit=CLI default). Idle enforcement applies only when outputFormat is stream-json; it is ignored for text/json.
providerFlagsNoFlags passed to the provider binary verbatim, keyed exactly as the binary spells them (e.g. {"--best-of-n": "3", "--verbatim": true, "--rules": ["a", "b"]}). Use this for any flag your installed CLI accepts that this schema does not name: the binary decides what it supports, not the gateway. true emits the flag alone; a list REPEATS the flag once per item (pass a joined string if your CLI wants a comma-separated value). Values may not start with '-', and a flag the gateway is already emitting for this request is refused rather than duplicated. LOCAL stdio callers only: remote HTTP/OAuth callers are refused every flag here and should use this tool's declared parameters, which carry their own host-path and approval gates.
approvalPolicyNoApproval policy when approvalStrategy is mcp_managed: strict|balanced|permissive (default balanced). Ignored under legacy strategy.
optimizePromptNoOptimize prompt before execution
permissionModeNoClaude --permission-mode: default|acceptEdits|auto|bypassPermissions|manual|dontAsk|plan. `default` is a no-op (no flag emitted). Under mcp_managed, bypassPermissions requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1.
settingSourcesNoClaude --setting-sources: comma-separated setting sources to load (user|project|local) for reproducible/isolated headless runs.
continueSessionNoContinue the most recent Claude conversation in the selected workspace (emits --continue; real CLI continuity). Stable workspace selection is required via workingDir, a registered workspace, or the configured default workspace.
disallowedToolsNoDisallowed tools
strictMcpConfigNoRestrict Claude to provided MCP config only. mcp_managed always enforces this isolation, even when false is supplied.
approvalStrategyNoApproval strategy: legacy (default) lets Claude's own flags decide; mcp_managed routes the run through the gateway approval gate and uses acceptEdits by default. An explicit bypassPermissions request requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1.legacy
compressResponseNoCompress the response display text via the native compressor (default: [compression].enabled in config.toml, off unless opted in). Skipped for structured output.
createNewSessionNoForce new session
optimizeResponseNoOptimize response output
systemPromptFileNoClaude --system-prompt-file: replace the system prompt from a file path (path variant of systemPrompt).
includeHookEventsNoClaude --include-hook-events: include all hook lifecycle events in the output stream. Only takes effect with outputFormat=stream-json (the default).
appendSystemPromptNoClaude --append-system-prompt: append to the existing system prompt. Mutually exclusive with systemPrompt. Under mcp_managed, an override requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1.
replayUserMessagesNoClaude --replay-user-messages: re-emit user messages from stdin back on stdout for acknowledgment. Only works with input-format=stream-json and outputFormat=stream-json (the cacheControl path).
requestInstructionsNoPer-request Kit instructions. Available only when [personal_config].enabled = true.
noSessionPersistenceNoClaude --no-session-persistence: do not write this session to disk (ephemeral one-shot runs; mirrors codex --ephemeral).
appendSystemPromptFileNoClaude --append-system-prompt-file: append a system prompt from a file path (path variant of appendSystemPrompt).
dangerouslySkipPermissionsNoDEPRECATED: prefer `permissionMode: "bypassPermissions"`. Maps to it when `permissionMode` is unset. Under mcp_managed, either form requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1.
excludeDynamicSystemPromptSectionsNoClaude --exclude-dynamic-system-prompt-sections: trim dynamic context blocks from the system prompt.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry the safety profile (readOnlyHint=false, destructiveHint=true, idempotentHint=false), so the bar for behavioral disclosure is lower. The description adds genuinely useful context beyond annotations: synchronous execution model, deferral to a pollable job past the sync deadline, and the prompt/promptParts exclusivity requirement. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One dense sentence with zero waste: primary behavior front-loaded, deferral logic in the parenthetical, and the key constraint at the end. Every clause earns its place, and the critical usage facts are all present despite the 53-parameter schema beneath.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool this complex (53 params, approval gates, worktree semantics, no output schema), the description itself is thin — it does not describe the response shape or return-value semantics. However, the outputFormat parameter in the schema documents the return behavior (stream-json parsing, usage events, observability), and the 100% schema coverage carries the burden. Adequate for correct invocation, with return-value details left to the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% with exceptionally detailed parameter docs (e.g., worktree, providerFlags, outputFormat), so the baseline of 3 applies and the description need not compensate. The only param guidance in the description — 'Requires exactly one of prompt or promptParts' — is redundant with the schema's own mutual-exclusivity note on prompt.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Run a Claude Code CLI request synchronously') and clearly differentiates from sibling claude_request_async by describing the sync execution model and auto-deferral behavior. The exclusivity constraint on prompt/promptParts adds further precision. An agent can immediately tell this apart from the async variant and from codex_request/gemini_request etc.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description conveys when the sync behavior applies and when the call auto-defers to a pollable job ('when async jobs are enabled... otherwise runs to completion'), which is the key operational decision for this tool. It does not explicitly name claude_request_async as the alternative for long-running work, so the routing guidance is implicit rather than explicit, but the context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

claude_request_asyncA
Destructive

Start a Claude Code CLI request as a durable background job. Poll with llm_job_status, collect with llm_job_result.

ParametersJSON Schema
NameRequiredDescriptionDefault
bareNoClaude --bare: minimal mode (skip hooks, LSP, plugin sync, attribution, auto-memory, keychain reads, CLAUDE.md auto-discovery). Under mcp_managed, this repository-rule suppression requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1.
nameNoClaude --name: display name for this session (shown in pickers/titles).
agentNoClaude --agent: dispatch to a named single sub-agent.
debugNoClaude -d/--debug: enable debug mode. true emits a bare --debug; a string emits --debug <filter> (e.g. "api,hooks"). Debug output goes to stderr only.
modelNoModel name or alias (e.g. sonnet, claude-sonnet-4-5-20250929, latest)
toolsNoClaude --tools: restrict the available built-in tool set (distinct from allowedTools permission gating). Pass [""] to disable all tools.
addDirNoClaude --add-dir: additional directories the CLI is allowed to read/write beyond the process cwd. Each entry is emitted as its own --add-dir instance. Under mcp_managed, non-empty addDir requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1. Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
agentsNoClaude --agents: inline JSON map of agent name → { description, prompt, tools?, model? }.
effortNoClaude --effort: low|medium|high|xhigh|max.
promptNoPrompt text for Claude (mutually exclusive with promptParts)
maxTurnsNoClaude --max-turns: cap on agent loop iterations.
safeModeNoClaude --safe-mode: start with all customizations (CLAUDE.md, skills, plugins, hooks, MCP, commands, agents) disabled for troubleshooting. Under mcp_managed, this repository-rule suppression requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1.
settingsNoClaude --settings: path to a settings JSON file or a JSON literal of additional settings. Powerful: settings can define hooks/permissions/model; passed verbatim.
worktreeNoSlice Ī»: run this request inside a dedicated git worktree owned by the gateway. `true` creates a fresh worktree at `<repoRoot>/.worktrees/<uuid>` branched from HEAD. `{ name?, ref? }` lets the caller supply a sanitized name and/or a git ref (default: HEAD). When the request carries a sessionId and the session already has a worktree, reuse requires same-host ownership metadata and a matching live Git registration. Named path collisions never reuse manager state. Gateway-managed worktrees require the local file-backed session manager and fail closed with PostgreSQL sessions. The Grok, Devin, and Mistral adapters require an explicit provider-native sessionId; fresh, createNewSession, and resumeLatest-only worktree requests fail closed because they cannot durably reselect the worktree. The request must select a registered workspace explicitly, through caller-owned session metadata, or through the configured default. Worktrees never fall back to the gateway process cwd and cannot be combined with local workingDir, addDir, or includeDirs paths. The gateway spawns the child CLI with `cwd: <worktree-path>`; no `-w`/`--worktree` flag is ever emitted to the underlying CLI. On worktree materialization, the gateway suppresses repository, system, and global Git hooks and configured clean, smudge, and process checkout filters, sparse checkout, and lazy object fetching. Filter-dependent content such as Git LFS remains in its repository representation instead of executing host commands. On session_delete or TTL eviction the gateway hides the session and runs `git worktree remove --force`. Failed removal retains a durable cleanup-pending tombstone which blocks reuse and is retried when the file store is registered on the owning host. The tombstone is finalized only after verified Git removal. Successful responses are prefixed with `[gateway] worktree=<absolute-path>\n` so callers can use the path. For Claude approvalStrategy:mcp_managed, requesting or reusing a worktree requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1. Other adapters reject mcp_managed before launch. NOTE: callers should `.gitignore` the `.worktrees/` directory in their repo (the gateway does NOT auto-gitignore; see slice Ī» spec Q4).
debugFileNoClaude --debug-file: write debug logs to a specific file path (enables debug mode).
pluginDirNoClaude --plugin-dir: load a plugin from a directory or .zip for this session only. One --plugin-dir instance per entry.
pluginUrlNoClaude --plugin-url: load a plugin .zip from a URL for this session only. One --plugin-url instance per entry.
sessionIdNoOn a fresh request this id is emitted as Claude --session-id <uuid> (must be a valid UUID that does not already exist). Resume the latest cwd conversation with continueSession:true. gw-* ids are not valid Claude --session-id values.
workspaceNoRegistered workspace alias for remote HTTP/OAuth provider calls. Do not use this field, workspace_list, or workspace_register_existing_repo as a fallback for stdio/local provider path access; pass workingDir/addDir/includeDirs directly instead.
jsonSchemaNoClaude --json-schema: JSON Schema literal (NOT a path) constraining structured output. Object values are JSON.stringify-d; string values are passed verbatim. Use with outputFormat='json'. Set outputFormat:json so the gateway treats the reply as structured output (skips response optimization and warning injection); the default output format is not json, so pass it explicitly.
mcpServersNoMCP servers exposed to Claude
workingDirNoClaude process working directory. The gateway launches Claude in this directory. Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
forkSessionNoClaude --fork-session: branch from an existing session into a fresh fork.
promptPartsNoCache-aware structured prompt: { system?, tools?, context?, task, cacheControl? }. Same semantics as claude_request: stable head (system/tools/context) + volatile tail (task). Set `cacheControl: { system?, tools?, context?: boolean }` to opt into explicit Anthropic prefix caching via `--input-format stream-json` (slice Īŗ); requires `outputFormat: 'stream-json'` and hard-codes `ttl='1h'`. Mutually exclusive with `prompt`. Stable prefix hash logged to flight recorder.
allowedToolsNoAllowed tools (['Bash(git:*)','Edit','Write'])
forceRefreshNoBypass dedup and force a fresh CLI run even if a recent identical request exists
maxBudgetUsdNoClaude --max-budget-usd: spend cap for this request in USD.
outputFormatNoOutput format (text|json|stream-json). DEFAULT: stream-json — same rationale as claude_request: keeps usage/cache/cost observable for cache_state aggregates. Override to 'text' only when raw stdout is required (loses observability).stream-json
systemPromptNoClaude --system-prompt: replace the system prompt entirely. Mutually exclusive with appendSystemPrompt. Under mcp_managed, an override requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1.
correlationIdNoRequest trace ID (auto if omitted)
fallbackModelNoClaude --fallback-model: model name to auto-fallback to when the default model is overloaded (effective only with --print, which the gateway always uses).
idleTimeoutMsNoIdle timeout in ms (min 30s, max 1h, omit=CLI default). Idle enforcement applies only when outputFormat is stream-json; it is ignored for text/json.
providerFlagsNoFlags passed to the provider binary verbatim, keyed exactly as the binary spells them (e.g. {"--best-of-n": "3", "--verbatim": true, "--rules": ["a", "b"]}). Use this for any flag your installed CLI accepts that this schema does not name: the binary decides what it supports, not the gateway. true emits the flag alone; a list REPEATS the flag once per item (pass a joined string if your CLI wants a comma-separated value). Values may not start with '-', and a flag the gateway is already emitting for this request is refused rather than duplicated. LOCAL stdio callers only: remote HTTP/OAuth callers are refused every flag here and should use this tool's declared parameters, which carry their own host-path and approval gates.
approvalPolicyNoApproval policy when approvalStrategy is mcp_managed: strict|balanced|permissive (default balanced). Ignored under legacy strategy.
optimizePromptNoOptimize prompt before execution
permissionModeNoClaude --permission-mode: default|acceptEdits|auto|bypassPermissions|manual|dontAsk|plan. `default` is a no-op. Under mcp_managed, bypassPermissions requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1.
settingSourcesNoClaude --setting-sources: comma-separated setting sources to load (user|project|local) for reproducible/isolated headless runs.
continueSessionNoContinue the most recent Claude conversation in the selected workspace (emits --continue; real CLI continuity). Stable workspace selection is required via workingDir, a registered workspace, or the configured default workspace.
disallowedToolsNoDisallowed tools
strictMcpConfigNoRestrict Claude to provided MCP config only. mcp_managed always enforces this isolation, even when false is supplied.
approvalStrategyNoApproval strategy: legacy (default) lets Claude's own flags decide; mcp_managed routes the run through the gateway approval gate and uses acceptEdits by default. An explicit bypassPermissions request requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1.legacy
compressResponseNoCompress the response display text when collected via llm_job_result (native compressor; default: [compression].enabled).
createNewSessionNoForce new session
systemPromptFileNoClaude --system-prompt-file: replace the system prompt from a file path (path variant of systemPrompt).
includeHookEventsNoClaude --include-hook-events: include all hook lifecycle events in the output stream. Only takes effect with outputFormat=stream-json (the default).
appendSystemPromptNoClaude --append-system-prompt: append to the existing system prompt. Mutually exclusive with systemPrompt. Under mcp_managed, an override requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1.
replayUserMessagesNoClaude --replay-user-messages: re-emit user messages from stdin back on stdout for acknowledgment. Only works with input-format=stream-json and outputFormat=stream-json (the cacheControl path).
requestInstructionsNoPer-request Kit instructions. Available only when [personal_config].enabled = true.
noSessionPersistenceNoClaude --no-session-persistence: do not write this session to disk (ephemeral one-shot runs; mirrors codex --ephemeral).
appendSystemPromptFileNoClaude --append-system-prompt-file: append a system prompt from a file path (path variant of appendSystemPrompt).
dangerouslySkipPermissionsNoDEPRECATED: prefer `permissionMode: "bypassPermissions"`. Maps to it when `permissionMode` is unset. Under mcp_managed, either form requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1.
excludeDynamicSystemPromptSectionsNoClaude --exclude-dynamic-system-prompt-sections: trim dynamic context blocks from the system prompt.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry the safety profile (readOnlyHint=false, destructiveHint=true, idempotentHint=false, openWorldHint=true), so the description's burden is reduced. It adds genuinely useful context: 'durable' implies the job outlives the invocation, and the poll/collect workflow clarifies the lifecycle. However, it does not disclose that launching a job consumes tokens/cost or may execute arbitrary Claude Code operations beyond what the destructiveHint already flags. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero filler. The primary action is front-loaded, the durability qualifier is essential, and the second sentence gives the complete continuation workflow. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 52 parameters, nested objects, and no output schema, the description is quite thin: it never states what the tool returns (presumably a job identifier to pass to llm_job_status/llm_job_result), and it doesn't touch on cost, cleanup, or session persistence. The exhaustive 100%-coverage schema and the rich annotation set compensate heavily, but the missing return contract is a real gap for an agent deciding how to chain calls.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline of 3 applies even though the tool description itself adds zero parameter information. The schema's parameter descriptions are unusually detailed (flag spellings, approval gates, provider restrictions, mutual exclusions), so the description does not need to compensate. There is no gap to penalize beyond the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Start'), a specific resource ('a Claude Code CLI request'), and the distinguishing mode ('durable background job'). This clearly differentiates it from the synchronous claude_request sibling and the other *_request_async variants, while 'Poll with llm_job_status, collect with llm_job_result' names the exact follow-up tools. An agent can understand what this does and how it differs from siblings without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'durable background job' conveys the core selection criterion (async vs. the sync sibling), and naming llm_job_status/llm_job_result gives the agent the polling/collection workflow. However, it never explicitly says 'use claude_request when you need an inline synchronous result' or states when NOT to use this variant, leaving the sync/async decision partly implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

cli_upgradeA
Destructive

Plan (dryRun, default true) or execute an upgrade for one provider CLI using its native update mechanism.

ParametersJSON Schema
NameRequiredDescriptionDefault
cliYesCLI to upgrade (claude|codex|gemini|grok|mistral|devin|cursor)
dryRunNoWhen true, return the upgrade plan without running it
targetNoPackage tag/version/target to install (default: latest)latest
timeoutMsNoUpgrade timeout in ms when dryRun=false

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry the safety profile (readOnlyHint=false, destructiveHint=true, idempotentHint=false), and the description adds value beyond them by disclosing that destruction only happens on explicit opt-out of the dryRun default, plus the behavioral trait that upgrades are delegated to the CLI's native mechanism rather than a managed install. It doesn't detail side effects (global state, network needs) of that native mechanism, but given annotation coverage the bar is lower and it clears it. No contradiction with annotations: the tool is destructive-capable and the description's default-safe mode is consistent with that.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single 19-word sentence that front-loads the behavior (plan vs execute) and the safety default before the mechanism. Every word earns its place, and the plan/execute contrast is stated before the 'native update mechanism' qualifier. This is appropriately sized and structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive-capable tool with no output schema, the description falls short of fully complete: it never says what a plan actually returns, whether the native updater can run non-interactively (an agent-execution risk), what happens on failure, or whether prerequisites like the CLI being installed exist. The 100%-covered schema and accurate annotations carry much of the load, so this is adequate but with clear gaps on the execute path.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all four parameters, setting the baseline at 3. The description adds only marginal meaning: it restates the dryRun default and clarifies that the operation targets one CLI at a time, but it does not enrich target semantics or explain when to set timeoutMs beyond what the schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb pair (plan/execute), a concrete resource (an upgrade for one provider CLI), and a distinguishing qualifier ('native update mechanism'). The 'one provider CLI' phrasing plus the mechanism scopes it apart from sibling tools like cli_versions (listing) and provider_version_guard (guarding), so an agent can tell what this tool does without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear invocation context: by default the tool only produces a plan (dryRun=true), and execution requires explicit opt-in via dryRun=false. This tells the agent how to use the tool safely in its default mode. It does not state exclusions or route to alternatives (e.g., checking versions via cli_versions), but since this is the only upgrade tool among the siblings, the mode guidance is the primary usage signal.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

cli_versionsA
Read-onlyIdempotent

Report installed provider CLI versions, availability, and login status for all registered CLI providers (claude|codex|gemini|grok|mistral|devin|cursor) or one.

ParametersJSON Schema
NameRequiredDescriptionDefault
cliNoCLI filter (claude|codex|gemini|grok|mistral|devin|cursor)

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds useful scope context beyond that — that the tool reports availability and login status, not just versions, for all registered providers or one — but it does not disclose edge behavior such as how missing/unregistered CLIs or failed login checks surface.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence that leads with the action and reported dimensions before enumerating providers. The provider list is marginally redundant with the schema enum, but it keeps the description self-contained at low cost.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only tool with one optional enum parameter and annotations fully covering the safety profile, the description states what it does, its provider scope, and its filtering option. With no output schema, it names the three reported dimensions so the agent knows what to expect, though it stops short of describing absence/error behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%: the single cli parameter has its own description and a complete enum listing the same seven providers. The description's 'or one' phrasing mirrors the parameter's optional-filter semantics without adding new syntax or format detail, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Report') and a well-defined resource (installed provider CLI versions, availability, and login status), then delimits the exact scope with the provider enumeration. This clearly distinguishes it from adjacent siblings like cli_upgrade, provider_version_guard, and provider_tool_capabilities.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The report-oriented framing implies when to use it — whenever the agent needs to know which provider CLIs are installed, available, or logged in — but no alternative is named and no when-not-to-use condition is given. With siblings covering adjacent concerns (cli_upgrade, provider_version_guard, provider_subcommands_list), explicit routing would add value.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

codex_fork_sessionA
Destructive

UNAVAILABLE from the gateway: codex fork is an interactive subcommand requiring a controlling terminal, which an MCP server cannot provide, so every call fails fast with an explanation instead of spawning a child that cannot succeed. To continue an existing Codex conversation use codex_request with a real Codex session UUID or resumeLatest: true, which run codex exec resume and work headlessly. Retained because Codex exposes no non-interactive fork today; this prompt remains argv-bound and still rejects oversized UTF-8 input as non-retryable input_too_large before the unavailability check, so the argv builder stays ready if a headless fork appears.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelNoModel name or alias (e.g. gpt-5.5, latest)
promptYesPrompt text for the forked Codex session. This codex fork path remains argv-bound and rejects oversized UTF-8 input.
forkLastNoFork from the most recent Codex session. Mutually exclusive with `sessionId`.
sessionIdNoCodex session UUID to fork from. Mutually exclusive with `forkLast`.
workspaceNoRegistered workspace alias for remote HTTP/OAuth provider calls. Do not use this field, workspace_list, or workspace_register_existing_repo as a fallback for stdio/local provider path access; pass workingDir/addDir/includeDirs directly instead.
sandboxModeNoCodex --sandbox. NEW SESSIONS ONLY: the gateway filters --sandbox out of a resume argv, so this field has no effect on a resumed request. That is NOT a guarantee that the resumed session keeps its original posture: configOverrides still passes through and can set sandbox_mode, and Codex re-resolves configuration on a cold resume. Establish the posture on the first request and verify it when it matters. On a new session, omitting it does NOT guarantee read-only: the gateway emits no --sandbox flag and Codex resolves the policy from configuration, project trust, and its own fallback, so a trusted project can resolve to workspace-write. Pass read-only explicitly for inspection. Pass workspace-write to let Codex edit files in the working dir, or danger-full-access for unrestricted access.
correlationIdNoRequest trace ID (auto if omitted)
idleTimeoutMsNoIdle timeout in ms (min 30s, max 1h, omit=CLI default)
approvalPolicyNoapprovalPolicy is unavailable for this provider. It has no effect with legacy, and mcp_managed is rejected before launch because ambient MCP configuration cannot be isolated.
askForApprovalNoDEPRECATED compatibility input: accepted but ignored because current Codex no longer accepts --ask-for-approval.
approvalStrategyNoApproval strategy: legacy is supported. mcp_managed is rejected before launch because this adapter cannot isolate ambient MCP configuration.legacy

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses the actual runtime behavior beyond annotations: every call fails fast rather than spawning a child, and oversized UTF-8 input is rejected as 'non-retryable input_too_large before the unavailability check.' Although annotations mark destructiveHint true, the description clarifies the tool cannot actually execute destructively because it is unavailable from the gateway.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the critical 'UNAVAILABLE' status and then gives routing advice and maintenance context. It is longer than minimal, but every sentence carries information about failure mode, alternative, or retained-purpose, so it earns a high score without being padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a deliberately unavailable tool with an output-free failure path, the description is complete: it explains why it is unavailable, what failure looks like, the exact alternative to use, and the one input edge case that still matters. The rich 100%-covered schema supplies the remaining parameter details.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and each parameter already has a detailed description, including the prompt's argv-bound maxLength and the mutually exclusive forkLast/sessionId. The tool description adds little parameter-level meaning beyond noting the active check order; therefore the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states exactly what the tool is: an unavailable stub for `codex fork` that 'every call fails fast with an explanation' because the interactive subcommand needs a controlling terminal. It also differentiates itself from the sibling by pointing to codex_request as the headless alternative, so an agent can distinguish it from other Codex tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly tells the agent when not to use this tool and what to use instead: 'To continue an existing Codex conversation use codex_request with a real Codex session UUID or resumeLatest: true.' It also explains the tool is retained only because no non-interactive fork exists, making the intended routing unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

codex_requestA
Destructive

Run an OpenAI Codex CLI request synchronously (when async jobs are enabled, auto-defers to a pollable job past the sync deadline; otherwise runs to completion). Requires exactly one of prompt or promptParts.

ParametersJSON Schema
NameRequiredDescriptionDefault
ossNoCodex --oss: use the open-source provider. New sessions only.
colorNoCodex --color: output color mode (always|never|auto). New sessions only.
modelNoModel name or alias (e.g. gpt-5.5, gpt-5.4, latest)
addDirNoCodex --add-dir <DIR>: additional writable workspace directories. Emitted once per entry on new sessions only: the flag is filtered from resume argv. That does NOT pin a resumed session's writable-dir policy; do not rely on it. Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
enableNoCodex --enable <FEATURE> (repeatable): enable a feature for this run (equivalent to -c features.<name>=true). Accepted on resume. Local callers only, remote HTTP/OAuth requests are rejected.
imagesNoCodex -i <path>: image attachments. Each path must exist; missing paths fail fast.
promptNoPrompt text for Codex (mutually exclusive with promptParts)
searchNoDEPRECATED compatibility input: accepted but ignored because current Codex exec no longer accepts --search.
disableNoCodex --disable <FEATURE> (repeatable): disable a feature for this run (equivalent to -c features.<name>=false). Accepted on resume. Local callers only, remote HTTP/OAuth requests are rejected.
profileNoCodex --profile <name>: select a profile from ~/.codex/config.toml.
fullAutoNoDEPRECATED: prefer `sandboxMode`. Expands to `--sandbox workspace-write`; current Codex no longer accepts approval-policy flags.
worktreeNoSlice Ī»: run this request inside a dedicated git worktree owned by the gateway. `true` creates a fresh worktree at `<repoRoot>/.worktrees/<uuid>` branched from HEAD. `{ name?, ref? }` lets the caller supply a sanitized name and/or a git ref (default: HEAD). When the request carries a sessionId and the session already has a worktree, reuse requires same-host ownership metadata and a matching live Git registration. Named path collisions never reuse manager state. Gateway-managed worktrees require the local file-backed session manager and fail closed with PostgreSQL sessions. The Grok, Devin, and Mistral adapters require an explicit provider-native sessionId; fresh, createNewSession, and resumeLatest-only worktree requests fail closed because they cannot durably reselect the worktree. The request must select a registered workspace explicitly, through caller-owned session metadata, or through the configured default. Worktrees never fall back to the gateway process cwd and cannot be combined with local workingDir, addDir, or includeDirs paths. The gateway spawns the child CLI with `cwd: <worktree-path>`; no `-w`/`--worktree` flag is ever emitted to the underlying CLI. On worktree materialization, the gateway suppresses repository, system, and global Git hooks and configured clean, smudge, and process checkout filters, sparse checkout, and lazy object fetching. Filter-dependent content such as Git LFS remains in its repository representation instead of executing host commands. On session_delete or TTL eviction the gateway hides the session and runs `git worktree remove --force`. Failed removal retains a durable cleanup-pending tombstone which blocks reuse and is retried when the file store is registered on the owning host. The tombstone is finalized only after verified Git removal. Successful responses are prefixed with `[gateway] worktree=<absolute-path>\n` so callers can use the path. For Claude approvalStrategy:mcp_managed, requesting or reusing a worktree requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1. Other adapters reject mcp_managed before launch. NOTE: callers should `.gitignore` the `.worktrees/` directory in their repo (the gateway does NOT auto-gitignore; see slice Ī» spec Q4).
ephemeralNoCodex --ephemeral: do not persist the session to disk.
sessionIdNoCodex session UUID to resume via `codex exec resume <ID>`. Must be a real Codex session ID (from `~/.codex/sessions/` or the `codex resume` picker). Gateway-generated `gw-*` IDs are rejected. For a brand-new session no resumable sessionId is returned; continue with resumeLatest:true or a real Codex UUID.
workspaceNoRegistered workspace alias for remote HTTP/OAuth provider calls. Do not use this field, workspace_list, or workspace_register_existing_repo as a fallback for stdio/local provider path access; pass workingDir/addDir/includeDirs directly instead.
mcpServersNoThis provider does not receive gateway-managed MCP configuration. mcpServers has no effect with legacy, and mcp_managed is rejected before launch because ambient MCP configuration cannot be isolated.
workingDirNoCodex -C/--cd <DIR>: working root for this session. Emitted on new sessions only: the flag is filtered from resume argv. That does NOT pin a resumed session's directory, because the child is still spawned with the gateway-resolved cwd; do not rely on a resumed session's working directory. Personal Agent Config Kit mode requires an absolute path. Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
ignoreRulesNoCodex --ignore-rules: skip project rule files for this run.
promptPartsNoCache-aware structured prompt: { system?, tools?, context?, task }. Mutually exclusive with prompt. Stable parts hash into cache_state for prefix-discipline tracking.
sandboxModeNoCodex --sandbox. NEW SESSIONS ONLY: the gateway filters --sandbox out of a resume argv, so this field has no effect on a resumed request. That is NOT a guarantee that the resumed session keeps its original posture: configOverrides still passes through and can set sandbox_mode, and Codex re-resolves configuration on a cold resume. Establish the posture on the first request and verify it when it matters. On a new session, omitting it does NOT guarantee read-only: the gateway emits no --sandbox flag and Codex resolves the policy from configuration, project trust, and its own fallback, so a trusted project can resolve to workspace-write. Pass read-only explicitly for inspection. Pass workspace-write to let Codex edit files in the working dir, or danger-full-access for unrestricted access.
forceRefreshNoBypass dedup and force a fresh CLI run even if a recent identical request exists
outputFormatNoCodex caller-facing output format. Token/cache usage is recorded in the flight recorder regardless. `text` (default) returns the plain reply; `json` returns the raw `--json` JSONL event stream.
outputSchemaNoCodex --output-schema. Pass a path (string) or an inline JSON Schema object; object is materialised to a 0o600 temp file under os.tmpdir() and deleted after the run.
resumeLatestNoResume a previous Codex session via `codex exec resume --last`. UNDER REVIEW: do not rely on which session this selects or on the resumed working directory. `--last` is filtered by cwd upstream unless `--all` is passed, which the gateway does not emit, and the child is still spawned with the gateway-resolved cwd even though `-C`/`--add-dir` are dropped from the resume argv. Verify the target, or start a fresh session when it must be certain. Ignored if sessionId is set; an explicit real Codex UUID targets that session. A brand-new session returns no resumable sessionId; continue with resumeLatest:true or a real Codex UUID.
strictConfigNoCodex --strict-config: error out when config.toml contains fields not recognized by this Codex version. New sessions only.
correlationIdNoRequest trace ID (auto if omitted)
idleTimeoutMsNoIdle timeout in ms (min 30s, max 1h, omit=CLI default)
localProviderNoCodex --local-provider: local OSS provider (lmstudio|ollama), used with oss. New sessions only.
providerFlagsNoFlags passed to the provider binary verbatim, keyed exactly as the binary spells them (e.g. {"--best-of-n": "3", "--verbatim": true, "--rules": ["a", "b"]}). Use this for any flag your installed CLI accepts that this schema does not name: the binary decides what it supports, not the gateway. true emits the flag alone; a list REPEATS the flag once per item (pass a joined string if your CLI wants a comma-separated value). Values may not start with '-', and a flag the gateway is already emitting for this request is refused rather than duplicated. LOCAL stdio callers only: remote HTTP/OAuth callers are refused every flag here and should use this tool's declared parameters, which carry their own host-path and approval gates.
approvalPolicyNoapprovalPolicy is unavailable for this provider. It has no effect with legacy, and mcp_managed is rejected before launch because ambient MCP configuration cannot be isolated.
askForApprovalNoDEPRECATED compatibility input: accepted but ignored because current Codex no longer accepts --ask-for-approval.
optimizePromptNoOptimize prompt before execution
configOverridesNoCodex -c key=value overrides. Keys: /^[a-zA-Z0-9._]+$/. Values: no CR/LF. Local callers only, remote HTTP/OAuth requests are rejected.
approvalStrategyNoApproval strategy: legacy is supported. mcp_managed is rejected before launch because this adapter cannot isolate ambient MCP configuration.legacy
compressResponseNoCompress the response display text via the native compressor (default: [compression].enabled in config.toml, off unless opted in). Skipped for structured output.
createNewSessionNoForce a fresh session (no resume)
ignoreUserConfigNoCodex --ignore-user-config: ignore ~/.codex/config.toml for this run.
optimizeResponseNoOptimize response output
outputLastMessageNoCodex -o/--output-last-message <FILE>: write the agent's last message to a file. New sessions only.
requestInstructionsNoPer-request Kit instructions. Available only when [personal_config].enabled = true.
useLegacyFullAutoFlagNoDEPRECATED compatibility input: accepted but ignored because current Codex no longer accepts --full-auto.
dangerouslyBypassHookTrustNoCodex --dangerously-bypass-hook-trust: run enabled hooks without persisted hook trust for this invocation. DANGEROUS.
dangerouslyBypassApprovalsAndSandboxNoRun Codex without approvals/sandbox.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide destructiveHint=true and readOnlyHint=false, so the safety profile is covered. The description adds genuine value by disclosing the sync-to-pollable-job deferral trait and the run-to-completion behavior when async is disabled. It does not elaborate on the destructive consequences (file edits, sandbox posture), but the annotations carry that burden.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero filler, with the core action front-loaded. The sync/defer behavior and the one hard precondition are both packed in without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 43-parameter destructive tool with no output schema, the tool-level description stays minimal: it does not describe the response shape or point to outputFormat/outputSchema for return semantics, and async routing guidance is implied rather than explicit. The voluminous per-parameter docs mostly compensate, but the top-level description alone leaves gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and every parameter has a rich, often exceptional, description (worktree, sandboxMode, providerFlags, workingDir). The tool description's only param contribution is the mutual exclusivity of prompt/promptParts, which is already stated in both params' schema descriptions. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Run an OpenAI Codex CLI request') plus the synchronous execution mode, which distinguishes it from the codex_request_async sibling without ambiguity. The parenthetical about auto-deferring to a pollable job further pins down the exact execution contract.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The deferral behavior implies a usage boundary (short synchronous runs when async is enabled) but never explicitly says 'use codex_request_async for long-running work' or names any alternative. The 'requires exactly one of prompt or promptParts' line is a precondition, not when-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

codex_request_asyncA
Destructive

Start an OpenAI Codex CLI request as a durable background job. Poll with llm_job_status, collect with llm_job_result.

ParametersJSON Schema
NameRequiredDescriptionDefault
ossNoCodex --oss: use the open-source provider. New sessions only.
colorNoCodex --color: output color mode (always|never|auto). New sessions only.
modelNoModel name or alias (e.g. gpt-5.5, gpt-5.4, latest)
addDirNoCodex --add-dir <DIR>: additional writable workspace directories (repeat per entry). Emitted once per entry on new sessions only: the flag is filtered from resume argv. That does NOT pin a resumed session's writable-dir policy; do not rely on it. Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
enableNoCodex --enable <FEATURE> (repeatable): enable a feature for this run (equivalent to -c features.<name>=true). Accepted on resume. Local callers only, remote HTTP/OAuth requests are rejected.
imagesNoCodex -i <path>: image attachments.
promptNoPrompt text for Codex (mutually exclusive with promptParts)
searchNoDEPRECATED compatibility input: accepted but ignored because current Codex exec no longer accepts --search.
disableNoCodex --disable <FEATURE> (repeatable): disable a feature for this run (equivalent to -c features.<name>=false). Accepted on resume. Local callers only, remote HTTP/OAuth requests are rejected.
profileNoCodex --profile <name>.
fullAutoNoDEPRECATED: prefer `sandboxMode`. Expands to `--sandbox workspace-write`; current Codex no longer accepts approval-policy flags.
worktreeNoSlice Ī»: run this request inside a dedicated git worktree owned by the gateway. `true` creates a fresh worktree at `<repoRoot>/.worktrees/<uuid>` branched from HEAD. `{ name?, ref? }` lets the caller supply a sanitized name and/or a git ref (default: HEAD). When the request carries a sessionId and the session already has a worktree, reuse requires same-host ownership metadata and a matching live Git registration. Named path collisions never reuse manager state. Gateway-managed worktrees require the local file-backed session manager and fail closed with PostgreSQL sessions. The Grok, Devin, and Mistral adapters require an explicit provider-native sessionId; fresh, createNewSession, and resumeLatest-only worktree requests fail closed because they cannot durably reselect the worktree. The request must select a registered workspace explicitly, through caller-owned session metadata, or through the configured default. Worktrees never fall back to the gateway process cwd and cannot be combined with local workingDir, addDir, or includeDirs paths. The gateway spawns the child CLI with `cwd: <worktree-path>`; no `-w`/`--worktree` flag is ever emitted to the underlying CLI. On worktree materialization, the gateway suppresses repository, system, and global Git hooks and configured clean, smudge, and process checkout filters, sparse checkout, and lazy object fetching. Filter-dependent content such as Git LFS remains in its repository representation instead of executing host commands. On session_delete or TTL eviction the gateway hides the session and runs `git worktree remove --force`. Failed removal retains a durable cleanup-pending tombstone which blocks reuse and is retried when the file store is registered on the owning host. The tombstone is finalized only after verified Git removal. Successful responses are prefixed with `[gateway] worktree=<absolute-path>\n` so callers can use the path. For Claude approvalStrategy:mcp_managed, requesting or reusing a worktree requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1. Other adapters reject mcp_managed before launch. NOTE: callers should `.gitignore` the `.worktrees/` directory in their repo (the gateway does NOT auto-gitignore; see slice Ī» spec Q4).
ephemeralNoCodex --ephemeral.
sessionIdNoCodex session UUID to resume via `codex exec resume <ID>`. Must be a real Codex session ID (from `~/.codex/sessions/` or the `codex resume` picker). Gateway-generated `gw-*` IDs are rejected. For a brand-new session no resumable sessionId is returned; continue with resumeLatest:true or a real Codex UUID.
workspaceNoRegistered workspace alias for remote HTTP/OAuth provider calls. Do not use this field, workspace_list, or workspace_register_existing_repo as a fallback for stdio/local provider path access; pass workingDir/addDir/includeDirs directly instead.
mcpServersNoThis provider does not receive gateway-managed MCP configuration. mcpServers has no effect with legacy, and mcp_managed is rejected before launch because ambient MCP configuration cannot be isolated.
workingDirNoCodex -C/--cd <DIR>: working root for this session. New sessions only: the flag is filtered from resume argv. That does NOT pin a resumed session's directory, because the child is still spawned with the gateway-resolved cwd; do not rely on it. Personal Agent Config Kit mode requires an absolute path. Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
ignoreRulesNoCodex --ignore-rules.
promptPartsNoCache-aware structured prompt: { system?, tools?, context?, task }. Mutually exclusive with prompt. Stable parts hash into cache_state for prefix-discipline tracking.
sandboxModeNoCodex --sandbox. NEW SESSIONS ONLY: the gateway filters --sandbox out of a resume argv, so this field has no effect on a resumed request. That is NOT a guarantee that the resumed session keeps its original posture: configOverrides still passes through and can set sandbox_mode, and Codex re-resolves configuration on a cold resume. Establish the posture on the first request and verify it when it matters. On a new session, omitting it does NOT guarantee read-only: the gateway emits no --sandbox flag and Codex resolves the policy from configuration, project trust, and its own fallback, so a trusted project can resolve to workspace-write. Pass read-only explicitly for inspection. Pass workspace-write to let Codex edit files in the working dir, or danger-full-access for unrestricted access.
forceRefreshNoBypass dedup and force a fresh CLI run even if a recent identical request exists
outputFormatNoCodex caller-facing output format. Token/cache usage is recorded in the flight recorder regardless. `text` (default) returns the plain reply; `json` returns the raw `--json` JSONL event stream.
outputSchemaNoCodex --output-schema. Pass a path (string) or an inline JSON Schema object.
resumeLatestNoResume a previous Codex session via `codex exec resume --last`. UNDER REVIEW: do not rely on which session this selects or on the resumed working directory. `--last` is filtered by cwd upstream unless `--all` is passed, which the gateway does not emit, and the child is still spawned with the gateway-resolved cwd even though `-C`/`--add-dir` are dropped from the resume argv. Verify the target, or start a fresh session when it must be certain. Ignored if sessionId is set; an explicit real Codex UUID targets that session. A brand-new session returns no resumable sessionId; continue with resumeLatest:true or a real Codex UUID.
strictConfigNoCodex --strict-config: error out when config.toml contains fields not recognized by this Codex version. New sessions only.
correlationIdNoRequest trace ID (auto if omitted)
idleTimeoutMsNoIdle timeout in ms (min 30s, max 1h, omit=CLI default)
localProviderNoCodex --local-provider: local OSS provider (lmstudio|ollama), used with oss. New sessions only.
providerFlagsNoFlags passed to the provider binary verbatim, keyed exactly as the binary spells them (e.g. {"--best-of-n": "3", "--verbatim": true, "--rules": ["a", "b"]}). Use this for any flag your installed CLI accepts that this schema does not name: the binary decides what it supports, not the gateway. true emits the flag alone; a list REPEATS the flag once per item (pass a joined string if your CLI wants a comma-separated value). Values may not start with '-', and a flag the gateway is already emitting for this request is refused rather than duplicated. LOCAL stdio callers only: remote HTTP/OAuth callers are refused every flag here and should use this tool's declared parameters, which carry their own host-path and approval gates.
approvalPolicyNoapprovalPolicy is unavailable for this provider. It has no effect with legacy, and mcp_managed is rejected before launch because ambient MCP configuration cannot be isolated.
askForApprovalNoDEPRECATED compatibility input: accepted but ignored because current Codex no longer accepts --ask-for-approval.
optimizePromptNoOptimize prompt before execution
configOverridesNoCodex -c key=value overrides. Keys: /^[a-zA-Z0-9._]+$/. Values: no CR/LF. Local callers only, remote HTTP/OAuth requests are rejected.
approvalStrategyNoApproval strategy: legacy is supported. mcp_managed is rejected before launch because this adapter cannot isolate ambient MCP configuration.legacy
compressResponseNoCompress the response display text when collected via llm_job_result (native compressor; default: [compression].enabled).
createNewSessionNoForce a fresh session (no resume)
ignoreUserConfigNoCodex --ignore-user-config.
outputLastMessageNoCodex -o/--output-last-message <FILE>: write the agent's last message to a file. New sessions only.
requestInstructionsNoPer-request Kit instructions. Available only when [personal_config].enabled = true.
useLegacyFullAutoFlagNoDEPRECATED compatibility input: accepted but ignored because current Codex no longer accepts --full-auto.
dangerouslyBypassHookTrustNoCodex --dangerously-bypass-hook-trust: run enabled hooks without persisted hook trust for this invocation. DANGEROUS.
dangerouslyBypassApprovalsAndSandboxNoRun Codex without approvals/sandbox.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry the safety profile (destructiveHint=true, readOnlyHint=false, idempotentHint=false), so the description only needs to add context beyond that. It adds the 'durable' background-job semantics and the poll/collect lifecycle, but says nothing about the immediate return payload, subprocess side effects, cost, or approval gates — meaningful but thin for a tool that launches an external CLI.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, action first, with zero filler: the first states what the tool does and the second provides the follow-up protocol. For a tool whose 42 parameters are each thoroughly documented in the schema, this is appropriately sized and front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, open-world, async tool with no output schema, the description omits what the start call returns (job ID/receipt) and never frames the sync-versus-async decision. The schema and annotations carry most of the invocation correctness burden, but the tool-level description leaves the request lifecycle only partially specified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline 3 applies and the tool description correctly adds no parameter-level detail. The schema's per-parameter prose is exceptionally rich (sandboxMode resume caveats, worktree ownership and tombstone rules, providerFlags refusal for remote callers), but that documentation lives in the schema, not in the tool description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description pairs a specific verb and resource — 'Start an OpenAI Codex CLI request' — with a clear operating mode, 'durable background job,' which implicitly separates it from the synchronous codex_request sibling. However, it never explicitly names that sibling or the other async provider variants, so differentiation is implied rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides concrete post-invocation workflow guidance ('Poll with llm_job_status, collect with llm_job_result'), which is genuinely useful. But it gives no when-to-use versus the synchronous codex_request, no when-not-to-use, and no criteria for choosing among the eight async provider variants; selection guidance is largely implied by the word 'durable.'

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

compare_answersA
Read-onlyIdempotent

Summarize agreement/differences between caller-provided answers LOCALLY — does not call any provider.

ParametersJSON Schema
NameRequiredDescriptionDefault
answersYesTwo or more answers to compare.
questionYesQuestion the answers respond to.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnlyHint, idempotentHint, and destructiveHint=false. The description adds valuable execution-context behavior — that it runs locally and makes no provider calls — which is not captured by the annotations alone. No contradiction; it reinforces the non-destructive, side-effect-free nature.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence that conveys purpose and a critical behavioral qualifier with no extraneous words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter local comparison tool with safety-relevant annotations, the description covers what the tool does, its execution context, and its inputs via schema. The lack of an output schema is a minor gap, but 'summarize' conveys the nature of the result, so the definition is complete enough for selection and invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with both `question` and `answers` documented in the schema itself. The description adds no further parameter specifics beyond implying that answers are caller-provided, so the schema carries the semantic load.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('summarize'), a specific resource ('caller-provided answers'), and a key differentiator ('LOCALLY — does not call any provider'). This distinguishes it from the many sibling tools that invoke external providers (e.g., claude_request, gemini_request, validate_with_models). No ambiguity about the operation performed.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description makes clear this is a local operation by emphasizing 'LOCALLY' and 'does not call any provider,' which tells an agent to choose it when comparing answers without external model calls. However, it does not explicitly name sibling alternatives or state when not to use it, leaving some inference to the agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

config_ack_staleA

Acknowledge the current stale Personal Agent Config release for at most 24 hours.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations indicate the tool is not read-only and not destructive, and the description adds a useful behavioral trait: the acknowledgement lasts at most 24 hours. However, it does not explain what side effects occur, whether the acknowledgement can be reset, or what happens after expiration, so transparency is only partial.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence with no filler. It starts with the action and resource and immediately states the limit, making it easy to parse and remember.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter tool with a simple state change and no output schema, the description captures the essential behavior: acknowledge the current stale release for a bounded duration. Minor unknowns such as return behavior or expiry handling are acceptable for such a simple operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and the schema coverage is 100%, so the description has no parameter burden. Per the zero-parameter baseline, this is a strong score with no missing parameter documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Acknowledge') with a specific resource ('current stale Personal Agent Config release') and adds a clear temporal boundary ('at most 24 hours'). This is sufficiently distinct from siblings like config_sync, config_rollback, and config_status, so an agent can tell what the tool does without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage: acknowledge a stale Personal Agent Config release when it is currently stale and a temporary acknowledgement is acceptable. However, it does not explicitly state when not to use it or mention alternatives such as config_sync or config_rollback, leaving the routing partly to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

config_initA
Destructive

Initialize or clone the local Personal Agent Config baseline. This never activates a release by itself.

ParametersJSON Schema
NameRequiredDescriptionDefault
remoteNoOptional private Git remote to clone

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations indicate destructiveHint=true, so the agent already knows this can be destructive. The description adds one useful behavioral guarantee—it never activates a release by itself—which helps distinguish it from release-related steps. However, it does not disclose what may be overwritten or destroyed during initialization/cloning, which would be valuable for a destructive operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences with no filler. The purpose is front-loaded, and the clarifying statement about not activating a release earns its place by preventing misuse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple, one-optional-parameter tool this is minimally adequate, but there is no output schema and the destructive annotation is not elaborated. The agent is left to guess what side effects 'initialize or clone' may have on existing local files, which matters for a destructiveHint=true tool in a larger config-related tool family.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides 100% parameter coverage, including a description for the optional 'remote' parameter ('Optional private Git remote to clone'). The tool description only repeats the cloning concept and adds no additional parameter-level meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Initialize or clone') on a specific resource ('the local Personal Agent Config baseline'), which clearly distinguishes it from related config operations. The added sentence 'This never activates a release by itself' further clarifies that this is not a publish/release tool, making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly implies the use case: when you need to set up or clone the local baseline. It also provides an explicit when-not: this is not for activating a release. However, it does not name sibling tools like config_publish or config_sync or give conditions for choosing between them, so guidance is only partially explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

config_publishA

Push the clean local Personal Agent Config baseline to its configured Git upstream without force-pushing.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal that this is a write operation that is not destructive; the description adds meaningful context by specifying that it will not force-push and requires a clean local baseline. This goes beyond the structured annotations and helps an agent understand the safety profile of the operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, tightly worded sentence that front-loads the core action and includes only essential qualifiers. No redundant or filler content is present.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter tool with annotations covering the read/write and destructive profile, the description adequately covers the operation, source, destination, and safety constraint. It does not describe failure behavior when the upstream has diverged, but that is a minor omission given the low complexity and available annotations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parameters, and the input schema is empty, so there is nothing to document. The description's reference to a 'configured Git upstream' makes clear that the target is preconfigured rather than passed as an argument, which is sufficient context.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('push'), the object ('clean local Personal Agent Config baseline'), and the destination ('configured Git upstream'), with an explicit safety constraint ('without force-pushing'). It is specific enough to understand what the tool does, though it does not explicitly differentiate itself from sibling tools like config_sync.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'clean local Personal Agent Config baseline' implies this tool should be used when the local configuration is clean and ready to publish, but it does not provide explicit guidance on when to choose this over config_sync, config_status, or config_rollback. Usage context is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

config_recover_kit_attemptA
Destructive

Fence and release one exact unadmitted durable Kit attempt after the previous gateway process has been stopped. Copy the execution and attempt identity from local session_get output. This action is local-only and cannot recover an existing durable job.

ParametersJSON Schema
NameRequiredDescriptionDefault
providerYes
attemptIdYes
executionYes
sessionIdYes
acknowledgementYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool as destructive and not read-only, so the description does not need to restate that. It adds useful behavioral context beyond the annotations: the action is local-only, affects exactly one attempt, and cannot recover durable jobs. This meaningfully informs the agent about scope and limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The core action and precondition are front-loaded, followed by a sourcing instruction and a clear limitation. Every sentence adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, local-only recovery action with a nested execution object, the description gives the essential context: the prerequisite, the scope, and the source for the required identities. It does not describe the response shape or failure modes, but there is no output schema and the instructions are practical enough for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 0% description coverage, so the description must compensate. It partially does by instructing the agent to copy 'execution and attempt identity' from local session_get output, which maps to attemptId and execution. However, it does not explain provider choice, sessionId sourcing, or the acknowledgement field beyond what the schema's literal constants already convey. The guidance is helpful but incomplete for all five parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific action ('Fence and release'), a specific resource ('one exact unadmitted durable Kit attempt'), and a key precondition ('after the previous gateway process has been stopped'). It also disambiguates itself by stating it 'cannot recover an existing durable job.' This is enough for an agent to identify what the tool does and how it differs from other recovery-related tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly states when to use the tool: only for one exact unadmitted attempt and only after the previous gateway process has been stopped. It also gives an explicit exclusion ('cannot recover an existing durable job') and tells the agent where to source values ('from local session_get output'). It does not name a specific sibling alternative, but the when/not-when guidance is strong.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

config_rollbackA

Atomically activate an already verified retained Personal Agent Config release.

ParametersJSON Schema
NameRequiredDescriptionDefault
releaseIdYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish that this is a non-read, non-destructive action, and the description adds the useful 'atomically' detail, indicating the activation is all-or-nothing. It also adds the state requirements 'verified' and 'retained.' Still, it does not disclose side effects such as whether the previously active config remains available or whether the rollback can be reversed, so transparency is adequate but incomplete.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence with no filler or redundant restatement of the tool name. The key qualifier 'atomically' is front-loaded, and every word contributes meaning within the sentence's scope.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter tool with no output schema, the description covers the core action, atomicity, and a prerequisite. However, it does not explain how to obtain a valid releaseId, what the outcome of activation looks like, or how this tool relates to config_publish and config_sync. An agent could likely call it correctly, but important surrounding context is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description bears the burden of explaining releaseId. The phrase 'activate ... release' ties the parameter to the release being activated, and 'already verified retained' narrows the acceptable release state. That adds useful meaning, but the description never explicitly names releaseId or explains how to obtain a valid value beyond the schema's hex pattern.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific action ('activate') and a specific resource ('Personal Agent Config release'), and adds meaningful qualifiers ('atomically', 'already verified retained') that clarify what kind of activation this is. It does not explicitly differentiate from sibling config tools, but the action and resource are clear enough that an agent can tell what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'already verified retained' implies a precondition for using this tool: only verified, retained releases should be activated through it. However, it does not say when to prefer this tool over config_publish, config_sync, or other config-related siblings, nor does it state any when-not-to-use conditions. Usage guidance is mostly left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

config_statusA
Read-only

Show Personal Agent Config state without exposing baseline paths or local machine binding values.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only; description adds that it does not expose baseline paths or local binding values, going beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single 12-word sentence, no waste, perfectly concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only status tool with no output schema, the description fully covers purpose and behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters, schema coverage 100% (trivially); baseline 4 for zero params. Description adds no param info but that's unnecessary.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states 'Show Personal Agent Config state' (specific verb+resource) and distinguishes by noting it excludes sensitive values, differentiating from siblings like config_sync.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implies usage for viewing config state without sensitive details; provides context but lacks explicit when-not-to-use or alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

config_syncA

Synchronize, verify, compile, and atomically activate a Personal Agent Config release. It never pushes.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations indicate non-read-only and non-destructive, and the description adds behavioral context: atomic activation and the 'never pushes' constraint. This goes beyond annotations, though details about failure handling or side effects are absent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence, concise and front-loaded with key actions. Every word contributes meaning, with no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no parameters and no output schema, the description adequately covers its purpose and key behavior. However, it omits context about failure modes or prerequisites, which could help a cautious agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero parameters with 100% coverage, so the description naturally adds no parameter details. Per guidelines, zero parameters warrant a baseline of 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool synchronizes, verifies, compiles, and atomically activates a Personal Agent Config release, and explicitly notes it never pushes. This provides a specific verb+resource identification and distinguishes from siblings by clarifying its scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given on when to use this tool versus alternatives like config_recover_kit_attempt. There is no mention of conditions or prerequisites for invocation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

consensus_checkB
Destructive

Ask provider CLIs whether they agree or disagree with a claim (starts validation jobs).

ParametersJSON Schema
NameRequiredDescriptionDefault
claimYesClaim to check across providers.
modelsNoProviders to ask for agreement or disagreement.
selectNoOptional least-cost routing: fill the provider target(s) from the LCR selector instead of the explicit list. 'cheapest' picks the single cheapest eligible provider; 'cheapest_per_tier' picks the cheapest in each quality tier. Requires [least_cost].enabled=true; fails closed (no default-list fallback) when disabled or nothing is eligible.

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds the behavioral detail that the tool 'starts validation jobs,' which is important beyond the annotations. However, it does not explain whether the operation is asynchronous, how results are retrieved, whether external provider CLIs execute arbitrary work, or what 'destructive' side effects might occur beyond starting jobs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence with no filler. It front-loads the core purpose and parenthetically adds the important side effect of starting validation jobs. Every element earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description should explain what the caller receives back and how results relate to the job lifecycle. It only says 'starts validation jobs,' leaving the agent to infer return values, job IDs, and how to retrieve consensus outcomes from sibling tools like validation_receipt or job_status.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with clear descriptions for claim, models, and select. The tool description itself adds no parameter-level meaning, so the baseline of 3 is appropriate; the schema carries the semantic weight.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific action ('Ask provider CLIs'), a resource ('provider CLIs'), and the object of the action ('whether they agree or disagree with a claim'). It is more than a tautology and aligns with the tool name, but it does not clearly differentiate this tool from closely related siblings such as validate_with_models, second_opinion, or compare_answers.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided about when to use this tool versus the many sibling validation/consensus tools, nor are exclusions or prerequisites mentioned. The only implicit usage signal is the phrase 'starts validation jobs,' which hints at a workflow but does not say when this should be chosen over alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

cursor_requestA
Destructive

Run a Cursor Agent request synchronously (auto-defers to a pollable job past the sync deadline when async jobs are enabled; otherwise runs to completion). Default cli uses headless print mode (cursor-agent --print); gated acp uses native cursor-agent acp and accepts prompt, model, a gateway ACP session, and a registered workspace alias.

ParametersJSON Schema
NameRequiredDescriptionDefault
modeNoCursor execution mode: plan (read-only planning) or ask (Q&A/read-only)
forceNoEmit --force (Cursor yolo mode; auto-allows commands unless explicitly denied)
modelNoModel name or alias passed via --model
trustNoTrust the workspace in headless mode (--trust)
addDirNoAdditional workspace root directories (--add-dir, repeatable).
promptYesPrompt text for Cursor Agent CLI
sandboxNoCursor sandbox mode override (--sandbox enabled|disabled)
sessionIdNoOn transport=cli, Cursor chat/session ID to resume (emits --resume <id>); gateway gw-* tracking ids are not CLI session ids. On transport=acp, gateway-owned ACP session ID returned by an earlier ACP call; Cursor-native and CLI session ids are rejected.
transportNoTransport selector. Default `cli` uses cursor-agent --print. `acp` uses native cursor-agent acp and fails closed unless [acp].enabled plus [acp.providers.cursor].enabled and runtime_enabled are true. ACP accepts prompt, model, a gateway ACP sessionId, and a registered workspace alias; Cursor CLI-only controls are rejected.cli
workspaceNoWorkspace directory or saved workspace name (--workspace) on transport=cli. transport=acp requires a registered gateway workspace alias. Remote HTTP/OAuth callers must pass an alias; local callers may pass local Cursor workspace paths only on transport=cli.
autoReviewNoEmit --auto-review (Cursor Smart Auto classifier for tool calls)
workingDirNoLocal Cursor Agent process working directory. Distinct from --workspace, which selects a Cursor workspace or saved workspace name; this sets the process cwd. Passing both an absolute workspace path and a different workingDir is rejected rather than silently ranked. Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
forceRefreshNoBypass dedup and force a fresh CLI run even if a recent identical request exists
outputFormatNoCursor --output-format for --print modetext
resumeLatestNoResume the latest Cursor chat (--continue) on transport=cli. true is rejected on transport=acp.
correlationIdNoRequest trace ID (auto if omitted)
idleTimeoutMsNoTotal-runtime bound, not an idle timer: this provider emits no output until it exits, so the child is killed after this duration even while healthy. Min 30s, max 1h, omit=1h default. Cursor only: this holds for the default text invocation; with outputFormat stream-json the CLI streams incrementally, so the same timer behaves as a genuine idle window.
providerFlagsNoFlags passed to the provider binary verbatim, keyed exactly as the binary spells them (e.g. {"--best-of-n": "3", "--verbatim": true, "--rules": ["a", "b"]}). Use this for any flag your installed CLI accepts that this schema does not name: the binary decides what it supports, not the gateway. true emits the flag alone; a list REPEATS the flag once per item (pass a joined string if your CLI wants a comma-separated value). Values may not start with '-', and a flag the gateway is already emitting for this request is refused rather than duplicated. LOCAL stdio callers only: remote HTTP/OAuth callers are refused every flag here and should use this tool's declared parameters, which carry their own host-path and approval gates.
approvalPolicyNoOn transport=cli, approvalPolicy has no effect because mcp_managed is unavailable. On transport=acp, supplying approvalPolicy is rejected because ACP has its own permission bridge.
optimizePromptNoOptimize prompt before execution
approvalStrategyNoApproval strategy. legacy is the only executable CLI strategy; mcp_managed is rejected before Cursor launches because the CLI adapter cannot isolate ambient MCP configuration. transport=acp has its own permission bridge and also rejects mcp_managed.legacy
compressResponseNoCompress the response display text via the native compressor (default: [compression].enabled in config.toml, off unless opted in). Skipped for structured output.
createNewSessionNoForce a new session on transport=cli. true is rejected on transport=acp.
optimizeResponseNoOptimize response output

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false and destructiveHint=true, and the description does not contradict them. The description adds behavioral context not present in the annotations: the sync-deadline deferral behavior, the run-to-completion fallback, the default headless print mode, and the gated acp mode. This gives the agent a clearer model of how the tool executes beyond the safety hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two dense sentences with no filler, front-loading the core action before transport details. It packs significant information about sync behavior, deferral, default transport, and acp gating without becoming bloated. Some complexity is unavoidable given the tool's scope, but the structure keeps it readable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 24-parameter tool with no output schema, the description leaves some gaps: it does not describe what the response looks like, how the deferral should be surfaced, or how the agent should poll the resulting job. The parameter schema is exceptionally rich and compensates for much of the missing context, but the description alone is not fully self-sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and individual parameter descriptions are unusually detailed, covering transport-specific rejections, defaults, and flag behavior. The main description adds only a brief summary of which parameters acp accepts, which is largely redundant with the schema. This matches the baseline of 3 for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action and resource: 'Run a Cursor Agent request synchronously'. It also distinguishes this tool from async variants by explicitly mentioning the sync deadline and auto-deferral to a pollable job. It does not name a sibling like cursor_request_async directly, but the synchronous framing is enough to separate it from the async family of tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives useful context about when the tool runs synchronously and when it defers to a pollable job, and it explains the default cli transport versus the gated acp transport. However, it never explicitly tells an agent when to prefer this tool over cursor_request_async or other request tools, nor does it state a clear when-not-to-use condition. The guidance is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

cursor_request_asyncA
Destructive

Start a Cursor Agent CLI request as a durable background job. Poll with llm_job_status, collect with llm_job_result.

ParametersJSON Schema
NameRequiredDescriptionDefault
modeNoCursor execution mode: plan (read-only planning) or ask (Q&A/read-only)
forceNoEmit --force (Cursor yolo mode; auto-allows commands unless explicitly denied)
modelNoModel name or alias passed via --model
trustNoTrust the workspace in headless mode
addDirNoAdditional workspace root directories (--add-dir, repeatable).
promptYesPrompt text for Cursor Agent CLI
sandboxNoCursor sandbox mode override (--sandbox enabled|disabled)
sessionIdNoCursor chat/session ID to resume (emits --resume <id>). Note: the gw-* id minted for a brand-new gateway session is not resumable via sessionId; continue with resumeLatest:true.
workspaceNoWorkspace directory or saved workspace name (--workspace). This async tool always uses the CLI transport; remote HTTP/OAuth callers must pass a registered workspace alias, while local callers may pass local Cursor workspace paths.
autoReviewNoEmit --auto-review (Cursor Smart Auto classifier for tool calls)
workingDirNoLocal Cursor Agent process working directory. Distinct from --workspace, which selects a Cursor workspace or saved workspace name; this sets the process cwd. Passing both an absolute workspace path and a different workingDir is rejected rather than silently ranked. Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
forceRefreshNoBypass dedup and force a fresh CLI run even if a recent identical request exists
outputFormatNoCursor --output-format for --print modetext
resumeLatestNoResume the latest Cursor chat (--continue). Note: the gw-* id minted for a brand-new gateway session is not resumable via sessionId; continue with resumeLatest:true.
correlationIdNoRequest trace ID (auto if omitted)
idleTimeoutMsNoTotal-runtime bound, not an idle timer: this provider emits no output until it exits, so the child is killed after this duration even while healthy. Min 30s, max 1h, omit=1h default. Cursor only: this holds for the default text invocation; with outputFormat stream-json the CLI streams incrementally, so the same timer behaves as a genuine idle window.
providerFlagsNoFlags passed to the provider binary verbatim, keyed exactly as the binary spells them (e.g. {"--best-of-n": "3", "--verbatim": true, "--rules": ["a", "b"]}). Use this for any flag your installed CLI accepts that this schema does not name: the binary decides what it supports, not the gateway. true emits the flag alone; a list REPEATS the flag once per item (pass a joined string if your CLI wants a comma-separated value). Values may not start with '-', and a flag the gateway is already emitting for this request is refused rather than duplicated. LOCAL stdio callers only: remote HTTP/OAuth callers are refused every flag here and should use this tool's declared parameters, which carry their own host-path and approval gates.
approvalPolicyNoapprovalPolicy is unavailable for this provider. It has no effect with legacy, and mcp_managed is rejected before launch because ambient MCP configuration cannot be isolated.
optimizePromptNoOptimize prompt before execution
approvalStrategyNoApproval strategy: legacy is supported. mcp_managed is rejected before launch because this adapter cannot isolate ambient MCP configuration.legacy
compressResponseNoCompress the response display text when collected via llm_job_result (native compressor; default: [compression].enabled).
createNewSessionNoForce a new session

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds meaningful behavioral context beyond annotations: the request runs as a durable background job rather than blocking, and results are retrieved separately through the poll/collect pattern. Combined with the rich schema-level behavior (no output until exit, total-runtime timeout, yolo mode, rejection of mcp_managed), the agent gets a solid picture of how this tool behaves. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero waste. The first sentence front-loads the core action and durable-background nature, and the second gives the essential follow-up workflow. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 22 parameters and complex provider-specific constraints, the description is quite complete because the schema carries the heavy parameter-level burden and the description covers the job lifecycle. It falls slightly short by not explicitly naming the synchronous cursor_request alternative or stating when to use the async form, but the 'durable background job' phrasing and poll/collect instructions make the core workflow clear.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline of 3 applies. The tool description itself does not add parameter-specific semantics beyond the schema; the mention of poll and collect relates to job lifecycle rather than any input parameter. It neither worsens nor improves on the schema's already thorough parameter documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Start a Cursor Agent CLI request as a durable background job.' This clearly distinguishes it from the synchronous cursor_request sibling and from other providers' async tools. It also signals the intended follow-up via llm_job_status and llm_job_result, making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear usage context: this is a background job that should be polled with llm_job_status and collected with llm_job_result. However, it does not explicitly explain when to prefer this over the synchronous cursor_request or other async variants, so the guidance stops short of full when/not-to-use routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

devin_requestA
Destructive

Run a Cognition Devin CLI request synchronously (auto-defers to a pollable job past the sync deadline when async jobs are enabled; otherwise runs to completion). Headless print mode (devin -p).

ParametersJSON Schema
NameRequiredDescriptionDefault
modelNoModel name or alias (e.g. opus, latest)
configNoConfig file path (Devin --config <PATH>)
promptNoPrompt text for Devin CLI. Required in practice; promptFile is additive (loads an initial prompt from a file).
sandboxNoRun the Devin session in a sandbox (Devin --sandbox). Safety control: never defaulted on; pass true to opt in.
worktreeNoSlice Ī»: run this request inside a dedicated git worktree owned by the gateway. `true` creates a fresh worktree at `<repoRoot>/.worktrees/<uuid>` branched from HEAD. `{ name?, ref? }` lets the caller supply a sanitized name and/or a git ref (default: HEAD). When the request carries a sessionId and the session already has a worktree, reuse requires same-host ownership metadata and a matching live Git registration. Named path collisions never reuse manager state. Gateway-managed worktrees require the local file-backed session manager and fail closed with PostgreSQL sessions. The Grok, Devin, and Mistral adapters require an explicit provider-native sessionId; fresh, createNewSession, and resumeLatest-only worktree requests fail closed because they cannot durably reselect the worktree. The request must select a registered workspace explicitly, through caller-owned session metadata, or through the configured default. Worktrees never fall back to the gateway process cwd and cannot be combined with local workingDir, addDir, or includeDirs paths. The gateway spawns the child CLI with `cwd: <worktree-path>`; no `-w`/`--worktree` flag is ever emitted to the underlying CLI. On worktree materialization, the gateway suppresses repository, system, and global Git hooks and configured clean, smudge, and process checkout filters, sparse checkout, and lazy object fetching. Filter-dependent content such as Git LFS remains in its repository representation instead of executing host commands. On session_delete or TTL eviction the gateway hides the session and runs `git worktree remove --force`. Failed removal retains a durable cleanup-pending tombstone which blocks reuse and is retried when the file store is registered on the owning host. The tombstone is finalized only after verified Git removal. Successful responses are prefixed with `[gateway] worktree=<absolute-path>\n` so callers can use the path. For Claude approvalStrategy:mcp_managed, requesting or reusing a worktree requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1. Other adapters reject mcp_managed before launch. NOTE: callers should `.gitignore` the `.worktrees/` directory in their repo (the gateway does NOT auto-gitignore; see slice Ī» spec Q4).
agentTypeNoACP agent variant for transport=acp (`devin acp --agent-type`): 'summarizer' (no tools, text summary) or 'review' (read-only + shell code-review). Ignored for the CLI transport.
sessionIdNoOn transport=cli, Devin session ID to resume (emits --resume <id>; use resumeLatest for --continue); gateway gw-* tracking ids are not CLI session ids. On transport=acp, gateway-owned ACP session ID returned by an earlier ACP call; Devin-native and CLI session ids are rejected.
transportNoTransport: 'cli' (default) runs the Devin CLI. 'acp' routes through `devin acp` only when [acp].enabled plus [acp.providers.devin].enabled and runtime_enabled are true (fails closed otherwise). ACP accepts prompt, model, a gateway ACP sessionId, and the validated agentType; Devin CLI-only controls are rejected.cli
workspaceNoRegistered workspace alias for remote HTTP/OAuth provider calls. Do not use this field, workspace_list, or workspace_register_existing_repo as a fallback for stdio/local provider path access; pass workingDir/addDir/includeDirs directly instead.
promptFileNoLoad the initial prompt from a file (--prompt-file)
workingDirNoLocal Devin process working directory. Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
agentConfigNoAgent config file path (Devin --agent-config <FILE>). devin 3000.4.16 and newer no longer advertise this flag and will reject it; the gateway passes it through rather than refusing it, because older devin installs still accept it and the binary is the authority on its own flags.
forceRefreshNoBypass dedup and force a fresh CLI run even if a recent identical request exists
resumeLatestNoResume the most recent Devin session in cwd (--continue) on transport=cli. true is rejected on transport=acp.
correlationIdNoRequest trace ID (auto if omitted)
exportSessionNoExport the conversation (Devin --export [<PATH>]). ON BY DEFAULT to a gateway-owned path under ~/.llm-cli-gateway/devin-transcripts: devin writes only its final text to stdout, so without the export a run leaves no reconstructable record. Pass false to opt out, true for a bare --export (devin picks the path), or a string for your own path.
idleTimeoutMsNoTotal-runtime bound, not an idle timer: this provider emits no output until it exits, so the child is killed after this duration even while healthy. Min 30s, max 1h, omit=1h default.
providerFlagsNoFlags passed to the provider binary verbatim, keyed exactly as the binary spells them (e.g. {"--best-of-n": "3", "--verbatim": true, "--rules": ["a", "b"]}). Use this for any flag your installed CLI accepts that this schema does not name: the binary decides what it supports, not the gateway. true emits the flag alone; a list REPEATS the flag once per item (pass a joined string if your CLI wants a comma-separated value). Values may not start with '-', and a flag the gateway is already emitting for this request is refused rather than duplicated. LOCAL stdio callers only: remote HTTP/OAuth callers are refused every flag here and should use this tool's declared parameters, which carry their own host-path and approval gates.
approvalPolicyNoOn transport=cli, approvalPolicy has no effect because mcp_managed is unavailable. On transport=acp, supplying approvalPolicy is rejected because ACP has its own permission bridge.
optimizePromptNoOptimize prompt before execution
permissionModeNoDevin CLI permission mode (--permission-mode). auto auto-approves read-only tools; accept-edits also auto-approves workspace edits; smart additionally auto-runs actions a fast model judges safe; dangerous auto-approves all. When omitted, Devin uses its own headless default; choose an explicit mode for unattended runs.
approvalStrategyNoApproval strategy. legacy is supported. mcp_managed is rejected before Devin launches because the CLI adapter cannot isolate ambient MCP configuration; transport=acp has its own permission bridge and also rejects mcp_managed.legacy
compressResponseNoCompress the response display text via the native compressor (default: [compression].enabled in config.toml, off unless opted in). Skipped for structured output.
createNewSessionNoForce a new session on transport=cli. true is rejected on transport=acp.
optimizeResponseNoOptimize response output
respectWorkspaceTrustNoRespect workspace trust (Devin --respect-workspace-trust <bool>). Devin defaults true for interactive and false for print mode; set explicitly to override.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, so the bar for added behavioral disclosure is lower. The description adds valuable detail by explaining that the call can auto-defer to a pollable job past the sync deadline and that it runs in headless print mode. There is no contradiction with the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler: the core action and headless mode are front-loaded, and the async-deflection nuance is compactly nested in a parenthetical. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 26-parameter, destructive, open-world tool with no output schema, the description is too thin on return semantics: it does not state what a successful response contains or how an agent should locate and poll the deferred job. It also omits side-effect and routing guidance, leaving the agent to infer these from annotations and sibling names.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3 and the description does not need to compensate. It contains no parameter-specific guidance, but the schema already documents all 26 parameters, including enums, defaults, and constraints.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource ('Run a Cognition Devin CLI request synchronously') and adds the exact invocation mode (`devin -p` headless print). The sync versus auto-defer-to-pollable-job phrasing distinguishes this tool from the async sibling and from other provider request tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context through 'synchronously' and 'otherwise runs to completion', but it never explicitly names devin_request_async or states when to prefer that sibling. The auto-defer clause is a behavioral note rather than a clear routing rule.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

devin_request_asyncA
Destructive

Start a Cognition Devin CLI request as a durable background job. Poll with llm_job_status, collect with llm_job_result.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelNoModel name or alias (e.g. opus, latest)
configNoConfig file path (Devin --config <PATH>)
promptNoPrompt text for Devin CLI. Required in practice; promptFile is additive (loads an initial prompt from a file).
sandboxNoRun the Devin session in a sandbox (Devin --sandbox). Safety control: never defaulted on; pass true to opt in.
worktreeNoSlice Ī»: run this request inside a dedicated git worktree owned by the gateway. `true` creates a fresh worktree at `<repoRoot>/.worktrees/<uuid>` branched from HEAD. `{ name?, ref? }` lets the caller supply a sanitized name and/or a git ref (default: HEAD). When the request carries a sessionId and the session already has a worktree, reuse requires same-host ownership metadata and a matching live Git registration. Named path collisions never reuse manager state. Gateway-managed worktrees require the local file-backed session manager and fail closed with PostgreSQL sessions. The Grok, Devin, and Mistral adapters require an explicit provider-native sessionId; fresh, createNewSession, and resumeLatest-only worktree requests fail closed because they cannot durably reselect the worktree. The request must select a registered workspace explicitly, through caller-owned session metadata, or through the configured default. Worktrees never fall back to the gateway process cwd and cannot be combined with local workingDir, addDir, or includeDirs paths. The gateway spawns the child CLI with `cwd: <worktree-path>`; no `-w`/`--worktree` flag is ever emitted to the underlying CLI. On worktree materialization, the gateway suppresses repository, system, and global Git hooks and configured clean, smudge, and process checkout filters, sparse checkout, and lazy object fetching. Filter-dependent content such as Git LFS remains in its repository representation instead of executing host commands. On session_delete or TTL eviction the gateway hides the session and runs `git worktree remove --force`. Failed removal retains a durable cleanup-pending tombstone which blocks reuse and is retried when the file store is registered on the owning host. The tombstone is finalized only after verified Git removal. Successful responses are prefixed with `[gateway] worktree=<absolute-path>\n` so callers can use the path. For Claude approvalStrategy:mcp_managed, requesting or reusing a worktree requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1. Other adapters reject mcp_managed before launch. NOTE: callers should `.gitignore` the `.worktrees/` directory in their repo (the gateway does NOT auto-gitignore; see slice Ī» spec Q4).
sessionIdNoDevin session ID to resume (--resume <id>; use resumeLatest for --continue). Note: the gw-* id minted for a brand-new session is not resumable via sessionId; continue with resumeLatest:true.
workspaceNoRegistered workspace alias for remote HTTP/OAuth provider calls. Do not use this field, workspace_list, or workspace_register_existing_repo as a fallback for stdio/local provider path access; pass workingDir/addDir/includeDirs directly instead.
promptFileNoLoad the initial prompt from a file (--prompt-file)
workingDirNoLocal Devin process working directory. Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
agentConfigNoAgent config file path (Devin --agent-config <FILE>). devin 3000.4.16 and newer no longer advertise this flag and will reject it; the gateway passes it through rather than refusing it, because older devin installs still accept it and the binary is the authority on its own flags.
forceRefreshNoBypass dedup and force a fresh CLI run even if a recent identical request exists
resumeLatestNoResume the most recent Devin session in cwd (--continue). Note: the gw-* id minted for a brand-new session is not resumable via sessionId; continue with resumeLatest:true.
correlationIdNoRequest trace ID (auto if omitted)
exportSessionNoExport the conversation (Devin --export [<PATH>]). ON BY DEFAULT to a gateway-owned path under ~/.llm-cli-gateway/devin-transcripts: devin writes only its final text to stdout, so without the export a run leaves no reconstructable record. Pass false to opt out, true for a bare --export (devin picks the path), or a string for your own path.
idleTimeoutMsNoTotal-runtime bound, not an idle timer: this provider emits no output until it exits, so the child is killed after this duration even while healthy. Min 30s, max 1h, omit=1h default.
providerFlagsNoFlags passed to the provider binary verbatim, keyed exactly as the binary spells them (e.g. {"--best-of-n": "3", "--verbatim": true, "--rules": ["a", "b"]}). Use this for any flag your installed CLI accepts that this schema does not name: the binary decides what it supports, not the gateway. true emits the flag alone; a list REPEATS the flag once per item (pass a joined string if your CLI wants a comma-separated value). Values may not start with '-', and a flag the gateway is already emitting for this request is refused rather than duplicated. LOCAL stdio callers only: remote HTTP/OAuth callers are refused every flag here and should use this tool's declared parameters, which carry their own host-path and approval gates.
approvalPolicyNoapprovalPolicy is unavailable for this provider. It has no effect with legacy, and mcp_managed is rejected before launch because ambient MCP configuration cannot be isolated.
optimizePromptNoOptimize prompt before execution
permissionModeNoDevin CLI permission mode (--permission-mode). auto, accept-edits, smart, or dangerous. When omitted, Devin uses its own headless default; choose an explicit mode for unattended runs.
approvalStrategyNoApproval strategy: legacy is supported. mcp_managed is rejected before launch because this adapter cannot isolate ambient MCP configuration.legacy
compressResponseNoCompress the response display text when collected via llm_job_result (native compressor; default: [compression].enabled).
createNewSessionNoForce a new session
respectWorkspaceTrustNoRespect workspace trust (Devin --respect-workspace-trust <bool>). Devin defaults true for interactive and false for print mode; set explicitly to override.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already supply the safety profile (readOnlyHint=false, destructiveHint=true, idempotentHint=false), so the bar for the description is lower. The description adds 'durable background job' and the poll/collect lifecycle, which is useful, but it does not disclose concrete side effects such as spawning a child CLI, worktree creation, or transcript exports; those appear only in parameter-level schema text.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero filler. The main action and the necessary follow-up lifecycle are front-loaded, and every word contributes to the agent's understanding of how to use the tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (23 parameters, nested objects, no output schema), the description is lean but the rich schema and annotations carry substantial weight. It names the status/result tools for retrieval, though it does not explicitly state that a job identifier is returned or how to obtain it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline of 3 applies. The top-level description adds no parameter-level meaning; all parameter semantics are carried by the detailed input-schema descriptions (e.g., worktree, idleTimeoutMs, exportSession).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Start a Cognition Devin CLI request') and immediately distinguishes the tool by its async mode ('durable background job'). It also names the exact follow-up tools (llm_job_status, llm_job_result), making it easy to tell apart from synchronous siblings like devin_request.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear usage context by instructing the agent to poll with llm_job_status and collect with llm_job_result, which implies when this tool is appropriate (background, long-running work). It does not explicitly contrast with synchronous devin_request or other provider async variants, so exclusions and alternative-selection rules are absent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

explain_effective_configB
Read-only

Explain the selected Personal Agent Config release and context provenance without returning local paths or instruction text.

ParametersJSON Schema
NameRequiredDescriptionDefault
workspaceNoRegistered workspace alias for remote HTTP/OAuth provider calls. Do not use this field, workspace_list, or workspace_register_existing_repo as a fallback for stdio/local provider path access; pass workingDir/addDir/includeDirs directly instead.
workingDirNoAbsolute working directory whose Personal Agent Config Kit scope should be inspected. Relative paths are rejected so scope never depends on the gateway process cwd.
requestInstructionsNo

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true. Description adds value by specifying that local paths and instruction text are not returned, but does not elaborate further on behavior like whether it makes remote calls.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence that is concise and front-loaded. It is efficient but could add more detail without being verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, description does not specify what the returned 'explanation' looks like. It clarifies what is not returned but lacks details on the format or scope of the explanation. The three-parameter tool with one undocumented parameter adds to the gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67%. Description adds meaning to workspace (usage warnings) and workingDir (absolute path), but requestInstructions has no description in schema or description text. The description partially compensates for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states the tool explains Personal Agent Config release and provenance, with a restriction on output. However, it does not explicitly differentiate from sibling tools like config_status or config_recover_kit_attempt.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit guidance on when to use this tool versus alternatives. A note in the workspace parameter about not using it for local path access is a parameter constraint, not usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

gemini_requestA
Destructive

Run a Google Antigravity CLI (agy) request through the Gemini-compatible gateway tool synchronously (when async jobs are enabled, auto-defers to a pollable job past the sync deadline; otherwise runs to completion). Requires exactly one of prompt or promptParts.

ParametersJSON Schema
NameRequiredDescriptionDefault
yoloNoEmit `--dangerously-skip-permissions` to auto-approve all actions.
modelNoModel name or alias passed to agy --model (e.g. gemini-3-pro-preview, gemini-2.5-flash, pro, flash, latest)
promptNoPrompt text for Antigravity CLI (mutually exclusive with promptParts)
projectNoAntigravity 1.0.13 --project <ID>: select the project for this session. Mutually exclusive with newProject.
sandboxNoRun Antigravity in sandbox mode (--sandbox)
worktreeNoSlice Ī»: run this request inside a dedicated git worktree owned by the gateway. `true` creates a fresh worktree at `<repoRoot>/.worktrees/<uuid>` branched from HEAD. `{ name?, ref? }` lets the caller supply a sanitized name and/or a git ref (default: HEAD). When the request carries a sessionId and the session already has a worktree, reuse requires same-host ownership metadata and a matching live Git registration. Named path collisions never reuse manager state. Gateway-managed worktrees require the local file-backed session manager and fail closed with PostgreSQL sessions. The Grok, Devin, and Mistral adapters require an explicit provider-native sessionId; fresh, createNewSession, and resumeLatest-only worktree requests fail closed because they cannot durably reselect the worktree. The request must select a registered workspace explicitly, through caller-owned session metadata, or through the configured default. Worktrees never fall back to the gateway process cwd and cannot be combined with local workingDir, addDir, or includeDirs paths. The gateway spawns the child CLI with `cwd: <worktree-path>`; no `-w`/`--worktree` flag is ever emitted to the underlying CLI. On worktree materialization, the gateway suppresses repository, system, and global Git hooks and configured clean, smudge, and process checkout filters, sparse checkout, and lazy object fetching. Filter-dependent content such as Git LFS remains in its repository representation instead of executing host commands. On session_delete or TTL eviction the gateway hides the session and runs `git worktree remove --force`. Failed removal retains a durable cleanup-pending tombstone which blocks reuse and is retried when the file store is registered on the owning host. The tombstone is finalized only after verified Git removal. Successful responses are prefixed with `[gateway] worktree=<absolute-path>\n` so callers can use the path. For Claude approvalStrategy:mcp_managed, requesting or reusing a worktree requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1. Other adapters reject mcp_managed before launch. NOTE: callers should `.gitignore` the `.worktrees/` directory in their repo (the gateway does NOT auto-gitignore; see slice Ī» spec Q4).
sessionIdNoAntigravity conversation ID to resume (emits --conversation <id>). agy owns conversation ids; a fresh request returns no resumable sessionId, continue via resumeLatest:true.
skipTrustNoUnsupported for Antigravity CLI; true is rejected.
workspaceNoRegistered workspace alias for remote HTTP/OAuth provider calls. Do not use this field, workspace_list, or workspace_register_existing_repo as a fallback for stdio/local provider path access; pass workingDir/addDir/includeDirs directly instead.
mcpServersNoThis provider does not receive gateway-managed MCP configuration. mcpServers has no effect with legacy, and mcp_managed is rejected before launch because ambient MCP configuration cannot be isolated.
newProjectNoAntigravity 1.0.13 --new-project: create a new project for this session. Mutually exclusive with project.
workingDirNoLocal Antigravity process working directory. Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
attachmentsNoUnsupported for Antigravity CLI; non-empty values are rejected.
includeDirsNoAdditional workspace directories passed as --add-dir. Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
policyFilesNoUnsupported for Antigravity CLI; non-empty values are rejected.
promptPartsNoCache-aware structured prompt: { system?, tools?, context?, task }. Mutually exclusive with prompt. Stable parts hash into cache_state for prefix-discipline tracking.
allowedToolsNoUnsupported for Antigravity CLI; non-empty values are rejected
approvalModeNoApproval mode for legacy strategy: default leaves agy prompted, auto_edit emits --mode accept-edits, plan emits --mode plan, and yolo emits --dangerously-skip-permissions.
forceRefreshNoBypass dedup and force a fresh CLI run even if a recent identical request exists
outputFormatNoOutput format (text|json|stream-json), default text. stream-json is the only agy wire that carries the working directory, the tool list, per-tool parameters and per-step token usage; text carries none of them, so per-request usage and cost are unavailable on the default.text
printTimeoutNoAntigravity --print-timeout <DURATION>: print-mode wait timeout as a Go duration string (e.g. '5m0s', '30s').
resumeLatestNoContinue the most recent conversation. agy owns conversation ids; a fresh request returns no resumable sessionId, continue via resumeLatest:true.
correlationIdNoRequest trace ID (auto if omitted)
idleTimeoutMsNoTotal-runtime bound, not an idle timer: this provider emits no output until it exits, so the child is killed after this duration even while healthy. Min 30s, max 1h, omit=1h default.
providerFlagsNoFlags passed to the provider binary verbatim, keyed exactly as the binary spells them (e.g. {"--best-of-n": "3", "--verbatim": true, "--rules": ["a", "b"]}). Use this for any flag your installed CLI accepts that this schema does not name: the binary decides what it supports, not the gateway. true emits the flag alone; a list REPEATS the flag once per item (pass a joined string if your CLI wants a comma-separated value). Values may not start with '-', and a flag the gateway is already emitting for this request is refused rather than duplicated. LOCAL stdio callers only: remote HTTP/OAuth callers are refused every flag here and should use this tool's declared parameters, which carry their own host-path and approval gates.
approvalPolicyNoapprovalPolicy is unavailable for this provider. It has no effect with legacy, and mcp_managed is rejected before launch because ambient MCP configuration cannot be isolated.
optimizePromptNoOptimize prompt before execution
adminPolicyFilesNoUnsupported for Antigravity CLI; non-empty values are rejected.
approvalStrategyNoApproval strategy: legacy is supported. mcp_managed is rejected before launch because this adapter cannot isolate ambient MCP configuration.legacy
compressResponseNoCompress the response display text via the native compressor (default: [compression].enabled in config.toml, off unless opted in). Skipped for structured output.
createNewSessionNoForce new session
optimizeResponseNoOptimize response output

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses a non-obvious execution behavior: it runs synchronously but auto-defers to a pollable job past the sync deadline, and otherwise runs to completion. This goes beyond the annotations, which already flag the tool as non-read-only and destructive. It does not elaborate on side effects, but the destructiveHint annotation already covers that risk profile.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact — two sentences — and front-loads the primary action before the execution caveat and input requirement. Every clause earns its place, and there is no repetition of schema content or verbose context.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 32-parameter provider tool with no output schema and no explicit return-value description, the high-level description is adequate but not complete. It does not summarize what the caller gets back, what 'pollable job' means in practice, or how the destructive nature of the CLI should affect invocation choices. The rich schema covers parameter-level details, but the description leaves some operational context implicit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds value beyond the schema by stating the critical cardinality invariant: exactly one of prompt or promptParts must be supplied. That constraint is encoded in the parameter descriptions but not as a top-level schema rule, so the explicit advisory is genuinely helpful.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific action and resource: running a Google Antigravity CLI (`agy`) request through the Gemini-compatible gateway tool. It also clarifies the synchronous execution mode, which distinguishes it from the async sibling tools. The phrase 'synchronously' plus the auto-defer behavior makes the core purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives useful execution context — synchronous by default, auto-deferring to a pollable job when async jobs are enabled — but it never explicitly names the async sibling or says when to prefer it. A caller can infer the usage model, but the routing guidance is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

gemini_request_asyncA
Destructive

Start a Google Antigravity CLI (agy) request as a durable background job through the Gemini-compatible gateway tool. Poll with llm_job_status, collect with llm_job_result.

ParametersJSON Schema
NameRequiredDescriptionDefault
yoloNoEmit `--dangerously-skip-permissions` to auto-approve all actions.
modelNoModel name or alias passed to agy --model (e.g. gemini-3-pro-preview, gemini-2.5-flash, pro, flash, latest)
promptNoPrompt text for Antigravity CLI (mutually exclusive with promptParts)
projectNoAntigravity 1.0.13 --project <ID>: select the project for this session. Mutually exclusive with newProject.
sandboxNoRun Antigravity in sandbox mode (--sandbox)
worktreeNoSlice Ī»: run this request inside a dedicated git worktree owned by the gateway. `true` creates a fresh worktree at `<repoRoot>/.worktrees/<uuid>` branched from HEAD. `{ name?, ref? }` lets the caller supply a sanitized name and/or a git ref (default: HEAD). When the request carries a sessionId and the session already has a worktree, reuse requires same-host ownership metadata and a matching live Git registration. Named path collisions never reuse manager state. Gateway-managed worktrees require the local file-backed session manager and fail closed with PostgreSQL sessions. The Grok, Devin, and Mistral adapters require an explicit provider-native sessionId; fresh, createNewSession, and resumeLatest-only worktree requests fail closed because they cannot durably reselect the worktree. The request must select a registered workspace explicitly, through caller-owned session metadata, or through the configured default. Worktrees never fall back to the gateway process cwd and cannot be combined with local workingDir, addDir, or includeDirs paths. The gateway spawns the child CLI with `cwd: <worktree-path>`; no `-w`/`--worktree` flag is ever emitted to the underlying CLI. On worktree materialization, the gateway suppresses repository, system, and global Git hooks and configured clean, smudge, and process checkout filters, sparse checkout, and lazy object fetching. Filter-dependent content such as Git LFS remains in its repository representation instead of executing host commands. On session_delete or TTL eviction the gateway hides the session and runs `git worktree remove --force`. Failed removal retains a durable cleanup-pending tombstone which blocks reuse and is retried when the file store is registered on the owning host. The tombstone is finalized only after verified Git removal. Successful responses are prefixed with `[gateway] worktree=<absolute-path>\n` so callers can use the path. For Claude approvalStrategy:mcp_managed, requesting or reusing a worktree requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1. Other adapters reject mcp_managed before launch. NOTE: callers should `.gitignore` the `.worktrees/` directory in their repo (the gateway does NOT auto-gitignore; see slice Ī» spec Q4).
sessionIdNoAntigravity conversation ID to resume (emits --conversation <id>). agy owns conversation ids; a fresh request returns no resumable sessionId, continue via resumeLatest:true.
skipTrustNoUnsupported for Antigravity CLI; true is rejected.
workspaceNoRegistered workspace alias for remote HTTP/OAuth provider calls. Do not use this field, workspace_list, or workspace_register_existing_repo as a fallback for stdio/local provider path access; pass workingDir/addDir/includeDirs directly instead.
mcpServersNoThis provider does not receive gateway-managed MCP configuration. mcpServers has no effect with legacy, and mcp_managed is rejected before launch because ambient MCP configuration cannot be isolated.
newProjectNoAntigravity 1.0.13 --new-project: create a new project for this session. Mutually exclusive with project.
workingDirNoLocal Antigravity process working directory. Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
attachmentsNoUnsupported for Antigravity CLI; non-empty values are rejected.
includeDirsNoAdditional workspace directories passed as --add-dir. Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
policyFilesNoUnsupported for Antigravity CLI; non-empty values are rejected.
promptPartsNoCache-aware structured prompt: { system?, tools?, context?, task }. Mutually exclusive with prompt. Stable parts hash into cache_state for prefix-discipline tracking.
allowedToolsNoUnsupported for Antigravity CLI; non-empty values are rejected
approvalModeNoApproval mode for legacy strategy: default leaves agy prompted, auto_edit emits --mode accept-edits, plan emits --mode plan, and yolo emits --dangerously-skip-permissions.
forceRefreshNoBypass dedup and force a fresh CLI run even if a recent identical request exists
outputFormatNoOutput format (text|json|stream-json), default text. stream-json is the only agy wire that carries the working directory, the tool list, per-tool parameters and per-step token usage; text carries none of them, so per-request usage and cost are unavailable on the default.text
printTimeoutNoAntigravity --print-timeout <DURATION>: print-mode wait timeout as a Go duration string (e.g. '5m0s', '30s').
resumeLatestNoContinue the most recent conversation. agy owns conversation ids; a fresh request returns no resumable sessionId, continue via resumeLatest:true.
correlationIdNoRequest trace ID (auto if omitted)
idleTimeoutMsNoTotal-runtime bound, not an idle timer: this provider emits no output until it exits, so the child is killed after this duration even while healthy. Min 30s, max 1h, omit=1h default.
providerFlagsNoFlags passed to the provider binary verbatim, keyed exactly as the binary spells them (e.g. {"--best-of-n": "3", "--verbatim": true, "--rules": ["a", "b"]}). Use this for any flag your installed CLI accepts that this schema does not name: the binary decides what it supports, not the gateway. true emits the flag alone; a list REPEATS the flag once per item (pass a joined string if your CLI wants a comma-separated value). Values may not start with '-', and a flag the gateway is already emitting for this request is refused rather than duplicated. LOCAL stdio callers only: remote HTTP/OAuth callers are refused every flag here and should use this tool's declared parameters, which carry their own host-path and approval gates.
approvalPolicyNoapprovalPolicy is unavailable for this provider. It has no effect with legacy, and mcp_managed is rejected before launch because ambient MCP configuration cannot be isolated.
optimizePromptNoOptimize prompt before execution
adminPolicyFilesNoUnsupported for Antigravity CLI; non-empty values are rejected.
approvalStrategyNoApproval strategy: legacy is supported. mcp_managed is rejected before launch because this adapter cannot isolate ambient MCP configuration.legacy
compressResponseNoCompress the response display text when collected via llm_job_result (native compressor; default: [compression].enabled).
createNewSessionNoForce new session

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal destructiveHint=true, readOnlyHint=false, and idempotentHint=false. The description adds the 'durable background job' framing and the poll/collect lifecycle, which is helpful. But it does not disclose what side effects occur during execution, cost implications, or what happens to in-flight work after cancellation or failure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler: the core action is stated first, and the necessary follow-up tools are named. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 31-parameter async tool with no output schema, the description explains how to start and how to poll/collect, but it does not state what the initial call returns (e.g., a job ID). It also relies heavily on the schema to communicate major caveats like rejected parameters and worktree behavior, leaving the top-level description thin for such a complex tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the input schema already documents all 31 parameters in detail, including mutual exclusions and rejected values. The scalar description adds no parameter-level information, which is acceptable given the complete schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Start'), a specific resource ('Google Antigravity CLI (`agy`) request'), and a distinct execution mode ('durable background job'). This clearly differentiates it from the synchronous gemini_request tool and from other providers' async tools by naming the Gemini/agy scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives concrete follow-up guidance ('Poll with llm_job_status, collect with llm_job_result'), which is useful. However, it does not explicitly say when to choose this async tool over gemini_request or other provider async tools, and it offers no exclusions or alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

grok_requestA
Destructive

Run an xAI Grok CLI request synchronously (when async jobs are enabled, auto-defers to a pollable job past the sync deadline; otherwise runs to completion). Requires exactly one of prompt or promptParts.

ParametersJSON Schema
NameRequiredDescriptionDefault
denyNoGrok --deny <RULE>: permission deny rules. Each entry is emitted as its own --deny instance (per `grok --help`: "Repeat to add multiple rules").
agentNoGrok --agent <NAME>: agent name or definition file path.
allowNoGrok --allow <RULE>: permission allow rules. Each entry is emitted as its own --allow instance (per `grok --help`: "Repeat to add multiple rules").
checkNoGrok --check: append a self-verification loop to the prompt (headless only). Not advertised by grok 1.0.4+; passed through for older installs.
modelNoModel name or alias (e.g. grok-4.5, latest)
oauthNoGrok --oauth: use OAuth during authentication.
rulesNoGrok --rules <RULES>: extra rules to append to the system prompt. Supports `@file` prefix per `grok --help` to load from a file; gateway passes the value verbatim and lets Grok parse the prefix.
agentsNoGrok --agents <JSON>: inline subagent definitions (JSON string or name → { description, prompt, … } map).
effortNoGrok effort level. Known values: low, medium, high, xhigh, max. Your installed grok decides what it accepts; these are not enforced.
noPlanNoGrok --no-plan: disable plan mode.
promptNoPrompt text for Grok (mutually exclusive with promptParts)
bestOfNNoGrok --best-of-n <N>: run the task N ways in parallel and pick the best (headless only). Not advertised by grok 1.0.4+; passed through for older installs.
sandboxNoGrok --sandbox <PROFILE>: sandbox profile for filesystem and network access. Freeform per `grok --help` (no enum constraint on Grok 0.1.210); also settable via GROK_SANDBOX env var. Caller responsibility to pass a valid profile name.
maxTurnsNoGrok `--max-turns N`: cap on agent-loop iterations for cost / latency control (Phase 4 slice Ī“). Bounded to safe integers ≤ 10000.
noMemoryNoGrok --no-memory: disable cross-session memory.
todoGateNoGrok --todo-gate: enable runtime turn-end TodoGate for this session (session-scoped, not persisted).
verbatimNoGrok --verbatim: send the prompt exactly as given. Also skips gateway optimizePrompt when true.
worktreeNoSlice Ī»: run this request inside a dedicated git worktree owned by the gateway. `true` creates a fresh worktree at `<repoRoot>/.worktrees/<uuid>` branched from HEAD. `{ name?, ref? }` lets the caller supply a sanitized name and/or a git ref (default: HEAD). When the request carries a sessionId and the session already has a worktree, reuse requires same-host ownership metadata and a matching live Git registration. Named path collisions never reuse manager state. Gateway-managed worktrees require the local file-backed session manager and fail closed with PostgreSQL sessions. The Grok, Devin, and Mistral adapters require an explicit provider-native sessionId; fresh, createNewSession, and resumeLatest-only worktree requests fail closed because they cannot durably reselect the worktree. The request must select a registered workspace explicitly, through caller-owned session metadata, or through the configured default. Worktrees never fall back to the gateway process cwd and cannot be combined with local workingDir, addDir, or includeDirs paths. The gateway spawns the child CLI with `cwd: <worktree-path>`; no `-w`/`--worktree` flag is ever emitted to the underlying CLI. On worktree materialization, the gateway suppresses repository, system, and global Git hooks and configured clean, smudge, and process checkout filters, sparse checkout, and lazy object fetching. Filter-dependent content such as Git LFS remains in its repository representation instead of executing host commands. On session_delete or TTL eviction the gateway hides the session and runs `git worktree remove --force`. Failed removal retains a durable cleanup-pending tombstone which blocks reuse and is retried when the file store is registered on the owning host. The tombstone is finalized only after verified Git removal. Successful responses are prefixed with `[gateway] worktree=<absolute-path>\n` so callers can use the path. For Claude approvalStrategy:mcp_managed, requesting or reusing a worktree requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1. Other adapters reject mcp_managed before launch. NOTE: callers should `.gitignore` the `.worktrees/` directory in their repo (the gateway does NOT auto-gitignore; see slice Ī» spec Q4).
sessionIdNoOn transport=cli, provider-native session ID to resume (emits --resume <id>; use resumeLatest for --continue); gateway gw-* tracking ids are not CLI session ids. On transport=acp, gateway-owned ACP session ID returned by an earlier ACP call; provider-native and CLI session ids are rejected.
transportNoTransport: 'cli' (default) runs the Grok CLI. 'acp' routes through `grok agent stdio` only when [acp].enabled plus [acp.providers.grok].enabled and runtime_enabled are true (fails closed otherwise). ACP accepts prompt, model, a gateway ACP sessionId, and a registered workspace alias; Grok CLI-only controls are rejected.cli
workspaceNoRegistered workspace alias for remote HTTP/OAuth provider calls. Do not use this field, workspace_list, or workspace_register_existing_repo as a fallback for stdio/local provider path access; pass workingDir/addDir/includeDirs directly instead.
jsonSchemaNoGrok 0.2.73 --json-schema: constrain output to a JSON Schema (string literal or object; implies json output). Set outputFormat:json so the gateway treats the reply as structured output (skips response optimization and warning injection); the default output format is not json, so pass it explicitly.
mcpServersNoThis provider does not receive gateway-managed MCP configuration. mcpServers has no effect with legacy, and mcp_managed is rejected before launch because ambient MCP configuration cannot be isolated.
promptFileNoGrok --prompt-file <PATH>: single-turn prompt loaded from a file.
promptJsonNoGrok --prompt-json <JSON>: single-turn prompt JSON blocks (string or serializable value).
workingDirNoGrok --cwd <DIR>: working directory for this invocation. Lets headless callers run Grok against a directory other than the gateway process's cwd.
forkSessionNoGrok 0.2.73 --fork-session: when resuming (--resume/--continue), fork into a new session ID instead of reusing the original.
noAltScreenNoGrok --no-alt-screen: run inline without alt screen.
noSubagentsNoGrok --no-subagents: disable subagent spawning.
promptPartsNoCache-aware structured prompt: { system?, tools?, context?, task }. Mutually exclusive with prompt. Stable parts hash into cache_state for prefix-discipline tracking.
restoreCodeNoGrok --restore-code: check out the original session commit when resuming.
worktreeRefNoGrok 0.2.73 --worktree-ref <REF>: git ref (branch/tag/commit) to base the native worktree on. Requires nativeWorktree.
allowedToolsNoAllowed built-in tools (passed as --tools comma list)
forceRefreshNoBypass dedup and force a fresh CLI run even if a recent identical request exists
leaderSocketNoGrok 0.2.32+ --leader-socket <PATH>: custom leader socket path (default ~/.grok/leader.sock). Targets an isolated leader process, e.g. a local/branch Grok build; name it ~/.grok/leader-*.sock to keep `grok leader list/kill` discovery working.
outputFormatNoOutput format for headless mode. Grok default is plain. The gateway parses json and streaming-json; other formats are passed through as raw output.
resumeLatestNoResume the most recent Grok session in cwd (--continue) on transport=cli. true is rejected on transport=acp.
alwaysApproveNoAuto-approve all tool executions (--always-approve).
correlationIdNoRequest trace ID (auto if omitted)
idleTimeoutMsNoIdle timeout in ms (min 30s, max 1h). Omit = gateway default of 600000ms (10 min) with no output before the process is killed.
providerFlagsNoFlags passed to the provider binary verbatim, keyed exactly as the binary spells them (e.g. {"--best-of-n": "3", "--verbatim": true, "--rules": ["a", "b"]}). Use this for any flag your installed CLI accepts that this schema does not name: the binary decides what it supports, not the gateway. true emits the flag alone; a list REPEATS the flag once per item (pass a joined string if your CLI wants a comma-separated value). Values may not start with '-', and a flag the gateway is already emitting for this request is refused rather than duplicated. LOCAL stdio callers only: remote HTTP/OAuth callers are refused every flag here and should use this tool's declared parameters, which carry their own host-path and approval gates.
approvalPolicyNoOn transport=cli, approvalPolicy has no effect because mcp_managed is unavailable. On transport=acp, supplying approvalPolicy is rejected because ACP has its own permission bridge.
compactionModeNoGrok --compaction-mode: summary (default; no pointer) | transcript (points at the raw transcript) | segments (persists per-segment markdown to grep). Sets GROK_COMPACTION_MODE.
nativeWorktreeNoGrok -w/--worktree: native CLI worktree flag (`true` → bare `--worktree`, string → named). NOT gateway slice Ī» `worktree`.
optimizePromptNoOptimize prompt before execution
permissionModeNoGrok permission mode: default|acceptEdits|auto|dontAsk|bypassPermissions|plan.
disallowedToolsNoDisallowed built-in tools (passed as --disallowed-tools comma list)
reasoningEffortNoReasoning effort for reasoning models. Known values: low, medium, high, xhigh, max. Not enforced; the installed binary decides.
approvalStrategyNoApproval strategy. legacy is supported. mcp_managed is rejected before Grok launches because the CLI adapter cannot isolate ambient MCP configuration; transport=acp has its own permission bridge and also rejects mcp_managed.legacy
compactionDetailNoGrok --compaction-detail: verbatim segment detail (none|minimal|balanced|verbose, default verbose). Only affects `--compaction-mode segments`. Sets GROK_COMPACTION_DETAIL.
compressResponseNoCompress the response display text via the native compressor (default: [compression].enabled in config.toml, off unless opted in). Skipped for structured output.
createNewSessionNoForce a new session on transport=cli. true is rejected on transport=acp.
disableWebSearchNoGrok --disable-web-search: disable web search and remote retrieval tools.
optimizeResponseNoOptimize response output
experimentalMemoryNoGrok --experimental-memory: enable cross-session memory.
systemPromptOverrideNoGrok --system-prompt-override <PROMPT>: replace the agent's system prompt entirely. Distinct from Claude's --system-prompt / --append-system-prompt (Grok has only one override flag, not a pair).

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry the safety profile (destructiveHint=true, readOnlyHint=false, openWorldHint=true), so the bar is lower and no contradiction exists. The description adds genuine behavioral context beyond annotations: the synchronous execution mode, the auto-deferral to a pollable job past the sync deadline, and the exactly-one-of-prompt requirement. It does not detail output or failure behavior, but its added value over annotations justifies a 4.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly packed sentences with zero waste: core purpose front-loaded first, the async-deferral nuance second, and the mandatory requirement last. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 56-parameter tool with nested objects and no output schema, the description is thin. With no output schema, the description carries the burden of explaining return values, yet it never states what the caller receives (raw output, parsed JSON, job reference, error behavior), nor does it address transport selection, the sync deadline value, or failure modes at the tool level. The schema covers parameters richly, but the high-level invocation contract is incomplete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3 with the schema doing the heavy lifting. The description adds the 'exactly one of prompt or promptParts' constraint, but this mutual exclusion is already stated in both parameter descriptions. It introduces no new parameter meaning beyond what the schema documents.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Run an xAI Grok CLI request synchronously') and clarifies the execution mode. The provider (xAI Grok), the sync/async distinction, and the mandatory prompt/promptParts requirement sharply distinguish it from siblings like grok_request_async, claude_request, and the other provider request tools without needing to open the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context on execution mode: the tool auto-defers to a pollable job past the sync deadline when async jobs are enabled, otherwise runs to completion. This effectively tells an agent when the call becomes async-like, but it never names grok_request_async as the explicit alternative for guaranteed-async cases, nor does it state when-not-to-use this tool. Clear context, no explicit exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

grok_request_asyncA
Destructive

Start an xAI Grok CLI request as a durable background job. Poll with llm_job_status, collect with llm_job_result.

ParametersJSON Schema
NameRequiredDescriptionDefault
denyNoGrok --deny <RULE>: permission deny rules. Each entry → its own --deny instance.
agentNoGrok --agent <NAME>: agent name or definition file path.
allowNoGrok --allow <RULE>: permission allow rules. Each entry → its own --allow instance.
checkNoGrok --check: append a self-verification loop to the prompt (headless only). Not advertised by grok 1.0.4+; passed through for older installs.
modelNoModel name or alias (e.g. grok-4.5, latest)
oauthNoGrok --oauth: use OAuth during authentication.
rulesNoGrok --rules <RULES>: extra rules to append to the system prompt. Supports `@file` prefix; gateway passes the value verbatim.
agentsNoGrok --agents <JSON>: inline subagent definitions (JSON string or name → { description, prompt, … } map).
effortNoGrok effort level. Known values: low, medium, high, xhigh, max. Your installed grok decides what it accepts; these are not enforced.
noPlanNoGrok --no-plan: disable plan mode.
promptNoPrompt text for Grok (mutually exclusive with promptParts)
bestOfNNoGrok --best-of-n <N>: run the task N ways in parallel and pick the best (headless only). Not advertised by grok 1.0.4+; passed through for older installs.
sandboxNoGrok --sandbox <PROFILE>: sandbox profile for filesystem and network access. Freeform per `grok --help` (no enum constraint); also settable via GROK_SANDBOX env var.
maxTurnsNoGrok `--max-turns N`: cap on agent-loop iterations for cost / latency control (Phase 4 slice Ī“). Bounded to safe integers ≤ 10000.
noMemoryNoGrok --no-memory: disable cross-session memory.
todoGateNoGrok --todo-gate: enable runtime turn-end TodoGate for this session (session-scoped, not persisted).
verbatimNoGrok --verbatim: send the prompt exactly as given. Also skips gateway optimizePrompt when true.
worktreeNoSlice Ī»: run this request inside a dedicated git worktree owned by the gateway. `true` creates a fresh worktree at `<repoRoot>/.worktrees/<uuid>` branched from HEAD. `{ name?, ref? }` lets the caller supply a sanitized name and/or a git ref (default: HEAD). When the request carries a sessionId and the session already has a worktree, reuse requires same-host ownership metadata and a matching live Git registration. Named path collisions never reuse manager state. Gateway-managed worktrees require the local file-backed session manager and fail closed with PostgreSQL sessions. The Grok, Devin, and Mistral adapters require an explicit provider-native sessionId; fresh, createNewSession, and resumeLatest-only worktree requests fail closed because they cannot durably reselect the worktree. The request must select a registered workspace explicitly, through caller-owned session metadata, or through the configured default. Worktrees never fall back to the gateway process cwd and cannot be combined with local workingDir, addDir, or includeDirs paths. The gateway spawns the child CLI with `cwd: <worktree-path>`; no `-w`/`--worktree` flag is ever emitted to the underlying CLI. On worktree materialization, the gateway suppresses repository, system, and global Git hooks and configured clean, smudge, and process checkout filters, sparse checkout, and lazy object fetching. Filter-dependent content such as Git LFS remains in its repository representation instead of executing host commands. On session_delete or TTL eviction the gateway hides the session and runs `git worktree remove --force`. Failed removal retains a durable cleanup-pending tombstone which blocks reuse and is retried when the file store is registered on the owning host. The tombstone is finalized only after verified Git removal. Successful responses are prefixed with `[gateway] worktree=<absolute-path>\n` so callers can use the path. For Claude approvalStrategy:mcp_managed, requesting or reusing a worktree requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1. Other adapters reject mcp_managed before launch. NOTE: callers should `.gitignore` the `.worktrees/` directory in their repo (the gateway does NOT auto-gitignore; see slice Ī» spec Q4).
sessionIdNoProvider-native session ID to resume (emits --resume <id>; use resumeLatest for --continue). Note: the gw-* id minted for a brand-new session is not resumable via sessionId; continue with resumeLatest:true.
workspaceNoRegistered workspace alias for remote HTTP/OAuth provider calls. Do not use this field, workspace_list, or workspace_register_existing_repo as a fallback for stdio/local provider path access; pass workingDir/addDir/includeDirs directly instead.
jsonSchemaNoGrok 0.2.73 --json-schema: constrain output to a JSON Schema (string literal or object; implies json output). Set outputFormat:json so the gateway treats the reply as structured output (skips response optimization and warning injection); the default output format is not json, so pass it explicitly.
mcpServersNoThis provider does not receive gateway-managed MCP configuration. mcpServers has no effect with legacy, and mcp_managed is rejected before launch because ambient MCP configuration cannot be isolated.
promptFileNoGrok --prompt-file <PATH>: single-turn prompt loaded from a file.
promptJsonNoGrok --prompt-json <JSON>: single-turn prompt JSON blocks (string or serializable value).
workingDirNoGrok --cwd <DIR>: working directory for this invocation. Lets headless callers run Grok against a directory other than the gateway process's cwd. Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
forkSessionNoGrok 0.2.73 --fork-session: when resuming (--resume/--continue), fork into a new session ID instead of reusing the original.
noAltScreenNoGrok --no-alt-screen: run inline without alt screen.
noSubagentsNoGrok --no-subagents: disable subagent spawning.
promptPartsNoCache-aware structured prompt: { system?, tools?, context?, task }. Mutually exclusive with prompt. Stable parts hash into cache_state for prefix-discipline tracking.
restoreCodeNoGrok --restore-code: check out the original session commit when resuming.
worktreeRefNoGrok 0.2.73 --worktree-ref <REF>: git ref (branch/tag/commit) to base the native worktree on. Requires nativeWorktree.
allowedToolsNoAllowed built-in tools (passed as --tools comma list)
forceRefreshNoBypass dedup and force a fresh CLI run even if a recent identical request exists
leaderSocketNoGrok 0.2.32+ --leader-socket <PATH>: custom leader socket path (default ~/.grok/leader.sock). Targets an isolated leader process, e.g. a local/branch Grok build; name it ~/.grok/leader-*.sock to keep `grok leader list/kill` discovery working.
outputFormatNoOutput format for headless mode. Grok default is plain. The gateway parses json and streaming-json; other formats are passed through as raw output.
resumeLatestNoResume most recent Grok session in cwd (--continue). Note: the gw-* id minted for a brand-new session is not resumable via sessionId; continue with resumeLatest:true.
alwaysApproveNoAuto-approve all tool executions (--always-approve).
correlationIdNoRequest trace ID (auto if omitted)
idleTimeoutMsNoIdle timeout in ms (min 30s, max 1h). Omit = gateway default of 600000ms (10 min) with no output before the process is killed.
providerFlagsNoFlags passed to the provider binary verbatim, keyed exactly as the binary spells them (e.g. {"--best-of-n": "3", "--verbatim": true, "--rules": ["a", "b"]}). Use this for any flag your installed CLI accepts that this schema does not name: the binary decides what it supports, not the gateway. true emits the flag alone; a list REPEATS the flag once per item (pass a joined string if your CLI wants a comma-separated value). Values may not start with '-', and a flag the gateway is already emitting for this request is refused rather than duplicated. LOCAL stdio callers only: remote HTTP/OAuth callers are refused every flag here and should use this tool's declared parameters, which carry their own host-path and approval gates.
approvalPolicyNoapprovalPolicy is unavailable for this provider. It has no effect with legacy, and mcp_managed is rejected before launch because ambient MCP configuration cannot be isolated.
compactionModeNoGrok --compaction-mode: summary (default) | transcript | segments. Sets GROK_COMPACTION_MODE.
nativeWorktreeNoGrok -w/--worktree: native CLI worktree flag (`true` → bare `--worktree`, string → named). NOT gateway slice Ī» `worktree`.
optimizePromptNoOptimize prompt before execution
permissionModeNoGrok permission mode: default|acceptEdits|auto|dontAsk|bypassPermissions|plan.
disallowedToolsNoDisallowed built-in tools (passed as --disallowed-tools comma list)
reasoningEffortNoReasoning effort for reasoning models. Known values: low, medium, high, xhigh, max. Not enforced; the installed binary decides.
approvalStrategyNoApproval strategy: legacy is supported. mcp_managed is rejected before launch because this adapter cannot isolate ambient MCP configuration.legacy
compactionDetailNoGrok --compaction-detail: segment verbatim detail (none|minimal|balanced|verbose, default verbose). Only affects segments mode. Sets GROK_COMPACTION_DETAIL.
compressResponseNoCompress the response display text when collected via llm_job_result (native compressor; default: [compression].enabled).
createNewSessionNoForce new session
disableWebSearchNoGrok --disable-web-search: disable web search and remote retrieval tools.
experimentalMemoryNoGrok --experimental-memory: enable cross-session memory.
systemPromptOverrideNoGrok --system-prompt-override <PROMPT>: replace the agent's system prompt entirely.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry the safety profile (readOnlyHint=false, destructiveHint=true, idempotentHint=false, openWorldHint=true), and the description does not contradict them. It adds modest value beyond annotations by disclosing the durable-background-job behavior and the poll/collect protocol, but omits details like immediate return shape, job retention/expiry, or the cancellation path (llm_job_cancel exists as a sibling).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with zero wasted words. The verb and resource are front-loaded, and the lifecycle pointers occupy the second sentence. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The schema richly documents the parameter surface and annotations cover the safety profile, so the description only needs to cover the async job lifecycle — which it does by naming the poll and collect tools. It is adequate but has clear gaps: no output schema exists and the description never states what the call immediately returns (e.g., a job ID), nor does it mention failure or cancellation behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% — all 54 parameters, many complex, are individually documented in the schema, so the baseline of 3 applies. The description contributes no parameter-level meaning, which is acceptable because the schema fully carries that burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Start'), a resource ('xAI Grok CLI request'), and a distinguishing mode ('durable background job'), which clearly separates it from the synchronous grok_request sibling and from other providers' *_request_async tools. It also names the lifecycle tools (llm_job_status, llm_job_result), making the async job pattern explicit. An agent can tell what this tool does without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when this tool fits: when a durable background job is desired, followed by explicit polling (llm_job_status) and collection (llm_job_result) steps. However, it does not state exclusions or compare against the synchronous grok_request alternative (e.g., when to prefer async over sync), leaving that routing decision implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

job_resultA
Read-onlyIdempotent

Collect a VALIDATION job's normalized provider output — distinct from llm_job_result, which returns raw provider request job output.

ParametersJSON Schema
NameRequiredDescriptionDefault
jobIdYesValidation job ID.
maxCharsNoMaximum result size.
providerNoProvider that produced the job, used for normalized validation output.

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds the important normalized-vs-raw distinction but does not disclose lifecycle requirements, error behavior, or pagination/truncation behavior. This is acceptable but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler. It states the core behavior first and then adds the distinguishing contrast with llm_job_result. Every part earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the strong annotations, complete parameter descriptions, and straightforward retrieval nature, the description is mostly sufficient. It clarifies the output category (normalized provider output) but does not describe the exact return shape or whether the job must be completed before calling; this is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so each parameter is already documented in the schema. The description re-emphasizes that this is a validation job result and mentions 'normalized provider output', but it does not add significant meaning beyond what the parameter descriptions provide. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Collect') and resource ('a VALIDATION job's normalized provider output'), making the tool's function clear. It explicitly distinguishes itself from llm_job_result, so an agent can tell them apart without inspecting schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description names the relevant alternative (llm_job_result) and explains the key distinction: normalized validation output vs raw provider request job output. This gives the agent a clear selection rule for choosing between the two tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

job_statusA
Read-onlyIdempotent

Check a VALIDATION job's status (jobs started by validate_with_models/ask_model/etc.) — distinct from llm_job_status, which tracks provider request jobs.

ParametersJSON Schema
NameRequiredDescriptionDefault
jobIdYesValidation job ID.

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false. The description adds the job-family scope and sibling distinction, but does not describe output format, polling behavior, or possible errors. With annotation coverage, this is acceptable but not especially rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence that front-loads the key verb and resource, clarifies scope in a parenthetical, and closes with a precise sibling distinction. No filler or redundant restating of the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read-only status tool with full schema coverage and strong annotations, the description is complete. It tells the agent exactly what kind of job to query and which sibling to use for provider request jobs.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema already explains jobId as 'Validation job ID.' The description reinforces the validation-job context but adds no format, source, or lookup details beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Check'), names the exact resource ('a VALIDATION job's status'), and explicitly distinguishes itself from llm_job_status. An agent can immediately tell what this tool does and how it differs from its closest sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states which jobs are relevant (jobs started by validate_with_models/ask_model/etc.) and explicitly contrasts with llm_job_status for provider request jobs. This gives the agent a clear when-to-use vs. when-not-to-use rule with a named alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_available_modelsA
Read-onlyIdempotent

List models and capabilities for every available provider CLI (takes no arguments; complements per-provider list_models).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds that it covers every available provider CLI and takes no arguments, but it does not disclose behavioral details such as how 'available' is determined, whether provider CLIs are probed at runtime, or what happens when no providers are installed. This is acceptable but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence that leads with the action and resource, includes the no-argument note, and clarifies the relationship to a sibling tool. Every clause earns its place with no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a no-argument, read-only, idempotent listing tool, the description along with the annotations is complete. It states what is listed, the scope, the no-input requirement, and how it relates to the per-provider alternative. There is no missing information an agent would need to select or invoke this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With zero parameters and a schema description coverage of 100%, the schema already fully defines the input. The description adds the useful explicit statement 'takes no arguments', which reinforces the empty schema, but it does not add meaning beyond that, so the 0-parameter baseline of 4 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('List') and a clear resource ('models and capabilities for every available provider CLI'). It also explicitly distinguishes itself from the sibling 'list_models' by framing itself as the cross-provider complement, so an agent can tell the tools apart.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'complements per-provider list_models' clearly signals when to use this tool: when you need a cross-provider overview rather than a single provider's list. It could be even stronger with explicit when-not-to-use language, but the context is clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_modelsB
Read-onlyIdempotent

List models, aliases, and defaults for one provider (claude|codex|gemini|grok|mistral|devin|cursor, or an enabled API provider name), or omit cli to list all providers. API providers are returned under an apiProviders array.

ParametersJSON Schema
NameRequiredDescriptionDefault
cliNoProvider filter (claude|codex|gemini|grok|mistral|devin|cursor, or an enabled API provider name)

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already cover the read-only, idempotent, non-destructive nature of the tool. The description adds one useful detail: API providers are returned under an apiProviders array. It does not describe further behavioral aspects like ordering or how aliases/defaults are structured, but given the annotation coverage this is adequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is short and front-loaded with the core operation and filter behavior, and the apiProviders note adds useful return-structure context. The enumerated provider list duplicates the schema enum somewhat, but the overall size is still appropriate.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only tool with one optional parameter, the core usage is adequately covered. However, with no output schema, the description only partially explains the result shape and does not distinguish this tool from list_available_models, leaving some ambiguity for an agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already documents the single cli parameter with an enum and description, so the baseline would be 3. However, the description's phrase 'or an enabled API provider name' conflicts with the enum, which only allows the seven listed values. This is misleading and could cause an agent to submit a value that fails schema validation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies a read-only listing operation over models, aliases, and defaults, and explains the optional provider filter. It is specific about the resource and scope, but it does not differentiate itself from the sibling tool list_available_models, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear parameter-level guidance: pass a provider name to filter, or omit it to list all providers. However, it provides no guidance on when to use this tool instead of the similarly named sibling list_available_models, leaving tool selection partly implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

llm_job_cancelA
DestructiveIdempotent

Cancel a running gateway async or deferred-sync job by jobId.

ParametersJSON Schema
NameRequiredDescriptionDefault
jobIdYesAsync job ID from *_request_async

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate destructiveHint=true and idempotentHint=true. The description adds that the tool cancels 'running' jobs and applies to 'gateway async or deferred-sync' jobs, providing useful context beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, clear sentence with no extraneous information, efficiently conveying the tool's purpose and required parameter.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has only one parameter, no output schema, and comprehensive annotations, the description adequately covers all necessary details for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% for the single required parameter jobId, and the description merely repeats 'by jobId' without adding additional semantics beyond the schema's description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Cancel', the resource 'gateway async or deferred-sync job', and the method 'by jobId'. It distinguishes this tool from sibling read-oriented tools like job_status and job_result.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when a job needs to be stopped, but does not explicitly state when not to use it or suggest alternative tools for checking job state first.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

llm_job_resultA
Read-onlyIdempotent

Retrieve captured stdout/stderr for a gateway async or deferred-sync job by jobId. Use rawOutput:true with independent stream offsets for resumable pages.

ParametersJSON Schema
NameRequiredDescriptionDefault
jobIdYesAsync job ID from *_request_async
maxCharsNoMaximum chars returned per stdout/stderr page
rawOutputNoReturn captured provider streams without display parsing or compression. Available only to local stdio callers. Required for resumable offsets.
stderrOffsetCharsNoCaptured stderr character offset for resumable retrieval. Non-zero offsets require rawOutput:true.
stdoutOffsetCharsNoCaptured stdout character offset for resumable retrieval. Non-zero offsets require rawOutput:true.
nativeTranscriptOffsetCharsNoProvider-native transcript character offset for resumable retrieval. Non-zero offsets require rawOutput:true.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the bar is low. The description adds behavioral context beyond those annotations: the tool serves both async and deferred-sync jobs and supports independent per-stream offset resumption across pages. No contradiction with the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero waste: the first states the purpose, the second states the critical usage mode. The most important operational detail (rawOutput:true for resumable offsets) is front-loaded right after the purpose statement.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only tool with rich annotations (four hints) and fully documented parameters, the description is mostly sufficient, and the return content is reasonably hinted by 'captured stdout/stderr'. However, with no output schema and a sibling list containing near-duplicates (llm_request_result, job_result), the absence of disambiguation or return-structure guidance leaves the definition incomplete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and each of the six parameters is thoroughly documented in the schema itself, including the rawOutput:true prerequisite for non-zero offsets. The description adds only a thin conceptual framing — linking rawOutput and offsets to 'resumable pages' — which is helpful context but not new parameter-level meaning. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('Retrieve'), a precise resource ('captured stdout/stderr for a gateway async or deferred-sync job'), and the key selector (jobId). It reads distinctly from status/watch/cancel siblings, but never explicitly disambiguates from the near-identical llm_request_result and job_result tools that appear in the sibling list.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is clear in-tool guidance — 'Use rawOutput:true with independent stream offsets for resumable pages' — which tells the agent how to invoke the resumable mode. However, nothing states when to select this tool over close siblings like llm_request_result, job_result, or llm_job_status, which is a significant gap given the large sibling set.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

llm_job_statusA
Read-onlyIdempotent

Check lifecycle status and bounded privacy-safe normalized progress for a gateway async or deferred-sync job by jobId.

ParametersJSON Schema
NameRequiredDescriptionDefault
jobIdYesAsync job ID from *_request_async
progressLimitNoMaximum next normalized progress events to return in forward sequence order
afterProgressSeqNoReturn normalized progress events with a sequence greater than this value

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnly, idempotent, non-destructive behavior, so the bar is lower. The description adds that progress is normalized, bounded, and privacy-safe, but it does not explain lifecycle semantics, retention, or error behavior. This is useful but not rich context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, well-ordered sentence places the action and resource first, then qualifies the response. Every phrase ('lifecycle status', 'bounded', 'privacy-safe', 'normalized progress') earns its place without repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given full schema parameter documentation and annotations covering the safety profile, the description is mostly sufficient: it states what is returned (lifecycle status and normalized progress). The only gap is lack of explicit guidance for choosing among the closely related job_status, llm_job_watch, llm_job_result, and llm_request_result siblings.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and all three parameters are individually documented (jobId source, progressLimit bound, afterProgressSeq cursor). The description does not need to compensate, and it does not add parameter detail beyond what the schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Check') and names the resource precisely: lifecycle status and normalized progress for a gateway async or deferred-sync job by jobId. This separates it from generic job_status and result-retrieval siblings by emphasizing normalized, bounded progress rather than raw results.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the use case—querying by jobId to poll status/progress on async or deferred-sync jobs—but never names alternatives or states when not to use it. With many siblings like llm_job_watch, llm_job_result, and job_status, explicit routing would be stronger.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

llm_job_watchB
Read-onlyIdempotent

Wait briefly for privacy-safe normalized progress on an owned async job. When the MCP request carries a progress token, notifications are emitted only while this watch request remains active.

ParametersJSON Schema
NameRequiredDescriptionDefault
jobIdYesAsync job ID from *_request_async
waitMsNo
progressLimitNo
afterProgressSeqNo

TDQS

B3.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint false. The description adds behavioral context beyond those annotations: notifications are ephemeral and only delivered while the watch request remains active, and the progress is privacy-safe and normalized. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences carry the core purpose and an important behavioral condition without excessive length. The phrase 'privacy-safe normalized progress' is somewhat jargon-heavy but the overall structure is tight and front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a basic invocation with just jobId, the description is probably sufficient. However, with no output schema and unclear semantics for progressLimit and afterProgressSeq, the definition is incomplete for nuanced use and does not explain what notifications or return values actually contain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 25%, with only jobId documented. The description does not explain waitMs, progressLimit, or afterProgressSeq, and does not describe how they influence the watching behavior. With low schema coverage, the description needed to compensate but largely did not.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific action ('Wait briefly') and a specific resource ('progress on an owned async job'), and adds the key distinction of notifications being emitted only while the watch request is active. It is clear enough to separate from llm_job_status and llm_job_result, though it does not explicitly name those alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use it: when the MCP request carries a progress token and the caller wants live progress notifications. However, it does not explicitly say when to prefer this over llm_job_status or llm_job_result, nor when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

llm_process_healthA
Read-onlyIdempotent

Report gateway process health: async-job manager state, the resolved durable persistence configuration, and flight-recorder health on that configured engine.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds useful context about what is inspected (async-job manager, resolved durable persistence, flight-recorder), but it does not disclose potential failure modes, latency, or whether it triggers any resolution/computation on the gateway. This is acceptable given the read-only annotations, but not deeply transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single tightly structured sentence: the verb/resource pair is front-loaded, followed by a colon and a comma-separated enumeration of the three health areas. Every phrase carries meaning and there is no filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no parameters, the description carries the burden of telling an agent what the report contains, and it does so by naming the three specific health dimensions. It does not explain the result format or mention caveats like 'requires configured engine', but for a read-only health report tool, the core information is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero properties, so there are no parameters for the description to document. Following the rubric's baseline for 0-parameter tools, a score of 4 is appropriate since there is nothing missing in parameter explanations and the description correctly focuses on the report content rather than nonexistent inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource, 'Report gateway process health', and immediately details three concrete report areas: async-job manager state, resolved durable persistence configuration, and flight-recorder health. This level of specificity clearly distinguishes it from sibling status tools like job_status, config_status, and llm_job_status, whose names indicate different scopes.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit guidance about when to use this tool versus the many sibling tools. The description implies it is for health reporting, but it never states conditions, excludes alternatives, or mentions prerequisites such as a running gateway or configured persistence engine. An agent is left to infer when this report is the right choice among the dozens of status/configuration tools listed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

llm_request_listA
Read-onlyIdempotent

List recent persisted requests (sync and async) newest-first WITHOUT a correlation id, to find one. Returns metadata only; pass a returned correlationId to llm_request_result for the prompt/response, or a returned asyncJobId to llm_job_status.

ParametersJSON Schema
NameRequiredDescriptionDefault
cliNoRestrict to one provider as recorded (claude, codex, gemini, grok, mistral, devin, cursor, or an API provider id)
limitNoMax rows to return (1-200)
sinceNoISO-8601 timestamp lower bound, e.g. 2026-08-21T00:00:00Z
sessionIdNoRestrict to one gateway session id

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the read-only/idempotent annotations, the description discloses that the tool 'Returns metadata only', that results are sorted 'newest-first', and that it covers both 'sync and async' requests. It also hints at the shape of the response by referencing correlationId and asyncJobId. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences: the first defines the action and ordering, the second defines the return type and onward routing. No filler, every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Although there is no output schema, the description compensates by telling the agent that the response is metadata-only and how to use the returned identifiers with llm_request_result and llm_job_status. All four optional parameters are fully documented in the schema, and the use case is clear, so nothing needed for a correct call is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%: each parameter (cli, limit, since, sessionId) already has a clear description with examples/ranges. The tool description adds no parameter-specific detail, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'List recent persisted requests (sync and async) newest-first without a correlation id, to find one.' This states the exact purpose and distinguishes the tool from follow-up tools like llm_request_result and llm_job_status by naming the returned identifiers to pass along.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit when-to-use condition ('without a correlation id, to find one') and explicit routing for the results ('pass a returned correlationId to llm_request_result... or a returned asyncJobId to llm_job_status'). This tells an agent exactly how this list tool fits into the workflow and when to switch to an alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

llm_request_resultA
Read-onlyIdempotent

Read back any persisted request (sync or async) from the flight recorder by correlationId, including prompt and response. Local callers can also include the linked complete job record.

ParametersJSON Schema
NameRequiredDescriptionDefault
maxCharsNoMax chars of the persisted response to return
correlationIdYesCorrelation id from a prior request's structuredContent.correlationId (sync or async)
includePromptNoInclude the full persisted prompt text in the result
includeJobRecordNoInclude the linked raw provider capture and replay context when called over local stdio. Remote callers receive no transcript or host paths.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, and the description adds useful context about the flight-recorder source, sync/async coverage, and the local-only job-record behavior. However, claiming the read-back includes 'prompt and response' is ambiguous or potentially misleading because includePrompt defaults to false, and maxChars truncation is not mentioned.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that front-loads the action, identifies the lookup key, mentions scope (sync/async), and includes the key local/remote caveat. There is no filler, tautology, or redundant restatement of schema fields.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only tool with strong annotations and a fully described input schema, the description gives enough context to invoke it correctly: source, correlationId lookup, sync/async coverage, and the local-only job-record option. The lack of an output schema makes the ambiguous 'including prompt and response' wording more noticeable, but overall the core contract is clear.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and each parameter already has a meaningful, self-contained description. The tool description adds high-level context but does not materially deepen the semantics of correlationId, maxChars, includePrompt, or includeJobRecord beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('read back') and a concrete resource ('persisted request ... from the flight recorder by correlationId'). It clearly covers sync/async requests, prompt/response content, and the local-only job-record option, which separates it from list/status tools like llm_request_list or llm_job_result.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly frames the tool as a by-correlationId lookup for persisted flight-recorder requests, and it notes the local vs remote caller distinction. It does not explicitly name alternatives or state when not to use it, so it stops short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mistral_requestA
Destructive

Run a Mistral Vibe CLI request synchronously (when async jobs are enabled, auto-defers to a pollable job past the sync deadline; otherwise runs to completion). Requires exactly one of prompt or promptParts. Defaults to --agent accept-edits (auto-accepts file edits; dangerous ops such as shell stay gated).

ParametersJSON Schema
NameRequiredDescriptionDefault
modelNoModel alias (e.g. mistral-medium-3.5, latest). Resolved alias is injected via VIBE_ACTIVE_MODEL env var; Vibe has no --model flag.
trustNoEmit `--trust` so Vibe trusts the cwd for this invocation only (not persisted to trusted_folders.toml) and skips the interactive trust prompt (Phase 4 slice γ).
addDirNoVibe --add-dir <DIR>: additional writable workspace directories. Each entry is emitted as its own --add-dir instance (Vibe states this flag may be specified multiple times). Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
promptNoPrompt text for Mistral Vibe (mutually exclusive with promptParts)
maxPriceNoVibe `--max-price DOLLARS`: interrupt the session when cumulative cost crosses this cap (programmatic mode only, Phase 4 slice Ī“). Bounded to finite values ≤ 10000 USD.
maxTurnsNoVibe `--max-turns N`: cap the agent-loop iteration count (programmatic mode only, Phase 4 slice Ī“). Bounded to safe integers ≤ 10000.
worktreeNoSlice Ī»: run this request inside a dedicated git worktree owned by the gateway. `true` creates a fresh worktree at `<repoRoot>/.worktrees/<uuid>` branched from HEAD. `{ name?, ref? }` lets the caller supply a sanitized name and/or a git ref (default: HEAD). When the request carries a sessionId and the session already has a worktree, reuse requires same-host ownership metadata and a matching live Git registration. Named path collisions never reuse manager state. Gateway-managed worktrees require the local file-backed session manager and fail closed with PostgreSQL sessions. The Grok, Devin, and Mistral adapters require an explicit provider-native sessionId; fresh, createNewSession, and resumeLatest-only worktree requests fail closed because they cannot durably reselect the worktree. The request must select a registered workspace explicitly, through caller-owned session metadata, or through the configured default. Worktrees never fall back to the gateway process cwd and cannot be combined with local workingDir, addDir, or includeDirs paths. The gateway spawns the child CLI with `cwd: <worktree-path>`; no `-w`/`--worktree` flag is ever emitted to the underlying CLI. On worktree materialization, the gateway suppresses repository, system, and global Git hooks and configured clean, smudge, and process checkout filters, sparse checkout, and lazy object fetching. Filter-dependent content such as Git LFS remains in its repository representation instead of executing host commands. On session_delete or TTL eviction the gateway hides the session and runs `git worktree remove --force`. Failed removal retains a durable cleanup-pending tombstone which blocks reuse and is retried when the file store is registered on the owning host. The tombstone is finalized only after verified Git removal. Successful responses are prefixed with `[gateway] worktree=<absolute-path>\n` so callers can use the path. For Claude approvalStrategy:mcp_managed, requesting or reusing a worktree requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1. Other adapters reject mcp_managed before launch. NOTE: callers should `.gitignore` the `.worktrees/` directory in their repo (the gateway does NOT auto-gitignore; see slice Ī» spec Q4).
maxTokensNoVibe `--max-tokens N`: cap cumulative prompt + completion tokens for the session (programmatic mode only). Bounded to safe integers ≤ 100000000.
sessionIdNoSession ID (user-provided CLI handle for --resume). Current Vibe defaults session logging on; doctor flags explicit [session_logging] enabled = false. Note: the gw-* id minted for a brand-new session is not resumable via sessionId; continue with resumeLatest:true.
transportNoTransport: 'cli' (default) runs the Vibe CLI; 'acp' routes through `vibe-acp` when [acp].enabled and the provider's runtime_enabled are set (fails closed otherwise).cli
workspaceNoRegistered workspace alias for remote HTTP/OAuth provider calls. Do not use this field, workspace_list, or workspace_register_existing_repo as a fallback for stdio/local provider path access; pass workingDir/addDir/includeDirs directly instead.
mcpServersNoThis provider does not receive gateway-managed MCP configuration. mcpServers has no effect with legacy, and mcp_managed is rejected before launch because ambient MCP configuration cannot be isolated.
workingDirNoVibe --workdir <DIR>: change to this directory before running. Single value (Vibe accepts one --workdir per invocation). Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
promptPartsNoCache-aware structured prompt: { system?, tools?, context?, task }. Mutually exclusive with prompt. Stable parts hash into cache_state for prefix-discipline tracking.
allowedToolsNoAllowlist of built-in tools — each emitted as a separate --enabled-tools <tool> flag
forceRefreshNoBypass dedup and force a fresh CLI run even if a recent identical request exists
outputFormatNoOutput format for Vibe 2.x (text|json|streaming). Legacy aliases plain→text and stream-json→streaming are accepted.
resumeLatestNoResume most recent Vibe session in cwd (--continue). Note: the gw-* id minted for a brand-new session is not resumable via sessionId; continue with resumeLatest:true.
correlationIdNoRequest trace ID (auto if omitted)
idleTimeoutMsNoTotal-runtime bound, not an idle timer: this provider emits no output until it exits, so the child is killed after this duration even while healthy. Min 30s, max 1h, omit=1h default.
providerFlagsNoFlags passed to the provider binary verbatim, keyed exactly as the binary spells them (e.g. {"--best-of-n": "3", "--verbatim": true, "--rules": ["a", "b"]}). Use this for any flag your installed CLI accepts that this schema does not name: the binary decides what it supports, not the gateway. true emits the flag alone; a list REPEATS the flag once per item (pass a joined string if your CLI wants a comma-separated value). Values may not start with '-', and a flag the gateway is already emitting for this request is refused rather than duplicated. LOCAL stdio callers only: remote HTTP/OAuth callers are refused every flag here and should use this tool's declared parameters, which carry their own host-path and approval gates.
approvalPolicyNoapprovalPolicy is unavailable for this provider. It has no effect with legacy, and mcp_managed is rejected before launch because ambient MCP configuration cannot be isolated.
optimizePromptNoOptimize prompt before execution
permissionModeNoVibe --agent name. Legacy requests pass builtins (default|plan|accept-edits|auto-approve), install-gated builtins (e.g. lean), and custom agents from ~/.vibe/agents through to Vibe.
disallowedToolsNoDenylist of built-in tools, each emitted as a separate --disabled-tools <tool> flag
approvalStrategyNoApproval strategy: legacy is supported. mcp_managed is rejected before launch because this adapter cannot isolate ambient MCP configuration.legacy
compressResponseNoCompress the response display text via the native compressor (default: [compression].enabled in config.toml, off unless opted in). Skipped for structured output.
createNewSessionNoForce new session
optimizeResponseNoOptimize response output

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=false, and the description productively elaborates on them: the destructive behavior is auto-accepted file edits via the default --agent accept-edits, with a defined boundary ('dangerous ops such as shell stay gated'). It also discloses the runtime deferral behavior. This adds genuine context beyond the annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences of roughly 50 words pack the core action, the sync/defer behavior, the input requirement, and the safety-relevant default. Each clause earns its place and the most important fact (synchronous execution) is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 29-parameter tool with no output schema, the schema itself is exceptionally rich, and the description captures the non-obvious runtime contract: when it returns vs. defers, the required input shape, and the default agent with safety gating. The only gap is the absence of any hint about the response shape, which matters more because no output schema exists to fill that void.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so parameter meaning is already fully documented. The tool description adds only the aggregate constraint 'exactly one of prompt or promptParts' (already mirrored in each parameter's mutual-exclusivity note) and the default agent accept-edits, which permissionMode's schema description does not state. This is marginal additive value over an already-complete schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Run a Mistral Vibe CLI request synchronously') and immediately differentiates from the async sibling through the auto-defer behavior ('when async jobs are enabled, auto-defers to a pollable job past the sync deadline'). The 'Requires exactly one of prompt or promptParts' constraint and the default-agent note add operative specificity well beyond a restatement of the tool name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description conveys when the call returns versus defers to a pollable job, which implies the sync-use case, and states the hard input requirement (exactly one of prompt or promptParts). However, it never names the alternative (mistral_request_async) or states explicit when-to-use/when-not-to-use conditions. Usage context is present but implied rather than stated as exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mistral_request_asyncA
Destructive

Start a Mistral Vibe CLI request as a durable background job. Poll with llm_job_status, collect with llm_job_result.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelNoModel alias (resolved into VIBE_ACTIVE_MODEL env var — Vibe has no --model flag)
trustNoEmit `--trust` so Vibe trusts the cwd for this invocation only (not persisted to trusted_folders.toml) and skips the interactive trust prompt (Phase 4 slice γ).
addDirNoVibe --add-dir <DIR>: additional writable workspace directories. Each entry is emitted as its own --add-dir instance. Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
promptNoPrompt text for Mistral Vibe (mutually exclusive with promptParts)
maxPriceNoVibe `--max-price DOLLARS`: interrupt the session when cumulative cost crosses this cap (programmatic mode only, Phase 4 slice Ī“). Bounded to finite values ≤ 10000 USD.
maxTurnsNoVibe `--max-turns N`: cap the agent-loop iteration count (programmatic mode only, Phase 4 slice Ī“). Bounded to safe integers ≤ 10000.
worktreeNoSlice Ī»: run this request inside a dedicated git worktree owned by the gateway. `true` creates a fresh worktree at `<repoRoot>/.worktrees/<uuid>` branched from HEAD. `{ name?, ref? }` lets the caller supply a sanitized name and/or a git ref (default: HEAD). When the request carries a sessionId and the session already has a worktree, reuse requires same-host ownership metadata and a matching live Git registration. Named path collisions never reuse manager state. Gateway-managed worktrees require the local file-backed session manager and fail closed with PostgreSQL sessions. The Grok, Devin, and Mistral adapters require an explicit provider-native sessionId; fresh, createNewSession, and resumeLatest-only worktree requests fail closed because they cannot durably reselect the worktree. The request must select a registered workspace explicitly, through caller-owned session metadata, or through the configured default. Worktrees never fall back to the gateway process cwd and cannot be combined with local workingDir, addDir, or includeDirs paths. The gateway spawns the child CLI with `cwd: <worktree-path>`; no `-w`/`--worktree` flag is ever emitted to the underlying CLI. On worktree materialization, the gateway suppresses repository, system, and global Git hooks and configured clean, smudge, and process checkout filters, sparse checkout, and lazy object fetching. Filter-dependent content such as Git LFS remains in its repository representation instead of executing host commands. On session_delete or TTL eviction the gateway hides the session and runs `git worktree remove --force`. Failed removal retains a durable cleanup-pending tombstone which blocks reuse and is retried when the file store is registered on the owning host. The tombstone is finalized only after verified Git removal. Successful responses are prefixed with `[gateway] worktree=<absolute-path>\n` so callers can use the path. For Claude approvalStrategy:mcp_managed, requesting or reusing a worktree requires approval and LLM_GATEWAY_APPROVAL_ALLOW_BYPASS=1. Other adapters reject mcp_managed before launch. NOTE: callers should `.gitignore` the `.worktrees/` directory in their repo (the gateway does NOT auto-gitignore; see slice Ī» spec Q4).
maxTokensNoVibe `--max-tokens N`: cap cumulative prompt + completion tokens for the session (programmatic mode only). Bounded to safe integers ≤ 100000000.
sessionIdNoSession ID (user-provided CLI handle for --resume). Current Vibe defaults session logging on; doctor flags explicit [session_logging] enabled = false. Note: the gw-* id minted for a brand-new session is not resumable via sessionId; continue with resumeLatest:true.
workspaceNoRegistered workspace alias for remote HTTP/OAuth provider calls. Do not use this field, workspace_list, or workspace_register_existing_repo as a fallback for stdio/local provider path access; pass workingDir/addDir/includeDirs directly instead.
mcpServersNoThis provider does not receive gateway-managed MCP configuration. mcpServers has no effect with legacy, and mcp_managed is rejected before launch because ambient MCP configuration cannot be isolated.
workingDirNoVibe --workdir <DIR>: change to this directory before running. Single value per invocation. Stdio/local callers may pass local paths directly. Remote HTTP/OAuth callers must use relative paths inside a selected registered workspace. Do not call workspace_* tools to fix stdio/local provider path access.
promptPartsNoCache-aware structured prompt: { system?, tools?, context?, task }. Mutually exclusive with prompt. Stable parts hash into cache_state for prefix-discipline tracking.
allowedToolsNoAllowlist of built-in tools — each emitted as a separate --enabled-tools <tool> flag
forceRefreshNoBypass dedup and force a fresh CLI run even if a recent identical request exists
outputFormatNoOutput format for Vibe 2.x (text|json|streaming). Legacy aliases plain→text and stream-json→streaming are accepted.
resumeLatestNoResume most recent Vibe session in cwd (--continue). Note: the gw-* id minted for a brand-new session is not resumable via sessionId; continue with resumeLatest:true.
correlationIdNoRequest trace ID (auto if omitted)
idleTimeoutMsNoTotal-runtime bound, not an idle timer: this provider emits no output until it exits, so the child is killed after this duration even while healthy. Min 30s, max 1h, omit=1h default.
providerFlagsNoFlags passed to the provider binary verbatim, keyed exactly as the binary spells them (e.g. {"--best-of-n": "3", "--verbatim": true, "--rules": ["a", "b"]}). Use this for any flag your installed CLI accepts that this schema does not name: the binary decides what it supports, not the gateway. true emits the flag alone; a list REPEATS the flag once per item (pass a joined string if your CLI wants a comma-separated value). Values may not start with '-', and a flag the gateway is already emitting for this request is refused rather than duplicated. LOCAL stdio callers only: remote HTTP/OAuth callers are refused every flag here and should use this tool's declared parameters, which carry their own host-path and approval gates.
approvalPolicyNoapprovalPolicy is unavailable for this provider. It has no effect with legacy, and mcp_managed is rejected before launch because ambient MCP configuration cannot be isolated.
optimizePromptNoOptimize prompt before execution
permissionModeNoVibe --agent name. Legacy requests pass builtins (default|plan|accept-edits|auto-approve), install-gated builtins (e.g. lean), and custom agents from ~/.vibe/agents through to Vibe.
disallowedToolsNoDenylist of built-in tools, each emitted as a separate --disabled-tools <tool> flag
approvalStrategyNoApproval strategy: legacy is supported. mcp_managed is rejected before launch because this adapter cannot isolate ambient MCP configuration.legacy
compressResponseNoCompress the response display text when collected via llm_job_result (native compressor; default: [compression].enabled).
createNewSessionNoForce new session

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry the safety profile: readOnlyHint=false, destructiveHint=true, idempotentHint=false. The description adds the durable async execution model and the poll/collect workflow, which is useful context. It does not go deeper into destructive side effects or lifecycle details, but the annotations already flag those traits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single efficient two-clause sentence with no filler. It front-loads the action and immediately gives the caller the next steps (poll with llm_job_status, collect with llm_job_result).

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The schema is rich and covers all parameters, and the description covers the start/poll/collect lifecycle. However, there is no output schema and the description does not state what the start call returns (e.g., a job ID), nor does it address error handling or the destructiveHint implications. Adequate but minimal for such a complex tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% across 27 parameters, so the schema carries the parameter meaning. The tool description itself adds no parameter-level guidance, which is acceptable at the baseline of 3 given the full schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Start a Mistral Vibe CLI request'), identifies the resource, and clearly distinguishes this tool as the async variant by calling it a 'durable background job'. It also names the follow-up tools (llm_job_status, llm_job_result), which differentiates it from the synchronous mistral_request sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context: use this to start a durable background job, then poll and collect via llm_job_status and llm_job_result. It does not explicitly name mistral_request as the synchronous alternative or state when not to use this tool, but the background-job framing is enough to guide selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

provider_admin_listA
Read-onlyIdempotent

List provider CLI admin operations (auth status, model list, mcp list, plugin list, doctor, etc.) available on the installed CLIs, projected from runtime discovery. Read-only.

ParametersJSON Schema
NameRequiredDescriptionDefault
providerNoOptional provider filter
includeUnavailableNoInclude operations the installed CLI does not advertise or the policy hides

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnly, idempotent, and non-destructive hints. The description adds meaningful behavioral context with 'projected from runtime discovery', signaling that the result is inferred from the runtime environment rather than a static hardcoded list. It also lists representative operation categories, though it does not discuss potential staleness or exact output shape.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is one tightly written sentence that front-loads the action and resource, then gives examples, scope, and the read-only warning. There is no filler, no restatement of the tool name, and every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only catalog tool with two optional parameters, the description plus the rich schema descriptions are sufficient for an agent to call it correctly. There is no output schema, but the return shape is reasonably implied by 'List' and the concrete examples of operation categories, so the remaining ambiguity is minor.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so provider and includeUnavailable are already fully documented structurally. The description does not add extra meaning about filtering behavior or what including unavailable operations entails, so it stays at the baseline for schema-covered parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('List'), a resource ('provider CLI admin operations'), and a scope ('on the installed CLIs'), with concrete examples such as auth status, model list, mcp list, and doctor. The 'Read-only' marker and the admin-operation framing clearly distinguish it from siblings like provider_admin_run and provider_admin_mutate.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is for discovering which admin operations an installed CLI exposes, and the read-only note hints against using it for mutation. However, it never names alternatives or explicit when-not-to-use conditions, leaving the agent to infer routing relative to sibling catalog and execution tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

provider_admin_mutateA
Destructive

Execute a MUTATING provider CLI admin operation (mcp add/remove, login/logout, plugin install/remove, session delete/archive, ...). Disabled unless [admin] allow_mutating_cli_admin_ops=true; routed through approval and audited.

ParametersJSON Schema
NameRequiredDescriptionDefault
providerYesProvider whose admin operation to run
operationIdYesMutating operation id from provider_admin_list, e.g. 'mcp.remove'

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, and the description adds meaningful context beyond them: the tool is gated by configuration, routed through approval, and audited. This gives the agent a clear picture that invoking it has real, tracked side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The entire description is one dense, front-loaded sentence. It immediately communicates mutability, gives representative examples, and includes the gating/audit behavior without any filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description adequately covers what the tool does, when it is usable, and where the operationId comes from. It does not describe the response format, and there is no output schema, which is a minor gap; for a CLI-admin wrapper this is not a critical omission but the description could be slightly more complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with both provider and operationId already documented including an enum and an example. The description adds no significant parameter-level details beyond what the schema provides, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Execute a MUTATING provider CLI admin operation') with concrete examples such as mcp add/remove, login/logout, plugin install/remove, and session delete/archive. The mutating qualifier clearly separates this tool from read-only siblings like provider_admin_list and provider_admin_run.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear use context: this is for mutating admin operations only, requires allow_mutating_cli_admin_ops=true, and is routed through approval and audit. It also implies operationId should come from provider_admin_list, but it does not explicitly name alternatives or state when not to use this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

provider_admin_runA
Read-onlyIdempotent

Execute a READ-ONLY provider CLI admin operation (from provider_admin_list) and return redacted output. Rejects mutating operations.

ParametersJSON Schema
NameRequiredDescriptionDefault
providerYesProvider whose admin operation to run
operationIdYesOperation id from provider_admin_list, e.g. 'mcp.list' or 'doctor'

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds meaningful context beyond annotations by disclosing that output is redacted and that mutating inputs are rejected, which are behavioral guarantees an agent cannot infer from the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single dense sentence with no filler. It front-loads the read-only nature, names the source of valid operations, and states the rejection constraint in the same breath.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter read-only pass-through tool with no output schema, the description covers the operation source, the read-only constraint, and redacted output behavior. It does not describe output structure, but output shape is operation-dependent and would not be meaningfully generalized.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%: provider is an enum with descriptions, and operationId has a description plus example. The description adds value beyond the schema by clarifying operationId must come from provider_admin_list, which tells the agent where to discover valid operation IDs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('Execute'), a specific resource ('provider CLI admin operation'), and restricts scope to READ-ONLY operations sourced from provider_admin_list. The phrase 'Rejects mutating operations' clearly separates it from the mutating sibling tool provider_admin_mutate.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly tells the agent that operation IDs come from provider_admin_list and that mutating operations will be rejected, providing a clear when-not. It does not explicitly name provider_admin_mutate as the alternative for mutating operations, so it stops short of full alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

provider_subcommand_contractA
Read-onlyIdempotent

Return the detailed read-only contract for exactly one declared provider CLI subcommand.

ParametersJSON Schema
NameRequiredDescriptionDefault
providerYesProvider (claude|codex|gemini|grok|mistral|devin|cursor)
commandPathYesCommand path segments

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds context that the contract is 'read-only' and 'exactly one declared' subcommand, but it does not disclose return format, error behavior, or what 'contract' entails beyond the term itself. With annotations carrying the safety burden, the added context is moderate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, tightly constructed sentence. It front-loads the core operation ('Return'), the object ('detailed read-only contract'), and the scope ('exactly one declared provider CLI subcommand') with no filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter tool with fully documented parameters and strong safety annotations, the description is sufficient for an agent to select and invoke it. The lack of an output schema means the return shape isn't documented, but 'detailed read-only contract' sets a reasonable expectation. Missing explicit error or edge-case guidance is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%: both provider and commandPath have descriptions. The description adds a small amount of semantic context by tying the parameters to a 'declared provider CLI subcommand,' but it does not meaningfully extend the schema documentation. Baseline 3 is appropriate since the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Return the detailed read-only contract for exactly one declared provider CLI subcommand.' It clearly states the operation, object, and scope. The 'exactly one' qualifier distinguishes it from list-style siblings like provider_subcommands_list, and 'declared' separates it from drift/contract-management tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context: use this when you need the contract for a single declared provider subcommand, identified by provider and commandPath. It does not explicitly name alternative tools for listing or drift checking, so the when-not guidance is implied rather than explicit. This lands just below the explicit-alternatives bar.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

provider_subcommand_driftA
Read-onlyIdempotent

Probe declared provider subcommand --help surfaces and return compact drift rows without raw help output.

ParametersJSON Schema
NameRequiredDescriptionDefault
providerNoOptional provider filter (claude|codex|gemini|grok|mistral|devin|cursor)
includeCleanNoWhen false, return only unavailable, drifted, or untrusted-help-exit command paths

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description adds that it returns compact drift rows rather than raw help output, which is useful. However, it does not disclose details about how providers are probed, what failures may occur, or what constitutes 'drifted' versus 'untrusted-help-exit' behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single focused sentence that front-loads the action and output, with no wasted words. It communicates the essential behavior and output constraint in an efficient manner.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description's 'compact drift rows' is useful but underspecified; it does not describe what fields or statuses a drift row contains. The two parameters are well covered by the schema, and the annotations handle the safety profile, so the main gap is the lack of output detail and more explicit domain context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema already documents both parameters, including the provider enum and includeClean behavior. The description does not add parameter-level meaning, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific action ('Probe declared provider subcommand --help surfaces') and a specific deliverable ('compact drift rows'), which clearly sets it apart from generic listing tools. It could be slightly more explicit about what 'drift' means relative to declared contracts, but the core purpose is understandable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this tool is for detecting drift between declared provider subcommands and actual --help availability, but it does not explicitly state when to use this versus siblings like provider_subcommands_list or provider_subcommand_contract. No exclusions or alternative routing are provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

provider_subcommands_listA
Read-onlyIdempotent

Return a compact, filterable read-only catalog of declared provider CLI subcommands without flags or raw help.

ParametersJSON Schema
NameRequiredDescriptionDefault
riskNoOptional risk classification filter
tierNoOptional subcommand tier filter
exposureNoOptional MCP exposure filter
providerNoOptional provider filter (claude|codex|gemini|grok|mistral|devin|cursor)
commandPathPrefixNoOptional command path prefix filter, e.g. ['agent']

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover readOnlyHint, idempotentHint, and destructiveHint. The description adds useful behavioral context: the result is compact, filterable, based on declared subcommands, and deliberately excludes flags and raw help. No contradiction with annotations, and the behavior beyond the schema is described clearly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, densely informative sentence with no filler. It front-loads the action and resource, then adds the key constraints ('compact', 'filterable', 'without flags or raw help'). Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only, fully optional-parameter list tool, the description is nearly complete: it states the subject, the filtering capability, and what is deliberately excluded. There is no output schema, so a note on the exact item shape would add value, but the simplicity of the tool and strong annotations make this a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and every parameter already has a clear description with enums where applicable. The description's word 'filterable' reinforces the parameter model but adds no parameter-specific detail beyond what the schema provides, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('Return'), a resource ('catalog of declared provider CLI subcommands'), and explicit exclusions ('without flags or raw help'). This makes the tool's purpose unambiguous and clearly distinguishes it from raw help and deeper provider subcommand tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The read-only, catalog-oriented wording implies use for quick overviews or filtered listings rather than deep contract inspection. However, it does not explicitly name alternatives like provider_subcommand_contract or provider_subcommand_drift, nor state when those would be more appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

provider_tool_capabilitiesA
Read-onlyIdempotent

Report provider tool/feature capabilities and discovered local skill/tool integrations for claude|codex|gemini|grok|mistral|devin|cursor|grok_api, or an enabled API provider name.

ParametersJSON Schema
NameRequiredDescriptionDefault
cliNoProvider filter (claude|codex|gemini|grok|mistral|devin|cursor|grok_api, or an enabled API provider name)
refreshNoBypass the short-lived capability cache
includePathsNoInclude raw local filesystem paths in discovery output
includeSkillsNoInclude bounded local skill discovery results
includeUnsupportedNoInclude explicit unsupported/degraded input records
includeProviderToolsNoInclude provider-native tools extracted from local skills

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate read-only, idempotent, non-destructive behavior. The description adds context about cache bypass, inclusion of paths, skills, provider tools, and unsupported records, which is useful beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that front-loads the verb and resource, but it is somewhat long due to listing providers. Could be slightly more structured, but still efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only report tool with six boolean parameters and no output schema, the description adequately covers all relevant aspects: what is reported, cache bypass, path inclusion, skills, provider tools, and unsupported records. No gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so parameters are fully described in the schema. The description provides some additional context (e.g., 'discovered local skill/tool integrations') but adds limited meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('Report') and the resource ('provider tool/feature capabilities and discovered local skill/tool integrations'), and lists specific target providers, distinguishing it from sibling tools focused on requests or management.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for reporting capabilities of specified providers but does not explicitly state when to use this tool versus alternatives like claude_request or list_models. No exclusions or when-not guidance is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

provider_version_guardA
Read-onlyIdempotent

Compare installed provider CLI versions against their contracted targets, and optionally check whether a newer version is published. Reports which providers drifted and which can be upgraded, plus the exact upgrade command for each.

ParametersJSON Schema
NameRequiredDescriptionDefault
cliNoCLI filter (claude|codex|gemini|grok|mistral|devin|cursor)
timeoutMsNoPer-provider timeout for the upgrade check
checkUpgradesNoWhen true, query each provider's release source for a newer version. Costs network and one subprocess for grok; four of seven providers can be checked, the rest report unknown with a reason.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds behavioral context beyond the readOnly annotation by stating that it reports upgrade commands rather than executing them, and that upgrade checking is optional. It also implies external version-source queries for the optional check, consistent with openWorldHint. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two compact sentences with no filler. It front-loads the primary action, then adds the optional behavior and the key output, making every sentence earn its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the rich schema descriptions and annotations, the description is nearly complete: it covers what the tool compares, the optional upgrade check, and the report contents including exact upgrade commands. The only minor gap is not explicitly stating what happens when checkUpgrades is false, but that is implied and covered by the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents all three parameters. The description loosely maps to checkUpgrades with 'optionally check whether a newer version is published' but adds no new parameter-level meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: it compares installed provider CLI versions against contracted targets and reports drift/upgrade status. This clearly distinguishes it from sibling tools like cli_versions, upstream_contracts, and cli_upgrade by focusing on comparison, drift reporting, and upgrade-command generation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context for when to use the tool: when you need to know which provider CLIs have drifted from their contracted versions and which can be upgraded. It does not explicitly name alternatives or exclusions, such as directing actual upgrade execution to cli_upgrade, but the context is clear enough for an agent to select it appropriately.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

red_team_reviewA
Destructive

Challenge a plan, answer, or document for risks and failure modes via provider CLIs (starts validation jobs).

ParametersJSON Schema
NameRequiredDescriptionDefault
modelsNoProviders to ask for adversarial review.
selectNoOptional least-cost routing: fill the provider target(s) from the LCR selector instead of the explicit list. 'cheapest' picks the single cheapest eligible provider; 'cheapest_per_tier' picks the cheapest in each quality tier. Requires [least_cost].enabled=true; fails closed (no default-list fallback) when disabled or nothing is eligible.
contentYesPlan, answer, or document to challenge.
riskLevelNoHow aggressively to review.normal

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate the tool is not read-only, is not idempotent, and is potentially destructive. The description adds useful concrete behavioral detail by stating that it works 'via provider CLIs' and explicitly that it 'starts validation jobs,' which clarifies the side-effect nature beyond the annotations alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence that front-loads the core purpose, names the target resource, and adds a crucial side-effect note in parentheses. Every element earns its place and there is no filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is complex: it launches asynchronous validation jobs, has no output schema, and sits among many similar validation/review tools. The description mentions that jobs are started but does not explain what the caller receives, whether a receipt is returned, or how to retrieve job results via sibling tools like job_status or job_result. Params and annotations cover their domains well, but the async workflow is left incomplete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all four parameters are already documented in the input schema. The description adds only marginal semantic context through 'plan, answer, or document' and 'provider CLIs,' but it does not meaningfully expand on parameter meanings beyond the baseline established by the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('Challenge'), the resource ('a plan, answer, or document'), and the goal ('risks and failure modes'). It also notes that the tool starts validation jobs, which helps distinguish it from pure read-only analysis tools, though it does not explicitly differentiate it from closely named siblings like validate_with_models or second_opinion.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance about when to choose this tool over alternatives such as validate_with_models, second_opinion, or review_changes. The use case is implied by the purpose statement, but no exclusions, prerequisites, or alternative-routing advice is provided, which is a significant gap given the large sibling list.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

review_changesA
Read-only

Capture one complete, immutable Git evidence artifact, fence it as untrusted data, and start independent read-only provider reviews. Includes committed, staged, unstaged, and untracked changes without truncation.

ParametersJSON Schema
NameRequiredDescriptionDefault
baseNoExplicit Git base ref or commit. Overrides automatic base selection.
focusNoAdditional reviewer focus outside the untrusted evidence boundary.
pathsNoOptional literal repository-relative path filters.
scopeNoReview scope. auto reviews a diverged branch from its merge-base with working-tree evidence included, otherwise reviews dirty uncommitted changes, and falls back to the last commit when the tree is clean.auto
modelsNoIndependent providers to start. Defaults to Claude and Codex.
stanceNostandard
workspaceNoAuthorized workspace alias, required for remote HTTP/OAuth callers.
judgeModelNoOptional judge provider to reconcile terminal reviews in a second step. An HTTP/API judge requires allowApiUpload=true, which is bound to the durable validationId.
workingDirNoAbsolute local path to the checkout. Stdio/local callers should use this; remote HTTP/OAuth callers must use workspace instead.
allowApiUploadNoExplicitly allow repository review evidence to be sent to configured HTTP/API reviewers or a planned API judge. API judge consent is bound to the durable validationId; remote workspace reviews do not permit API upload.
maxPromptBytesNoFail-closed byte ceiling for the fenced provider prompt.
maxArtifactBytesNoFail-closed byte ceiling for the complete serialized Git artifact.
trustCursorWorkspaceNoLet cursor trust this repository even though it is not a workspace registered for cursor. Cursor refuses to review an untrusted directory, so without this a cursor seat on an unregistered path is skipped. Trust also lets the reviewed repository's own rules and AGENTS.md instruct the reviewer, which the review prompt otherwise forbids, so enable it only for a repository whose contents you trust.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint, openWorldHint, idempotentHint, and destructiveHint. The description adds meaningful behavioral context beyond these: the evidence is immutable, fenced as untrusted data, and includes all change types without truncation. This meaningfully clarifies the tool's safety boundary and execution model. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The first sentence front-loads the core action and object; the second adds the important scope guarantee of including all change types without truncation. Every phrase earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex tool with 13 parameters, zero required parameters, no output schema, and open-world side effects, the description gives a solid high-level summary but does not mention how results are retrieved, whether the operation is asynchronous, or what the caller receives back. The schema and annotations are rich, but the description alone leaves some workflow ambiguity for an agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 92%, so the schema already documents nearly all parameters well. The description does not add per-parameter meaning, though phrases like 'untrusted evidence boundary' loosely relate to maxPromptBytes and maxArtifactBytes. With high schema coverage, a baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action — capture a complete Git evidence artifact and start independent read-only provider reviews — and names the exact resource (Git changes) and scope (committed, staged, unstaged, untracked). It clearly differentiates this from sibling single-provider request tools by emphasizing multi-provider, evidence-based review.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the use case: review repository changes with multiple independent providers. However, it does not explicitly state when to use this tool over alternatives such as validate_with_models or the per-provider request tools, nor does it provide exclusions or conditions for choosing a different tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

second_opinionB
Destructive

Ask one provider CLI to review an answer (starts a validation job; poll job_status, collect job_result).

ParametersJSON Schema
NameRequiredDescriptionDefault
modelNoProvider to ask for the second opinion.codex
answerYesAnswer to review.
selectNoOptional least-cost routing: fill the provider target(s) from the LCR selector instead of the explicit list. 'cheapest' picks the single cheapest eligible provider; 'cheapest_per_tier' picks the cheapest in each quality tier. Requires [least_cost].enabled=true; fails closed (no default-list fallback) when disabled or nothing is eligible.
questionNoOriginal question, if available.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description usefully discloses the async behavioral pattern — 'starts a validation job; poll job_status, collect job_result' — which goes beyond what annotations convey. However, annotations mark destructiveHint=true, and the description gives no hint of what destructive side effect a 'second opinion review' could have; it neither confirms nor explains this non-obvious trait. No direct contradiction with the annotations, but the destructive flag is left unexplained.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tight sentence front-loads the core purpose and appends the essential async workflow in a parenthetical. There is no filler or redundancy. It could be slightly smoother, but every clause earns its place and the whole description is minimal without being under-specified.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an async tool with no output schema, the description does convey the critical post-invocation workflow (poll job_status, collect job_result). But it does not state what the initial call returns (e.g., a job identifier/receipt, given the sibling validation_receipt), and it leaves the destructiveHint=true annotation unaddressed. The schema covers parameters well, but the behavioral return contract is incomplete for an agent that must chain calls.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents all four parameters (model enum/default, answer, select LCR routing, question), justifying the baseline of 3. The description adds only marginal mapping context ('one provider' ↔ model; 'review an answer' ↔ answer) without enriching any parameter semantics beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource — 'Ask one provider CLI to review an answer' — and clarifies the async validation-job nature. It distinguishes itself from generation siblings (ask_model, *_request) by framing this as a review of an existing answer, and the 'one provider' phrasing separates it from multi-provider validation tools. However, it never explicitly names an alternative (e.g., validate_with_models or red_team_review), so differentiation is implicit rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied: you use this when you want a single provider to review an answer, and the parenthetical tells you the follow-up workflow (poll job_status, collect job_result). But there is no explicit when-to-use versus alternatives, no exclusions, and no guidance such as 'for multi-model validation use validate_with_models instead.'

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

session_clear_allA
DestructiveIdempotent

Delete all gateway session records, optionally scoped to one provider.

ParametersJSON Schema
NameRequiredDescriptionDefault
cliNoProvider filter (claude|codex|gemini|grok|mistral|devin|cursor|grok-api)

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry destructiveHint=true and idempotentHint=true, and the description is fully consistent with them. It adds value by specifying exactly what gets destroyed ('all gateway session records') and the optional provider scope, which is meaningful behavioral context beyond the annotation flags. It stops short of noting irreversibility or impact on active sessions, but with annotations covering the safety profile this is solid.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with zero filler: the primary action and resource are front-loaded, with the optional scoping modifier appended. Every word earns its place and there is nothing extraneous.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-optional-parameter tool with annotations covering the destructive/idempotent profile and full schema documentation, the description is nearly complete. The only gaps are the return value (there is no output schema) and whether deleting records affects currently active/selected sessions, both of which are minor for this simple delete operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%: the single 'cli' parameter has an enum plus a description listing all accepted provider values. The description's phrase 'optionally scoped to one provider' merely echoes the schema. Baseline 3 applies because the schema carries the parameter documentation burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Delete'), names the exact resource ('all gateway session records'), and states the optional provider scoping. It is clearly distinguishable from sibling tools like session_delete (targets a single session) and session_list/session_get (read operations), because 'all' signals bulk destruction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage context is implied: this is the bulk-clear tool, optionally restricted to one provider. However, the description never explicitly contrasts it with session_delete for single-session removal or warns that this is the batch alternative to per-session deletion. The guidance is inferable but not stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

session_createA

Create a gateway session record for a provider. NOTE: this is gateway bookkeeping (a plain UUID), not a provider-native session; Codex resume needs a real Codex UUID.

ParametersJSON Schema
NameRequiredDescriptionDefault
cliYesProvider type (claude|codex|gemini|grok|mistral|devin|cursor|grok-api)
descriptionNoSession description
setAsActiveNoSet as active session

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only state readOnlyHint=false, so the description carries the burden of explaining the mutation. It adds meaningful context: the created record is a plain UUID, not a provider-native session, and does not satisfy Codex resume. This goes beyond the schema, though it does not disclose return values or side effects like setAsActive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler: the first states the core operation, the second delivers the critical caveat. Every sentence earns its place and the key limitation is front-loaded near the main purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple create operation with full schema coverage and basic annotations, the description is mostly complete and includes the essential caveat about provider-native sessions. It does not explicitly state the return value or that setAsActive defaults to true, which would be useful given there is no output schema, but these are minor gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with each parameter (cli, description, setAsActive) already documented in the input schema. The description adds no additional parameter-level meaning, so the baseline score of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description specifies a concrete action ('Create') on a specific resource ('gateway session record') and clearly distinguishes it from provider-native sessions via the plain-UUID note. This differentiates it from sibling tools like codex_fork_session and codex_request without needing to inspect schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The warning that Codex resume needs a real Codex UUID provides an explicit when-not-to-use condition, and the 'gateway bookkeeping' phrasing clarifies the tool's narrow role. However, it does not name an alternative tool to use instead, leaving the agent to infer from sibling names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

session_deleteA
DestructiveIdempotent

Delete a gateway session record by ID (also removes any gateway-owned worktree attached to it).

ParametersJSON Schema
NameRequiredDescriptionDefault
sessionIdYesSession ID

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds an important side effect beyond the annotations: deletion also removes any gateway-owned worktree attached to the session. With destructiveHint already present, this extra context meaningfully improves transparency, though it does not cover every edge case.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence contains the core operation, the scoping mechanism, and a critical side effect. No filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-parameter delete operation, the description, schema, and annotations together provide enough information to invoke it correctly. The destructive and idempotent hints cover behavioral safety, and the worktree side effect is explicitly disclosed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already documents sessionId at 100% coverage, and the description does not add format, constraints, or additional semantics beyond 'by ID'. This matches the baseline for schema-covered parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Delete'), a specific resource ('gateway session record'), and a scoping mechanism ('by ID'), which clearly distinguishes it from session_clear_all. It also adds the worktree-removal detail, making the purpose even more precise.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'by ID' phrasing clearly establishes this tool is for targeted deletion of a single session, providing clear usage context. It does not explicitly contrast with session_clear_all or mention exclusions, so it stops short of full alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

session_getA
Read-onlyIdempotent

Get one gateway session record by session ID, including recent request history when available.

ParametersJSON Schema
NameRequiredDescriptionDefault
sessionIdYesSession ID

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile with readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds useful behavioral context beyond those, noting that recent request history is included when available, which tells the agent the response content is conditional. No contradictions with the annotations exist.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single focused sentence with no wasted words. It front-loads the core operation and appends the conditional history detail efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter read tool with strong safety annotations, the description is nearly complete: it identifies the resource, the lookup key, and an important output detail. The only minor gap is that the exact structure of the returned session record is not described, but the phrase 'gateway session record' plus the lack of an output schema keeps this acceptable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema describes sessionId as 'Session ID' and covers 100% of parameters, so the baseline is 3. The tool description repeats the lookup-by-session-ID concept but does not add format, source, or validation details beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Get'), a specific resource ('one gateway session record'), and the lookup key ('by session ID'). It also adds a distinguishing detail ('including recent request history when available') that separates it from broader sibling tools like session_list.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'by session ID' phrasing makes it clear this is the targeted single-record retrieval counterpart to session_list, giving implied usage context. However, it does not explicitly say when not to use it or name any alternative tool, so the routing guidance is left mostly to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

session_listA
Read-onlyIdempotent

List gateway session records and the active session per provider, optionally filtered by provider.

ParametersJSON Schema
NameRequiredDescriptionDefault
cliNoProvider filter (claude|codex|gemini|grok|mistral|devin|cursor|grok-api)

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint=true, idempotentHint=true, destructiveHint=false), so the bar is lower. The description adds value beyond annotations by disclosing the response scope — both raw gateway session records and the per-provider active session — plus the optional filtering behavior. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence that front-loads the verb, states the resource scope, and appends the optional filter. Every clause earns its place and there is no fluff, redundancy, or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a low-complexity tool with one optional enum parameter and a full annotation safety profile, the description covers the operation, the output scope, and the filter. Since there is no output schema, the 'records and active session per provider' phrasing partially compensates by indicating the return categories, though exact record shape is unspecified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% — the 'cli' parameter is fully documented in the schema with its enum values. The description merely restates that filtering by provider is optional, reinforcing the schema without adding syntax or format detail. This meets the high-coverage baseline of 3 but does not exceed it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('List') and a specific resource ('gateway session records and the active session per provider'), making the tool's function immediately clear. Its collective listing scope inherently distinguishes it from the session mutation/retrieval siblings (session_create, session_delete, session_get, session_set_active) and the per-provider active-session detail is a unique identifying feature.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'optionally filtered by provider' clause gives useful context for when the sole parameter applies, and the 'List' verb implies this is the browse/inspect tool among session_* siblings. However, it never explicitly states when to prefer this over session_get or when not to use it, and no alternative is named.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

session_set_activeA
Idempotent

Set or clear the active session for a provider; the active session is used when a request omits sessionId.

ParametersJSON Schema
NameRequiredDescriptionDefault
cliYesProvider type (claude|codex|gemini|grok|mistral|devin|cursor|grok-api)
sessionIdYesSession ID (null to clear)

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate idempotent and non-destructive mutation. The description adds the key behavioral fact that this session becomes the default for requests omitting sessionId, which goes beyond what annotations convey. No contradictions exist.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that front-loads the action and follows with the critical usage context. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a simple two-parameter tool with full schema coverage and clear annotations. The description explains the operation and its effect well enough for an agent to invoke it correctly without an output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and both parameters have descriptive text, including 'null to clear' for sessionId. The description adds little beyond the schema but does not need to, since the schema fully documents parameter meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific action ('Set or clear'), a specific resource ('active session for a provider'), and defines what 'active' means. This clearly differentiates it from sibling session tools like session_create, session_delete, and session_clear_all.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context: the active session is the default used when a request omits sessionId. It does not explicitly name alternatives or exclusions, but the usage context is sufficient for an agent to decide when this tool is relevant.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

synthesize_validationA
Destructive

Run an explicit judge model over validation results. General validation uses caller-supplied terminal results; review_changes rebuilds its question and results from the owned durable run.

ParametersJSON Schema
NameRequiredDescriptionDefault
questionNoOriginal request for general validation. Ignored for review_changes, which uses the question stored in the durable run.
workspaceNoFor a remote review_changes run, the same authorized workspace alias.
judgeModelNoProvider to run the judge synthesis.codex
workingDirNoFor a review_changes run, the same absolute local checkout path used at kickoff.
validationIdNoRun id from kickoff. Optional for general validation, but required for review_changes so the stored question, provider jobs, repository, planned judge, and upload policy can be enforced.
providerResultsNoTerminal normalized results for general validation. Ignored for review_changes, which reloads every exact linked durable job result.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description clarifies the important behavioral distinction that providerResults and question are ignored for review_changes in favor of reloading from the durable run. Annotations already declare readOnlyHint=false and destructiveHint=true, so the safety profile is signaled, but the description does not add detail about what could be destroyed, whether the run creates persistent state, or error behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler. The purpose is front-loaded and the mode contrast is in the second sentence. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has six optional parameters, no output schema, and a destructiveHint=true annotation, yet the description never explains what the synthesized result looks like, what side effects may occur, or how the caller should treat the returned value. The two-mode explanation is helpful but incomplete for safe invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and individual parameter descriptions are detailed. The description adds contextual framing but no parameter-level details beyond the schema, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a clear verb+resource: 'Run an explicit judge model over validation results.' It then distinguishes the two modes and names review_changes as the sibling with different data sourcing. It is slightly jargon-heavy ('explicit judge model', 'owned durable run') but not tautological.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second sentence gives explicit usage conditions: general validation uses caller-supplied terminal results, while review_changes rebuilds from the durable run. This effectively tells an agent when each mode applies, though it does not mention other possible alternatives or say when not to call the tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

upstream_contractsA
Read-onlyIdempotent

Return the gateway's declared provider CLI contracts; with probeInstalled true, diff against installed --help surfaces to detect flag drift.

ParametersJSON Schema
NameRequiredDescriptionDefault
cliNoCLI filter (claude|codex|gemini|grok|mistral|devin|cursor)
probeInstalledNoWhen true, run local --help probes and compare advertised flags against the declared contract. Strongly recommended after any provider CLI upgrade to detect drift.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark it read-only, idempotent, and non-destructive. The description adds the meaningful behavioral detail that probeInstalled runs local --help probes and diffs them against declared contracts. It stops short of explaining the shape of the returned contracts, but the main side-effect behavior is disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One compact sentence front-loads the main purpose and then appends the conditional probe behavior. No filler or repetition; every phrase earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only, zero-required-parameter tool, the description plus schema fully covers invocation: the cli enum is specified, the probe mode is explained, and there is no ambiguity about what is returned. The lack of an output schema means the agent won't know the exact return shape, but that is less critical for a simple retrieval call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents cli filtering and the probeInstalled behavior. The description's mention of diffing restates the schema's 'compare advertised flags against the declared contract' without adding new parameter-level semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a concrete action ('Return') and a specific resource ('the gateway's declared provider CLI contracts'), and it is immediately distinguishable from installed-CLI drift tools. It does not explicitly name sibling alternatives, so it stops short of top-tier differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'with probeInstalled true' clause gives a clear contextual trigger for the probe/diff mode—detecting flag drift—and the schema adds the post-upgrade recommendation. It does not explicitly state when to prefer a sibling such as provider_subcommand_drift or when not to use this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validate_with_modelsA
Destructive

Ask two or more provider CLIs to independently validate a question. Starts validation jobs — poll with job_status, collect with job_result (not llm_job_*).

ParametersJSON Schema
NameRequiredDescriptionDefault
focusNoWhat reviewers should pay attention to.correctness, missing assumptions, and practical next steps
modelsNoProviders to ask. Defaults to Claude and Codex.
selectNoOptional least-cost routing: fill the provider target(s) from the LCR selector instead of the explicit list. 'cheapest' picks the single cheapest eligible provider; 'cheapest_per_tier' picks the cheapest in each quality tier. Requires [least_cost].enabled=true; fails closed (no default-list fallback) when disabled or nothing is eligible.
questionYesQuestion or content to validate.
judgeModelNoOptional provider to run an explicit judge synthesis job.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses the key behavioral trait beyond annotations: the call is asynchronous and merely starts jobs whose results must be fetched separately via job_status/job_result. Annotations already carry the safety profile (destructiveHint=true, readOnlyHint=false), and the description does not contradict them. It does not explain what 'destructive' means here (e.g., consuming provider quota/credits), but the operationally critical behavior is covered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences totaling roughly 30 words, with the core purpose front-loaded and the operational caveat second. Every clause earns its place; the 'not llm_job_*' disambiguation is high-value given the sibling set.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no output schema and an async job lifecycle, the description covers the critical chain (start → poll with job_status → collect with job_result) and flags the misleading llm_job_* family. Gaps remain: it never states what the call returns (presumably a job identifier), does not flag the cost/quota implications behind destructiveHint, and does not differentiate from the validation-family siblings. Overall it is complete enough for correct invocation of the core flow.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents all five parameters; per the baseline rule this is a 3. The description adds only the 'two or more' multiplicity signal, which sits slightly at odds with the schema's minItems:1 (though the default of two providers reconciles it). No material parameter semantics are added beyond what the schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Ask two or more provider CLIs to independently validate a question') with a clear resource and mechanism. The 'not llm_job_*' note distinguishes the result-collection path from a large family of sibling tools, and the multi-provider framing separates it from single-model tools like ask_model and the various *_request tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit post-invocation workflow guidance: poll with job_status, collect with job_result, plus an explicit exclusion ('not llm_job_*') that prevents a likely mistake given the many llm_job_* siblings. However, it does not name alternative validation tools (e.g., second_opinion, consensus_check, compare_answers) or state when to choose them instead.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validation_receiptA
Read-onlyIdempotent

Retrieve the canonically hashed immutable receipt of a terminal cross-LLM validation run by validationId. Returns minted | pending | expired_unminted (no receipt exists and none can be minted) | verification_failed (a stored receipt does not verify against its run) | not_found (own-or-not-found).

ParametersJSON Schema
NameRequiredDescriptionDefault
formatNoResponse format. markdown returns the human-readable rendering (derived on read, never stored or hashed).json
validationIdYesThe run-level validationId from a validation kickoff response (not a job/correlation id).
includeRawResponsesNoInline complete provider answer text when the owned linked job still exposes identity-verified output (read-time only; never persisted or hashed).

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the operation as read-only, idempotent, and non-destructive; the description adds meaningful behavior beyond that by enumerating all possible return states: minted, pending, expired_unminted, verification_failed, and not_found. It also discloses that the receipt is canonically hashed and immutable, which is useful semantic context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single dense sentence that front-loads the core purpose and packs the status vocabulary into a well-scoped parenthetical. Every clause earns its place, and there is no redundant padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only retrieval tool, the description covers the lookup key, the semantics of the receipt, and all possible return statuses despite the absence of an output schema. An agent has enough context to call the tool correctly and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the parameters are already fully documented in the schema. The description itself adds little parameter-level detail beyond framing validationId as the lookup key, which is expected given the high schema coverage baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Retrieve'), a precise resource ('canonically hashed immutable receipt of a terminal cross-LLM validation run'), and the key parameter (validationId). It clearly distinguishes this from sibling tools like job_status or job_result by focusing on the validation receipt lifecycle rather than job execution status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly situates the tool as the way to obtain receipts for terminal cross-LLM validation runs, and the parameter schema reinforces that it expects a run-level validationId from a validation kickoff response. It does not explicitly name alternatives or exclusion conditions, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

workspace_createA
Destructive

Create a remote HTTP/OAuth workspace alias by creating a new local folder or git repo under a configured allowed root. Not for stdio/local provider path access. Requires LLM_GATEWAY_WORKSPACE_ADMIN=1 and OAuth scope workspace:admin.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNogit
rootYesAllowed-root alias from workspace_list.
slugYesSafe relative path under the allowed root.
aliasYesRegistered workspace alias for remote HTTP/OAuth provider calls. Stdio/local callers should not use workspace_* tools to fix provider path access; pass local workingDir/addDir/includeDirs directly.
setDefaultNo

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate a non-read-only, destructive operation. The description adds useful context beyond annotations: it requires environment and OAuth privileges, and it reveals that the operation creates a new local folder or git repo. It does not discuss collision behavior or side effects of setDefault, but there is no contradiction with the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with no filler. The primary purpose is front-loaded, the excluded use case is stated immediately, and the permission requirements are concise and actionable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutating creation tool with no output schema, the description covers purpose, prerequisites, exclusions, and what gets created. It stops short of a 5 because it does not address what happens if the alias already exists or what setDefault=true actually does at the workspace level.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already documents root, slug, and alias reasonably well. The description reinforces that creation happens 'under a configured allowed root' and distinguishes remote HTTP/OAuth aliases from local paths, but it adds no new meaning for kind or setDefault. At 60% schema coverage, the description helps but does not fully compensate for the undocumented parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Create a remote HTTP/OAuth workspace alias by creating a new local folder or git repo under a configured allowed root.' It clearly distinguishes this from read-only siblings like workspace_list/workspace_get and from workspace_register_existing_repo, which implies registering an existing repo rather than creating a new one.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly excludes stdio/local provider path access and states required privileges (LLM_GATEWAY_WORKSPACE_ADMIN=1, OAuth workspace:admin). It does not explicitly name workspace_register_existing_repo as the alternative for existing repos, but 'creating a new local folder or git repo' and the exclusion of local callers provide clear routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

workspace_getA
Read-onlyIdempotent

Inspect a registered remote HTTP/OAuth workspace alias. Does not list files. Not needed for stdio/local provider calls; do not use workspace_* tools to fix local path access.

ParametersJSON Schema
NameRequiredDescriptionDefault
aliasYesRegistered workspace alias for remote HTTP/OAuth provider calls. Stdio/local callers should not use workspace_* tools to fix provider path access; pass local workingDir/addDir/includeDirs directly.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds the crucial behavioral detail that the tool 'Does not list files' and clarifies the scope to remote HTTP/OAuth aliases, reinforcing the read-only nature. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise: only two sentences, each carrying essential information. It is front-loaded with the main purpose and immediately provides exclusions and usage caveats. No filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simple tool signature (one required parameter, no output schema) and rich annotations, the description covers all necessary context: purpose, scope (remote HTTP/OAuth), exclusions (not for local/stdio, does not list files), and a usage warning. Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% for the single required parameter 'alias', and its description already explains the format and usage context. The tool description adds no additional semantic value beyond the schema, so a baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Inspect a registered remote HTTP/OAuth workspace alias' and explicitly distinguishes what it does not do ('Does not list files'). It also sets the scope (remote HTTP/OAuth) and contrasts with local/stdio contexts.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when not to use the tool ('Not needed for stdio/local provider calls; do not use workspace_* tools to fix local path access'). However, it lacks an explicit statement of when to use it or a comparison with sibling tools like workspace_create or workspace_list, which share the 'workspace' prefix.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

workspace_listA
Read-onlyIdempotent

List registered workspace aliases for remote HTTP/OAuth provider calls. Does not browse files. Stdio/local callers should not use workspace_* tools to fix provider path access; pass local workingDir/addDir/includeDirs directly.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already cover read-only, idempotent, and non-destructive behavior. The description adds meaningful behavioral context: it clarifies the tool only lists aliases, does not browse files, and is scoped to remote provider calls. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with no filler. The primary purpose is front-loaded, followed by a critical exclusion and a direct alternative. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only list tool, the description is complete. It covers purpose, scope, exclusions, and alternatives. The absence of an output schema is not a significant gap given the simplicity of the operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and schema coverage is 100%, so there are no parameter gaps to fill. The description correctly does not invent parameters. Baseline for 0 params is 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('List') and resource ('registered workspace aliases') and states the purpose ('for remote HTTP/OAuth provider calls'). It also explicitly distinguishes the tool from file browsing ('Does not browse files'), making it easy to differentiate from sibling workspace tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly specifies when to use the tool (remote HTTP/OAuth provider calls) and when not to, telling Stdio/local callers to avoid workspace_* tools and instead pass workingDir/addDir/includeDirs directly. This is strong, actionable routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

workspace_register_existing_repoA

Register an existing local Git repo as a remote HTTP/OAuth workspace alias. Not for stdio/local provider path access. Requires LLM_GATEWAY_WORKSPACE_ADMIN=1 and OAuth scope workspace:admin.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesAbsolute path to an existing Git repo under an allowed root.
aliasYesRegistered workspace alias for remote HTTP/OAuth provider calls. Stdio/local callers should not use workspace_* tools to fix provider path access; pass local workingDir/addDir/includeDirs directly.
setDefaultNo

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal this is not read-only, and the description adds important authorization requirements beyond them. It does not, however, describe what happens if the alias already exists or whether the registration persists or overwrites, leaving some side-effect ambiguity.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two front-loaded sentences cover purpose, exclusion, and prerequisites with no filler. Every sentence earns its place and the description avoids repeating schema details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is adequate for basic invocation, covering purpose, exclusions, and auth requirements. However, with no output schema, no explanation of setDefault semantics, and no statement about persistence or failure behavior, there are clear gaps that prevent it from being fully self-contained.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67%, and the schema already describes path and alias. The description adds little semantic detail beyond the schema. The setDefault parameter has no description in the schema and is not mentioned in the description, so its meaning is left to inference.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action and resource: 'Register an existing local Git repo as a remote HTTP/OAuth workspace alias.' This clearly identifies what the tool does and differentiates it from local/stdio access and from sibling workspace tools like workspace_list or workspace_create.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says the tool is 'Not for stdio/local provider path access' and directs those callers to pass local workingDir/addDir/includeDirs directly, both in the description and in the alias parameter description. It also lists concrete prerequisites: LLM_GATEWAY_WORKSPACE_ADMIN=1 and OAuth scope workspace:admin.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 59 tool updatesv3.2.0
    • Addedapproval_list
    • Addedask_model
    • Addedclaude_request
    • Addedclaude_request_async
    • Addedcli_upgrade
    • Addedcli_versions
    • Addedcodex_fork_session
    • Addedcodex_request
    • Addedcodex_request_async
    • Addedcompare_answers
    • Addedconfig_ack_stale
    • Addedconfig_init
    • Addedconfig_publish
    • Changedconfig_recover_kit_attempt1 field changed
      • changedInput schema / properties / provider / enum
        Previous value: -[
        -  "claude",
        -  "codex"
        -]New value: +[
        +  "claude",
        +  "codex",
        +  "mistral"
        +]
    • Addedconfig_rollback
    • Addedconsensus_check
    • Addedcursor_request
    • Addedcursor_request_async
    • Addeddevin_request
    • Addeddevin_request_async
    • Addedgemini_request
    • Addedgemini_request_async
    • Addedgrok_request
    • Addedgrok_request_async
    • Addedjob_result
    • Addedjob_status
    • Addedlist_available_models
    • Addedlist_models
    • Changedllm_job_result2 fields changed
      • addedInput schema / properties / nativeTranscriptOffsetChars
        Added value: +{
        +  "default": 0,
        +  "description": "Provider-native transcript character offset for resumable retrieval. Non-zero offsets require rawOutput:true.",
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • changedInput schema / properties / rawOutput / description
        Previous value: -"Return captured provider streams without display parsing or compression. Local stdio pages concatenate to the captured streams; remote pages redact provider session IDs. Required for resumable offsets."New value: +"Return captured provider streams without display parsing or compression. Available only to local stdio callers. Required for resumable offsets."
    • Addedllm_job_status
    • Addedllm_job_watch
    • Addedllm_process_health
    • Addedllm_request_list
    • Addedllm_request_result
    • Addedmistral_request
    • Addedmistral_request_async
    • Addedprovider_admin_list
    • Addedprovider_admin_mutate
    • Addedprovider_admin_run
    • Addedprovider_subcommand_contract
    • Addedprovider_subcommand_drift
    • Addedprovider_subcommands_list
    • Addedprovider_version_guard
    • Addedred_team_review
    • Addedreview_changes
    • Addedsecond_opinion
    • Changedsession_clear_all1 field changed
      • changedInput schema / properties / cli / description
        Previous value: -"Provider filter (claude|codex|gemini|grok|mistral|grok-api)"New value: +"Provider filter (claude|codex|gemini|grok|mistral|devin|cursor|grok-api)"
    • Addedsession_create
    • Addedsession_delete
    • Addedsession_get
    • Addedsession_list
    • Addedsession_set_active
    • Addedsynthesize_validation
    • Addedupstream_contracts
    • Addedvalidate_with_models
    • Addedvalidation_receipt
    • Addedworkspace_create
    • Addedworkspace_list
    • Addedworkspace_register_existing_repo
  2. 53 tool updatesv3.0.0
    • Removedapproval_list
    • Removedask_model
    • Removedclaude_request
    • Removedclaude_request_async
    • Removedcli_upgrade
    • Removedcli_versions
    • Removedcodex_fork_session
    • Removedcodex_request
    • Removedcodex_request_async
    • Removedcompare_answers
    • Addedconfig_recover_kit_attempt
    • Addedconfig_status
    • Addedconfig_sync
    • Removedconsensus_check
    • Removedcursor_request
    • Removedcursor_request_async
    • Removeddevin_request
    • Removeddevin_request_async
    • Addedexplain_effective_config
    • Removedgemini_request
    • Removedgemini_request_async
    • Removedgrok_request
    • Removedgrok_request_async
    • Removedjob_result
    • Removedjob_status
    • Removedlist_available_models
    • Removedlist_models
    • Changedllm_job_result4 fields changed
      • changedInput schema / properties / maxChars / description
        Previous value: -"Max chars returned per stream"New value: +"Maximum chars returned per stdout/stderr page"
      • addedInput schema / properties / rawOutput
        Added value: +{
        +  "default": false,
        +  "description": "Return captured provider streams without display parsing or compression. Local stdio pages concatenate to the captured streams; remote pages redact provider session IDs. Required for resumable offsets.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / stderrOffsetChars
        Added value: +{
        +  "default": 0,
        +  "description": "Captured stderr character offset for resumable retrieval. Non-zero offsets require rawOutput:true.",
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedInput schema / properties / stdoutOffsetChars
        Added value: +{
        +  "default": 0,
        +  "description": "Captured stdout character offset for resumable retrieval. Non-zero offsets require rawOutput:true.",
        +  "minimum": 0,
        +  "type": "integer"
        +}
    • Removedllm_job_status
    • Removedllm_process_health
    • Removedllm_request_result
    • Removedmistral_request
    • Removedmistral_request_async
    • Removedprovider_admin_list
    • Removedprovider_admin_mutate
    • Removedprovider_admin_run
    • Removedprovider_subcommand_contract
    • Removedprovider_subcommand_drift
    • Removedprovider_subcommands_list
    • Removedred_team_review
    • Removedsecond_opinion
    • Removedsession_create
    • Removedsession_delete
    • Removedsession_get
    • Removedsession_list
    • Removedsession_set_active
    • Removedsynthesize_validation
    • Removedupstream_contracts
    • Removedvalidate_with_models
    • Removedvalidation_receipt
    • Removedworkspace_create
    • Removedworkspace_list
    • Removedworkspace_register_existing_repo
  3. 53 tool updatesv2.16.0
    • First observedapproval_list
    • First observedask_model
    • First observedclaude_request
    • First observedclaude_request_async
    • First observedcli_upgrade
    • First observedcli_versions
    • First observedcodex_fork_session
    • First observedcodex_request
    • First observedcodex_request_async
    • First observedcompare_answers
    • First observedconsensus_check
    • First observedcursor_request
    • First observedcursor_request_async
    • First observeddevin_request
    • First observeddevin_request_async
    • First observedgemini_request
    • First observedgemini_request_async
    • First observedgrok_request
    • First observedgrok_request_async
    • First observedjob_result
    • First observedjob_status
    • First observedlist_available_models
    • First observedlist_models
    • First observedllm_job_cancel
    • First observedllm_job_result
    • First observedllm_job_status
    • First observedllm_process_health
    • First observedllm_request_result
    • First observedmistral_request
    • First observedmistral_request_async
    • First observedprovider_admin_list
    • First observedprovider_admin_mutate
    • First observedprovider_admin_run
    • First observedprovider_subcommand_contract
    • First observedprovider_subcommand_drift
    • First observedprovider_subcommands_list
    • First observedprovider_tool_capabilities
    • First observedred_team_review
    • First observedsecond_opinion
    • First observedsession_clear_all
    • First observedsession_create
    • First observedsession_delete
    • First observedsession_get
    • First observedsession_list
    • First observedsession_set_active
    • First observedsynthesize_validation
    • First observedupstream_contracts
    • First observedvalidate_with_models
    • First observedvalidation_receipt
    • First observedworkspace_create
    • First observedworkspace_get
    • First observedworkspace_list
    • First observedworkspace_register_existing_repo

TDQS

A3.5/5.0
Disambiguation3/5

The provider request tools are cleanly separated by provider and sync/async variants, but the validation family (validate_with_models, second_opinion, red_team_review, consensus_check, ask_model) all start validation jobs with subtly different intents, and job_status vs llm_job_status are easy to confuse. Descriptions help, but an agent could still misselect between these overlapping surfaces.

Naming Consistency3/5

Most names are snake_case and readable, and the provider_request / provider_request_async pattern is consistent. However, conventions are mixed between verb-first names like list_models and noun-first names like session_create, and near-duplicate names such as job_status vs llm_job_status and list_available_models vs list_models create avoidable confusion.

Tool Count2/5

65 tools is far above the 25+ threshold and creates a heavy surface for an agent to navigate. The multi-provider gateway scope justifies some of the bulk, but the per-provider request families, validation tools, and provider-metadata tools could be consolidated substantially.

Completeness4/5

The tool set covers request lifecycle execution, async job management, cross-LLM validation, config releases, sessions, workspaces, provider admin, and request history with no obvious dead ends. Minor gaps exist—there is no workspace delete/update and no direct validation-job listing—but agents can work around them.

Maintenance

ActivityActive
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    C
    maintenance
    This is a powerful Model Context Protocol (MCP) server that integrates multiple AI coding agents—Anthropic Claude Code, OpenAI Codex, and Google Gemini—directly into your workflow. It enables seamless cross-provider analysis, leveraging Gemini's massive token window, Codex's specialized coding capabilities, and Claude's advanced reasoning.
    10
    19
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Unified local MCP AI Gateway that routes across Groq, OpenRouter, Mistral, and local Ollama providers, with OpenAI-compatible APIs, MCP tools, fallback/racing router, monitoring, and web dashboard.
    -
  • A
    license
    A
    quality
    A
    maintenance
    One local gateway for all your MCP servers — shared by every AI coding tool (Claude, Cursor, VS Code, Codex). Set up each server once; keys stay in the OS keychain; lazy discovery keeps agent context small. Local-first, open source.
    4
    0
    203
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/verivus-oss/llm-cli-gateway'

If you have feedback or need assistance with the MCP directory API, please join our Discord server