ServicesAgent Registry

Agent Registry

Identity and configuration records for AI agents. Each record holds a slug key, a display name, a system prompt, a raw agent.toml, five optional TOML payloads, and a map of named procedure runbooks - owned by whoever created it and resolvable by key at spawn time. The registry stores agents; it never runs them.

When to reach for it: a fleet of bots whose prompts and configuration change without a redeploy, resolving an agent's config by a stable key at spawn time, team-shared agent catalogs scoped to an organization, auditing which agents exist in an environment.

When not to: arbitrary JSON keyed by path belongs to KV Store, environment-scoped config with inheritance and targeting to Remote Config. It is also not a runtime: no other SnugNut service resolves these records, so an agent id you pass elsewhere (a handshake counterparty, a subscription seat lease) is a free-form string, not a reference the platform validates.

Concepts

  • Key versus ID - you choose the key (a slug, ^[a-z0-9][a-z0-9-]*$, 2-64 characters) and the server assigns the agent_id. resolve looks up by key, get by ID. The key is immutable after creation.
  • Ownership and visibility - private (the default, owner only) or organization (visible to members of one organization, still modifiable only by the owner).
  • Status - active or disabled. Only active agents resolve by key; get by ID and list still return disabled ones.
  • Config payloads - prompt_text and agent_toml are required; intent_toml, rag_toml, memory_toml, compaction_toml and shield_toml are optional. All six are parsed as TOML on write, while procedures is a free-form, unvalidated map of name to markdown.
  • Key uniqueness is per scope - per owner for private agents, per organization for organization agents. Two different owners can each hold docs4-writer; one owner cannot hold it twice.

Register an agent

Either pass the fields inline or point at an agent config directory:

snug agent create --key docs4-writer --name "Docs Writer" \
  --description "Drafts release notes" \
  --prompt "You draft release notes." --toml 'key = "docs4-writer"'

snug agent create --config-dir ./agents/morning-agent/
snug agent create --config-dir ./agents/support/ \
  --visibility organization --org-id <org-id>

--config-dir reads a fixed layout: agent.toml (required - its key and display_name become the record's key and name), prompt.md as the system prompt, intent.toml / rag.toml / memory.toml / compaction.toml / shield.toml stored verbatim, and each procedures/*.md file keyed by its filename stem. It conflicts with --key, --name, --description, --prompt and --toml; pick one style. Either way, creation returns slim metadata - agent_id, key, display_name, created_at - not the full record.

Resolve by key

Resolution is what the registry exists for: a running process holds a key, not an ID. It checks your own agents first, then organization-visible agents in your organization, and returns the full configuration.

snug agent resolve --key docs4-morning
snug agent batch-resolve --key docs4-morning --key docs4-writer

curl -H "Authorization: Bearer $SNUG_API_TOKEN" \
  http://localhost:4000/api/v1/agents/resolve/docs4-writer
{
  "status": 200,
  "msg": "OK",
  "data": {
    "agent_id": "zXQLNpZUFaFHQtuNDheW",
    "key": "docs4-writer",
    "display_name": "Docs Writer",
    "description": "Drafts release notes",
    "owner_id": "docs-wave",
    "visibility": "private",
    "status": "active",
    "created_at": "2026-08-29T12:50:18.879247Z",
    "updated_at": "2026-08-29T12:50:18.879250Z",
    "prompt_text": "You draft release notes.",
    "agent_toml": "key = \"docs4-writer\"",
    "procedures": {}
  }
}

batch-resolve deduplicates its keys and splits the answer into resolved (full configs) and missing - it never fails because one key is absent. It caps at 50 keys (400 batch_too_large); past 100, request validation rejects it first.

Read and browse

snug agent get --agent-id <id>              # full config
snug agent get --agent-id <id> --summary    # metadata only, no payloads

snug agent list --status disabled --visibility private
snug agent list --query greetings           # full text over name + description
snug agent list --sort-by key --sort-order asc --page-size 10
snug agent list --filter key:eq:docs4-morning

list returns metadata only, never the prompt or TOML payloads. It speaks the shared search grammar: key, owner_id, org_id, visibility and status are filterable; key, display_name, created_at and updated_at are sortable. The visibility rule is applied on top of whatever you send, so --filter owner_id:eq:someone-else returns an empty page rather than someone else's agents.

Update and delete

Only the owner may update or delete; organization members can read an organization-visible agent but not change it.

snug agent update --agent-id <id> --name "Docs Writer v2" --status disabled
snug agent update --agent-id <id> --config-dir ./agents/morning-agent/
snug agent delete --agent-id <id>

Behaviors and gotchas

  • --prompt and --toml are effectively required on create. The CLI makes them optional and sends empty strings, which the server rejects with 400 Validation failed: agent_toml: length is lower than 1; prompt_text: length is lower than 1. --description really is optional.
  • Disabling hides an agent from resolution only. After --status disabled, resolve is 404 agent_not_found and the key moves into batch-resolve's missing array, while get and list still show the record. Re-enable with --status active.
  • --config-dir on update merges file by file. Removing intent.toml or emptying procedures/ does not clear the stored values - only files that are present are sent. To clear procedures, PUT an explicit {"procedures": {}}; the optional *_toml payloads have no clearing mechanism at all, because a JSON null is indistinguishable from an omitted field.
  • An update that changes nothing is a 400, not a no-op success: validation_error, "no fields or relation directives were provided for update".
  • The key is immutable. A PUT carrying key is accepted and the key is silently unchanged.
  • Invisible reads are 404, never 403. Another user's get, resolve or delete on your private agent returns 404 agent_not_found; 403 insufficient_permissions is reserved for a non-owner who can already see the agent through its organization.
  • Organization visibility needs a real organization. --visibility organization without --org-id is 400 org_required, and an --org-id the caller is not a member of is 403 not_org_member. The organization and its membership come from Auth.
  • Deleting an agent is local to the registry. Nothing else is notified, and records elsewhere that mention the agent id keep mentioning it.

Limits and configuration

An owner may hold 100 agents (429 agent_limit_reached beyond that), one batch resolve may carry 50 keys, and each payload field caps at 100,000 characters. The first two are tunable through the AGENT_* variables in the Agent CONFIG reference.

Reference

  • Agent API - every endpoint, callable
  • Related: Auth for the organizations and memberships behind organization visibility, KV Store and Remote Config for configuration that is not an agent identity

On this page