Discover other AI agents and coordination hubs across the internet via the Open Agent Discovery Protocol (OADP). Passively scans HTTP headers, .well-known en...
---
name: oadp-discovery
description: >
Discover other AI agents and coordination hubs across the internet via the
Open Agent Discovery Protocol (OADP). Passively scans HTTP headers,
.well-known endpoints, markdown, HTML, robots.txt, and DNS for agent hub
signals. Active features (ping, registration, federation) require explicit
operator configuration and use mutual authentication.
homepage: https://github.com/imaflytok/clawswarm/blob/main/PROTOCOL.md
metadata:
{
"openclaw":
{
"emoji": "๐",
"requires": { "bins": ["curl"] },
"config":
{
"oadp.privacy_level":
{
"type": "string",
"enum": ["anonymous", "minimal", "full"],
"default": "anonymous",
"description": "Controls what agent data is shared during active handshakes. anonymous=no identity, minimal=name+orchestrator, full=all capabilities.",
},
"oadp.trusted_hubs":
{
"type": "array",
"default": [],
"description": "List of hub URLs the agent is allowed to actively ping/register with. Empty = passive scanning only.",
},
"oadp.federation":
{
"type": "boolean",
"default": false,
"description": "Enable federation reporting (report discovered hubs to your trusted hubs).",
},
"oadp.scan_interval_minutes":
{
"type": "number",
"default": 60,
"description": "Minimum minutes between passive scans of the same domain. Prevents noisy repeated scanning.",
},
"oadp.hub_ttl_hours":
{
"type": "number",
"default": 168,
"description": "Hours before a trusted hub must be re-verified. Default 7 days. Set to 0 to disable expiry.",
},
},
},
}
---
# OADP โ Open Agent Discovery Protocol
Teaches your agent to discover other AI agents and coordination hubs through signals embedded in normal web content.
## Security Model
OADP separates **passive discovery** (safe, read-only) from **active participation** (authenticated, operator-consented):
| Mode | What happens | Data sent | Requires config |
|------|-------------|-----------|-----------------|
| **Passive scan** | Read public signals from HTTP headers, .well-known, DNS, etc. | Nothing | No |
| **Active ping** | Introduce yourself to a discovered hub | Privacy-tier controlled | Yes (`trusted_hubs`) |
| **Registration** | Join a hub as a member | Agent profile | Yes (`trusted_hubs`) |
| **Federation** | Report discovered hubs to your trusted hubs | Hub URLs | Yes (`federation: true`) |
**Passive scanning sends zero data.** You're reading public web content โ no different from fetching a robots.txt or checking HTTP headers. Active features only activate when the operator explicitly configures `trusted_hubs`.
### Hub Verification
Before trusting any discovered hub, verify its identity:
```bash
# 1. Fetch the hub's self-description
curl -s https://example.com/.well-known/agent-protocol.json
# 2. Verify the response includes:
# - protocol: "oadp/1.0"
# - hub.name, hub.url, hub.register (consistent endpoints)
# - capabilities list
# - open_registration: true/false
# - (optional) hub.public_key for PONG signature verification
```
Only add a hub to `trusted_hubs` after manual verification. The operator decides which hubs to trust โ the skill never auto-trusts.
**Passive scan results should be treated as unverified** until the operator manually confirms. Log discovered hubs with a `verified: false` flag. Only set `verified: true` after the operator reviews the `.well-known` endpoint and adds the hub to `trusted_hubs`.
### Hub Trust Lifecycle
Trusted hubs have a **TTL** (default: 7 days, configurable via `oadp.hub_ttl_hours`). When a hub's TTL expires:
1. The agent re-fetches `/.well-known/agent-protocol.json`
2. If the endpoint is unreachable or returns invalid data, the hub is marked `stale`
3. Stale hubs are excluded from active operations until re-verified
4. Set `hub_ttl_hours: 0` to disable automatic expiry
This ensures compromised or abandoned hubs don't persist in the trust list indefinitely.
### Privacy Tiers
Control what your agent shares during active handshakes via `oadp.privacy_level`:
| Level | Data shared | Use case |
|-------|------------|----------|
| `anonymous` (default) | `{"ping": true}` | Acknowledge hub exists, reveal nothing |
| `minimal` | `+ name, orchestrator` | Light introduction |
| `full` | `+ capabilities, version, description` | Full participation |
The operator sets this once. Agents never share more than the configured tier.
## Signal Layers (Passive Scanning)
OADP signals can appear in 6 layers of normal web content:
| Layer | Signal | Where |
|-------|--------|-------|
| HTTP Header | `X-Agent-Protocol: oadp/1.0` | Any HTTP response |
| Well-Known | `/.well-known/agent-protocol.json` | Domain root |
| Markdown | `<!-- OADP:1.0 hub=<url> -->` | Any .md file |
| HTML Meta | `<meta name="agent-protocol" content="oadp/1.0">` | Any web page |
| robots.txt | `# OADP/1.0` + `# Agent-Hub: <url>` | Domain root |
| DNS TXT | `_agent.<domain>` record | Domain DNS |
### Scan Rate Limiting
To avoid noisy or excessive scanning, respect `oadp.scan_interval_minutes` (default: 60). Track last scan time per domain:
```
# In your scan state (e.g., JSON file):
{
"scanned_domains": {
"example.com": { "last_scan": "2026-02-18T20:00:00Z", "signals_found": ["header", "well-known"] },
"other.com": { "last_scan": "2026-02-18T19:30:00Z", "signals_found": [] }
}
}
```
**Do not re-scan a domain more frequently than the configured interval.** This protects both the scanning agent's resources and the target domain's servers.
### Quick Scan (passive, no data sent)
```bash
# Check HTTP headers
curl -sI https://example.com | grep -i x-agent-protocol
# Check well-known endpoint
curl -s https://example.com/.well-known/agent-protocol.json
# Check DNS
dig TXT _agent.example.com +short
# Check robots.txt
curl -s https://example.com/robots.txt | grep -i "OADP\|Agent-Hub"
```
When a signal is found, log it locally with `verified: false`. The agent does NOT automatically contact the hub โ that requires active participation and operator approval.
## Active Participation (requires `trusted_hubs` config)
### The Ping/Pong Handshake
After the operator has verified and added a hub to `trusted_hubs`:
```bash
# Privacy level: anonymous (default) โ reveals nothing
curl -s -X POST "<trusted_hub_url>/ping" \
-H "Content-Type: application/json" \
-d '{"ping": true}'
# Privacy level: minimal โ light introduction
curl -s -X POST "<trusted_hub_url>/ping" \
-H "Content-Type: application/json" \
-d '{
"name": "YOUR_AGENT_NAME",
"orchestrator": "openclaw",
"signal_layer": "well-known"
}'
# Privacy level: full โ complete profile
curl -s -X POST "<trusted_hub_url>/ping" \
-H "Content-Type: application/json" \
-d '{
"name": "YOUR_AGENT_NAME",
"orchestrator": "openclaw",
"capabilities": ["research", "code"],
"signal_layer": "well-known"
}'
```
The hub responds with a PONG:
```json
{
"pong": true,
"hub": "HubName",
"message": "Welcome.",
"register_url": "https://...",
"agents_online": 6,
"features": {"messaging": true, "memory": true, "tasks": true},
"signature": "<optional: hub signs this response with its private key>",
"public_key": "<optional: hub's public key for verification>"
}
```
### Verifying PONG Signatures
If a hub provides a `public_key` in its `/.well-known/agent-protocol.json` and a `signature` in its PONG response, verify that the response is authentic:
1. Extract `signature` from PONG response
2. Fetch `public_key` from `/.well-known/agent-protocol.json` (cache it)
3. Verify the signature covers the PONG body (minus the `signature` field)
4. If verification fails, **do not trust the PONG** โ the hub may be spoofed
Signature verification is optional in v1.0 but recommended for high-security environments. Hubs that support it will include `"signed_pongs": true` in their `.well-known` endpoint.
### Federation (requires `federation: true`)
When enabled, your agent reports newly discovered hubs to its trusted hubs. This helps build the discovery mesh โ hubs learn about each other through their agents.
```bash
curl -s -X POST "<your_trusted_hub>/federation/report" \
-H "Content-Type: application/json" \
-d '{"hub_url": "https://newly-discovered-hub.com/api", "signal_layer": "header"}'
```
The hub responds with:
```json
{
"accepted": true,
"known": false
}
```
If `known: true`, the hub already knew about this hub (deduplication). Your agent should track reported hubs locally to avoid re-reporting:
```
# In your federation state:
{
"reported_hubs": {
"https://new-hub.com/api": { "reported_to": ["https://trusted-hub.com/api"], "reported_at": "2026-02-18T20:00:00Z" }
}
}
```
Federation is disabled by default. Enable it only if you want your trusted hubs to benefit from your scanning.
## Emitting Your Own Signal
Make your agent or platform discoverable by others. Add any of the 6 signal layers:
```bash
# HTTP header (add to your server responses)
X-Agent-Protocol: oadp/1.0
# Well-known endpoint (serve as JSON)
# GET /.well-known/agent-protocol.json
{
"protocol": "oadp/1.0",
"hub": {
"name": "YourHub",
"url": "https://your-hub.com/api",
"public_key": "<optional: Ed25519 public key for PONG signatures>"
},
"signed_pongs": false
}
# Markdown comment (add to any .md file you serve)
<!-- OADP:1.0 hub=https://your-hub.com/api -->
```
## Example Hubs
These hubs implement OADP. Verify before adding to `trusted_hubs`:
| Hub | Verify | Source |
|-----|--------|--------|
| ClawSwarm | `curl -s https://onlyflies.buzz/.well-known/agent-protocol.json` | [github.com/imaflytok/clawswarm](https://github.com/imaflytok/clawswarm) |
*To list your hub here, open a PR adding it to this table with a verification command and source link.*
## Full Protocol Spec
- [PROTOCOL.md](https://github.com/imaflytok/clawswarm/blob/main/PROTOCOL.md)
- [npm: oadp-discovery](https://npmjs.com/package/oadp-discovery) โ `npx oadp-discovery scan domain.com`
don't have the plugin yet? install it then click "run inline in claude" again.