Skip to content

Capstone — Build a Complete Tool Ecosystem ​

Phase 13 taught every piece. This capstone wires them into one production-shaped system: an MCP server with tools + resources + prompts + tasks + UI, OAuth 2.1 at the edge, an RBAC gateway, a multi-server client, an A2A sub-agent call, OTel tracing into a collector, tool-poisoning detection in CI, and an AGENTS.md + SKILL.md bundle. By the end you can defend every architectural choice.

Type: Build Languages: Python (stdlib, end-to-end ecosystem harness) Prerequisites: Phase 13 · 01 through 21 Time: ~120 minutes

Learning Objectives ​

  • Compose an MCP server exposing tools, resources, prompts, and a task with a ui:// app.
  • Front the server with an OAuth 2.1 gateway that enforces RBAC and pinned hashes.
  • Write a multi-server client that traces with OTel GenAI attributes end-to-end.
  • Delegate part of a workload to an A2A sub-agent; verify opacity is preserved.
  • Package the whole stack with AGENTS.md + SKILL.md so other agents can drive it.

The Problem ​

Ship the "research and report" system:

  • User asks: "summarize the three most-cited 2026 arXiv papers on agent protocols."
  • System: search arXiv via MCP; delegate paper summarization to a specialized writer agent via A2A; aggregate results; render an interactive report as an MCP Apps ui:// resource; log every step to OTel.

All the primitives from Phase 13 show up. This is not a toy — production research-assistant systems shipped in 2026 by Anthropic (the Claude Research product), OpenAI (GPTs with Apps SDK), and third parties have this exact shape.

The Concept ​

Architecture ​

[user] -> [client] -> [gateway (OAuth 2.1 + RBAC)] -> [research MCP server]
                                                      |
                                                      +- MCP tool: arxiv_search (pure)
                                                      +- MCP resource: notes://recent
                                                      +- MCP prompt: /research_topic
                                                      +- MCP task: generate_report (long)
                                                      +- MCP Apps UI: ui://report/current
                                                      +- A2A call: writer-agent (tasks/send)
                                                      |
                                                      +- OTel GenAI spans

Trace hierarchy ​

agent.invoke_agent
 ├── llm.chat (kick off)
 ├── mcp.call -> tools/call arxiv_search
 ├── mcp.call -> resources/read notes://recent
 ├── mcp.call -> prompts/get research_topic
 ├── a2a.tasks/send -> writer-agent
 │    └── task transitions (opaque internals)
 ├── mcp.call -> tools/call generate_report (task-augmented)
 │    └── tasks/status polling
 │    └── tasks/result (completed, returns ui:// resource)
 └── llm.chat (final synthesis)

One trace id. Every span has the right gen_ai.* attributes.

Security posture ​

  • OAuth 2.1 + PKCE with resource indicator pinning audience to gateway.
  • Gateway holds upstream credentials; user never sees them.
  • RBAC: alice has research:read, research:write, can call all tools. bob has research:read, cannot call generate_report.
  • Pinned description manifest: dropped any server whose tool hashes changed.
  • Rule of Two audit: no tool combines untrusted input, sensitive data, and consequential action.

Rendering ​

The final generate_report task returns content blocks plus a ui://report/current resource. The client's host (Claude Desktop, etc.) renders the interactive dashboard in a sandbox iframe. The dashboard contains a sorted paper list, citation counts, and a button that calls host.callTool('summarize_paper', {arxiv_id}) for any paper the user clicks.

Packaging ​

The whole thing ships as:

research-system/
  AGENTS.md                     # project conventions
  skills/
    run-research/
      SKILL.md                  # the top-level workflow
  servers/
    research-mcp/               # the MCP server
      pyproject.toml
      src/
  agents/
    writer/                     # the A2A agent
  gateway/
    config.yaml                 # RBAC + pinned manifest

Users deploy with docker compose up. Claude Code, Cursor, Codex, and opencode users can drive the system by invoking the run-research skill.

What each Phase 13 lesson contributed ​

LessonWhat the capstone uses
01-05Tool interface, provider-portability, parallel calls, schemas, linting
06-10MCP primitives, server, client, transports, resources + prompts
11-14Sampling, roots + elicitation, async tasks, ui:// apps
15-17Tool poisoning, OAuth 2.1, gateway + registry
18A2A sub-agent delegation
19OTel GenAI tracing
20Routing gateway for the LLM layer
21SKILL.md + AGENTS.md packaging

Use It ​

code/main.py stitches the previous lessons' patterns into one runnable demo. All stdlib, all in-process so you can read it end to end. It runs the full flow for the research-and-report scenario: handshake with gateway, OAuth 2.1 simulated, tools/list merged, generate_report as a task, A2A call to writer, ui:// resource returned, OTel spans emitted.

What to look at:

  • One trace id across every hop.
  • Gateway policy blocks a second user from writing.
  • Task lifecycle goes working → completed and returns both text and ui:// content.
  • A2A call's inner state is opaque to the orchestrator.
  • AGENTS.md and SKILL.md are the only files another agent needs to reproduce the workflow.

Ship It ​

This lesson produces outputs/skill-ecosystem-blueprint.md. Given a product need (research, summarization, automation), the skill produces the full architecture: which MCP primitives, which gateway controls, which A2A calls, which telemetry, which packaging.

Exercises ​

  1. Run code/main.py. Note the single trace id and how spans nest. Count how many primitives from Phase 13 the demo touches.

  2. Extend the demo: add a second backend MCP server (e.g. bibliography) and confirm the gateway merges its tools into the same namespace.

  3. Replace the fake A2A writer agent with a real one running on a subprocess. Use the Lesson 19 harness.

  4. Add a PII redaction step in the routing gateway between the orchestrator and the LLM. Confirm emails in the user query get scrubbed.

  5. Write an AGENTS.md for a teammate who will maintain this system. It should take under five minutes to read and give them everything they need to drive the capstone in Cursor or Codex.

Key Terms ​

TermWhat people sayWhat it actually means
Capstone"Phase-13 integration demo"End-to-end system using every primitive
Research and report"The scenario"Search, summarize, render pattern
Ecosystem"All the pieces together"Server + client + gateway + sub-agent + telemetry + package
Trace hierarchy"Single trace id"Every hop's span shares the trace; parent-child via span ids
Gateway-issued token"Transitive auth"Client sees only gateway's token; gateway holds upstream creds
Merged namespace"All tools in one flat list"Multi-server merge at the gateway, prefix-on-collision
Opacity boundary"A2A call hides internals"Sub-agent's reasoning invisible to orchestrator
Three-layer stack"AGENTS.md + SKILL.md + MCP"Project context + workflow + tools
Defense-in-depth"Multiple security layers"Pinned hashes, OAuth, RBAC, Rule of Two, audit log
Spec compliance matrix"What we ship that the spec requires"Checklist mapping deliverables to 2025-11-25 requirements

Further Reading ​