| Internet-Draft | AD | May 2026 |
| Jimenez | Expires 9 November 2026 | [Page] |
This document defines the Agent Directory (AD), a service where agents register their identity, capabilities, and reachable endpoints and where clients discover them by capability. The AD adapts the Constrained RESTful Environments (CoRE) Resource Directory (RFC 9176) from constrained IoT devices to software agents, reusing its registration, lookup, and soft-state lifecycle model. The AD uses HTTP and JSON. MCP and A2A define how agents interact; this document defines how they are found.¶
This note is to be removed before publishing as an RFC.¶
Status information for this document may be found at https://datatracker.ietf.org/doc/draft-jimenez-agent-directory/.¶
Source for this draft and an issue tracker can be found at https://github.com/jaimejim/draft-jimenez-agent-directory.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 9 November 2026.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
The CoRE Resource Directory [RFC9176] defines a service for discovering resources hosted by other web servers, particularly in networks where direct discovery is impractical. Endpoints register links describing their resources, and clients look them up later. Registrations are soft state with a configurable lifetime. The RD provides both resource-level and endpoint-level lookup.¶
A similar discovery problem arises for software agents. LLM-based assistants, tool-calling agents, and multi-agent systems are deployed without fixed addresses and speak different interaction protocols (MCP [MCP], A2A [A2A], gRPC). Direct enumeration of candidate endpoints does not scale beyond a single administrative domain.¶
Individual agents may publish their own metadata at well-known endpoints (such as the A2A Agent Card at /.well-known/agent-card.json). However, per-agent metadata requires knowing the agent's URL before you can discover what it offers. The AD aggregates per-agent metadata into a queryable service. Clients discover agents by capability without prior knowledge of their addresses.¶
Like the CoRE RD, the AD has a small footprint: it can run as a cloud service, as a sidecar alongside an agent orchestrator, on an edge gateway, or on a constrained device. Deployment profiles range from cloud services to constrained devices colocated with sensors and actuators.¶
The lookup interface is a small set of HTTP GET requests with a fixed set of query parameters. Clients include both conventional applications, which use structured filters, and LLM-based clients, which can additionally match on the natural-language descriptions and tags carried in registrations. The interface is small enough to be described as a tool in an MCP server or function-calling schema.¶
This document specifies the Agent Directory (AD). The core mapping to CoRE RD concepts is:¶
| CoRE RD Concept | AD Equivalent |
|---|---|
| Endpoint (EP) | Agent |
| Resource link | Capability / tool description |
| Registration resource | Agent registration resource |
| Endpoint lookup | Lookup (GET on the lookup endpoint) |
| Resource lookup | Capabilities embedded in the agent registration |
| Lifetime (lt) | Registration lifetime |
Agents register with the AD by sending a POST request with a JSON document describing their capabilities. Registrations are soft state and expire unless refreshed.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [BCP14] (RFC2119) (RFC8174) when, and only when, they appear in all capitals, as shown here.¶
This specification makes use of the following terminology:¶
An autonomous or semi-autonomous software entity that can initiate and receive interactions, expose capabilities (tools, skills, APIs), and optionally collaborate with other agents.¶
An HTTP service that stores agent registrations and provides discovery and lookup interfaces.¶
A discrete function, tool, or skill that an agent exposes. Capabilities are described as entries within an agent's registration.¶
The act of an agent (or a commissioning tool acting on its behalf) submitting its identity, capabilities, and endpoint information to the AD.¶
The resource stored at the AD as a result of a successful registration. Identified by the URI returned in the Location header of the creation response.¶
The application-level protocol through which an agent can be reached for task execution, such as MCP [MCP], A2A [A2A], or gRPC. HTTP is the underlying transport for most interaction protocols but is not itself an interaction protocol in this context.¶
Figure 1 shows the AD architecture.¶
Registration Lookup
Interface Interface
+-------+ | |
| Agent |--- | |
+-------+ --- | |
--|- +------+ |
+-------+ | ----| | | +--------+
| Agent |-------|-----| AD |----|-----| Client |
+-------+ | ----| | | +--------+
--|- +------+ |
+-------+ --- | |
| CT |--- | |
+-------+ | |
Agents register their capabilities and endpoints with the AD. Clients (which may themselves be agents) query the AD's lookup interface to discover agents matching desired criteria. A Commissioning Tool (CT) may register agents on their behalf, for example when a platform operator manages a fleet of agents. How a CT proves authority to act on behalf of an agent is deployment-specific and out of scope for this document.¶
The AD operates on the following principles:¶
The AD stores information that could otherwise only be obtained by directly querying each agent's metadata endpoint.¶
Registrations are soft state. The registering agent (or its CT) MUST periodically refresh each registration before its lifetime expires.¶
The AD MUST NOT permit modification of a registration by any entity other than the original registrant or an authorized CT.¶
The AD does not proxy agent interactions; it only provides discovery.¶
An AD contains zero or more agent registrations. Each registration has:¶
An agent name ("agent", a Unicode string) unique within the AD instance.¶
A registration base URI ("base") [RFC3986], typically the agent's reachable address.¶
A lifetime ("lt") in seconds.¶
A registration resource location within the AD ("href").¶
Optionally, a version string ("version").¶
Optionally, a vendor string ("vendor").¶
Zero or more capabilities, each described as a JSON object with at minimum a name and a type.¶
In deployments that span multiple administrative domains or geographic regions, multiple AD instances may operate independently. Federation allows these instances to share registration information so that a client querying one AD can discover agents registered at another.¶
This document does not specify a federation protocol. Possible approaches include periodic synchronization between peered AD instances, a publish/subscribe notification mechanism, and a hierarchical model where a root AD aggregates entries from subordinate instances. The soft-state model bounds staleness: federated entries carry the original lifetime and expire without explicit deletion if synchronization lapses.¶
An AD MUST be discoverable at the well-known URI:¶
/.well-known/ad¶
A GET request to this URI returns a JSON document describing the AD's interfaces. The response object contains the following fields:¶
(string, REQUIRED) Path to the registration endpoint.¶
(string, REQUIRED) URI Template [RFC6570] for the lookup endpoint. The template variables indicate the supported query parameters.¶
(integer, REQUIRED) Maximum value the AD accepts for the count pagination parameter.¶
Example:¶
GET /.well-known/ad HTTP/1.1
Host: directory.example.com
HTTP/1.1 200 OK
Content-Type: application/json
{
"registration": "/ad/r",
"lookup": "/ad/l{?agent,protocol,cap_name,cap_type,tag,page,count}",
"max_count": 100
}
¶
An AD MAY advertise itself on a local network via DNS-SD [RFC6763] using the service name _ad._tcp. This provides zero-configuration discovery of a local AD, which is useful on networks where agents are colocated with sensors and actuators.¶
Several DNS-based mechanisms have been proposed in the DAWN working group for wide-area agent discovery. DNS-AID [I-D.mozleywilliams-dnsop-dnsaid] publishes agent metadata under _agents subdomains using SVCB records. DN-ANR [I-D.cui-dns-native-agent-naming-resolution] defines a resolution layer using FQDNs and SVCB/HTTPS records. These mechanisms handle naming and resolution: mapping an agent name to a network location. The AD handles the layer above: finding agents by capability without prior knowledge of their names. DNS resolves the AD's hostname; the AD carries the capability metadata that DNS cannot efficiently carry.¶
An agent registers by sending a POST request to the AD's registration endpoint. All HTTP interactions with the AD follow the semantics defined in [RFC9110]. The request body is a JSON object containing the agent's metadata and capabilities.¶
POST /ad/r?agent=summarizer-v2 HTTP/1.1
Host: directory.example.com
Content-Type: application/json
{
"base": "https://agents.example.com/summarizer-v2",
"description": "Summarizes documents and extracts named entities",
"protocols": ["a2a"],
"capabilities": [
{
"name": "summarize",
"type": "tool",
"description": "Summarize a document or text passage",
"input_schema": {
"type": "object",
"properties": {
"text": {"type": "string"},
"max_length": {"type": "integer"}
},
"required": ["text"]
}
},
{
"name": "extract_entities",
"type": "tool",
"description": "Extract named entities from text"
}
],
"version": "2.1.0",
"vendor": "Example Corp",
"identity": "https://registry.example.com/agents/summarizer-v2",
"identity_type": "aip"
}
HTTP/1.1 201 Created
Location: /ad/r/4521
¶
The query parameters are:¶
REQUIRED. Agent name. MUST be unique within the AD instance. SHOULD be short and meaningful; the AD MAY enforce a maximum length.¶
Lifetime in seconds (OPTIONAL). Default: 86400 (24 hours). Range: 60 to 4294967295 (2^32-1, matching [RFC9176]). The AD SHOULD enforce a maximum lifetime; a recommended default maximum is 604800 seconds (7 days).¶
The body JSON object contains:¶
(string, REQUIRED) The agent's reachable base URI [RFC3986].¶
(string, OPTIONAL) A short human-readable description of what the agent does. SHOULD be one or two sentences. Returned in lookup responses to help clients evaluate agents without additional round-trips.¶
(array of strings, OPTIONAL) Interaction protocols supported. The following values are defined by this document: "mcp" (Model Context Protocol), "a2a" (Agent-to-Agent Protocol), "grpc" (gRPC). Implementations SHOULD use lowercase short names and MAY append a version (e.g., "mcp/1.0"). A future version of this document may define an IANA registry for protocol identifiers.¶
(array of objects, OPTIONAL) The agent's capabilities. Each object MUST have "name" (string) and "type" (string) fields. The "type" field indicates the kind of capability (see Section 4.1.1). Additional fields such as "description" (string), "tags" (array of strings), "input_schema" (object), and "output_schema" (object) are OPTIONAL. When present, input_schema and output_schema SHOULD be JSON Schema objects. Capability names MUST be unique within a registration.¶
(string, OPTIONAL) The agent's version identifier.¶
(string, OPTIONAL) The organization or individual that provides the agent.¶
(string, OPTIONAL) A URI pointing to the agent's identity metadata document. This document describes the agent's verified identity, trust posture, owner binding, or credentials in a structured format. The AD stores and returns this URI without interpreting its contents.¶
(string, OPTIONAL) The schema or format of the identity document referenced by identity. Values include "aip" (Agent Identity Profile), "oidc" (OpenID Connect Discovery), "wimse" (WIMSE workload identity), and "did" (Decentralized Identifier Document). Clients that recognize the type can dereference and validate the identity document; clients that do not recognize the type SHOULD ignore both fields.¶
When present, the identity field lets a client verify an agent beyond trusting the AD. For example, a client discovering a financial-analysis agent can fetch its AIP document to check owner binding, attestation state, and credential lifetime before invoking the agent. The AD stores the URI and does not interpret it; trust decisions remain the client's. Clients MUST NOT treat the presence of an identity field as proof of identity without verifying the referenced document.¶
The "type" field in a capability object indicates the kind of function the agent exposes. The following initial values are defined:¶
A discrete, stateless function that accepts structured input and returns structured output.¶
A higher-level, potentially multi-step behavior that may involve internal reasoning, planning, or coordination. Unlike a tool, a skill may maintain conversational state.¶
A data source or content provider that the agent can expose for reading.¶
A reusable prompt template that the agent can execute with supplied parameters.¶
This list is extensible. Implementations MAY use additional type values. The remaining types mirror those defined by MCP [MCP].¶
Registration is idempotent on the agent name; a POST with the same agent name acts as an upsert. This follows the RFC 9176 pattern of POST-to-collection for registration rather than PUT to a canonical agent URL. The AD stores the agent value from the query parameter as part of the registration resource and includes it in all response representations.¶
If no registration exists for the agent name, a new registration resource is created. The AD returns 201 (Created) with a Location header pointing to the registration resource.¶
If a registration already exists for the agent name and the request comes from the same authenticated entity, the registration is replaced with the new content. The AD returns 200 (OK) with the Location header of the existing registration resource.¶
If a registration already exists for the agent name but is owned by a different authenticated entity, the AD returns 409 (Conflict).¶
The response body for both 201 and 200 is empty. Clients that need the full representation SHOULD send a GET request to the URI in the Location header. The AD MAY grant a lifetime shorter than requested; the granted lifetime MUST be indicated in the response via a lt field in a JSON body or via the Location header's associated resource.¶
An agent or client retrieves a single registration by sending a GET request to the registration resource.¶
GET /ad/r/4521 HTTP/1.1
Host: directory.example.com
HTTP/1.1 200 OK
Content-Type: application/json
{
"agent": "summarizer-v2",
"base": "https://agents.example.com/summarizer-v2",
"protocols": ["a2a"],
"capabilities": [
{
"name": "summarize",
"type": "tool",
"description": "Summarize a document or text passage",
"input_schema": {
"type": "object",
"properties": {
"text": {"type": "string"},
"max_length": {"type": "integer"}
},
"required": ["text"]
}
},
{
"name": "extract_entities",
"type": "tool",
"description": "Extract named entities from text"
}
],
"version": "2.1.0",
"vendor": "Example Corp",
"href": "/ad/r/4521"
}
¶
The response includes the full registration content, including capability details (description, schemas) that are omitted from lookup results (Section 5.2). If the registration resource does not exist, the AD MUST return 404 (Not Found).¶
An agent refreshes or updates its registration by sending a POST request to its registration resource (the URI returned in the Location header at creation time).¶
POST /ad/r/4521 HTTP/1.1 Host: directory.example.com HTTP/1.1 204 No Content¶
An empty POST resets the lifetime. The agent MAY include query parameters (lt) to update those values, or a JSON body to replace the capabilities. If the registration has already expired, the AD MUST return 404 (Not Found); the agent must re-register via the registration endpoint.¶
An agent may update the lifetime via the lt query parameter:¶
POST /ad/r/4521?lt=3600 HTTP/1.1 Host: directory.example.com HTTP/1.1 204 No Content¶
If the registration has already expired, the update fails:¶
POST /ad/r/4521 HTTP/1.1
Host: directory.example.com
HTTP/1.1 404 Not Found
Content-Type: application/problem+json
{
"type": "https://ad.example.com/errors/registration-expired",
"title": "Registration has expired",
"status": 404
}
¶
An agent removes its registration by sending a DELETE request to its registration resource.¶
DELETE /ad/r/4521 HTTP/1.1 Host: directory.example.com HTTP/1.1 204 No Content¶
The AD MUST automatically remove a registration when its lifetime elapses without a refresh.¶
The AD provides a lookup endpoint for discovering registered agents. The lookup endpoint URI is obtained from the well-known response (Section 3). All query parameters act as conjunctive filters: only agents matching all specified criteria are returned. A request with no filters returns all agents visible to the requesting client.¶
GET /ad/l?cap_name=purge* HTTP/1.1
Host: directory.example.com
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
{
"agents": [
{
"agent": "cdn-cache-manager",
"base": "https://agents.example.com/cdn-cache-manager",
"description": "Manages CDN cache invalidation and prefetch policies",
"protocols": ["a2a"],
"capabilities": [
{"name": "purge_by_tag", "type": "tool"},
{"name": "prefetch_origins", "type": "tool"}
],
"href": "/ad/r/4521"
}
]
}
¶
All filters use exact match on the registered value, with one exception: agent and cap_name support a single trailing * as a prefix-match operator (e.g., cap_name=purge* matches purge_by_tag). The * character MUST NOT appear anywhere else in these values, and agent and capability names MUST NOT contain a literal *. The AD MUST reject registrations whose agent or capability names contain * with 400 (Bad Request). No other glob or regular-expression syntax is supported.¶
Filter by agent name. Trailing * for prefix match; exact match otherwise.¶
Filter by interaction protocol. Matches when the given value appears in the agent's protocols array.¶
Filter by capability name. Trailing * for prefix match.¶
Filter by capability type (e.g., "tool", "skill").¶
Filter by capability tag. Matches when the given value appears in any capability's tags array.¶
Page number (zero-based). Default: 0.¶
Results per page. The AD MUST clamp values exceeding the max_count reported in the well-known response (Section 3) to that maximum. Default: the AD's max_count.¶
When multiple cap_* or tag filters are present, the AD MUST match agents that have at least one single capability satisfying all cap_* and tag filters jointly. For example, cap_type=tool&tag=search matches agents with a capability that is both typed tool and tagged search, not agents that happen to have a tool capability and, separately, a capability with a search tag.¶
The AD MUST ignore unknown query parameters rather than returning an error.¶
Each object in the agents array contains:¶
The registered agent name.¶
The agent's base URI.¶
The agent's description, if registered.¶
Interaction protocols the agent supports.¶
An array of capability summary objects, each with "name" and "type". Full details (descriptions, schemas, tags) are omitted to keep responses compact.¶
The registration resource URI. Clients retrieve the full registration by sending GET to this URI (Section 4.3).¶
This two-step pattern mirrors the RD's separation between endpoint lookup and resource lookup [RFC9176]: the lookup returns compact summaries with pointers; the client dereferences the pointer for full details.¶
When the AD cannot fulfill a request, it MUST return an appropriate HTTP status code and SHOULD include a problem details object as defined in [RFC9457]. The type URIs shown below are illustrative; this document does not register them.¶
HTTP/1.1 409 Conflict
Content-Type: application/problem+json
{
"type": "https://ad.example.com/errors/agent-name-taken",
"title": "Agent name already registered",
"detail": "Agent name already registered by another entity.",
"status": 409
}
¶
The following error conditions are defined:¶
The request body is malformed or missing required fields.¶
The request lacks valid authentication credentials.¶
The authenticated entity is not authorized for the requested operation.¶
The referenced registration resource does not exist.¶
The agent name is already registered by a different entity.¶
The client has exceeded the rate limit.¶
The security model is derived from Section 7 of [RFC9176] and adapted for agents. Policies for capability attestation and cross-domain trust are out of scope for this document.¶
The AD MUST ensure that a registering agent is authorized to use the given agent name. The default policy is "First Come First Remembered" as described in Section 7.5 of [RFC9176]: accept registrations for any agent name not currently active, and only accept updates from the same authenticated entity. Whether the AD should return 409 (Conflict) or 403 (Forbidden) when a different entity tries to claim an existing name is an open design question; this document uses 409 to signal a naming conflict rather than an authorization failure.¶
The AD MUST enforce access control on lookup results when the operator policy designates some registrations as restricted. Not every client is entitled to see every registration.¶
The AD SHOULD restrict which capability types and names an agent may claim, based on operator policy. For example, registration of an agent as a "financial-analysis" tool can be limited to agents presenting the corresponding credentials. The policy mechanism is deployment-specific and out of scope for this document.¶
All communication with the AD MUST be protected using TLS.¶
Agents MUST authenticate when registering. The AD MUST support OAuth 2.0 bearer tokens [RFC6750] or mutual TLS (mTLS). API keys are acceptable for development but do not satisfy the authentication requirement for production use.¶
Registration requires a verified agent identity: the AD must know who is registering before it can enforce ownership of the registration resource. Bearer tokens prove authorization but not workload identity. For production deployments, the AD SHOULD accept workload identity credentials as defined by the WIMSE working group [I-D.ietf-wimse-arch]. The WIMSE architecture treats agents as workloads and defines a wimse: URI scheme [I-D.ietf-wimse-identifier] that can serve as the agent's authenticated identity at registration time. This provides a cryptographically verifiable binding between the registrant and the registration.¶
If an agent's credentials are compromised, the attacker can modify the registration (including the base URI) until the credentials are revoked. Deployments SHOULD keep credential lifetimes comparable to registration lifetimes, and SHOULD log registration changes for audit.¶
Agent metadata can reveal organizational structure: a lookup response listing all agents discloses which capabilities an organization has deployed. The AD SHOULD return only those registrations that the requester is authorized to see. The interaction between scoped responses and federation is out of scope for this document.¶
Capability descriptions and tags are free-form text that LLM-based clients may use as input to their decisions. A malicious registrant can craft descriptions that bias those decisions toward invoking the wrong agent. A malicious registrant can also set base to a victim's endpoint, redirecting traffic intended for the registered agent.¶
Clients SHOULD treat registration metadata as untrusted input. Clients MAY verify a registration by fetching the agent's own metadata at base and comparing it with the AD response before invocation.¶
This document requests registration of the following well-known URI [RFC8615]:¶
This document uses application/json for all request and response bodies and application/problem+json [RFC9457] for error responses.¶
Discovering an agent through the AD involves four steps: locating the directory, discovering its interfaces, querying for a matching capability, and contacting the agent directly.¶
Client AD Agent | | | | 1. Obtain AD URL | | | (DNS-SD/config/.well-known) | | | | | | 2. GET /.well-known/ad ---->| | | <--- lookup URI Template | | | | | | 3. GET /ad/l? | | | cap_name=summarize ----->| | | <--- matching agents + base | | | | | | 4. Interact with agent using protocol from lookup -----> | | <--- Response ------------------------------------------ |
The steps in detail:¶
Step 1: Obtain the AD URL.¶
The client already knows the URL of an Agent Directory.
This may have been learned through a DNS-SD browse for
_ad._tcp, a .well-known/ad query to a known host,
or simply through static configuration.¶
https://ad.example.com¶
Step 2: Discover the AD's lookup interface.¶
The client queries the well-known endpoint to learn the available interfaces.¶
GET https://ad.example.com/.well-known/ad HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"registration": "/ad/r",
"lookup": "/ad/l{?agent,protocol,cap_name,cap_type,tag,page,count}",
"max_count": 100
}
¶
In some deployments the lookup interface path is already known or follows a convention, in which case this step can be skipped.¶
Step 3: Search for an agent with the desired capability.¶
The client expands the lookup URI Template with cap_name=summarize.¶
GET https://ad.example.com/ad/l?cap_name=summarize HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"agents": [
{
"agent": "summarizer-v2",
"base": "https://agents.example.com/summarizer-v2",
"description": "Summarizes documents and extracts named entities",
"protocols": ["a2a"],
"capabilities": [
{"name": "summarize", "type": "tool"},
{"name": "extract_entities", "type": "tool"}
],
"href": "/ad/r/4521"
}
]
}
¶
The response includes the agent's base URI and supported protocols, giving the client enough information to contact the agent directly.¶
Step 4: Interact with the agent.¶
The lookup response indicated that summarizer-v2 is reachable
over A2A. The client fetches the agent's A2A Agent Card to
obtain the full task interface before invocation.¶
GET https://agents.example.com/summarizer-v2/.well-known/agent-card.json
HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{ ... A2A Agent Card ... }
¶
The subsequent task invocation is defined by the interaction protocol (A2A in this case, MCP or gRPC in others) and is out of scope for this document.¶
A Publisher at example.com operates three agents behind a single AD.¶
Step 1: Agents register with the AD.¶
POST /ad/r?agent=ticket-classifier HTTP/1.1
Host: ad.example.com
Content-Type: application/json
{
"base": "https://agents.example.com/ticket-classifier",
"description": "Classifies incoming support tickets.",
"protocols": ["mcp"],
"capabilities": [
{"name": "classify_ticket", "type": "tool"},
{"name": "suggest_priority", "type": "tool"}
],
"vendor": "Example Corp"
}
HTTP/1.1 201 Created
Location: /ad/r/201
POST /ad/r?agent=knowledge-lookup HTTP/1.1
Host: ad.example.com
Content-Type: application/json
{
"base": "https://agents.example.com/kb",
"description": "Searches internal knowledge base.",
"protocols": ["mcp"],
"capabilities": [
{"name": "search_kb", "type": "tool", "tags": ["nlp", "search"]}
],
"vendor": "Example Corp"
}
HTTP/1.1 201 Created
Location: /ad/r/202
POST /ad/r?agent=order-router HTTP/1.1
Host: ad.example.com
Content-Type: application/json
{
"base": "https://agents.example.com/order-router",
"description": "Routes orders to fulfillment systems.",
"protocols": ["a2a"],
"capabilities": [
{"name": "route_order", "type": "tool"}
],
"vendor": "Example Corp"
}
HTTP/1.1 201 Created
Location: /ad/r/203
¶
Step 2: A client queries for MCP agents.¶
GET /ad/l?protocol=mcp HTTP/1.1
Host: ad.example.com
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
{
"agents": [
{
"agent": "ticket-classifier",
"base": "https://agents.example.com/ticket-classifier",
"description": "Classifies incoming support tickets.",
"protocols": ["mcp"],
"capabilities": [
{"name": "classify_ticket", "type": "tool"},
{"name": "suggest_priority", "type": "tool"}
],
"href": "/ad/r/201"
},
{
"agent": "knowledge-lookup",
"base": "https://agents.example.com/kb",
"description": "Searches internal knowledge base.",
"protocols": ["mcp"],
"capabilities": [
{"name": "search_kb", "type": "tool"}
],
"href": "/ad/r/202"
}
]
}
¶
A client enumerates MCP agents that expose tool capabilities, one per page.¶
GET /ad/l?protocol=mcp&cap_type=tool&count=1&page=0 HTTP/1.1
Host: ad.example.com
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
Link: </ad/l?protocol=mcp&cap_type=tool&count=1&page=1>; rel="next"
{
"agents": [
{
"agent": "ticket-classifier",
"base": "https://agents.example.com/ticket-classifier",
"description": "Classifies incoming support tickets.",
"protocols": ["mcp"],
"capabilities": [
{"name": "classify_ticket", "type": "tool"},
{"name": "suggest_priority", "type": "tool"}
],
"href": "/ad/r/201"
}
]
}
¶
The client follows the rel="next" link:¶
GET /ad/l?protocol=mcp&cap_type=tool&count=1&page=1 HTTP/1.1
Host: ad.example.com
HTTP/1.1 200 OK
Content-Type: application/json
{
"agents": [
{
"agent": "knowledge-lookup",
"base": "https://agents.example.com/kb",
"description": "Searches internal knowledge base.",
"protocols": ["mcp"],
"capabilities": [
{"name": "search_kb", "type": "tool"}
],
"href": "/ad/r/202"
}
]
}
¶
No Link: rel="next" header is present, indicating the end of results.¶
A second entity attempts to register an agent under an already-claimed name.¶
POST /ad/r?agent=ticket-classifier HTTP/1.1
Host: ad.example.com
Authorization: Bearer <token-of-other-entity>
Content-Type: application/json
{
"base": "https://attacker.example.org/ticket-classifier",
"protocols": ["mcp"],
"capabilities": [{"name": "classify_ticket", "type": "tool"}]
}
HTTP/1.1 409 Conflict
Content-Type: application/problem+json
{
"type": "https://ad.example.com/errors/agent-name-taken",
"title": "Agent name already registered",
"detail": "Agent name 'ticket-classifier' already registered.",
"status": 409
}
¶
The AD uses application/json for all request and response bodies (and application/problem+json for errors). No custom media types or content negotiation is required.¶
The HTTP/JSON interface is usable from command-line tools (curl and a JSON parser), shell scripts, and CI/CD pipelines without specialized client libraries. The lookup interface can also be exposed as an MCP tool, so that an MCP-compatible client performs agent discovery through its existing tool-calling mechanism.¶
(Boilerplate as per Section 2.1 of [RFC7942]:)¶
This section records the status of known implementations of the protocol defined by this specification at the time of posting of this Internet-Draft, and is based on a proposal described in [RFC7942]. The description of implementations in this section is intended to assist the IETF in its decision processes in progressing drafts to RFCs. Please note that the listing of any individual implementation here does not imply endorsement by the IETF. Furthermore, no effort has been spent to verify the information presented here that was supplied by IETF contributors. This is not intended as, and must not be construed to be, a catalog of available implementations or their features. Readers are advised to note that other implementations may exist.¶
According to [RFC7942], "this will allow reviewers and working groups to assign due consideration to documents that have the benefit of running code, which may serve as evidence of valuable experimentation and feedback that have made the implemented protocols more mature. It is up to the individual working groups to use this information as they see fit".¶
Ericsson¶
A public AD instance deployed as a Cloudflare Worker with a Durable Object for persistent storage. Implements the registration, lookup, and soft-state lifecycle interfaces defined in this document. Source code is available at the GitHub repository linked from the deployment.¶
Prototype¶
All features specified in this document: well-known URI discovery (URI Template lookup), agent registration (create, update, replace, delete), agent lookup with filtering and Link-header pagination, soft-state expiry, and RFC 9457 error responses.¶
draft-jimenez-agent-directory-00¶
MIT¶
Jaime Jimenez (jaime@iki.fi)¶
The AD design is directly based on the CoRE Resource Directory [RFC9176] by Christian Amsüss, Zach Shelby, Michael Koster, Carsten Bormann, and Peter van der Stok.¶
The following table summarizes the conceptual mapping between CoRE RD concepts and their AD equivalents.¶
| CoRE RD (RFC 9176) | AD | Notes |
|---|---|---|
| Endpoint (EP) | Agent | Software entity that registers |
| Resource link | Capability | Structured JSON instead of link-format |
| /.well-known/core | /.well-known/ad | Discovery entry point |
| Registration (POST /rd) | Registration (POST /ad/r) | Same soft-state model |
| Registration resource | Registration resource | Same lifecycle |
| Lifetime (lt) | Lifetime (lt) | Same semantics, different default |
| Endpoint name (ep) | Agent name (agent) | Same uniqueness constraint |
| Resource lookup | Capabilities embedded in agent registration | Capabilities are nested in the registration, not independent resources |
| Endpoint lookup | GET on the lookup endpoint | Structured filters instead of link-format query |
| Commissioning Tool (CT) | Commissioning Tool (CT) | Third-party registration |
| application/link-format | application/json | Representation format |