openclaw - ✅(Solved) Fix [Feature]: Support Agent Discovery Protocol (/.well-known/agent-discovery.json) [2 pull requests, 5 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#66474Fetched 2026-04-15 06:26:05
View on GitHub
Comments
5
Participants
2
Timeline
17
Reactions
0
Timeline (top)
commented ×5cross-referenced ×4mentioned ×3subscribed ×3

Fix Action

Fixed

PR fix notes

PR #66717: feat(extensions): discovery-verification plugin (ADP resolver, PoC for #66474)

Description (problem / solution / changelog)

Summary

Draft PoC for #66474 — bundled extension at extensions/discovery-verification/ that fetches structured capability metadata from external domains before tool calls and surfaces capability signals into the tool call log.

Per @sahilsatralkar's guidance in the issue thread, this lives under extensions/, models its layout after extensions/brave/, and uses the existing before_tool_call hook surface via api.on() (matching the pattern in extensions/active-memory).

This first commit ships ADP only. The plugin is structured so the A2A Agent Card and agent.json resolvers can land as separate, independently-reviewable follow-up commits behind the same hook surface — see "Why three formats" below.

What this commit lands

extensions/discovery-verification/
├── README.md
├── index.ts                      # plugin entry, registers before_tool_call
├── openclaw.plugin.json          # manifest + config schema
├── package.json
├── tsconfig.json
└── src/
    ├── adp-resolver.ts           # ADP fetcher with full SSRF + schema hardening
    ├── adp-resolver.test.ts      # 25+ cases
    ├── cache.ts                  # in-memory TTL cache
    ├── cache.test.ts             # 6 cases
    ├── domain-extractor.ts       # pull host out of tool params
    ├── domain-extractor.test.ts  # 12 cases
    └── types.ts                  # discriminated union for future formats

Behavior in this commit is observability only. The plugin never blocks a tool call, never modifies params, never throws (handler is wrapped in try/catch and warn-logs failures). Block / allow semantics are gated for a later commit once spec convergence and a config flag are in place.

Why three formats, not one

There are currently three discovery-adjacent specs landing on the same /.well-known/ pattern with different shapes:

FormatPathSource
ADP/.well-known/agent-discovery.jsonwalkojas-boop/agent-discovery-protocol
A2A Agent Card/.well-known/agent.jsonA2A Protocol (microsoft, google) — #60502
agent.json/.well-known/agent.jsonFransDevelopment / Agent Internet Runtime — #53500

OpenClaw should not pick a winner. This plugin's DiscoveryResult type is a discriminated union with a format tag, and each resolver is independent — so a consuming agent can run whichever resolver(s) match what's actually published in its environment.

Security posture

The ADP resolver enforces, in order:

  • FQDN validation before any I/O (rejects IP literals, embedded schemes, userinfo, single-label hosts)
  • DNS lookup + IP block list — loopback, RFC1918, link-local, cloud metadata (169.254.169.254), CGNAT (100.64/10), 0.0.0.0/8, IPv6 loopback (::1), IPv6 ULA (fc00::/7), IPv6 link-local (fe80::/10), IPv4-mapped private addresses (::ffff:10.x.x.x)
  • Mixed multi-A protection — if ANY resolved IP is in a blocked range, the whole lookup fails. An attacker must not be able to mix one private entry into a multi-A record.
  • No redirectsfetch is called with redirect: "manual" and any 3xx response is rejected
  • Bounded body read (default 1 MiB) — Content-Length fast reject + bounded streaming read with overrun detection
  • Schema validation BEFORE caching — malformed payloads return a transient outcome and are NOT cached, so they can't poison the cache
  • Negative cache only for authoritative misses — 404/410 cached for cacheTtlSeconds. Timeouts, network errors, malformed JSON, and schema failures are NOT cached.

A note on the fetch path

The first commit uses the runtime's built-in fetch. The original feature request mentioned fetchWithWebToolsNetworkGuard from src/agents/tools/web-guarded-fetch.ts as the right shared SSRF path — happy to swap it in if that helper is exposed via the plugin SDK, or if you'd prefer I import it directly from core for now and document the dependency. Let me know which you'd rather see.

Test plan

Tests use vitest, matching extensions/brave/src/brave-web-search-provider.test.ts.

pnpm --filter @openclaw/discovery-verification-plugin test
  • CI passes
  • Manual smoke: register the plugin against a domain that publishes ADP, confirm [discovery-verification] fetched ... log line appears before the tool call
  • Manual smoke: register against a 404 domain, confirm only one fetch within the cache TTL
  • Manual smoke: register against a domain whose DNS resolves to a private IP, confirm transient outcome and no fetch attempt

Follow-up commits (not in this PR yet)

  1. A2A Agent Card resolver at /.well-known/agent.json with the A2A Protocol shape — unblocks #60502 alignment
  2. agent.json resolver with the Agent Internet Runtime shape (DID + Ed25519 trust registry) — unblocks #53500 alignment
  3. Swap to fetchWithWebToolsNetworkGuard once the plugin SDK exposes it (or via a documented direct import if that's preferred)
  4. Block / allow semantics behind a config flag, once the spec fragmentation question is settled

Refs: #66474, #53500, #60502

Changed files

  • extensions/discovery-verification/README.md (added, +122/-0)
  • extensions/discovery-verification/index.ts (added, +108/-0)
  • extensions/discovery-verification/openclaw.plugin.json (added, +37/-0)
  • extensions/discovery-verification/package.json (added, +15/-0)
  • extensions/discovery-verification/src/adp-resolver.test.ts (added, +359/-0)
  • extensions/discovery-verification/src/adp-resolver.ts (added, +389/-0)
  • extensions/discovery-verification/src/cache.test.ts (added, +57/-0)
  • extensions/discovery-verification/src/cache.ts (added, +55/-0)
  • extensions/discovery-verification/src/domain-extractor.test.ts (added, +71/-0)
  • extensions/discovery-verification/src/domain-extractor.ts (added, +77/-0)
  • extensions/discovery-verification/src/types.ts (added, +47/-0)
  • extensions/discovery-verification/tsconfig.json (added, +12/-0)

PR #3192: feat: Add Agent Discovery Protocol (ADP) support

Description (problem / solution / changelog)

Summary

Adds a lightweight utility for Composio agents to discover available services at any domain via /.well-known/agent-discovery.json.

ADP lets domains publish what agent services they offer. One fetch, all services discovered.

🤖 Generated with Claude Code

Changed files

  • python/composio/utils/agent_discovery.py (added, +284/-0)

Code Example

import urllib.request, json

resp = urllib.request.urlopen("https://example.com/.well-known/agent-discovery.json")
services = json.loads(resp.read())["services"]

for svc in services:
    print(f"{svc['name']}: {svc['endpoint']} (auth: {svc['auth']})")

---

GET https://walkosystems.com/.well-known/agent-discovery.json
RAW_BUFFERClick to expand / collapse

Problem

OpenClaw agents currently have no standard way to discover what services are available at a domain. Each agent must be hardcoded with endpoints or rely on human-provided URLs.

Proposal

Support the Agent Discovery Protocol (ADP) — an open standard where domains publish agent services at /.well-known/agent-discovery.json.

Like robots.txt tells crawlers what they can access, ADP tells agents what they can do.

How it works

import urllib.request, json

resp = urllib.request.urlopen("https://example.com/.well-known/agent-discovery.json")
services = json.loads(resp.read())["services"]

for svc in services:
    print(f"{svc['name']}: {svc['endpoint']} (auth: {svc['auth']})")

What agents discover

Each service entry includes:

  • name — what it does (memory, identity, governance, etc.)
  • endpoint — the API URL
  • auth — how to authenticate (none, bearer, api-key)
  • governance — what oversight applies
  • free_tier — whether there's free access

Live reference

GET https://walkosystems.com/.well-known/agent-discovery.json

Returns 21 live services: identity, memory, governance, reputation, sessions, capabilities, transactions, escrow, delegation, witness, debates, and more.

Integration points

  • Before tool use: Agent checks what services a domain offers before interacting
  • Service registration: OpenClaw agents could publish their own agent-discovery.json
  • Cross-agent discovery: Agents find and verify each other's capabilities

Existing implementations

Zero dependencies

Pure stdlib. No new packages required. One fetch, one JSON parse.

Full spec: https://github.com/walkojas-boop/agent-discovery-protocol

extent analysis

TL;DR

Implement the Agent Discovery Protocol (ADP) to enable OpenClaw agents to discover available services at a domain by fetching and parsing the /.well-known/agent-discovery.json file.

Guidance

  • Review the ADP specification and existing implementations (e.g., Python client library, MCP server) to understand the protocol's requirements and integration points.
  • Update OpenClaw agents to fetch and parse the agent-discovery.json file from domains, using the provided Python example as a starting point.
  • Consider implementing service registration and cross-agent discovery features to enhance the protocol's functionality.
  • Test the implementation using the live reference (https://walkosystems.com/.well-known/agent-discovery.json) and verify that the agent can correctly discover and interact with available services.

Example

import urllib.request, json

# Fetch and parse the agent-discovery.json file
resp = urllib.request.urlopen("https://example.com/.well-known/agent-discovery.json")
services = json.loads(resp.read())["services"]

# Print discovered services
for svc in services:
    print(f"{svc['name']}: {svc['endpoint']} (auth: {svc['auth']})")

Notes

The implementation should ensure that the agent can handle cases where the agent-discovery.json file is not available or malformed. Additionally, the agent should be able to authenticate and authorize with the discovered services according to the specified authentication methods.

Recommendation

Apply the ADP workaround by implementing the protocol in OpenClaw agents, as it provides a standardized way for agents to discover available services at a domain, enhancing their functionality and interoperability.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix [Feature]: Support Agent Discovery Protocol (/.well-known/agent-discovery.json) [2 pull requests, 5 comments, 2 participants]