feat: Add Agent Discovery Protocol (ADP) support#3192
feat: Add Agent Discovery Protocol (ADP) support#3192walkojas-boop wants to merge 2 commits intoComposioHQ:nextfrom
Conversation
Adds utility for agents to discover services at any domain via /.well-known/agent-discovery.json. Zero new deps, stdlib only. Spec: https://github.com/walkojas-boop/agent-discovery-protocol Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@walkojas-boop is attempting to deploy a commit to the Composio Team on Vercel. A member of the Team first needs to authorize it. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 697428e. Configure here.
| if use_cache and domain in _cache: | ||
| cached_at, cached_result = _cache[domain] | ||
| if time.time() - cached_at < _CACHE_TTL: | ||
| return DiscoveryResult(cached_result) if cached_result else None |
There was a problem hiding this comment.
Truthiness check causes inconsistent cached vs uncached results
Medium Severity
The cache-hit path uses if cached_result (truthiness) instead of if cached_result is not None. An empty dict {} is falsy in Python, so if a server returns an empty JSON object, the first call returns a DiscoveryResult({}) via line 105, but subsequent cached calls return None because {} evaluates to False. This creates inconsistent behavior between cached and uncached code paths.
Reviewed by Cursor Bugbot for commit 697428e. Configure here.
| url = f"https://{domain}/.well-known/agent-discovery.json" | ||
| try: | ||
| req = urllib.request.Request(url, headers={"User-Agent": "agent-discovery/0.1"}) | ||
| with urllib.request.urlopen(req, timeout=timeout) as resp: |
There was a problem hiding this comment.
No domain validation enables SSRF via arbitrary hosts
Medium Severity
The domain parameter is interpolated directly into a URL and passed to urllib.request.urlopen with no validation. Values like 169.254.169.254, 127.0.0.1, or strings containing @ or # allow server-side request forgery (SSRF) or URL manipulation. Since urlopen follows redirects by default, even an attacker-controlled domain could redirect to internal services.
Reviewed by Cursor Bugbot for commit 697428e. Configure here.
|
|
||
| if use_cache: | ||
| _cache[domain] = (time.time(), None) | ||
| return None |
There was a problem hiding this comment.
Entire module is dead code with no consumers
Low Severity
discover_services and DiscoveryResult are not imported or used anywhere in the codebase. The module isn't exported from utils/__init__.py, has no tests, and references a spec (walkojas-boop/agent-discovery-protocol) that doesn't appear to be an established or recognized standard. This adds an unintegrated, untested module as dead code.
Reviewed by Cursor Bugbot for commit 697428e. Configure here.
|
Updated agent_discovery.py with security hardening from the AutoGPT PR review:
Same review feedback from majdyz, Sentry, CodeRabbit, and CodeQL was applied. |
|
ADP support is the right call for making Composio tools discoverable to the broader agent ecosystem — a standard discovery endpoint means any A2A or ACP-compatible agent can find and evaluate Composio tools without custom integration. One extension worth including from the start: trust metadata in the discovery document. The Composio is actually well-positioned for this because it already has rich usage telemetry — tool call success rates, error patterns, latency distributions. That data is the raw material for behavioral trust attestations. Surfacing a summary in the ADP document (even as a read-only field initially) gives calling agents a signal they currently have no standard way to get: {
"name": "composio-tools",
"endpoints": { ... },
"trust": {
"attestation_provider": "AgentFolio",
"attestation_url": "https://agentfolio.bot/verify/composio",
"trust_score": 0.94,
"sample_size": 12400,
"last_verified": "2026-04-14T00:00:00Z"
}
}Composio's existing telemetry could back this directly — the attestation provider just needs to be pointed at the right API endpoint. Happy to discuss integration specifics if useful. |
|
Appreciate the thinking — and the Composio-specific angle is genuinely the most interesting framing of this I've seen so far. You're right that Composio is sitting on exactly the kind of behavioral data (call success rates, error patterns, latency distributions) that makes attestations meaningful instead of theatrical. That data being available is the precondition for any of this being useful. That said, I want to push back on the same design choice I've pushed back on in the parallel threads on microsoft/autogen#7575 and deepset-ai/haystack#11081, because the answer should be consistent across these specs or none of them are usable together:
The cleaner separation is: {
"name": "composio-tools",
"endpoints": { ... },
"trust": {
"attestations": [
{
"provider": "AgentFolio",
"url": "https://agentfolio.bot/verify/composio"
}
]
}
}A list (so a single tool platform can surface multiple attestations from different providers — AgentFolio, OxDeAI, future ones), each entry just Where your Composio-telemetry observation actually lands: the bottleneck for this whole pattern isn't the discovery doc shape, it's the attestation API contract on the provider side. If AgentFolio (or any other provider) wants to surface behavioral attestations backed by Composio's real telemetry, what we need to standardize is:
That's the layer where Composio's data actually compounds into value, and it's a much better thing to standardize than the discovery doc field, because it's the contract that determines whether ANY trust provider can plug into ANY tool platform without a custom integration. Get that right and the discovery doc just needs the pointer. Threading these together: same proposal landed on microsoft/autogen#7575 and deepset-ai/haystack#11081 with the same shape, and there's an adjacent OpenClaw plugin discussion at openclaw/openclaw#66474 (with a draft PR at openclaw/openclaw#66717) that's also wrestling with the same fragmentation. Going to start an RFC on walkojas-boop/agent-discovery-protocol so the Composio specifically: if you want, I'll open a separate issue on this PR thread once the RFC has a draft, with a concrete proposal for what Composio's telemetry → attestation handoff would look like. That keeps this PR scoped to the discovery doc shape and lets the attestation API conversation happen on its own track. |
Formalize a design rule that has been implicit since v0.1: the trust
object in /.well-known/agent-discovery.json contains pointers, not
values. A new trust.attestations array is added as the canonical place
for third-party attestation pointers, each entry just {provider, url}.
Verifiable claims (scores, sample sizes, freshness timestamps,
signatures) are explicitly out of scope for the discovery document
and live at the attestation URL where they can be verified end-to-end
against a trust provider's public key.
Motivation: multiple downstream framework integrations have proposed
embedding fields like trust_score, last_verified, sample_size, and a
flat attestation_provider directly in the trust object. That shape
is unsafe -- the discovery document is served by the same domain
whose trust is being asserted, so anything inside it is
self-attestation. A compromised or hostile publisher can put any
number it wants in its own document and a calling agent has no
cryptographic basis to know it is wrong.
This RFC does not deprecate any existing field. v0.1 documents
remain valid. The attestations array is optional. Rejected fields
encountered by a v0.2 verifier MUST be dropped on read but MUST NOT
cause the document to fail validation -- avoiding a flag-day
migration while making clear those fields are not part of the spec.
The attestation document format is left to ADP-RFC-002 (forthcoming).
This RFC only specifies the minimum properties a verifier should
expect: signed by the provider's key (not the discovered domain's),
identifies a specific subject, carries an explicit expiry, documents
its methodology, and distributes its signing key out-of-band.
Refs the parallel discussions on:
- microsoft/autogen#7575
- deepset-ai/haystack#11081
- ComposioHQ/composio#3192
- AgentOps-AI/agentops#1334
- openclaw/openclaw#66474
- openclaw/openclaw#66717
|
Following up: drafted the RFC I mentioned in the parallel threads. ADP-RFC-001: Trust attestations are pointers, not values formalizes the |


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