feat(mcp): A2A control tools — exposure, card, allow-list, endpoints (ent#160)#1627
Closed
dolho wants to merge 1 commit into
Closed
feat(mcp): A2A control tools — exposure, card, allow-list, endpoints (ent#160)#1627dolho wants to merge 1 commit into
dolho wants to merge 1 commit into
Conversation
…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>
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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 runtimecall_a2a_agent(#736); this is the management plane (toggle exposure, read the served card, manage inbound allow-list, register outbound endpoints).Changes
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.403("not licensed") or an OSS-only404returns 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 onlyhas_credentials, so no tool echoes a secret.client.ts: 8 A2A methods.getA2AExposedMapswallows OSS-404 / unentitled-403 →{}.agents.ts:list_agents/get_agentbest-effort mergea2a_exposed(mirrorsmcp_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_foundresult anda2a_exposedis simply absent — no errors, no coupling.Test Plan
npm test→ 100 passed (10 new insrc/tools/a2a.test.ts: proxy contract, credentials-never-echoed, entitlement/human-only/404 gating)npm run build(tsc) cleanCompanion PR
Backend (private): trinity-enterprise#161 — the
enterprise.backend.a2amodule +/api/enterprise/a2a/*router. Must merge for these tools to have endpoints to call.Related to trinity-enterprise#160
🤖 Generated with Claude Code