Autohand Code Agent SDK for Rust
July 31, 2026 ยท View on GitHub
Rust SDK for building applications that control Autohand code agents through the Autohand CLI JSON-RPC mode.
Documentation: https://autohand.ai/docs/agent-sdk/
Beta: this SDK is actively evolving while the Agent SDK APIs stabilize. Pin versions in production and review release notes before upgrading.
What It Does
The Rust SDK wraps the existing Autohand CLI process and gives Rust applications an async, typed API for agent runs:
Rust app -> autohand-sdk -> Autohand CLI subprocess -> provider -> model
Use it when you want to embed Autohand inside a Rust service, developer tool, CLI, desktop app, or test harness while keeping the same CLI behavior users already trust.
Features
- Tokio-based subprocess transport over JSON-RPC 2.0
AgentandRunfor high-level application workflowsAutohandSdkfor direct low-level RPC access- Typed streaming events for messages, tools, permissions, and errors
- Permission response helpers for host-controlled approval flows
- Structured JSON helpers for typed agent output
- Example parity with the TypeScript SDK examples
- Typed replayable autoresearch lifecycle, ledger operations, events, and hooks
- Validated generic slash commands plus deep-research/autoresearch helpers
- Seven typed persistent-goal RPCs and live command discovery
- Current session, AGENTS.md, token, skill-source, prompt-file, MCP, agent, and plugin flags
- Startup feature settings, typed turn usage, and AutohandAI environment support
- Typed community-skill discovery/installation and MCP server/tool/configuration inspection
- Transactional, clone-safe lifecycle state and deterministic sub-50 ms startup gates
- A closed Blueprint answer-only profile with classified inputs, strict JSON results, passive runtime facts, deny-all child egress, and bounded capture
- A separate setup-only Autohand device-authorization profile that keeps private transaction state inside an opaque SDK handle
Requirements
- Rust 1.76 or later
- Tokio runtime
- Autohand CLI installed and authenticated
- A configured provider in
~/.autohand/config.json, or environment variables accepted by the CLI
Set AUTOHAND_CLI_PATH when you want to force a local CLI binary:
export AUTOHAND_CLI_PATH=/path/to/autohand
Installation
Until the crate is published, use the GitHub repo directly:
[dependencies]
autohand-sdk = { git = "https://github.com/autohandai/code-agent-sdk-rust" }
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
The crate name is planned as autohand-sdk.
Quick Start
use autohand_sdk::{Agent, Config, Result, SdkEvent};
#[tokio::main]
async fn main() -> Result<()> {
let mut agent = Agent::create(
Config::from_env()
.with_cwd(".")
.with_instructions("Review code with senior Rust judgement."),
)
.await?;
let mut run = agent.send("Review this repository for release readiness.").await?;
while let Some(event) = run.next().await {
match event? {
SdkEvent { event_type, raw } if event_type == "message_update" => {
if let Some(delta) = raw.get("delta").and_then(|value| value.as_str()) {
print!("{delta}");
}
}
SdkEvent { event_type, raw } if event_type == "permission_request" => {
eprintln!("permission requested: {raw}");
}
_ => {}
}
}
let result = run.wait().await?;
println!("\nRun {} finished with {}", result.id, result.status);
agent.close().await?;
Ok(())
}
Low-Level Control
Use AutohandSdk when your host needs direct access to the JSON-RPC control surface:
use autohand_sdk::{AutohandSdk, Config, PromptOptions, Result};
#[tokio::main]
async fn main() -> Result<()> {
let mut sdk = AutohandSdk::new(Config::from_env().with_cwd("."));
sdk.start().await?;
sdk.set_plan_mode(true).await?;
let mut events = sdk
.stream_prompt(
"Create a discovery plan for this SDK change.",
PromptOptions::default(),
)
.await?;
while let Some(event) = events.recv().await {
println!("{:?}", event?);
}
sdk.stop().await?;
Ok(())
}
Examples
The examples/ directory mirrors the TypeScript SDK example inventory:
01-hello-agent.rs02-streaming-query.rs03-code-reviewer.rs04-bash-command.rs05-file-editor.rs06-prompt-skills.rs07-direct-skills.rs08-memory-management.rs10-multi-tool-reasoning.rs13-permissions.rs20-sdlc-discovery-plan.rs21-sdlc-gated-implementation.rs22-sdlc-release-readiness.rs23-system-prompts.rs24-high-level-agent.rs25-structured-json.rs27-autoresearch-ledger.rsbasic-agent.rsbasic-usage.rsloop-strategies.rspermission-handling.rssdk-control-features.rsstreaming.rs
Run an example with:
cargo run --example 01-hello-agent
Live examples require an authenticated Autohand CLI and may ask for tool permissions depending on your CLI configuration.
Skill And MCP Discovery
Agent and AutohandSdk expose get_skills_registry, install_skill,
list_mcp_servers, list_mcp_tools, and get_mcp_server_configs. Their
request and response structures are typed, including SkillInstallScope and
McpTransport enums that match the current CLI wire contract.
Startup Performance
A deterministic fake-CLI gate measures publicImportMs, sdkStartReturnMs,
and fixtureSpawnToFirstRpcMs with five warmups and 50 samples. All
wrapper-controlled p95 values must stay below 50 ms. See
Startup Performance for boundaries, current
results, and why live CLI/provider readiness remains an environment-dependent
measurement.
Documentation
- Getting Started
- API Reference
- Configuration
- Event Streaming
- Permissions
- Plan Mode
- SDLC Workflows
- Error Handling
- Examples
- Replayable Autoresearch
- Conversation, Browser Handoff, And Auto-Mode Control
- Startup Performance
- Blueprint Answer And Setup-Only Contracts
- Contributing
- Security
Development
cargo fmt --check
cargo test
cargo check --examples
The transport tests use a deterministic fake CLI, so the unit suite does not require model credentials.
The declared MSRV is proved through a separate consumer crate rather than the SDK's own dependency graph:
cargo +1.76 check --manifest-path tests/msrv-consumer/Cargo.toml --locked
Blueprint Answer Contract
Blueprint uses the typed answer-only profile and run_answer; it does not pass
an untyped prompt to run_json:
use autohand_sdk::{
AnswerOnlyProfile, AutohandSdk, BlueprintArtifactClass,
ClassifiedAnswerEnvelope, ClassifiedArtifact, Config, StrictJsonSchema,
StructuredRunLimits,
};
let config = Config::default()
.with_cli_path("/reviewed/path/to/autohand")
.with_answer_only_profile(AnswerOnlyProfile::blueprint());
let mut sdk = AutohandSdk::new(config);
sdk.start().await?;
let schema = StrictJsonSchema::new(serde_json::json!({
"type": "object",
"properties": { "answer": { "type": "string" } },
"required": ["answer"],
"additionalProperties": false
}))?;
let envelope = ClassifiedAnswerEnvelope::new(
"3b8f9ffb1c1962b70c60a86d3ebfe3c2422e677865057c1b8bc31e813c1db2ed",
vec![ClassifiedArtifact {
id: "evidence-1".into(),
class: BlueprintArtifactClass::SourceSnippet,
content: "fn authenticated() {}".into(),
}],
&schema,
)?;
let answer = sdk
.run_answer::<serde_json::Value>(
envelope,
schema,
StructuredRunLimits::default(),
)
.await?;
See Blueprint answer and setup-only contracts for the full security and lifecycle contract.
Other SDKs
Support
- SDK docs: https://autohand.ai/docs/agent-sdk/
- Issues: https://github.com/autohandai/code-agent-sdk-rust/issues
- Security reports: security@autohand.ai