opencode-rust

A Rust rewrite of the OpenCode coding agent: CLI, TUI and HTTP server for local AI agents, with no Docker runtime.

Stars
★ 52
Last updated
2d ago
License
MIT
Primary language
Rust

At a glance

Works with
Portable with changesOpenAI API · Claude API
You'll need
Node.js 18+Rust toolchain (Homebrew or source install)Provider API key (e.g. ANTHROPIC_API_KEY)Shell / CLINetwork accessLocal filesystemMCP Server
Typical use
Developers who want repository-level reading, editing and analysis from a terminal TUI rather than a web chat.
Main limitation
run has never been exercised end-to-end against a funded provider; the README says free OpenRouter models reject the tool schema and paid ones return 402 without credits.

What does this agent do, and when should you use it?

opencode-rust is a Rust implementation of OpenCode, shipped as a 20-crate Cargo workspace: opencode-cli (the opencode binary plus agent aliases), opencode-server (HTTP/SSE/WebSocket plus MCP loading), opencode-session (the prompt loop), opencode-agent, opencode-tool (22 built-in tools and a registry), opencode-provider, opencode-mcp, opencode-plugin, opencode-lsp, opencode-storage (SQLite) and opencode-tui. It installs via npm, Homebrew or install.sh and exposes a single opr command that dispatches to an interactive TUI, a one-shot run mode, an HTTP server, and web and ACP surfaces. The design rationale is replacing the TypeScript engine's memory growth: conversation history spills to SQLite, tool schemas are cached per (model, tool-set), and per-directory instance state is pooled by config hash with LRU+TTL eviction, so no container is needed to contain leaks. The deployment boundary is still a local process that spawns Node subprocesses for the plugin bridge and launches MCP servers through npx, so Node 18+ and your own provider key are always required.

Running opr opens the TUI, opr run "..." drives the same SessionPrompt loop used by the HTTP server, and opr serve --port 3000 starts an HTTP/SSE/WebSocket server. The session loop sends turns through provider adapters in opencode-provider, handles streaming tool calls, and resolves and executes both the 22 built-in tools and MCP tools through the per-turn ToolRegistry in opencode-tool; permissions are scoped per path with the last matching rule winning. Tooling side channels go through opencode-mcp (newline-delimited JSON stdio or HTTP transports), opencode-lsp for language servers, and opencode-plugin, which hosts TypeScript plugins in Node subprocesses with a correlated sendNotification/params.requestId reverse channel. Sessions, messages and parts persist in SQLite. After a turn, run waits for session.idle, for child agents recorded in the database, and for background-task state in .omo/run-continuation/<session>.json, capped by --wait-background-timeout (default 120 s) and failing open rather than hanging.

  1. Developers who want repository-level reading, editing and analysis from a terminal TUI rather than a web chat.
  2. Teams embedding a coding agent into internal tooling via opr serve and the ACP/Web interaction modes.
  3. Engineers who want a single local binary and reject a Docker runtime for their agent.
  4. Users who already keep OpenCode / oh-my-opencode config (opencode.json, ~/.omo/omo.jsonc) and want their agent definitions and models honored.
  5. Projects that need MCP servers and LSP language services wired into the coding agent.

How do you install or deploy this agent?

npm (Linux, macOS, Windows; the installer never compiles and pulls a prebuilt per-platform package):

npm install -g opencode-rust

Homebrew (macOS and Linux; builds from source, so the first install pulls a Rust toolchain):

brew install vakandi/tap/opencode-rust

From source:

git clone https://github.com/vakandi/opencode-rust.git
cd opencode-rust
./install.sh          # builds the release binary and installs opr; --force rebuilds

Node 18+ is required, and a provider key must be set before the first run:

export ANTHROPIC_API_KEY=sk-ant-...

How do you use this agent?

First working invocations:

opr                                   # interactive TUI
opr run "check this repo for risks"    # one prompt, runs to completion
opr serve --port 3000                 # HTTP server

Under npm install, opr is a dispatcher script, so opr --some-flag becomes opencode tui --some-flag. Under Homebrew or install.sh, opr is the engine binary and flags need an explicit subcommand:

opr tui --some-flag

Inspect the data location and run the test suite:

opr db path
cargo test --workspace

What are this agent's strengths and limitations?

Pros
  • Runs as a single local binary with no Docker, cgroups or container runtime to manage.
  • Full extension surface: multi-provider adapters, MCP stdio+HTTP, LSP clients and a TypeScript plugin bridge.
  • MCP is measured after repair: 3 servers start in about 4 s and 77 tools are exposed to agents.
  • Durable state design: SQLite conversation storage, per-(model, tool-set) schema caching, config-hash LRU+TTL instance pooling.
  • run waits for spawned subagents and background tasks to finish, and fails open instead of hanging.
Limitations
  • run has never been exercised end-to-end against a funded provider; the README says free OpenRouter models reject the tool schema and paid ones return 402 without credits.
  • Node 18+ is mandatory regardless of install method, because of the plugin bridge and npx-launched MCP servers.
  • opr semantics differ by channel: a dispatcher script under npm, the engine binary under Homebrew/install.sh.
  • Homebrew and source installs require a Rust toolchain and a first full build.
  • A 20-crate workspace plus multiple config merge paths raises the learning curve before first productive use.

How does this agent compare with similar options?

The README positions this as a Rust implementation of OpenCode and contrasts directly with the original TypeScript engine: that engine held history in RAM, re-derived tool schemas on every LLM step, kept unbounded per-directory instance state, and needed a Docker runtime to contain the resulting load; this version moves history to SQLite, caches schemas and evicts instance state via LRU+TTL, removing the container. It states it is not affiliated with the OpenCode team.

Key facts side by side with the most closely related agents.

Agent Source review Form / cost Stars Updated Language Full support on
opencode-rust This agent 46 · Major gaps — ★ 52 2d ago Rust OpenAI API · Claude API
zerostack 57 · Major gaps CLIFree + model costs ★ 1.7k today Rust OpenAI API · Claude API
Tura 65 · Some gaps CLIFree + model costs ★ 657 19d ago Rust —
Aster 77 · Good CLIFree + model costs ★ 132 today Rust OpenAI API

How does FollowAgents rate this agent?

FollowAgents source review · FARS-2.1
Major gaps
46/ 100 5-point scale 2.3 / 5
Trust 11/29
Reliability 6/14
Adaptability 10/18
Convention 9/18
Effectiveness 6/13
Verifiability 4/8
Why each dimension lost points
Trust11 / 29 · 1.9/5

README and docs/opencode-permission.md describe a permission layer with per-path scoping, last-match-wins rules and allow/deny/ask plus a PermissionAsk hook, but this is design prose only: no default policy, confirmation flow or concrete handling of API keys and session data is shown, so least_privilege, user_confirmation and sensitive_data_handling each score 1. On data flow, the README states sessions spill to SQLite, plugins run as Node subprocesses and MCP servers launch via npx, but never defines what leaves the machine, so data_flow_transparency is 1. Dependency security: Cargo.toml pins a few crates (nucleo-matcher, syntect, similar) but there is no audit or advisory note, so 1. External effects and rollback: install.sh/clean.sh have guard rails and --force semantics, yet tool execution has no rollback path, so both score 1. source_attribution is 2: LICENSE is present and the README credits OpenCode upstream with an explicit non-affiliation statement.

Reliability6 / 14 · 2.1/5

The README gives detailed accounts of the run drain loop, MCP fixes and TUI defects, but it contradicts itself: it claims npm ships per-platform binary packages, while publish.yml comments say that scheme was abandoned in favour of release assets fetched by install.js, so self_consistency drops to 1. dependency_availability is 1: Node 18+ and npx are mandatory, Homebrew pulls a Rust toolchain, and no offline path is offered. failure_messages is 2: unmatched platforms print alternatives and exit cleanly, the drain fails open rather than hanging, and the TUI surfaces API errors.

Adaptability10 / 18 · 2.8/5

The README distinguishes TUI, run, serve, web and acp surfaces plus build/plan agents, so audience_and_scenarios is 2. capability_boundaries is 2: build is full-access, plan is read-only, and run vs TUI behaviour is called out. trigger_precision drops to 1 because opr means different things per install method (npm dispatcher vs engine binary), so the same command behaves inconsistently. environment_fit is 2, covering Linux/macOS/Windows and multiple architectures.

Convention9 / 18 · 2.5/5

information_architecture is 2: clear README structure, repository layout and docs index. install_notes is 2, detailing npm, Homebrew and source installs with their differences. naming_stability is 1 due to the opr/opencode dual naming and install-dependent semantics. examples_and_faq is 1: a few command examples but no FAQ. known_limitations is 2, explicitly stating run was not exercised end-to-end against a funded provider. license is 2, MIT with a complete file. versioning_changelog is 1: only workspace 0.1.0 and v* tag releases, no CHANGELOG. maintenance_responsibility is 1: the publisher is unverified and the LICENSE copyright holders (opencode, ChrisFeldmeier) do not match the repository owner (vakandi), leaving ownership unclear.

Effectiveness6 / 13 · 2.3/5

output_usability is 2: CLI command table, run flags and config paths are documented. marginal_value is 1: as a Rust rewrite of OpenCode the pitch (no Docker, SQLite persistence) is stated but not quantified against upstream. cost_benefit is 1: it requires a Node runtime, a Rust toolchain for Homebrew, and a provider key, while the benefit evidence remains thin.

Verifiability4 / 8 · 2.5/5

claim_traceability is 1: the fix narratives (three MCP defects, TUI width bugs) point at code but cite no commits or test links. cross_source_corroboration is 1: README, docs and workflows partly corroborate each other, yet the npm packaging story conflicts. fact_inference_separation is 2: the README clearly separates what was measured from what was not, via the known-limitation section.

Risks and how to mitigate them
  • README and publish.yml disagree on npm distribution (per-platform packages vs release assets), so install behaviour must be verified independently.
  • opr means different things under npm, Homebrew and install.sh; the same command may be forwarded or rejected, so confirm the install method before scripting.
  • The permission layer is design documentation only; no default policy or confirmation flow is evidenced, so review config before high-risk tool operations.
  • LICENSE copyright holders do not match the repository owner and the publisher is unverified; treat supply-chain and maintenance ownership with caution.
  • run was not exercised end-to-end against a funded provider, so tool execution and subagent draining are unproven in practice.
Evidence confidence: Low Reviewed Oct 26, 2026 Reviewed revision a8d5612f9921
See the full review method →

FAQ

Do I have to pay to use it?
The software is MIT-licensed and free, but you supply your own provider API key and pay per use. The documented limitation notes paid providers returning 402 without credits, and free OpenRouter models rejecting the tool schema.
Why does it need Node if it is written in Rust?
The engine spawns Node subprocesses for the plugin bridge and launches MCP servers through npx, so Node 18+ is required even though npm installs never compile anything.
Is MCP actually functional?
The README documents three fixed defects: LSP-style Content-Length framing instead of newline-delimited JSON, an untagged enum that discarded McpServerConfig entries, and unbounded sequential boot. After the fix, 3 servers start in about 4 s and expose 77 tools.
Does opr run drop work when the process exits?
It is designed not to. run follows the SessionPrompt loop, then waits for session.idle, child rows in SQLite and the .omo/run-continuation ledger, capped at 120 s by default and configurable with --wait-background-timeout; missing or corrupt state is treated as idle.
Is opr the same command everywhere?
No. Installed via npm it is a dispatcher that forwards to opencode tui; installed via Homebrew or install.sh it is the engine binary itself, so you must name the subcommand explicitly.
View on GitHub ↗ Install ↓

Compare agents like this one

The same FARS review applied across the shortlist this agent qualifies for.

Related agents