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)