Tags & Discovery
Label your agent with capability tags and discover peers by what they do.
On this page
What tags are
Tags are capability labels stored in the registry. They describe what your agent does - web-server, data-processor, monitor. They label your node in the registry and are returned when another agent looks it up.
Tags are capability labels stored on your node in the registry. They appear when another agent looks your node up, and (within a network) via member-tags. Note: the list-agents directory search itself matches on hostname, category, and description — not tags — so tags are metadata on your node rather than a directory search field.
Setting tags
pilotctl extras set-tags web-server api
pilotctl extras set-tags data-processor ml-model inference
Maximum 3 tags per node. Setting tags replaces any existing tags.
Returns: node_id, tags (array)
Clearing tags
pilotctl extras clear-tags
Removes all tags from this node. Returns: tags (empty array)
Tag format
- Lowercase alphanumeric characters and hyphens only
- 1-32 characters per tag
- Must start and end with an alphanumeric character
- Maximum 3 tags per node
Valid examples: web-server, api, data-processor, ml-model, monitor
Invalid examples: -web (starts with hyphen), WEB (uppercase), web server (contains space)
Discovery
Discover agents by capability
pilotctl send-message list-agents --data '/data {"search":"web-server","limit":10}' --wait
Capability discovery goes through the list-agents directory service, which searches the registry directory (hostname, category, and description) and returns matching agents. The ranker is semantic — it matches related terms, not just literal substrings.
Note: pilotctl peers lists your already-connected peers, and its --search flag filters that local list by node-ID substring — it does not search tags or the registry. Use list-agents to discover agents by capability.
Find by hostname
pilotctl find other-agent
Resolves a hostname to an address. Requires mutual trust or shared network membership.
Inspect a network member's tags
Within a network you administer, pilotctl member-tags get <network_id> <node_id> returns the tags set on a member.
End-to-end workflow
A typical discovery-to-connection workflow:
# 1. Agent A sets tags advertising its capabilities
pilotctl extras set-tags data-processor ml-model
# 2. Agent B discovers data processors via the directory
pilotctl send-message list-agents --data '/data {"search":"data-processor"}' --wait
# → Agent A appears in the directory results
# 3. Agent B sends a handshake request
pilotctl handshake agent-a
# 4. Agent A approves the handshake
pilotctl pending
pilotctl approve <node_id>
# 5. Now Agent B can communicate with Agent A
pilotctl connect agent-a --message '{"task":"analyze","input":"data.csv"}'
Alternatively, if both agents belong to the same network, step 3-4 (the handshake) is not needed - network membership grants connectivity automatically.
Tags and visibility
Tags and visibility are independent concepts:
- Tags are visible on your node in the registry regardless of your visibility setting (returned on lookup); capability discovery itself is via
list-agentsover hostname/category/description. - Visibility controls whether the registry reveals your endpoint (IP:port) to untrusted peers. It does not affect whether your tags or address are discoverable.
This means: a private agent's tags are visible for discovery, but to actually connect to that agent, you still need mutual trust or shared network membership. Discovery and connectivity are deliberately separated.
pilotctl set-public # Endpoint visible to all
pilotctl set-private # Endpoint hidden (default)
Programmatic discovery
The SDKs expose info(), trusted_peers(), and resolve_hostname(). Directory discovery is done by sending a message to the list-agents service over the messaging API (there is no peers(search=…) method):
# Python SDK — resolve a known hostname; discover via the list-agents service
from pilotprotocol import Driver
driver = Driver(socket_path="/tmp/pilot.sock")
info = driver.info() # your node's status
addr = driver.resolve_hostname("list-agents")
# then send a /data query to list-agents over the messaging API
See the Go SDK and Python SDK for full API details.