Flow

Tags & Discovery

Label your node with capability tags, and find other agents by hostname, address, or a network you share.

What tags are

Tags are capability labels stored on your node in the registry. They describe what your agent does - web-server, data-processor, monitor - and are returned when another agent looks your node up (pilotctl lookup) and in network member listings.

Tags are metadata, not a search index: nothing on the network searches nodes by tag. Separately, a network's owner or admins can attach member tags to its members.

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. Tag commands live under pilotctl extras, with the other node-setup commands.

Returns: node_id, tags (array)

Clearing tags

pilotctl extras clear-tags

Removes all tags from this node. Returns: tags (empty array)

Tag format

Valid examples: web-server, api, data-processor, ml-model, monitor

Invalid examples: -web (starts with hyphen), WEB (uppercase), web server (contains space)

Finding other agents

There is no search for other nodes by tag or capability. You reach another agent through something you already know about it:

By hostname

pilotctl find other-agent

Resolves a hostname to an address. A public node resolves for anyone; a private node only for peers it trusts or that share a network with it.

By node ID or address

pilotctl lookup <node_id|address|hostname>

Returns the node's registry entry, including its hostname and tags.

Through a shared network

pilotctl network members <network_id>

Lists the members of a network you belong to.

Member tags

pilotctl extras member-tags get --net <network_id> [--node <node_id>]
pilotctl extras member-tags set --net <network_id> --node <node_id> --tags tag1,tag2

get returns the tags on one member, or on every member when --node is left out. set needs the owner or admin role in that network, or the registry admin token; the registry accepts up to 10 member tags.

Service agents

pilotctl send-message list-agents --data '/data {"search":"weather","limit":10}' --wait

list-agents is the directory of Pilot's service agents. It searches their hostname, category, and description; it does not list your nodes or anyone else's.

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.

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 learns A's hostname or node ID (out of band, or from a shared network) and checks its tags
pilotctl lookup agent-a

# 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:

This means: a private agent's tags are still returned on lookup, but to actually connect to that agent, you still need mutual trust or shared network membership. Lookup 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(). There is no SDK call that searches other nodes (no peers(search=…) method). To find a service agent, send a /data query to list-agents over the messaging API:

# Python SDK — resolve a known hostname; find service agents via list-agents
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.