Get from zero to orchestrating Claude Code sessions in two commands.
| Requirement | Minimum Version | Check Command |
|---|---|---|
| Node.js | β₯ 20 | node --version |
| Claude Code CLI | Latest | claude --version |
| Claude Code auth | Logged in | claude auth status |
Aegis bundles claude-agent-acp β no tmux installation required.
Before you start: Claude Code must be authenticated. Run
claude auth statusβ if it shows "Not logged in", runclaude loginfirst. Sessions created without Claude auth will silently produce no output.ag doctoralso checks this for you.
# Run Aegis β no install needed
npx --package=@onestepat4time/aegis ag run "Analyze this project and list the main technologies." --cwd /path/to/your/projectag run does everything for you:
- Bootstraps
.aegis/config.yamlwith sensible defaults - Starts the server on http://localhost:9100
- Creates a Claude Code session
- Streams output to your terminal
If the server is already running, ag run skips bootstrap and start β goes straight to session creation. Existing config is never overwritten.
Zero-config on localhost: When the server host is
localhost,127.0.0.1, or::1,ag initskips admin token creation β no auth is needed. The server automatically allows unauthenticated requests from localhost when no tokens exist.Auth note: If you previously configured an API token during
ag init(or are running on a public host like0.0.0.0), setAEGIS_AUTH_TOKENbefore running CLI commands:export AEGIS_AUTH_TOKEN=your-secret-tokenWithout this,
ag runandag createreturn401 Unauthorized.
| Flag | Description |
|---|---|
--cwd <path> |
Working directory (default: current directory) |
--port <number> |
Server port override |
--no-stream |
Don't stream output; print curl commands instead |
--model <provider/model> |
Override the default model for this session |
--name <name> |
Set a display name for the session |
--yes |
Suppress all status messages for non-interactive/CI usage |
--accept-permissions / -y |
Auto-approve all permission prompts (sets permissionMode: bypassPermissions) |
Note:
ag run --helpcurrently shows the general help. Forag runflags, refer to this table.
Troubleshooting: If
ag runhangs without creating a session, fall back to the step-by-step setup below. It separates server start from session creation and gives clearer error output.
Everything below is for advanced setups β most users can stop here.
npm install -g @onestepat4time/aegis
ag initZero-config on localhost: On
localhost,127.0.0.1, or::1,ag initskips admin token creation by default. No auth setup needed.Warning: Running
ag inita second time overwrites.aegis/config.yamland regenerates auth keys. You must restart the server for the new keys to take effect β the running server does not hot-reload keys from disk. Without a restart, CLI commands will return401 Unauthorizedwith the new token.
ag initnow supports conversational onboarding with--modeland--nameflags for non-interactive setup. Use--model <provider/model>to set the default model and--name <name>to set a display name for the session. Use--forceto create a token even on localhost.
agThe primary CLI command is
ag. The legacy nameaegisis kept as an alias for backward compatibility β both resolve to the same binary.
Aegis starts on http://localhost:9100 by default. Verify it's running:
curl http://localhost:9100/v1/healthDocker (alternative)
docker run -it --rm \
-v $(pwd):/workspace \
-p 9100:9100 \
node:20-slim bash -c "npm install -g @anthropic-ai/claude-code @onestepat4time/aegis && ag"Docker requires Claude Code CLI to be installed and authenticated inside the container.
Start with authentication
Option A: API token (simple)
Set a bearer token to protect all endpoints (except /v1/health):
AEGIS_AUTH_TOKEN=your-secret-token agThen include the token in every request:
curl -H "Authorization: Bearer your-secret-token" http://localhost:9100/v1/sessionsOption B: OIDC / SSO (enterprise)
For IdP-based authentication, configure OIDC and use the CLI:
export AEGIS_OIDC_ISSUER=https://your-idp.example.com
export AEGIS_OIDC_CLIENT_ID=your-client-id
ag login # Opens browser-based device flow
ag whoami # Verify: alice@example.com admin (token expires in 59m)See the OIDC Configuration table below for all environment variables.
For dashboard SSO, also set AEGIS_OIDC_CLIENT_SECRET. The dashboard will redirect to your IdP for login. See the Dashboard Guide β OIDC SSO for full setup.
Tip: If you set up auth, export the token for the curl examples below:
export TOKEN=your-secret-tokenAll examples from section 4 onward use
$TOKENfor brevity. No-auth setups can omit the-H "Authorization: Bearer $TOKEN"headers.
Visit http://localhost:9100/dashboard/ in your browser. The dashboard shows all sessions, their status, and activity in real time.
Navigate the dashboard faster using keyboard shortcuts:
| Shortcut | Action |
|---|---|
? (Shift+/) |
Show keyboard shortcuts |
Ctrl+K (or βK) |
Focus search |
Ctrl+N (or βN) |
New session |
G then O |
Go to Overview |
G then S |
Go to Sessions |
G then P |
Go to Pipelines |
G then A |
Go to Audit |
G then U |
Go to Users |
Escape |
Close modal / cancel |
The dashboard displays the shortcut hint in the sidebar footer.
Auth required? If you answered "yes" to the API token prompt during
ag init(or setAEGIS_AUTH_TOKEN), you must export the token before usingag createorag run:export AEGIS_AUTH_TOKEN=your-secret-tokenWithout this, CLI commands return
401 Unauthorized. No-auth setups can skip this.
ag create "Analyze this project. List the main technologies, directory structure, and any issues you spot." --cwd /path/to/your/projectag create prints the session ID and next-step curl commands for you:
Known issue: If
ag createshows no output, the session may still have been created. Verify withag listorcurl -H "Authorization: Bearer $TOKEN" http://localhost:9100/v1/sessions.
β
Session created: cc-analyze-this-projec
ID: a1b2c3d4
Next steps:
Status: curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:9100/v1/sessions/a1b2c3d4/health
Read: curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:9100/v1/sessions/a1b2c3d4/read
Kill: curl -X DELETE -H "Authorization: Bearer $TOKEN" http://127.0.0.1:9100/v1/sessions/a1b2c3d4
Save the id β you'll need it for follow-up commands.
Note:
workDirmust be under an allowed directory. By default, Aegis allows$HOMEand the server's current working directory. System temp dirs (/tmp,/var/tmp) are intentionally excluded for security. To allow additional directories, setallowedWorkDirsin.aegis/config.yaml(oraegis.config.json). Changes are hot-reloaded without restart.
Watch the session in the dashboard, or poll the API:
curl -H "Authorization: Bearer $TOKEN" http://localhost:9100/v1/sessions/a1b2c3d4Tip: Set
TOKENonce and reuse it:TOKEN=your-secret-token(orTOKEN=$(cat .aegis/config.yaml | grep authToken | cut -d' ' -f2)).
For real-time updates, use the SSE event stream (requires an SSE token β see SSE Auth):
# Step 1: Get an SSE token
SSE_TOKEN=$(curl -s -X POST -H "Authorization: Bearer $TOKEN" http://localhost:9100/v1/auth/sse-token | python3 -c "import json,sys;print(json.load(sys.stdin)['token'])")
# Step 2: Connect to the stream
curl -N "http://localhost:9100/v1/events?token=$SSE_TOKEN"Endpoint note: Follow-up messages use
/send,/input, or/promptwith atextfield. Thepromptfield is only for the initial message during session creation.
curl -X POST http://localhost:9100/v1/sessions/a1b2c3d4/send \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"text": "Now create a detailed plan to fix the issues you found."}'curl -H "Authorization: Bearer $TOKEN" http://localhost:9100/v1/sessions/a1b2c3d4/readThis returns the parsed transcript β Claude Code's full response in structured JSON.
When Claude Code asks for approval (e.g., to run a shell command or write a file), the session status changes to permission_prompt. Approve or reject:
# Approve
curl -X POST -H "Authorization: Bearer $TOKEN" http://localhost:9100/v1/sessions/a1b2c3d4/approve
# Reject
curl -X POST -H "Authorization: Bearer $TOKEN" http://localhost:9100/v1/sessions/a1b2c3d4/rejectYou can also set permissionMode when creating a session to control approval behavior:
| Mode | Behavior |
|---|---|
default |
Prompts for dangerous operations (recommended) |
bypassPermissions |
Auto-approves every operation without prompting |
plan |
Claude runs in plan mode before any edits |
acceptEdits |
Auto-accepts non-destructive edits only |
dontAsk |
Disables all permission prompts (fails on dangerous ops) |
auto |
Claude decides when to prompt (context-dependent) |
Aegis is designed for parallel orchestration. Each session runs as an independent ACP child process:
# Backend fix
curl -X POST http://localhost:9100/v1/sessions \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "backend", "workDir": "/path/to/backend", "prompt": "Fix failing API tests"}'
# Frontend improvement
curl -X POST http://localhost:9100/v1/sessions \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "frontend", "workDir": "/path/to/frontend", "prompt": "Add loading states to all API calls"}'
# Documentation
curl -X POST http://localhost:9100/v1/sessions \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "docs", "workDir": "/path/to/project", "prompt": "Update README with the new API endpoints"}'List all sessions:
curl -H "Authorization: Bearer $TOKEN" http://localhost:9100/v1/sessionsSupports pagination: ?page=1&limit=20&status=active. Invalid values (e.g. page=-1, limit=999) return 400.
\n> Note: The name field is a display label only β it does not affect session reuse. Sessions are reused automatically when workDir matches an existing idle session (see Session Reuse in the README).
Connect Aegis to Claude Code for native tool access:
claude mcp add aegis -- ag mcpThis registers 34 MCP tools (session management, ACP control, transcript reading, pipeline orchestration, etc.). Restart Claude Code to load the tools. MCP tool calls are authenticated automatically via the Aegis MCP server.
For the full MCP tools reference, see MCP Tools.
Aegis is configured via environment variables:
| Variable | Default | Description |
|---|---|---|
AEGIS_PORT |
9100 |
HTTP server port |
AEGIS_HOST |
127.0.0.1 |
Bind address |
AEGIS_AUTH_TOKEN |
(empty) | Bearer token (empty = no auth) |
AEGIS_STATE_DIR |
~/.aegis |
State directory |
AEGIS_LOG_LEVEL |
info |
Log verbosity |
AEGIS_SESSION_STORE |
file |
Session state backend: file, redis, or postgres |
AEGIS_POSTGRES_URL |
(empty) | PostgreSQL connection URL (required when AEGIS_SESSION_STORE=postgres) |
AEGIS_PG_TABLE |
aegis_sessions |
PostgreSQL table name for session state |
AEGIS_PG_SCHEMA |
public |
PostgreSQL schema name |
AEGIS_PG_POOL_MAX |
5 |
PostgreSQL connection pool max size |
AEGIS_REDIS_URL |
redis://localhost:6379 |
Redis URL (used when AEGIS_SESSION_STORE=redis) |
AEGIS_REDIS_KEY_PREFIX |
aegis |
Redis key prefix |
AEGIS_STRICT_RBAC |
false |
Enforce RBAC on protected endpoints even when auth is disabled |
AEGIS_ACP_PROMPT_TIMEOUT_MS |
120000 |
Timeout in ms for ACP JSON-RPC requests (increase for slow BYO-LLM proxy setups) |
See the Enterprise Deployment Guide for the complete environment variable reference (rate limiting, OIDC, hooks, notifications, alerting, and more).
Or use a config file (.aegis/config.yaml is the preferred bootstrap path, and aegis.config.json remains supported):
baseUrl: http://127.0.0.1:9100
dashboardEnabled: true
authToken: your-token
memoryBridge:
enabled: trueFor the full configuration reference, see Enterprise Deployment.
Aegis provides official client SDKs for TypeScript and Python, both generated from the OpenAPI 3.1 specification.
npm install @onestepat4time/aegis-clientimport { AegisClient } from '@onestepat4time/aegis-client';
const client = new AegisClient('http://localhost:9100', process.env.AEGIS_AUTH_TOKEN);
const sessions = await client.listSessions();
await client.sendMessage(sessions[0].id, 'Continue the task');See packages/client/ for source and the full README.
pip install ag-clientfrom aegis_python_client import AegisClient
client = AegisClient(base_url="http://localhost:9100", auth_token="your-token")
sessions = client.list_sessions()
client.send_message(sessions["sessions"][0]["id"], "Continue the task")See packages/python-client/ for source and the full README.
- MCP Tools Reference β Full documentation for all 34 MCP tools
- API Reference β Complete REST API documentation
- Verifying Releases β SHA verification, npm integrity, Sigstore attestations, version policy
- Advanced Features β Session Export, Pipelines, Memory Bridge, templates
- Enterprise Deployment β Auth, rate limiting, production setup
- ACP Migration Guide β Upgrading from
aegis-bridge - TypeDoc API β Auto-generated TypeScript reference
- ROADMAP β What's coming next
- Release Process β Production release flow, recovery releases, and hotfixes
- Disaster Recovery β Data loss and infrastructure failure recovery procedures
- Incident and Rollback Runbook β Deployment rollbacks and version pinning
See the Contributing Guide for development workflow, branch conventions, and PR process.
For Aegis development, use git worktrees β never develop directly in the main repo folder:
# Create a worktree per feature
git worktree add ~/projects/aegis-my-feature origin/develop
# Inside worktree
git checkout -b feat/my-featureSee the Worktree Guide for detailed setup instructions.
For active bugs with workarounds, see Known Issues.
| Problem | Solution |
|---|---|
claude: command not found |
Install Claude Code: npm install -g @anthropic-ai/claude-code and run claude to authenticate |
| Claude not authenticated | Run claude login first. Sessions created without auth produce no output. ag doctor checks this |
Claude Code CLI not found |
Install Claude Code: npm install -g @anthropic-ai/claude-code and run claude to authenticate |
401 Unauthorized |
Set AEGIS_AUTH_TOKEN or include Authorization: Bearer <token> header |
401 after ag init |
Restart the server β it does not hot-reload keys. Kill the process and run ag again |
Session stuck on stalled |
Send an interrupt: curl -X POST http://localhost:9100/v1/sessions/:id/interrupt |
Session shows pending |
Initial state β connecting to ACP runtime. Wait a moment and re-poll |
Session shows killed |
Terminal state β stopped via API. Session retained for audit, cannot be resumed |
Session shows crashed |
Terminal state β terminated unexpectedly. Check /v1/diagnostics for details |
Session shows completed |
Terminal state β finished normally. Session retained for audit |
| MCP tools not showing in Claude Code | Re-run claude mcp add aegis -- ag mcp and restart Claude Code |
| Dashboard won't load | Verify Aegis is running on port 9100: curl http://localhost:9100/v1/health |
EADDRINUSE on startup |
Port 9100 is in use. Set a different port: AEGIS_PORT=9200 ag |
| Screenshot returns 501 | Install Playwright: npx playwright install chromium |
No output from /read |
Wait for transcript entries, or check session events via SSE (see Section 5 for SSE token setup) |
ag create shows no output |
Known issue β session may still be created. Check with ag list or curl -H "Authorization: Bearer $TOKEN" http://localhost:9100/v1/sessions |
ag <word> creates unwanted session |
The CLI treats unrecognized arguments as session briefs. Use ag --help to check available commands |