API Reference
Base URL
Section titled “Base URL”http://127.0.0.1:8787Authentication
Section titled “Authentication”All endpoints (except /status) require token authentication via the X-Agent-Token header:
X-Agent-Token: your-token-hereIf no token is configured on the server, authentication is disabled.
Endpoints
Section titled “Endpoints”GET /status
Section titled “GET /status”Server status check. No authentication required.
Response 200 OK
{ "ok": true, "pending_count": 3, "denied_count": 1, "token_required": true, "version": "0.1.0"}GET /health
Section titled “GET /health”Detailed health information with system metrics.
Response 200 OK
{ "status": "healthy", "uptime_seconds": 3621.4, "memory_mb": 42.7, "pending_count": 3, "runs_count": 15, "timestamp": "2025-01-15T14:30:22"}POST /plan
Section titled “POST /plan”Queue a command for human approval.
Request Body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
command | string | Yes | — | PowerShell command (1-10,000 chars) |
cwd | string|null | No | null | Working directory (max 500 chars) |
timeout_s | integer | No | 300 | Timeout in seconds (1-3600) |
note | string|null | No | null | Optional note (max 1000 chars) |
Example Request
curl -X POST http://127.0.0.1:8787/plan \ -H "X-Agent-Token: your-token" \ -H "Content-Type: application/json" \ -d '{"command": "Get-Process python", "note": "checking processes"}'Response 200 OK
{ "pending_id": "20250115_143022_a1b2c3d4", "queued": true, "command": "Get-Process python"}Errors
401— Invalid or missing token422— Validation error (command too long, invalid timeout, etc.)429— Rate limit exceeded
GET /pending
Section titled “GET /pending”List pending commands awaiting approval. Returns newest first.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 50 | Maximum items to return |
Response 200 OK
[ { "command": "Get-Process python", "cwd": null, "timeout_s": 300, "note": "checking processes", "pending_id": "20250115_143022_a1b2c3d4", "ts": 1705329022.123, "queued_at": "2025-01-15T14:30:22" }]POST /approve/{pending_id}
Section titled “POST /approve/{pending_id}”Approve and execute a pending command.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
pending_id | string | The pending command ID |
Response 200 OK
{ "run_id": "20250115_143122_e5f6g7h8", "cwd": "C:\\provara", "command": "Get-Process python", "exit_code": 0, "stdout": "Handles NPM(K) ...", "stderr": "", "ts": 1705329082.456, "duration_ms": 142.5}Errors
401— Invalid or missing token403— Command blocked by policy (includesreasonandcommandin detail)404— Pending command not found
403 Response Example
{ "detail": { "error": "policy_blocked", "reason": "deny:\\b(Remove-Item|del\\s|erase", "command": "Remove-Item C:\\Windows\\System32", "cwd": null }}POST /deny/{pending_id}
Section titled “POST /deny/{pending_id}”Deny a pending command. Moves it to the denied archive.
Response 200 OK
{ "pending_id": "20250115_143022_a1b2c3d4", "denied": true}Errors
401— Invalid or missing token404— Pending command not found
GET /runs
Section titled “GET /runs”Get recent command execution history.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 20 | Maximum items to return |
Response 200 OK
[ { "run_id": "20250115_143122_e5f6g7h8", "cwd": "C:\\provara", "command": "Get-Process python", "exit_code": 0, "stdout": "...", "stderr": "", "ts": 1705329082.456, "duration_ms": 142.5 }]GET /runs/{run_id}
Section titled “GET /runs/{run_id}”Get a specific command execution record.
Response 200 OK — Same schema as individual items in /runs
Errors
404— Run not found
GET /events
Section titled “GET /events”Server-Sent Events endpoint for real-time notifications.
Event Types
| Event | Emitted When |
|---|---|
run_started | Command execution begins |
run_finished | Command execution completes |
Example Event
data: {"type": "run_started", "run_id": "...", "ts": 1705329082.456, "command": "whoami", "cwd": "C:\\provara"}
data: {"type": "run_finished", "run_id": "...", "ts": 1705329082.598, "exit_code": 0, "stdout": "...", "stderr": ""}Usage (JavaScript)
const events = new EventSource( 'http://127.0.0.1:8787/events', { headers: { 'X-Agent-Token': token } });
events.onmessage = (e) => { const event = JSON.parse(e.data); console.log(event.type, event.run_id);};POST /file/read
Section titled “POST /file/read”Read a file from the project directory.
Request Body
| Field | Type | Description |
|---|---|---|
path | string | Relative or absolute path |
Response 200 OK
{ "path": "C:\\provara\\README.md", "content": "# Provara\n...", "size": 1234, "exists": true, "error": null}POST /file/write
Section titled “POST /file/write”Write a file to the project directory.
Request Body
| Field | Type | Default | Description |
|---|---|---|---|
path | string | — | Relative or absolute path |
content | string | — | File content |
create_dirs | boolean | false | Create parent directories |
GET /file/list
Section titled “GET /file/list”List files in a directory under the project root.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
path | string | . | Directory path |
pattern | string | * | Glob pattern |
Response 200 OK
{ "path": "C:\\provara", "files": [ { "name": "README.md", "path": "...", "is_dir": false, "size": 1234 }, { "name": "src", "path": "...", "is_dir": true, "size": null } ]}Error Responses
Section titled “Error Responses”All errors follow this format:
{ "error": "Error type", "detail": "Human-readable description"}| Status | Meaning |
|---|---|
401 | Authentication failed |
403 | Blocked by policy or path restriction |
404 | Resource not found |
422 | Validation error |
429 | Rate limit exceeded |
500 | Internal server error |
Rate Limiting
Section titled “Rate Limiting”The API enforces per-client rate limiting:
- Default: 100 requests per 60-second window
- 429 Response:
{ "error": "Rate limit exceeded", "retry_after_seconds": 60}CORS Policy
Section titled “CORS Policy”The server allows cross-origin requests only from localhost:
allow_origin_regex=r"^https?://(localhost|127\.0\.0\.1)(:\d+)?$"