# ralph-api
Rust-native bootstrap runtime for the RPC v1 control plane.
## What this crate provides (bootstrap scope)
- HTTP RPC endpoint: `POST /rpc/v1`
- WebSocket stream endpoint: `GET /rpc/v1/stream` (keepalive skeleton)
- Metadata endpoints:
- `GET /health`
- `GET /rpc/v1/capabilities`
- Protocol runtime for canonical RPC v1 envelopes
- Shared error envelope mapping (`INVALID_REQUEST`, `METHOD_NOT_FOUND`, etc.)
- Auth abstraction:
- `trusted_local`
- `token` mode hook
- Idempotency primitives for mutating methods with in-memory store
- Implemented methods:
- `system.health`
- `system.version`
- `system.capabilities`
- Full `task.*` family (`list/get/ready/create/update/close/archive/unarchive/delete/clear/run/run_all/retry/cancel/status`)
- Full `loop.*` family (`list/status/process/prune/retry/discard/stop/merge/merge_button_state/trigger_merge_task`)
- Full `planning.*` family (`list/get/start/respond/resume/delete/get_artifact`)
- Full `config.*` family (`get/update`)
- Full `preset.*` family (`list`)
- Full `collection.*` family (`list/get/create/update/delete/import/export`)
Persistence notes:
- `task.*` data is persisted in `.ralph/api/tasks-v1.json`
- `loop.*` reads/writes `.ralph/loops.json` and `.ralph/merge-queue.jsonl` via `ralph-core`
- `planning.*` data is persisted under `.ralph/planning-sessions/<session-id>/`
- `collection.*` data is persisted in `.ralph/api/collections-v1.json`
- `config.*` reads/writes `ralph.yml` with YAML validation + atomic replace semantics
- `preset.list` reads builtins from `presets/`, local files from `.ralph/hats/`, and collection-backed presets
Intentional migration differences vs legacy Node backend:
- `task.cancel` currently allows cancelling `pending` tasks (legacy allowed only `running`).
- `planning.start` returns a full `session` object instead of just `{sessionId}`.
## Run locally
From repository root:
```bash
cargo run -p ralph-api
```
For the MCP server:
```bash
./target/debug/ralph mcp serve --workspace-root /path/to/repo
```
The MCP server is workspace-scoped. One server instance manages one workspace root for
`ralph.yml`, `.ralph/api/*`, loops, planning sessions, and collections.
Environment variables:
- `RALPH_API_HOST` (default: `127.0.0.1`)
- `RALPH_API_PORT` (default: `3000`)
- `RALPH_API_SERVED_BY` (default: `ralph-api`)
- `RALPH_API_AUTH_MODE` (`trusted_local` or `token`, default: `trusted_local`)
- `trusted_local` is restricted to loopback hosts (`127.0.0.1`, `::1`, `localhost`)
- `RALPH_API_TOKEN` (required for practical token auth use)
- `RALPH_API_IDEMPOTENCY_TTL_SECS` (default: `3600`)
- `RALPH_API_WORKSPACE_ROOT` (default: current working directory)
- `RALPH_API_LOOP_PROCESS_INTERVAL_MS` (default: `30000`)
- `RALPH_API_RALPH_COMMAND` (default: `ralph`; command used for loop-side-effect parity flows like `loop.retry`)
## Smoke call examples
Health:
```bash
RPC system health:
```bash
curl -s http://127.0.0.1:3000/rpc/v1 \
-H 'content-type: application/json' \
-d '{
"apiVersion": "v1",
"id": "req-health-1",
"method": "system.health",
"params": {}