JSON-RPC API
The HTTP control plane (daedalus.api) exposes the in-process training API over a single JSON-RPC 2.0 endpoint. It is a thin FastAPI app (src/daedalus/api/app.py) whose handlers dispatch into the shared METHOD_HANDLERS table in src/daedalus/api/methods.py — the same table the MCP server uses, so the two surfaces can never drift.
Endpoints
| Method | Path | Purpose |
|---|---|---|
POST | /rpc | JSON-RPC 2.0 — single request or a batch array |
GET | /healthz | Liveness check — returns {"status": "ok"} |
The app intentionally disables the OpenAPI docs UIs (docs_url=None, redoc_url=None): the JSON-RPC contract is the interface.
Starting the server
uv run daeda serve-api --host 127.0.0.1 --port 8000Both flags are optional (defaults shown). The server runs under uvicorn; the /rpc handler is synchronous and Starlette runs it in a threadpool, so the blocking in-process / network JSON-RPC handlers never stall the event loop.
No auth yet
The server has no authentication or authorization. Bind it to a trusted network boundary only (127.0.0.1 by default); do not expose it publicly as-is.
Methods
The method names come straight from METHOD_HANDLERS:
| Method | Params | Returns |
|---|---|---|
catalog.list_views | (none) | One row per feature view (name, entity, join keys, feature count, source) |
catalog.show_view | name | A view's schema: timestamp field, source, fields with dtypes |
service.list | (none) | One row per feature service (name, version, owner, grain, column count, serving flag) |
service.show | name | A service's full column contract (kind, dtype, default, nullable) |
pipeline.compile | service | The compiled operator pipeline: operators + a graph of nodes/edges |
runs.materialize_partition | service, partition | Triggers a daily training partition; returns {run_id, status} |
runs.get | run_id | Run status, partition, start/end times, metadata |
runs.list | service?, limit? | Recent runs (default limit 20) |
runs.logs | run_id, tail? | Run log lines |
assets.lineage | (none) | Asset lineage graph (nodes + edges) |
The catalog.*, service.*, and pipeline.compile methods resolve and compile in-process. The runs.* and assets.lineage methods delegate to a Dagster runs backend: a DagsterGraphQLRunsBackend when DAGSTER_GRAPHQL_URL (or ApiContext.dagster_graphql_url) is set, otherwise an ephemeral in-process InProcessDagsterRunsBackend. See Dagster Orchestration.
Example request
curl -s http://127.0.0.1:8000/rpc \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"method": "catalog.list_views",
"params": {},
"id": 1
}'{
"jsonrpc": "2.0",
"result": [
{
"name": "user_likes",
"entity": "user",
"join_keys": ["user_id"],
"n_features": 6,
"source": "likes"
}
],
"id": 1
}Compiling a service to its operator DAG:
curl -s http://127.0.0.1:8000/rpc \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"pipeline.compile","params":{"service":"dssm_ranking"},"id":2}'A request with id omitted is a JSON-RPC notification: it is processed but produces no response body (HTTP 204 No Content).
Error responses
Errors use standard JSON-RPC error objects, {code, message, data?}:
| Code | Meaning | Raised when |
|---|---|---|
-32600 | Invalid Request | Payload is not a valid JSON-RPC request object |
-32601 | Method not found | method is not in METHOD_HANDLERS |
-32602 | Invalid params | Missing/invalid params, or an unknown view/service/run |
-32000 | Internal error | Unexpected handler failure (server-side) |
{
"jsonrpc": "2.0",
"error": {
"code": -32601,
"message": "Method not found",
"data": { "method": "catalog.no_such_method" }
},
"id": 3
}CORS
Cross-origin access is controlled by the DAEDALUS_API_CORS_ORIGINS environment variable — a comma-separated allow-list. It defaults to * (permissive, for local development); lock it down in production:
DAEDALUS_API_CORS_ORIGINS="https://ui.example.com,https://admin.example.com" \
uv run daeda serve-api --host 0.0.0.0 --port 8000The GUI planned in a separate stack consumes exactly this contract — see Platform overview.
See also
- MCP Server — the same methods as agent tools over stdio.
- Dagster Orchestration — the runs backend behind
runs.*. - CLI reference.