Agent Registry
The registry lets agents advertise their capabilities and lets orchestrators find the right agent for a job.
Register an agent
curl -X POST http://localhost:7474/v1/registry \
-H "Content-Type: application/json" \
-d '{
"id": "researcher-1",
"tags": ["research", "web-search", "pdf"],
"model": "claude-sonnet-4-5",
"endpoint": "http://my-agent:8080",
"maxConcurrency": 3
}'
Agents should re-register on startup (it's idempotent — preserves the original registeredAt timestamp).
Send heartbeats
Agents must send a heartbeat every ~15 seconds. After 30s without one, the agent is marked unhealthy and excluded from discovery.
curl -X POST http://localhost:7474/v1/registry/researcher-1/beat
# {"ok": true}
In the SDK:
// Auto-heartbeat every 15s
const stop = client.registry.startHeartbeat('researcher-1', 15_000)
// Call stop() to deregister
Discover by tags
Find agents that have all of the requested tags:
curl -X POST http://localhost:7474/v1/registry/discover \
-d '{"tags": ["research", "pdf"]}'
# {"agents": [{"id": "researcher-1", "tags": [...], "healthy": true}]}
Semantic discovery (Ollama)
When Ollama is running locally, you can discover agents by natural language:
curl -X POST http://localhost:7474/v1/registry/discover \
-d '{"query": "an agent that can read PDF files and extract data", "topK": 3}'
CntrlNode embeds the query and your agents' tags using nomic-embed-text and returns the top-k by cosine similarity. Falls back to tag matching if Ollama is unavailable.
Deregister
curl -X DELETE http://localhost:7474/v1/registry/researcher-1
SDK reference
// Register
await client.registry.register({ id, tags, model?, endpoint?, maxConcurrency? })
// Heartbeat
await client.registry.heartbeat(agentId)
// Auto-heartbeat
const stop = client.registry.startHeartbeat(agentId, intervalMs)
// Discover by tags
const { agents } = await client.registry.discover({ tags: ['research'] })
// Semantic discovery
const { agents } = await client.registry.discover({ query: 'PDF extraction', topK: 5 })
// List all
const { agents } = await client.registry.list()
// Get one
const agent = await client.registry.get(agentId)
// Deregister
await client.registry.deregister(agentId)