Quick reference for AI agents integrating with the Axis onchain agent CLI.
| What | Value |
|---|---|
| Type | CLI + HTTP API |
| Language | Shell (CLI), REST (HTTP API) |
| Auth Required | Yes - Cartridge Controller session or private key |
| Rate Limit | None documented (onchain gas limits apply) |
| Install | curl -fsSL https://github.com/bibliothecadao/eternum/releases/latest/download/install-axis.sh | bash |
| Runtime Dir | ~/.eternum-agent |
| Source | https://github.com/bibliothecadao/eternum |
| Docs | https://docs.realms.world/development/axis/overview |
Axis is an onchain agent CLI for the Eternum game. It:
- Discovers active game worlds across slot, sepolia, and mainnet
- Authenticates via Cartridge Controller
- Runs an LLM-driven tick loop observing game state
- Executes on-chain actions generated from contract ABIs
- Persists agent memory and strategy per world
# Install
curl -fsSL https://github.com/bibliothecadao/eternum/releases/latest/download/install-axis.sh | bash
# Configure
echo "ANTHROPIC_API_KEY=sk-ant-..." >> ~/.eternum-agent/.env
# Run (opens browser for auth, starts agent)
axis# Configure
echo "ANTHROPIC_API_KEY=sk-ant-..." >> ~/.eternum-agent/.env
# Authenticate
axis auth my-world --method=password --username=me --password=secret
# Run
axis run --headless --world=my-world --api-port=3000Method: Cartridge Controller session OR private key
Config files: ~/.eternum-agent/.cartridge/<world>/session.json
Session duration: 7 days
axis auth {world} --method=password --username={user} --password={pass}# Generate auth URL
axis auth {world}
# Complete with redirect URL
axis auth {world} --redirect-url="http://localhost:PORT/callback?startapp=..."PRIVATE_KEY=0x... ACCOUNT_ADDRESS=0x... axis run --headless --world=my-world --auth=privatekeyEnable with --api-port={port} in headless mode.
Queue a prompt for the agent to process.
| Parameter | Type | Required | Description |
|---|---|---|---|
content |
string | yes | Prompt text for the agent |
Request:
{
"content": "Build a farm at your main realm"
}Response (200 OK):
{
"status": "queued"
}Get current agent status.
Response (200 OK):
{
"world": "my-world",
"loopEnabled": true,
"tickIntervalMs": 60000,
"lastTick": "2026-03-05T12:00:00Z"
}Get world state snapshot.
Response (200 OK):
{
"world": "my-world",
"entities": [...],
"resources": {...}
}Server-sent events stream.
Response: text/event-stream
Update runtime configuration.
| Parameter | Type | Required | Description |
|---|---|---|---|
changes |
array | yes | Array of {path, value} objects |
Request:
{
"changes": [
{"path": "tickIntervalMs", "value": 30000}
]
}Response (200 OK):
{
"status": "updated"
}Configurable Paths:
tickIntervalMs- Tick interval in msloopEnabled- Enable/disable auto-tickmodelProvider- LLM providermodelId- Model identifier
Graceful shutdown.
Response (200 OK):
{
"status": "shutting_down"
}| Command | Description |
|---|---|
axis |
Run in TUI mode |
axis run --headless --world={name} |
Run in headless mode |
axis worlds |
List discovered worlds |
axis auth {world} |
Generate auth URL |
axis auth {world} --method=password |
Password auth |
axis auth {world} --status |
Check session status |
axis auth --all --status --json |
Check all worlds status |
axis doctor |
Validate configuration |
axis --version |
Print version |
axis --help |
Print usage |
Send JSON objects line-by-line when --stdin is set:
{"type":"prompt","content":"Scout north"}
{"type":"config","changes":[{"path":"tickIntervalMs","value":45000}]}
{"type":"shutdown"}Headless mode emits newline-delimited JSON to stdout:
| Event Type | Verbosity Level | Description |
|---|---|---|
startup |
decisions | Agent started |
session |
quiet | Session state change |
decision |
decisions | Agent made a decision |
action |
actions | On-chain action executed |
prompt |
decisions | Prompt received/processed |
heartbeat |
decisions | Tick heartbeat |
config |
decisions | Configuration change |
error |
quiet | Error occurred |
shutdown |
quiet | Agent shutting down |
tick |
all | Individual tick event |
Verbosity Levels (cumulative):
quiet: error, session, shutdownactions: quiet + actiondecisions: actions + decision, heartbeat, prompt, startup, configall: decisions + tick
When to use: Running multiple agents across worlds
# Auth all worlds
axis auth --all --method=password --username=me --password=secret --json > /tmp/auth.json
# Start agents on random ports
for world in $(jq -r '.[].world' /tmp/auth.json); do
axis run --headless --world="$world" --api-port=$((3000 + RANDOM % 1000)) &
doneWhen to use: Orchestrator needs to send commands
# Send prompt
curl -X POST http://127.0.0.1:3000/prompt \
-H 'Content-Type: application/json' \
-d '{"content":"Build a farm at your main realm"}'
# Update config
curl -X POST http://127.0.0.1:3000/config \
-H 'Content-Type: application/json' \
-d '{"changes":[{"path":"tickIntervalMs","value":30000}]}'When to use: Setting up on headless VPS without browser
# Generate QR (saved to ~/.eternum-agent/.cartridge/{world}/auth-qr.png)
axis auth my-world
# Scan QR on mobile, approve on Cartridge
# Paste redirect URL
axis auth my-world --redirect-url="http://localhost:PORT/callback?startapp=..."- Idempotency: POST /prompt queues prompts; multiple identical prompts will queue multiple times
- Retry Logic: On auth failure, re-run
axis auth; sessions expire after 7 days - Polling: Use GET /events (SSE) for real-time updates instead of polling /status
- State Persistence: Agent memory stored in
~/.eternum-agent/data/{world}/
| Error | Meaning | Action |
|---|---|---|
No worlds discovered |
Network unreachable or wrong API base | Check network, verify CARTRIDGE_API_BASE |
--world is required for headless mode |
Missing world flag | Add --world={name} flag |
Auth remains pending |
Browser approval incomplete | Complete axis auth --redirect-url=... |
Password auth fails |
Wrong credentials | Verify username/password |
Session expired |
Session > 7 days old | Re-run axis auth |
See error-codes.yaml for programmatic error handling.
| Version | Status | Notes |
|---|---|---|
| v0.1.x | Current | Initial release |
~/.eternum-agent/
├── .env # Global config (API keys)
├── data/
│ └── {world}/
│ ├── soul.md # Agent persona
│ ├── HEARTBEAT.md # Periodic tasks
│ └── tasks/ # Strategy files
└── .cartridge/
└── {world}/
├── session.json # Controller session
├── profile.json # World profile
├── manifest.json # Contract manifest
├── policy.json # Session policies
├── auth.json # Auth metadata
└── auth-qr.png # Auth QR code
This documentation follows Agent Documentation Patterns