Skip to content

feat(mcp): A2A control tools — exposure, card, allow-list, endpoints (ent#160)#1627

Closed
dolho wants to merge 1 commit into
devfrom
feature/160-a2a-mcp-tools
Closed

feat(mcp): A2A control tools — exposure, card, allow-list, endpoints (ent#160)#1627
dolho wants to merge 1 commit into
devfrom
feature/160-a2a-mcp-tools

Conversation

@dolho

@dolho dolho commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

The MCP surface for the A2A interoperability management plane — the third surface (Invariant #13) over the entitlement-gated enterprise backend (trinity-enterprise#160, /api/enterprise/a2a/*). Distinct from the runtime call_a2a_agent (#736); this is the management plane (toggle exposure, read the served card, manage inbound allow-list, register outbound endpoints).

Changes

  • New src/mcp-server/src/tools/a2a.ts — 7 tools:
    get_agent_a2a_config, set_agent_a2a_exposure, get_agent_a2a_card (proxies the OSS feat: serve A2A Agent Cards from template.yaml for external discoverability #737 served-card endpoint), set_a2a_inbound_allowlist, register_a2a_endpoint, list_a2a_endpoints, remove_a2a_endpoint.
  • Honest gating: an unentitled 403 ("not licensed") or an OSS-only 404 returns a structured { not_entitled | not_found }never a silent success. Mutations are owner/admin + human-only, enforced at the backend (an agent-scoped key → 403 human_only). Outbound credentials are write-only: the backend returns only has_credentials, so no tool echoes a secret.
  • client.ts: 8 A2A methods. getA2AExposedMap swallows OSS-404 / unentitled-403 → {}.
  • agents.ts: list_agents/get_agent best-effort merge a2a_exposed (mirrors mcp_exposed, feat: per-agent MCP exposure flag — dynamic dedicated tool per exposed agent #846) — omitted in editions without A2A, so no OSS↔enterprise coupling and the private table is never read by OSS code.
  • server.ts: register the tool group (connector-denied visibility, like the other operator tools).

Consumer safety

The tool code is edition-agnostic and ships in the public repo (the endpoints it calls are entitlement-gated). On an OSS-only or unentitled instance every tool returns a structured not_entitled/not_found result and a2a_exposed is simply absent — no errors, no coupling.

Test Plan

  • npm test100 passed (10 new in src/tools/a2a.test.ts: proxy contract, credentials-never-echoed, entitlement/human-only/404 gating)
  • npm run build (tsc) clean

Companion PR

Backend (private): trinity-enterprise#161 — the enterprise.backend.a2a module + /api/enterprise/a2a/* router. Must merge for these tools to have endpoints to call.

Related to trinity-enterprise#160

🤖 Generated with Claude Code

…160)

The MCP surface for the A2A interoperability management plane — the third
surface (Invariant #13) over the entitlement-gated enterprise backend
(trinity-enterprise#160, /api/enterprise/a2a/*). Distinct from the runtime
call_a2a_agent (#736).

New src/mcp-server/src/tools/a2a.ts (7 tools):
- get_agent_a2a_config, set_agent_a2a_exposure, get_agent_a2a_card (proxies the
  OSS #737 served-card endpoint), set_a2a_inbound_allowlist,
  register_a2a_endpoint, list_a2a_endpoints, remove_a2a_endpoint.
- Honest gating: an unentitled 403 ("not licensed") / OSS-only 404 return a
  structured { not_entitled | not_found } — never a silent success. Mutations
  are owner/admin + human-only, enforced at the backend (agent-scoped key → 403
  human_only). Outbound credentials are write-only — the backend returns only
  has_credentials, so no tool echoes a secret.

client.ts: 8 A2A methods (getA2AExposedMap swallows OSS-404/unentitled-403 → {}).
agents.ts: list_agents/get_agent best-effort merge a2a_exposed (mirrors
mcp_exposed, #846) — omitted in editions without A2A, no OSS↔enterprise coupling.
server.ts: register the tool group (connector-denied visibility, like the rest).

Tests: src/mcp-server/src/tools/a2a.test.ts (10) — proxy contract, credentials
never echoed, entitlement/human-only/404 gating. Full suite 100 pass; tsc clean.

Related to #160

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dolho

dolho commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

Consolidated into #1628 — the full A2A interoperability feature (inbound server + control MCP tools) now ships as one public PR per request. These MCP-tool commits are included there (and the redundant a2a_exposed merge was dropped since #157 surfaces it natively). Enterprise backend stays separate: trinity-enterprise#161.

@dolho dolho closed this Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant