agent-call
Call Claude, Codex, Devin, and OpenCode v2 from Rust through one async API.
agent-call uses your installed CLIs and their saved authentication. Each
request starts a fresh process and returns the final answer, elapsed time,
session ID, and token usage when the CLI reports it.
- Choose a provider and model without rewriting your application integration.
- Configure tool policies, HTTP MCP servers, and system prompts.
- Persist and resume sessions, and receive progress events where supported.
- Set timeouts and handle typed errors, including provider context.
API reference · crates.io · Releases
Requirements
Install and authenticate the CLI you want to use. AgentCli::discover finds
it on PATH. OpenCode must report major version 2; version 1 is rejected.
No provider API key is required by the library itself. Use env_remove if your
application needs to remove environment variables before spawning the CLI.
Quick start
Add the published crate:
[]
= "0.5.0"
= { = "1", = ["macros", "rt"] }
Then run a prompt:
use ;
use Duration;
async
Set model: None to use the selected CLI's configured default.
Providers
| CLI | Rust provider | Example model | JSON Schema | Sessions | Progress events |
|---|---|---|---|---|---|
| Claude | Provider::Claude |
sonnet@high |
Native | Persist and resume | Text deltas and tools |
| Codex | Provider::Codex |
gpt-5.6-sol@high |
Native | Persist and resume | Messages and tools |
| Devin | Provider::Devin |
swe-2-medium |
Caller validates | Unsupported | Unsupported |
| OpenCode v2 | Provider::OpenCodeV2 |
openai/gpt-5#high |
Caller validates | CLI persists; resume by ID | Messages and tools |
Choose model IDs available in your authenticated CLI configuration. The runnable example accepts a provider and an optional model:
Run these commands from a clone of this repository.
Tools, MCP servers and system prompts
The default policy uses each CLI's permissions described under
Execution behavior. For untrusted prompts, choose
ToolPolicy::McpOnly or ToolPolicy::Web to restrict built-in tools. These
policies disable shell, file access, and code execution in the CLI. Configure
MCP servers to expose only the tools your application intends to allow.
tool_policy |
Agent may use | Claude | Codex | Devin, OpenCode |
|---|---|---|---|---|
Default |
CLI permissions described below | ✅ | ✅ | ✅ |
McpOnly |
tools of the request's mcp_servers |
✅ | ✅ | InvalidRequest |
Web |
McpOnly plus built-in web search and fetch |
✅ | ✅ | InvalidRequest |
use ;
let request = RunRequest ;
Claude and Codex support per-request HTTP MCP servers. With a restricted
policy, the request's servers replace servers from the CLI's configuration.
Bearer tokens are passed through the child environment. A provider that cannot
enforce a requested policy or MCP configuration returns Error::InvalidRequest
before starting a process.
system_prompt appends instructions to the CLI's own system prompt for Claude
and Codex. Devin and OpenCode receive those instructions before the user prompt.
Use AgentCli::native_system_prompt() to check support. See SPEC.md
for the native command and permission contracts.
Sessions and progress events
Claude and Codex runs are ephemeral by default. Set persist_session: true
to retain a session, then pass RunResult::session_id as resume in a later
request with the same cwd. OpenCode manages persistence itself; Devin does
not support session resumption.
| Provider | Persist | Resume | Unknown session |
|---|---|---|---|
| Claude | drops --no-session-persistence |
--resume <id> |
Error::SessionNotFound |
| Codex | drops --ephemeral |
codex exec resume <id> (sandbox via -c sandbox_mode) |
Error::SessionNotFound |
| OpenCode v2 | always | --session <id> |
the CLI starts a new session with that id |
| Devin | — | InvalidRequest |
— |
on_event: Some(EventHandler::new(|event| …)) reports progress while the run goes on:
AgentEvent::TextDelta (Claude streams the answer with --output-format stream-json),
AgentEvent::Text (whole messages from Codex and OpenCode) and AgentEvent::ToolUse { name }
(web searches, MCP tools). The final RunResult is the same as without events.
Structured output and errors
Set RunRequest::json_schema to request native JSON Schema enforcement from
Claude or Codex. Devin and OpenCode return text for your application to validate.
RunResult::usage is None when token usage is unavailable or incomplete.
Use discover_with_context, with_binary_with_context, and
run_with_context when the caller needs the selected provider alongside a
failure. ProviderError exposes provider and the original source: Error;
exit_code() and stderr_tail() read the fields of an Error::Exit without
parsing its display text. The original methods remain available.
Development
Run the automated tests with fake CLIs, without using provider quota:
Real CLI smoke tests
The opt-in smoke tests make one short request per provider. Set the model to one supported by your authenticated CLI, then run a single test:
AGENT_CALL_CODEX_MODEL='gpt-5.6-sol@high' \
Replace CODEX and codex with CLAUDE/claude, DEVIN/devin, or
OPENCODE/opencode. These calls use real quota and have a 180-second timeout.
Claude and Codex receive a native JSON Schema; Devin and OpenCode output is
checked as JSON by the test because their adapters do not enforce schemas.
The regular cargo test suite uses fake CLIs and does not make real calls.
Execution behavior
Each request starts a new CLI process. A timeout or cancellation terminates
that process; the library does not retry automatically. Claude uses
bypassPermissions, Codex uses a read-only sandbox, Devin uses its auto
permission mode, and OpenCode follows its headless permission defaults without
--auto.
Releases
The Rust crate is published on crates.io. GitHub Releases provide version tags and changelogs. GitHub's Packages sidebar is separate from crates.io and does not list this crate.
For maintainers, see docs/releasing.md for the tag-driven release
process, Trusted Publishing setup, and recovery steps. Use Conventional Commits;
git-cliff generates the changelog. main carries the next version with -dev.
License
Licensed under MIT or Apache-2.0, at your option.