Run local AI agent CLIs through a small HTTP API.
agents-api exposes a consistent API for installed command-line agents such as Codex, Claude Code, and Antigravity CLI. It is designed for machines where one or more supported agents are already available and authenticated.
This package is implemented with Codex.
| Agent | CLI command | Non-interactive command used by agents-api | Run file access |
|---|---|---|---|
| Codex | codex |
codex exec ... <prompt> |
Staged filesystem paths; multiline prompts use stdin; image files also use --image |
| Claude Code | claude |
claude -p ... <prompt> |
Staged filesystem paths |
| Antigravity CLI | agy |
agy ... --print <prompt> |
Staged filesystem paths |
At least one supported agent must be installed and authenticated before the HTTP server can start.
Antigravity CLI support
Antigravity-backed runs are currently supported on Linux and WSL. Native Windows execution is not supported because known Antigravity CLI stdout capture issues can prevent
agents-apifrom reading the output produced byagy --print.Public issue reports: google-antigravity/antigravity-cli#76, google-gemini/gemini-cli#27466.
- Node.js
18or newer - npm, pnpm, or another Node package manager
- At least one supported agent CLI installed on the host
- The selected agent authenticated for the same OS user that runs
agentsapi
Install globally from npm:
npm install -g agents-apiVerify the installed version:
agentsapi --versionExpected version:
0.2.8
Check agent availability:
agentsapi agents statusGenerate an API token:
agentsapi auth generateConfigure an agent:
agentsapi config set codex "--json --model gpt-5.5"
agentsapi config set claude "--output-format text --model sonnet"
agentsapi config set antigravity "--model gemini-3.5-flash"Set the fallback agent:
agentsapi config default set codexStart the server:
agentsapi serve --host 0.0.0.0 --port 7357Call the API:
curl http://127.0.0.1:7357/api/runs \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{"agent":"codex","prompt":"Write only OK"}'Check all supported agents:
agentsapi agents statusThe command returns a JSON array. Each entry includes:
| Field | Description |
|---|---|
agent / provider |
Agent ID |
command |
CLI command used by agentsapi |
installed |
The command can be executed |
authenticated |
Authentication is available for non-interactive use |
ready |
The agent can be selected for runs |
version |
CLI version when available |
authStatus / error |
Authentication detail or failure reason |
When the HTTP server starts, it prints a compact line for each agent:
READY: installed and authenticatedNOT_AUTHENTICATED: command exists, but authentication check failedNOT_INSTALLED: command cannot be executed
If no agent is READY, the server exits.
Each supported CLI must be authenticated for the same OS user that starts agents-api. Readiness checks use the configured command path with the agent's native status command:
| Agent | Authentication check |
|---|---|
| Codex | codex login status |
| Claude Code | claude auth status |
| Antigravity CLI | agy models |
Complete the agent login in its CLI before using that agent through agents-api.
Antigravity CLI stdout capture
Antigravity runs use print mode. For
/api/runsand/api/runs/stream,agents-apireads the assistant response from stdout produced byagy --print, so the runtime environment that startsagents-apimust be able to capture that output:
agy --print "Write only OK"A successful check prints
OKto stdout. If this command exits successfully but redirected or subprocess output is empty, Antigravity-backed API runs are reported as unsuccessful because there is no assistant output to return.
Each agent has a shared argument string. The string is appended to the agent command before the prompt.
agentsapi config set codex '--json --model gpt-5 -c model_reasoning_effort=\"medium\"'
agentsapi config set claude "--model sonnet --permission-mode plan"
agentsapi config set antigravity "--model gemini-3.5-flash"Read or clear a shared configuration:
agentsapi config get codex
agentsapi config clear claudeSet the fallback agent used when a run request does not include agent or provider:
agentsapi config default set claude
agentsapi config default get
agentsapi config default clearConfigure only agent options. agentsapi supplies the command form used to pass the prompt:
| Agent | Command form |
|---|---|
| Codex | codex exec ... <prompt> |
| Claude Code | claude -p ... <prompt> |
| Antigravity CLI | agy ... --print <prompt> |
Full automation profile:
agentsapi config set codex '--json --dangerously-bypass-approvals-and-sandbox --skip-git-repo-check --model gpt-5.5 -c model_reasoning_effort=\"xhigh\"'
agentsapi config set claude "--output-format stream-json --dangerously-skip-permissions --verbose --model claude-opus-4-8 --effort max"
agentsapi config set antigravity "--model gemini-3.5-flash --dangerously-skip-permissions"Machine-readable output without automatic tool approval:
agentsapi config set codex '--json --model gpt-5.5 -c model_reasoning_effort=\"medium\"'
agentsapi config set claude "--output-format json --model sonnet --effort medium"
agentsapi config set antigravity "--model gemini-3.5-flash"Restricted tool execution:
agentsapi config set codex '--json --model gpt-5.5 --sandbox read-only -c model_reasoning_effort=\"medium\"'
agentsapi config set claude "--output-format text --model sonnet --permission-mode plan"
agentsapi config set antigravity "--model gemini-3.5-flash"A project binds an ID to a working directory and optional per-agent configuration.
agentsapi projects add webapp /srv/projects/webappIf the working directory does not exist, it is created.
Set project-level arguments:
agentsapi projects config webapp codex "--json --model gpt-5 --sandbox workspace-write"
agentsapi projects config webapp claude "--model opus"
agentsapi projects config webapp antigravity "--model gemini-3.5-flash"List or remove projects:
agentsapi projects list
agentsapi projects remove webappConfiguration precedence:
request config > project agent config > shared agent config
Generate and store a bearer token:
agentsapi auth generateCheck the current authentication state:
agentsapi auth statusSet or clear a token manually:
agentsapi auth set "token-long-random-value"
agentsapi auth clearYou can also provide the token with an environment variable:
AGENTSAPI_API_KEY="token-long-random-value" agentsapi serve --host 0.0.0.0 --port 7357When a token is configured, requests must include:
Authorization: Bearer <token>When binding to a public host such as 0.0.0.0, agentsapi requires an API token before it starts.
Start locally:
agentsapi serve --host 127.0.0.1 --port 7357Start for remote access:
agentsapi serve --host 0.0.0.0 --port 7357OpenAPI and Swagger UI:
http://127.0.0.1:7357/openapi.json
http://127.0.0.1:7357/docs
Health endpoint:
GET /api/health
Request body:
{
"agent": "codex",
"project": "webapp",
"prompt": "Write only OK",
"sessionId": "019...",
"config": "--json --model gpt-5",
"files": [
{
"path": "brief.md",
"content": "# Brief\n\nUse this file as source material."
},
{
"path": "diagram.png",
"content": "iVBORw0KGgo...",
"encoding": "base64",
"mimeType": "image/png"
}
],
"timeoutMs": 600000,
"idleTimeoutMs": 30000,
"responseMode": "normalized"
}Fields:
| Field | Required | Description |
|---|---|---|
prompt |
Yes | Prompt passed to the selected agent |
agent |
No | codex, claude, or antigravity |
provider |
No | Alias of agent |
project |
No | Project ID used to select working directory and project config |
sessionId |
No | Agent session to resume |
config |
No | Request-level argument string |
files |
No | Files made available to the selected agent for this run |
timeoutMs |
No | Positive integer timeout in milliseconds |
idleTimeoutMs |
No | Positive integer timeout in milliseconds without stdout/stderr output |
responseMode |
No | normalized or raw |
If neither agent nor provider is provided, the configured fallback agent is used. Without a fallback agent, the request is rejected.
For binary files and regular file uploads, use multipart/form-data with a JSON request part and one or more files parts:
curl http://127.0.0.1:7357/api/runs \
-H "Authorization: Bearer TOKEN" \
-F 'request={"agent":"codex","project":"webapp","prompt":"Read docs/brief.pdf and summarize it.","responseMode":"normalized"};type=application/json' \
-F 'files=@brief.pdf;filename=docs/brief.pdf;type=application/pdf'The multipart file filename is used as the request path for the attachment. For example, filename=docs/brief.pdf makes the attachment addressable as docs/brief.pdf in the run.
Each file is staged in a temporary run directory under the working directory with a generated filename such as attachment-1.pdf, and the selected agent receives the staged filesystem paths in the prompt before the user request. Request paths and filenames are treated as aliases for those staged paths, so agents are directed to read the uploaded copy instead of searching for same-named files elsewhere on the machine. Codex receives the augmented prompt through stdin and image files are also passed with --image.
JSON requests can also include files inline:
{
"agent": "claude",
"project": "webapp",
"prompt": "Summarize the attached brief.",
"files": [
{
"path": "brief.md",
"content": "# Launch brief\n\n..."
}
]
}Inline JSON file fields:
| Field | Required | Description |
|---|---|---|
path |
Yes | Relative file path visible to the agent |
content |
Yes | File content |
encoding |
No | utf8 or base64; defaults to utf8 |
mimeType |
No | Optional media type |
File paths from JSON path values and multipart filename values must be relative and cannot contain . or .. path segments. A request can include up to 20 files, 8 MiB per file, and 16 MiB total file content.
Normalized response:
{
"responseMode": "normalized",
"agent": "codex",
"provider": "codex",
"project": "webapp",
"ok": true,
"exitCode": 0,
"timedOut": false,
"idleTimedOut": false,
"output": "OK",
"sessionId": "019...",
"files": [
{
"path": "brief.md",
"runPath": "agents-api-run-files/run-.../attachment-1.md",
"stagedPath": "attachment-1.md",
"size": 41
}
],
"usage": null,
"errors": [],
"events": []
}Raw response:
{
"agent": "codex",
"prompt": "Write only OK",
"responseMode": "raw"
}Raw mode returns command metadata, stdout, and stderr. The promptTransport field is argument or stdin.
If timeoutMs is provided and the agent process does not finish in time, agents-api terminates the process and returns timedOut: true. If idleTimeoutMs is provided and the agent process stops producing stdout/stderr output, agents-api terminates the process and returns idleTimedOut: true.
For Codex, Claude Code, and Antigravity CLI, normalized mode extracts assistant text from the agent output format in use. Structured formats from Codex and Claude Code are mapped to the same response shape as plain text output. Antigravity CLI responses are normalized from agy --print text output when that stdout is available to the agents-api process.
Normalized responses include sessionId when the selected agent exposes it. Pass that value in a later /api/runs or /api/runs/stream request to continue the same conversation.
{
"agent": "codex",
"project": "webapp",
"sessionId": "019...",
"prompt": "Continue from the previous result"
}Session resume uses each agent's native local session store:
| Agent | Resume command shape |
|---|---|
| Codex | codex exec ... resume <sessionId> <prompt> |
| Claude Code | claude -p --resume <sessionId> ... <prompt> |
| Antigravity CLI | agy --conversation <sessionId> ... --print <prompt> |
Use the same agent, machine, and project working directory that created the session. Agent session files are local, so a session ID from one machine is not automatically available on another machine.
Uses the same request body as /api/runs.
Use this endpoint with agent output formats that emit progressive events. Codex --json and Claude Code --output-format stream-json are suitable choices. Non-streaming formats such as Claude Code --output-format json and Antigravity CLI print mode are valid, but most output is emitted only after the agent process completes.
Normalized stream events:
startsessionoutputresultreasoningtool_starttoolusageerrorexit
Raw stream events:
startstdoutstderrerrorexit
Example:
curl -N http://127.0.0.1:7357/api/runs/stream \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{"agent":"claude","prompt":"Write only OK","responseMode":"normalized"}'agentsapi serve [--host <host>] [--port <port>] [--log-level <level>]
agentsapi status
agentsapi agents status
agentsapi auth status|generate|set <token>|clear
agentsapi config default get|set <codex|claude|antigravity>|clear
agentsapi config get <codex|claude|antigravity>
agentsapi config set <codex|claude|antigravity> "<agent args>"
agentsapi config clear <codex|claude|antigravity>
agentsapi projects list
agentsapi projects add <id> <working_dir>
agentsapi projects remove <id>
agentsapi projects config <id> [<codex|claude|antigravity> ["<agent args>"|--clear]]
agentsapi run [--agent <codex|claude|antigravity>] [--project <id>] [--session-id <id>] [--timeout-ms <ms>] [--idle-timeout-ms <ms>] [--config "<agent args>"] <prompt>
agentsapi logs get
agentsapi logs level <debug|info|warning|error|off>
agentsapi logs requests <on|off>
agentsapi logs prompt <on|off>
Set the log level:
agentsapi logs level info
agentsapi logs level debugServer logs use readable text lines by default:
2026-06-26T11:09:52.546Z INFO Server started url=http://127.0.0.1:7357 logLevel=info auth=false authSource=none
2026-06-26T11:10:03.413Z INFO Run received request=mqutxehc-1 agent=codex project=null cwd=/srv/app mode=normalized files=1 prompt=47chars
2026-06-26T11:11:39.663Z INFO Run completed request=mqutxehc-1 agent=codex project=null mode=normalized exit=0 duration=1m36.3s stdout=928B stderr=57KiB
Disable request logging:
agentsapi logs requests offDebug logs include the complete agent prompt by default, including any run-file instructions and staged attachment paths:
agentsapi logs level debugPrompt logging can be disabled:
agentsapi logs prompt offRuntime override:
AGENTSAPI_LOG_LEVEL=debug agentsapi serve --host 0.0.0.0 --port 7357JSON log output is available for structured log collectors:
AGENTSAPI_LOG_FORMAT=json agentsapi serve --host 127.0.0.1 --port 7357Logs are emitted as JSON lines on stdout/stderr.
| Variable | Description |
|---|---|
AGENTSAPI_HOME |
Directory used to store config.json |
AGENTSAPI_API_KEY |
Bearer token used by the HTTP API |
AGENTSAPI_LOG_LEVEL |
Runtime log level |
AGENTSAPI_LOG_FORMAT |
Log format: text or json |
AGENTSAPI_CODEX_COMMAND |
Codex command path/name |
AGENTSAPI_CLAUDE_COMMAND |
Claude Code command path/name |
AGENTSAPI_ANTIGRAVITY_COMMAND |
Antigravity CLI command path/name |
For internet-facing deployments:
- bind
agentsapito127.0.0.1behind a reverse proxy when possible - expose HTTPS from the proxy
- keep port
7357private unless explicitly needed - require a bearer token
- run the process with the same OS user used to authenticate the agent CLIs
Check agent status:
agentsapi agents statusCommon cases:
| Symptom | Action |
|---|---|
NOT_INSTALLED |
Install the agent CLI or configure the command path with the matching environment variable |
NOT_AUTHENTICATED |
Run the agent login command as the same OS user that starts agentsapi |
| Antigravity run returns empty output | Verify that agy --print "Write only OK" prints text when stdout is redirected or captured by the same runtime environment; use a Linux/WSL runtime for Antigravity-backed runs if the local Windows CLI exits with empty captured output |
401 Unauthorized from agentsapi |
Send Authorization: Bearer <token> |
400 for a request without agent |
Pass agent or configure a fallback agent with agentsapi config default set <agent> |
503 Agent unavailable |
Select an installed and authenticated agent |
MIT