HTTP API
The runtime exposes a small JSON-over-HTTP API from internal/runtime/server.go.
Success responses are JSON. Error responses use Go's http.Error, so they are plain text rather than structured JSON.
GET /v1/catalog/effective
Returns the full catalog plus the selected effective view.
When runtime.server.auth is enabled, this endpoint requires Authorization: Bearer ... and the returned catalog is already filtered to the scopes authorized for that token.
Query parameters
| Parameter | Meaning |
|---|---|
config | Path to .cli.json. Required unless the daemon was started with a default config. |
mode | Optional mode override. |
agentProfile | Optional profile name. |
Example
curl -s 'http://127.0.0.1:8765/v1/catalog/effective?config=/work/demo/.cli.json&agentProfile=support' | jq
Response shape
{
"catalog": {
"catalogVersion": "1.0.0",
"sources": [],
"services": [],
"tools": [],
"workflows": [],
"effectiveViews": []
},
"view": {
"name": "support",
"mode": "curated",
"tools": []
}
}
POST /v1/tools/execute
Executes one normalized tool.
Request body
{
"configPath": "/work/demo/.cli.json",
"mode": "curated",
"agentProfile": "support",
"toolId": "tickets:createTicket",
"pathArgs": [],
"flags": {
"state": "open"
},
"body": "eyJ0aXRsZSI6IlByaW50ZXIgamFtIn0=",
"approval": true
}
Notes:
bodyis[]bytein Go, so JSON clients typically send it as base64 when talking to the runtime directly.- the stock
ocliclient handles marshaling for you. - the runtime accepts either the slugified CLI flag name or the original parameter name when it looks up values in
flags.
Success response
{
"statusCode": 201,
"body": {
"id": "T-100",
"title": "Printer jam"
}
}
If the upstream body is not valid JSON, the runtime returns:
{
"statusCode": 200,
"text": "plain text response"
}
Common error statuses
400for bad JSON or config/catalog load failures403for policy or approval rejections401for missing or invalid runtime bearer auth when server-side runtime auth is enabled404if the tool ID does not exist502if upstream execution fails before an HTTP response is returned
POST /v1/workflows/run
Validates a workflow and returns its step IDs.
curl -s \
-H 'Content-Type: application/json' \
-d '{"configPath":"/work/demo/.cli.json","workflowId":"triageTicket","approval":true}' \
http://127.0.0.1:8765/v1/workflows/run | jq
Success response:
{
"workflowId": "triageTicket",
"steps": ["list-open", "fetch"]
}
The runtime does not execute the workflow steps.
GET /v1/refresh and POST /v1/refresh
Forces a rebuild with ForceRefresh=true and reports source fetch outcomes.
GET form
curl -s 'http://127.0.0.1:8765/v1/refresh?config=/work/demo/.cli.json' | jq
POST form
curl -s \
-H 'Content-Type: application/json' \
-d '{"configPath":"/work/demo/.cli.json"}' \
http://127.0.0.1:8765/v1/refresh | jq
Example response:
{
"refreshedAt": "2026-03-14T12:00:00Z",
"sources": [
{
"id": "ticketsSource",
"uri": "https://api.example.com/openapi.json",
"cacheOutcome": "revalidated_hit",
"statusCode": 200,
"stale": false
}
]
}
When server-side runtime auth is enabled, refresh also requires a bearer token.
GET /v1/audit/events
Returns the full audit log as an array.
curl -s http://127.0.0.1:8765/v1/audit/events | jq
There is no filtering, paging, or server-side query API in the current implementation.
When the runtime has server-side auth enabled and a default config is known, this endpoint also requires bearer auth.
Each audit record is newline-delimited JSON with fields such as:
eventTypefor the high-level lifecycle category (tool_execution,authz_denial,catalog_filtered,authenticated_connect,authn_failure,token_refresh,session_close,session_expiry)principalwhen server-side runtime auth resolved an authenticated subjectsessionIdfor local lifecycle events- the existing execution fields like
toolId,serviceId,decision,reasonCode,statusCode, andlatencyMs
GET /v1/auth/browser-config
Returns the browser-login metadata that ocli uses for runtime.remote.oauth.mode: "browserLogin".
Example response:
{
"authorizationURL": "https://auth.example.com/authorize",
"tokenURL": "https://auth.example.com/token",
"clientId": "ocli-browser",
"audience": "oclird",
"required": true,
"scopePrefixes": ["bundle:", "profile:", "tool:"],
"tokenValidationProfiles": ["oidc_jwks"],
"authorizationEnvelope": {
"version": "1.0",
"scopePrefixes": ["bundle:", "profile:", "tool:"]
}
}
Notes:
requiredsignals whether bearer auth is enforced by the runtime for the selected config.tokenValidationProfilesadvertises the configured bearer-token validation profile(s) used by the daemon.scopePrefixesandauthorizationEnvelope.versionhelp operators confirm how catalog filtering and execution parity are derived from runtime scopes.
GET /v1/runtime/info
Returns runtime handshake metadata for discovery, diagnostics, and compatibility checks.
Example response:
{
"contractVersion": "1.1",
"capabilities": [
"catalog",
"execute",
"refresh",
"audit",
"brokered-auth",
"authorization-envelope"
],
"instanceId": "team-a",
"url": "http://127.0.0.1:18765",
"runtimeMode": "local",
"auditPath": "/state/instances/team-a/audit.log",
"stateDir": "/state/instances/team-a",
"cacheDir": "/cache/instances/team-a/http",
"auth": {
"required": true,
"audience": "oclird",
"scopePrefixes": ["bundle:", "profile:", "tool:"],
"tokenValidationProfiles": ["oidc_jwks"],
"browserLogin": {
"configured": true,
"configEndpoint": "/v1/auth/browser-config"
},
"principal": "agent-456",
"authorizationEnvelope": {
"version": "1.0",
"scopePrefixes": ["bundle:", "profile:", "tool:"]
}
},
"lifecycle": {
"capabilities": ["heartbeat", "session-close"],
"heartbeatSeconds": 15,
"missedHeartbeatLimit": 3,
"shutdown": "when-owner-exits",
"sessionScope": "terminal",
"shareMode": "exclusive",
"shareKeyPresent": false,
"configFingerprint": "sha256:...",
"activeSessions": 1
}
}
Notes:
contractVersionand top-levelcapabilitiesare the runtime handshake surface used byoclicompatibility checks.auth.required,auth.tokenValidationProfiles, andauth.browserLogintell remote clients whether they must attach a bearer token and whether browser login discovery is available. Common profiles areoidc_jwksandoauth2_introspection.auth.principalis echoed only when the runtime already resolved an authenticated subject for the current request.auth.authorizationEnvelope.versionandauth.scopePrefixeslet operators diagnose catalog/execution parity when runtime scopes are involved.runtimeModeis typicallyembeddedorlocalin the current implementation.shareKeyPresentis only a boolean marker; the daemon never echoes the rawshareKey.- The
lifecycleblock is present for lease-aware managed local runtimes and is whatocliuses to validate reuse before attaching.
POST /v1/runtime/heartbeat
Registers or renews a local managed-runtime session lease.
Request body
{
"sessionId": "terminal:pts-12",
"configFingerprint": "sha256:..."
}
Common error responses:
409 runtime_attach_conflictwhen the runtime is exclusive and a different session tries to attach409 runtime_attach_mismatchwhen the caller's effective local-runtime config fingerprint differs from the daemon's
POST /v1/runtime/stop
Invokes the runtime shutdown hook when the daemon was started with one configured.
Success response:
{
"stopped": true
}
POST /v1/runtime/session-close
Closes the current runtime session, removes its active lease, and clears session-scoped auth cache state under the runtime state directory.
Success response:
{
"closed": true,
"activeSessions": 0
}