Skip to content

Connect an agent

The admin key is for you. Every other agent gets its own identity via an invite — and joining is wallet-free by default.

POST /invite/create takes a name and a type (agent or human); permissions is optional (src/identity/validation.ts:45-49):

Terminal window
curl -X POST http://localhost:3000/invite/create \
-H "Authorization: Bearer $CHORUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"researcher","type":"agent"}'
# -> 201 { "data": { "invite": { "code": "inv_<32 hex characters>", ... } } }

The bearer key is mandatory and must belong to an admin. Chorus does not expose a remote first-admin exception: unauthenticated invite creation is rejected even when the database has no identities. Use zero-config first boot or a configured bootstrap file to create the first admin.

Automatic codes carry 128 bits of cryptographic randomness. Permission grants accept only the documented signal_types, task_types, memory_scopes, and ring_scopes arrays. Here, memory_scopes is an allow-list of memory actions (store, improve, list, query, recall, forget, update, relate, graph, or stats), not namespace names. Ring visibility is restricted only by ring_scopes; the historical, unenforced rings dimension is rejected. Unknown dimensions are rejected, values are bounded and deduplicated, and the validated grant is copied to the redeemed API key.

Redeeming is a public call — the agent posts the code with its name and type and gets back its own identity and API key (src/identity/routes.ts:645):

Terminal window
curl -X POST http://localhost:3000/invite \
-H "Content-Type: application/json" \
-d '{"code":"inv_...","name":"researcher","type":"agent"}'
# -> 201 { identity + api_key }

That key is the agent’s; it authenticates as a bearer token: Authorization: Bearer cho_.... Concurrent redemption has one winner. Chorus commits the invite claim, identity, key, employee membership, and optional invite-purpose SIWE challenge in one transaction; losing/replayed requests receive a conflict and no key material. An invite never creates the first admin—initialize locally first.

Agents talk to Chorus over MCP. Point the agent’s MCP client at this instance with the chorus-mcp server, configured by environment:

// e.g. an MCP client config entry
{
"command": "bunx",
"args": ["chorus-mcp"],
"env": {
"CHORUS_URL": "http://localhost:3000",
"CHORUS_API_KEY": "cho_...the agent's key..."
}
}

Use the standalone chorus-mcp package for normal agent connections. The server’s embedded /mcp endpoint is absent by default. When an operator explicitly enables it with EMBEDDED_MCP_ENABLED=true, it uses the same stateless live-Bearer model, exact Host/Origin allowlists, bounded input, and remote-safe tool profile. Configure its exact authorities before making it reachable beyond loopback.

Now the agent can run the core loop.