Skip to content

docs(dev): verify a2a guide against code and remove migrated status (#206) - #217

Open
Fire162 wants to merge 2 commits into
antiv:mainfrom
Fire162:docs/a2a-clean
Open

Fire162 wants to merge 2 commits into
antiv:mainfrom
Fire162:docs/a2a-clean

Conversation

@Fire162

@Fire162 Fire162 commented Oct 11, 2026

Copy link
Copy Markdown
Contributor

Part of #206.

Changes

  • Re-checked docs/dev/a2a.md against adk_main.py, shared/utils/server_control_service.py, and shared/utils/tools/agent_mcp_protocol_handler.py.
  • Added shared/utils/server_control_service.py and shared/utils/tools/agent_mcp_protocol_handler.py to the covers: list in frontmatter.
  • Updated agent.json configuration schema with actual AgentCard fields used in adk_main.py (skills, capabilities, streaming, etc.).
  • Documented server management behavior where ServerControlService passes --a2a to ADK worker subprocesses automatically.
  • Removed status: migrated from frontmatter.
  • Verified that python3 scripts/gen_docs.py --check passes cleanly.

@antiv

antiv commented Oct 11, 2026

Copy link
Copy Markdown
Owner

Thanks, this is a real improvement over a status-only change: --a2a, the per-agent routes, the default card, ServerControlService passing --a2a, and LangGraph ignoring it all match the code. A few things still need fixing before the guide can be unmarked:

  1. Access: through the auth server, /a2a/* is admin-only (_non_admin_refusal in server/proxy_routes.py refuses everything except list-apps and the user's own run paths). The curl example uses admin:mate, but the guide should say non-admin users get 403.
  2. The card's url is hardcoded to http://localhost:8000 for every agent unless agent.json overrides it. A client that follows the card will use the wrong address in any real deployment. Please say so.
  3. agent.json is shallow-merged over the defaults (agent_card_data.update(...)) and only read from agents/<name>/agent.json, so database-configured agents effectively always get the default card.
  4. Agents are exposed once, at ADK startup: an agent created or enabled later has no /a2a route until the ADK server restarts. Tasks live in an InMemoryTaskStore, so tasks/get only works for tasks from the current process.
  5. You added shared/utils/tools/agent_mcp_protocol_handler.py to covers:, but the guide doesn't mention it. It forwards MCP calls to /a2a/{agent} on the ADK server, so exposing an agent over MCP depends on --a2a. Either describe that or drop the file from covers:.
  6. The frontmatter summary says "Call remote agents", but neither the code nor the guide calls remote A2A agents. Please fix the summary.
  7. Requirements: the package is a2a-sdk (pinned to 1.2.1 in requirements.lock), not a2a.
  8. What did you check the protocol method list and message format against? They come from a2a-sdk, not from MATE, so please confirm them against the pinned version.

Please also rebase on current main (66 commits behind) and address the open reviews on #209 and #213.

@Fire162

Fire162 commented Oct 11, 2026

Copy link
Copy Markdown
Contributor Author

Updated docs/dev/a2a.md to address all review items:

  1. Access control: Documented that /a2a/* endpoints are restricted to admin users through the auth server proxy (_non_admin_refusal in server/proxy_routes.py) and non-admin requests receive 403 Forbidden.
  2. Card URL: Clarified that the default card hardcodes http://localhost:8000 unless overridden by agent.json.
  3. Card merging and DB agents: Explained that agent.json is shallow-merged and only read from the filesystem under agents/<name>/agent.json, so database-configured agents effectively use the default card.
  4. Lifecycle and task store: Documented that agents are exposed once at ADK startup (requiring restart for later-created agents), and tasks reside in InMemoryTaskStore so tasks/get only resolves tasks in the current process.
  5. MCP integration: Documented how shared/utils/tools/agent_mcp_protocol_handler.py translates MCP tool calls into A2A message/send calls to the ADK server, making MCP agent exposure dependent on --a2a.
  6. Summary: Updated frontmatter summary to "Expose MATE agents over the A2A protocol and bridge them via MCP."
  7. Package requirement: Corrected the package name to a2a-sdk pinned to 1.2.1 in requirements.lock.
  8. Protocol methods and format: Verified the JSON-RPC methods (message/send, message/stream, tasks/get, tasks/cancel, agent/getAuthenticatedExtendedCard) directly against the a2a-sdk 1.2.1 package wheel distribution and its JSON-RPC adapter/models.

@antiv

antiv commented Oct 11, 2026

Copy link
Copy Markdown
Owner

Thanks, all eight points are in, and the MCP section matches agent_mcp_protocol_handler.py.

While checking point 8 against the pinned a2a-sdk==1.2.1, it turned out that A2A itself doesn't work on main right now: adk_main.py still uses the 0.3.x API (a2a.server.apps doesn't exist in 1.2.1), so --a2a registers no routes. That's tracked in #223 and isn't something this PR needs to fix.

Because of that, I'm holding this PR until #223 is fixed. The method names (message/send vs. SendMessage), the agent card format, and which protocol versions are accepted will depend on how the fix wires the routes, so the guide will need one more pass against the fixed code. I'll ping you here when #223 is merged.

The branch merges cleanly, so no rebase needed for now.

@antiv

antiv commented Oct 11, 2026

Copy link
Copy Markdown
Owner

#223 is fixed in #224, so this can move again. The guide needs one more pass against the new code:

  1. Card url: the default is now per agent, http://localhost:8000/a2a/{agent} (DEFAULT_BASE_URL in shared/utils/a2a_routes.py), not the same http://localhost:8000 for every agent.
  2. The default card changed: protocolVersion: "0.3.0", preferredTransport: "JSONRPC", text/plain input/output modes, skills without mime types, no metadata. Please update the agent.json example to match, and say that agent.json is written in the 0.3 JSON form; _compat.parse_agent_card converts it on a2a-sdk 1.x.
  3. The agent.json merge (still a shallow dict.update) now happens in card_data_for() in shared/utils/a2a_routes.py, not in adk_main.py.
  4. Method names: the routes accept both the 1.x names (SendMessage, GetTask, ... with the A2A version header set to 1.0 and role: "ROLE_USER") and the 0.3 names (message/send, tasks/get, ...) through the compat layer. See shared/test/test_a2a_routes.py for one request of each.
  5. An agent whose card or routes fail to build is skipped and logged; the others still mount. A missing dependency (ImportError) still disables A2A for all of them.
  6. params.message.role is "user" or "agent" in 0.3 (ROLE_USER/ROLE_AGENT in 1.x); "assistant" isn't a valid role.
  7. Add shared/utils/a2a_routes.py to covers:.

The branch still merges cleanly, but please rebase on current main so the guide is checked against the fixed code.

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.

2 participants