Skip to main content
Version: Latest (1.9.x dev)

List the MCP servers and A2A agents a key may use

DVARA, the AI governance platform, already knows which MCP servers and A2A agents each workspace may use. Clients still had to be told by hand. DVARA can now answer that question in two standard shapes:

  • the MCP Registry API (v0.1), which MCP hosts read to find servers, and
  • an Agentic Resource Discovery (ARD) manifest, a list of agents that any ARD reader understands.

Each answer is built for the key that asks. It lists only what that key may use, in its own workspace, and every address in it is DVARA's. Upstream addresses, credentials and owners are never in it.

Enterprise only

Not included in DVARA Open Source.

Experimental

Both endpoints are off by default. The MCP Registry API is still a preview, and ARD is a proposal (v0.91), so the shapes may change. Turn them on to try them; do not build on them yet.

Turn them on​

Set these on the gateway and restart it.

SettingEnvironment variableDefaultWhat it does
dvara.mcp-gateway.discovery.enabledDVARA_MCPGATEWAY_DISCOVERY_ENABLEDfalseServe the MCP Registry API at /mcp/v0.1/servers
dvara.mcp-gateway.discovery.namespaceDVARA_MCPGATEWAY_DISCOVERY_NAMESPACElocal.dvaraThe first part of every server name, in reverse DNS of a domain you own, such as com.acme.dvara
a2a.discovery.ard.enabledA2A_DISCOVERY_ARD_ENABLEDfalseServe the ARD manifest at /a2a/.well-known/ard.json
a2a.discovery.ard.publisherA2A_DISCOVERY_ARD_PUBLISHERdvara.localThe domain in every agent's identifier, such as agents.acme.com

While a setting is off, its endpoint answers 404.

List MCP servers​

curl --silent https://<dvara-host>/mcp/v0.1/servers \
--header 'Authorization: Bearer <your-api-key>'
{
"servers": [
{
"server": {
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
"name": "com.acme.dvara/github",
"title": "github-mcp-server",
"description": "MCP server github, governed by the DVARA gateway",
"version": "1.4.2",
"remotes": [
{
"type": "streamable-http",
"url": "https://<dvara-host>/mcp/github",
"headers": [
{
"name": "Authorization",
"value": "Bearer {dvara_credential}",
"isRequired": true,
"isSecret": true
}
]
}
]
},
"_meta": {
"io.modelcontextprotocol.registry/official": { "status": "active", "isLatest": true },
"com.dvarahq/gateway": {
"serverId": "github",
"workspaceUrl": "https://<dvara-host>/mcp",
"toolPrefix": "github__",
"tools": ["create_issue", "search"]
}
}
}
],
"metadata": { "count": 1 }
}
  • Which servers. The active servers registered in your key's workspace. A suspended, disabled or quarantined server is not listed, because it cannot be called.
  • Where to connect. Each entry points at that server's own address on DVARA, /mcp/<server>. Connect there to use just that server: you see only its tools, prompts and resources, with their own names. See Connect to one server. workspaceUrl is the workspace's /mcp, where every server's tools are, each named <server>__<tool> (toolPrefix).
  • Version. The version the server reported when DVARA last synced it, or 0.0.0 if it reported none.
  • Paging and filters. limit (up to 100), cursor (from metadata.nextCursor), search (part of the name) and version.

Read one server by name, with the slash between the two parts written as a plain slash:

curl --silent https://<dvara-host>/mcp/v0.1/servers/com.acme.dvara/github/versions/latest \
--header 'Authorization: Bearer <your-api-key>'

The MCP Registry API asks clients to encode that slash as %2F. DVARA's web server refuses an encoded slash in a path, so that form answers 400. Listing is not affected.

Connect to one server​

Every registered MCP server has its own address on DVARA, https://<dvara-host>/mcp/<server-id>, with the same API key or access token as /mcp. It works with MCP 2025-06-18, 2025-11-25 and 2026-07-28.

curl --silent https://<dvara-host>/mcp/github \
--header 'Authorization: Bearer <your-api-key>' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json, text/event-stream' \
--header 'MCP-Protocol-Version: 2025-11-25' \
--data '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

The tools come back as the server names them, such as create_issue, and you call them by those names. Every call is checked exactly as on /mcp: the same policies, approvals, scans, limits and audit record. The audit record names the server and the tool, as before.

  • A server that is not an active server of your key's workspace answers 404, like a server that does not exist. Nothing is sent to any server.
  • X-Dvara-Virtual-Server is refused there (400): the address already names one server. Use /mcp for a virtual server.
  • An OAuth access token must still be issued for DVARA's MCP resource (the /mcp address), not for a server's own address.
  • A server whose id holds a slash has no address of its own; its entry points at /mcp.

List A2A agents​

curl --silent https://<dvara-host>/a2a/.well-known/ard.json \
--header 'Authorization: Bearer <your-api-key>'
{
"entries": [
{
"identifier": "urn:air:agents.acme.com:<workspace-id>:planner",
"displayName": "Trip Planner",
"type": "application/a2a-agent-card+json",
"url": "https://<dvara-host>/a2a/planner/.well-known/agent-card.json",
"description": "Plans trips",
"version": "2.1.0",
"capabilities": ["plan"],
"tags": ["travel"],
"metadata": { "dvara.agentId": "planner", "dvara.cardTrustState": "VERIFIED" }
}
]
}
  • Which agents. The active agents registered in your key's workspace.
  • The card. url is the Agent Card DVARA serves for the agent, governed for your key, never the peer's own address.
  • Skills. capabilities lists only the skills your workspace allows for the agent.
  • Trust. dvara.cardTrustState is what DVARA found when it checked the card's signature: VERIFIED, SELF_SIGNED, UNSIGNED or INVALID.

DVARA serves a manifest, not an ARD registry: it has no search.

Who can see what​

  • Both endpoints take the same key as /mcp and /a2a. On the MCP endpoint an OAuth access token works too, when OAuth is on.
  • A key with no scopes sees everything its workspace may use. A key with scopes needs mcp:read or mcp:call to list MCP servers, and a2a:read or a2a:send to list agents. Otherwise the answer is 403.
  • A missing or revoked key is 401. A suspended workspace is 403.
  • No answer ever includes another workspace's servers or agents.
  • Answers are private to the caller and never cached by a proxy (Cache-Control: private, no-store).

Listing an agent does not approve a call to it. Every call still goes through the workspace's policies, approvals and audit.

Where to go next​