Quickstart
Create an API key, install the SDK, and run Fantail or Moa from your host language.
The examples below use the current CLI-backed SDK flow where each wrapper starts or controls the Autohand runtime, streams events, and returns a final run result. Requests to Autohand-hosted models authenticate with AUTOHAND_API_KEY.
1. Choose your language TypeScript
Pick the SDK you want to start with. The install command and first prompt example update to match.
2. Create an API key
Open API Keys in the Autohand Console and select Create API Key. Use a recognizable name for the machine, service, or environment that will run the SDK.
- Enter a descriptive name such as
local-sdkorproduction-reviewer. - Select Create Key.
- Copy the raw key immediately. The Console will not show the complete value again.
Keep the key server-side. Do not place it in browser code, commit it to a repository, or include it in screenshots and logs. Revoke the key in the Console before rotating the client that uses it.
3. Check prerequisites
- Node.js or Bun.
- The Autohand CLI config in
~/.autohand/config.json. - A repo you want the agent to work in.
- Python 3.10 or newer.
- The Autohand CLI config in
~/.autohand/config.json. - A repo you want the agent to work in.
- Go 1.21 or newer.
- The Autohand CLI config in
~/.autohand/config.json. - A repo you want the agent to work in.
- Java 21 or newer.
- Maven 3.9 or newer.
- The Autohand CLI config in
~/.autohand/config.json.
- Swift 6.0 or newer.
- A provider key such as OpenAI or OpenRouter for the native Swift SDK.
- A repo you want the agent to work in.
- Rust 1.80 or newer.
- Tokio runtime.
- Autohand CLI installed, authenticated, and configured.
- Ruby 3.2 or newer.
- Bundler.
- Autohand Code CLI installed with
bundle exec autohand-sdk install-clior supplied withcli_path:.
- .NET 8 or newer.
- Autohand CLI installed, authenticated, and configured.
- Optional
AUTOHAND_CLI_PATHfor local CLI builds.
- C++20 compiler.
- CMake 3.22 or newer.
- Autohand CLI installed, authenticated, and configured.
4. Install the SDK
bun
bun i @autohandai/agent-sdk
npm
npm install @autohandai/agent-sdkuv
uv add autohand-sdk
pip
pip install autohand-sdkgo get
go get github.com/autohandai/agent-sdk-goMaven
<dependency>
<groupId>ai.autohand</groupId>
<artifactId>agent-sdk-java</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>Package.swift
// swift-tools-version: 6.0
import PackageDescription
let package = Package(
name: "MyAgentApp",
platforms: [.macOS(.v14)],
dependencies: [
.package(path: "../AgentSDK")
],
targets: [
.executableTarget(
name: "MyAgentApp",
dependencies: ["AgentSDK"]
)
]
)Cargo.toml
[dependencies]
autohand-sdk = { git = "https://github.com/autohandai/code-agent-sdk-rust" }
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }Gemfile
gem "autohand_sdk", git: "https://github.com/autohandai/code-agent-sdk-ruby"
CLI
bundle install
bundle exec autohand-sdk install-cli
bundle exec autohand-sdk doctor.NET
dotnet add package Autohand.CodeAgentSdk
Source
# Until the NuGet package is published, reference the project or repository directly from your solution.CMake
include(FetchContent)
FetchContent_Declare(
autohand_sdk
GIT_REPOSITORY https://github.com/autohandai/code-agent-sdk-cpp.git
GIT_TAG main
)
FetchContent_MakeAvailable(autohand_sdk)
target_link_libraries(my_app PRIVATE autohand::sdk)5. Configure authentication
Export the key in the shell or secret manager that launches your application. The CLI-backed SDKs read AUTOHAND_API_KEY from the server environment.
macOS / Linux
export AUTOHAND_API_KEY="your-api-key"
PowerShell
$env:AUTOHAND_API_KEY = "your-api-key"Use fantail for focused, latency-sensitive coding loops and moa for deeper repository-wide work. The examples on the documentation home page show both model identifiers for every supported language.
If you bring your own provider instead, configure that provider in ~/.autohand/config.json or through the provider-native SDK adapter. Keep every provider credential server-side.
6. Run your first prompt
main.ts
import { AutohandSDK } from '@autohandai/agent-sdk';
async function main() {
const sdk = new AutohandSDK({ cwd: '.', debug: true });
await sdk.start();
for await (const event of sdk.streamPrompt({
message: 'List the main source files and tell me what looks risky.'
})) {
if (event.type === 'message_update') {
process.stdout.write(event.delta);
}
}
await sdk.stop();
}
main();main.py
import asyncio
from autohand_sdk import AutohandSDK
async def main():
async with AutohandSDK(cwd='.') as sdk:
async for event in sdk.stream_prompt('List the main source files and tell me what looks risky.'):
if event['type'] == 'message_update':
print(event.get('delta', ''), end='')
asyncio.run(main())main.go
package main
import (
"context"
"fmt"
"log"
autohand "github.com/autohandai/agent-sdk-go"
)
func main() {
ctx := context.Background()
sdk := autohand.NewSDK(&autohand.Config{CWD: "."})
if err := sdk.Start(ctx); err != nil {
log.Fatal(err)
}
defer sdk.Close()
events, err := sdk.StreamPrompt(ctx, &autohand.PromptParams{
Message: "List the main source files and tell me what looks risky.",
})
if err != nil {
log.Fatal(err)
}
for event := range events {
if e, ok := event.(autohand.MessageUpdateEvent); ok {
fmt.Print(e.Delta)
}
}
}Main.java
import ai.autohand.sdk.sdk.Agent;
import ai.autohand.sdk.sdk.AgentOptions;
import ai.autohand.sdk.types.Events;
public final class Main {
public static void main(String[] args) throws Exception {
Agent agent = Agent.create(AgentOptions.builder()
.cwd(".")
.instructions("Be concise and specific.")
.build());
var run = agent.send("List the main source files and tell me what looks risky.");
run.stream(event -> {
if (event instanceof Events.MessageUpdateEvent mue) {
System.out.print(mue.delta());
}
});
agent.close();
}
}main.swift
import AgentSDK
import Foundation
let provider = OpenAIProvider(apiKey: "sk-...")
let agent = Agent(
name: "Reviewer",
instructions: "Be concise and specific.",
tools: [.readFile, .bash],
model: ModelID("gpt-4o"),
provider: provider
)
let stream = Runner.runStream(
agent: agent,
prompt: "List the main source files and tell me what looks risky."
)
for try await event in stream {
if event.type == .content, let data = event.data {
print(data, terminator: "")
}
}main.rs
use autohand_sdk::{Agent, Config, Result};
#[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 result = agent
.run("List the main source files and tell me what looks risky.")
.await?;
println!("{}", result.text);
agent.close().await?;
Ok(())
}main.rb
require "autohand_sdk"
AutohandSDK::Agent.open(
cwd: ".",
instructions: "Review code with staff-level Ruby judgement.",
permission_mode: "interactive"
) do |agent|
run = agent.send("List the main source files and tell me what looks risky.")
run.stream.each do |event|
print event["delta"] if event["type"] == "message_update"
end
result = run.wait
puts result.fetch(:text)
endProgram.cs
using Autohand.CodeAgentSdk;
await using var agent = await Agent.CreateAsync(new AgentOptions
{
WorkingDirectory = ".",
Instructions = "Review code with staff-level C# judgement.",
});
var run = agent.Send("List the main source files and tell me what looks risky.");
await foreach (var item in run.StreamAsync())
{
if (item is MessageUpdateEvent message)
{
Console.Write(message.Delta);
}
}
var result = await run.WaitAsync();
Console.WriteLine(result.Text);main.cpp
#include <autohand/sdk.hpp>
#include <iostream>
int main() {
autohand::Agent agent(
autohand::Config::from_environment()
.with_cwd(".")
.with_instructions("Review code with senior C++ judgement."));
auto run = agent.send("List the main source files and tell me what looks risky.");
run.stream([](const autohand::SdkEvent& event) {
if (event.type == "message_update") {
std::cout << event.text_delta();
}
});
auto result = run.wait();
std::cout << result.text << "\n";
agent.close();
}Run the example
Bun
bun main.ts
Node.js
npx tsx main.tsPython
python main.pyGo
go run .Maven
mvn compile exec:java -Dexec.mainClass=MainSwift
swift runCargo
cargo runRuby
bundle exec ruby main.rb.NET
dotnet runCMake
cmake -S . -B build
cmake --build build
./build/my_appCompletion checkpoint
You’re connected when the response streams from your repository
The exact answer depends on the project. A successful first run should start without an authentication error, stream text into the terminal, and refer to files in the working directory.
Representative output
Analyzing the current repository…
src/main.ts
src/runtime/session.ts
The highest-risk change is…- The runtime starts without an API-key or CLI-path error.
- Response events arrive before the final result completes.
- The answer names files or risks from the current repository.
7. Next moves
- Go to Handle approvals and user input when you need human review in the loop.
- Open the language guides: TypeScript, Python, Go, Java, Swift, Rust, Ruby, C#/.NET, C++.
- Use the streaming docs next if you are building a terminal UI, dashboard, or chat surface around the SDK.