Documentation / Local API
Local API
Discover the active Cairn process, authenticate with its owner-only token, and call the live descriptor registry.
API 1.0 scope
The current API is a local control and plugin-management surface. It does not expose workspace, terminal, session, screen-band, or layout operations.
Connection sequence
- Discover. Read
$CAIRN_HOME/state/control.json, or~/.local/state/ghostty/control.jsonwhenCAIRN_HOMEis unset. It is a symlink to the active mode-0600control.<pid>.json. - Verify the instance. Parse
apiVersion,pid,socketPath,tokenPath,startedAt, andtransport. Read the mode-0600 token file. - Connect locally. Open the mode-0600 Unix-domain socket. Cairn rejects peers whose effective user ID differs from the server’s before routing requests.
- Authenticate once. The first useful call is
api/hello. Request only the capabilities you need; Cairn grants the intersection available to the token. - Exchange NDJSON. Send one UTF-8 JSON-RPC 2.0 object per newline. Each record is limited to 4 MiB. Responses and event notifications use the same connection.
{"jsonrpc":"2.0","id":1,"method":"api/hello","params":{
"token":"<contents of tokenPath>",
"capabilities":["api.read"]
}}
Methods
The table below is generated from DeveloperAPICatalog and PluginAPICatalog.
api/describe
api.read
Return the live method, event, and capability catalog.
Params
{
}Result
{
"apiVersion" : "string",
"capabilities" : [
],
"events" : [
],
"methods" : [
],
"transport" : "string"
}api/hello
public handshake
Authenticate a connection and negotiate capabilities.
Params
{
"capabilities" : [
"string"
],
"token" : "string"
}Result
{
"apiVersion" : "string",
"grantedCapabilities" : [
"string"
],
"sessionId" : "uuid"
}api/ping
api.read
Check authenticated API liveness.
Params
{
"nonce" : "any JSON value"
}Result
{
"nonce" : "any JSON value",
"ok" : true
}api/subscribe
events.subscribe
Subscribe this session to named API events.
Params
{
"events" : [
"event name"
]
}Result
{
"subscriptionId" : "uuid"
}api/unsubscribe
events.subscribe
Remove one event subscription from this session.
Params
{
"subscriptionId" : "uuid"
}Result
{
"removed" : true
}plugins/grants/set
plugins.manage
Replace one plugin's explicit capability grants.
Params
{
"capabilities" : [
"manifest-declared capability"
],
"pluginId" : "reverse-DNS plugin identifier"
}Result
{
"grantedCapabilities" : [
"capability"
],
"pluginId" : "reverse-DNS plugin identifier"
}plugins/list
plugins.read
List discovered plugins and their explicit grants.
Params
{
}Result
{
"plugins" : [
{
"activationEvents" : [
"activation event"
],
"commands" : [
"command identifier"
],
"declaredCapabilities" : [
"capability"
],
"grantedCapabilities" : [
"capability"
],
"id" : "reverse-DNS plugin identifier",
"name" : "display name",
"panels" : [
"panel identifier"
],
"version" : "plugin version"
}
]
}plugins/reload
plugins.manage
Rediscover plugin manifests and stop replaced processes.
Params
{
}Result
{
"pluginCount" : 0
}Events
Authenticate with events.subscribe, call api/subscribe with one or more known event names, and retain the returned subscription UUID. Notifications have no id. Use api/unsubscribe to stop delivery.
{"jsonrpc":"2.0","id":2,"method":"api/subscribe",
"params":{"events":["api/catalogChanged","api/serverStopping"]}}
{"jsonrpc":"2.0","method":"api/catalogChanged",
"params":{"apiVersion":"1.0"}}
| Event | Meaning | Capability | Params |
|---|---|---|---|
api/catalogChanged |
The live descriptor catalog changed. | events.subscribe | {
"apiVersion" : "string"
} |
api/serverStopping |
The local developer API server is stopping. | events.subscribe | {
"pid" : 0
} |
Subscriptions belong to the calling connection. Cairn removes them when the socket closes and re-checks the event capability at publish time.