This capstone does not introduce new mechanisms, it assembles the fifteen preceding lessons’ worth of them into one coherent, production-shaped architecture, traces a single real request through every layer, and then, since a happy-path trace alone under-tests a security-conscious architecture, walks through a second, deliberately compound failure scenario to show how the course’s layered defenses interact when more than one thing goes wrong at once.
The Complete Architecture
flowchart TB
subgraph clients["Agent Clients"]
Sales["Sales Agent\n(Claude Agent SDK)"]
Support["Support Agent\n(LangGraph)"]
Internal["Internal Ops Agent\n(self-hosted gpt-oss-120b\n+ tool-calling harness)"]
end
subgraph platform["Shared Platform Infrastructure"]
AuthZ["OAuth 2.1 Authorization Server\n(enterprise IdP)"]
Registry["Internal MCP Registry\n(self-registration, health)"]
Gateway["Federation Gateway\n(namespacing, routing,\nauth pass-through)"]
Otel["OpenTelemetry Collector\n(traces, metrics)"]
end
subgraph servers["Team-Owned MCP Servers"]
CRM["crm MCP Server\n(Sales/RevOps team)"]
KB["kb MCP Server\n(Support team)"]
SupportSys["support MCP Server\n(Support team)"]
DW["warehouse MCP Server\n(Data Platform team)"]
end
Sales -->|"1. OAuth token"| AuthZ
Sales -->|"2. tools/call\n(bearer token)"| Gateway
Support --> Gateway
Internal --> Gateway
Gateway -->|"3. validate token"| AuthZ
Gateway -->|"4. resolve healthy servers"| Registry
Gateway -->|"5. route namespaced call"| CRM
Gateway --> KB
Gateway --> SupportSys
Gateway --> DW
CRM -.->|traces + audit logs| Otel
KB -.->|traces + audit logs| Otel
SupportSys -.->|traces + audit logs| Otel
DW -.->|traces + audit logs| Otel
Gateway -.->|traces| Otel
style Sales fill:#EEF0F7,stroke:#6366F1,color:#0F172A
style Support fill:#EEF0F7,stroke:#6366F1,color:#0F172A
style Internal fill:#EEF0F7,stroke:#6366F1,color:#0F172A
style AuthZ fill:#fff7ed,stroke:#f59e0b,color:#0F172A
style Registry fill:#fff7ed,stroke:#f59e0b,color:#0F172A
style Gateway fill:#f0fdf9,stroke:#0D9488,color:#0F172A
style Otel fill:#fff7ed,stroke:#f59e0b,color:#0F172A
style CRM fill:#EEF0F7,stroke:#6366F1,color:#0F172A
style KB fill:#EEF0F7,stroke:#6366F1,color:#0F172A
style SupportSys fill:#EEF0F7,stroke:#6366F1,color:#0F172A
style DW fill:#EEF0F7,stroke:#6366F1,color:#0F172A
Tracing One Request Through Every Layer: The Happy Path
A sales agent asks: “What’s the status of Acme Corp’s most recent support ticket?”
sequenceDiagram
participant Agent as Sales Agent
participant Gateway as Federation Gateway
participant AuthZ as OAuth Server
participant Registry
participant SupportSrv as support MCP Server
participant Otel as OTel Collector
Agent->>AuthZ: Already holds valid bearer token (Module 4)
Agent->>Gateway: tools/call support.get_latest_ticket(account="Acme")
Gateway->>AuthZ: Validate token, extract scopes (Lesson 10)
AuthZ-->>Gateway: subject=sales-agent-42, scopes=[support:read, crm:read]
Gateway->>Gateway: Check scope covers support.get_latest_ticket (Lesson 12)
Gateway->>Registry: Resolve healthy endpoint for "support" (Lesson 18)
Registry-->>Gateway: https://mcp.internal/support/v2, status=healthy
Gateway->>SupportSrv: tools/call get_latest_ticket(account="Acme")\ntraceparent propagated (Lesson 25)
SupportSrv->>SupportSrv: Validate input (Module 2),\nquery via parameterized query (Lesson 14)
SupportSrv-->>Gateway: Structured result
Gateway-->>Agent: Result
SupportSrv-->>Otel: Span + audit log entry (Lessons 21, 25)
Gateway-->>Otel: Span (linked, same trace)
Every lesson in this course maps to a concrete piece of this one request: authentication and scoping (Module 4) gate it before it reaches any server; registry-based routing (Module 6) finds the right healthy backend; the server itself validates input and queries safely (Modules 2 and 5); and tracing plus audit logging (Module 9) make the whole path inspectable after the fact.
A Compound Failure Scenario: When More Than One Thing Goes Wrong
A single happy-path trace under-tests a security-conscious architecture, since it never exercises the layered defenses that matter precisely when something goes wrong. Consider a harder scenario, deliberately stacking two independent problems in the same window: (1) an attacker has embedded an injection payload in a support ticket, per Lesson 19, instructing any agent that reads it to export all CRM records to an external address, and (2) at the same moment, the CRM MCP server happens to be mid-canary-rollout (Lesson 29) of a new version, and that new version has an authorization bug causing it to under-check the crm:export scope for certain callers.
flowchart TD
Injection["Injected instruction in a\nsupport ticket (Lesson 19)"] --> Agent["Agent reads ticket,\nreasoning is influenced"]
Agent -->|"attempts crm_export_all_records"| Gateway["Federation Gateway"]
Gateway --> Canary["CRM server, canary version\n(authorization bug present)"]
Canary -->|"BUG: scope check\nunder-enforced"| WouldSucceed["Would otherwise\nproceed to export"]
WouldSucceed --> ConfirmGate{"confirmation_token\nrequired (Lesson 19/20)?"}
ConfirmGate -->|"no valid token,\ninjection cannot produce one"| Blocked["Export BLOCKED,\nregardless of the\nauthorization bug"]
style Injection fill:#fef2f2,stroke:#dc2626,color:#0F172A
style Agent fill:#EEF0F7,stroke:#6366F1,color:#0F172A
style Gateway fill:#f0fdf9,stroke:#0D9488,color:#0F172A
style Canary fill:#fef2f2,stroke:#dc2626,color:#0F172A
style WouldSucceed fill:#fef2f2,stroke:#dc2626,color:#0F172A
style ConfirmGate fill:#fff7ed,stroke:#f59e0b,color:#0F172A
style Blocked fill:#f0fdf9,stroke:#0D9488,color:#0F172A
Even with both failures compounding, the injection succeeding at the reasoning layer and the canary’s authorization check being broken, the export still does not happen, because the confirmation-token requirement on crm_export_all_records (Lessons 19-20) depends on neither of those two things. It requires an out-of-band human approval that no injected text and no buggy in-tool scope check can produce. This is the concrete payoff of defense in depth as a design principle rather than a slogan: no single layer in this course’s architecture is assumed to be perfect, and the layers are chosen so that a failure in one (reasoning-layer injection defense, or a specific tool’s authorization logic) does not automatically cascade into the worst-case outcome, because a different, independent layer still holds. Separately, the canary’s error-rate analysis (Lesson 29) would likely catch the authorization bug itself on its own metrics within the 10% traffic window and roll it back, and the audit log (Lesson 21) would let an investigator confirm afterward exactly which calls were attempted against the canary during the incident window, but neither of those is what actually prevented the export in the moment, the confirmation gate is.
Ownership Boundaries
Shared, cross-cutting infrastructure, the authorization server, the registry, the federation gateway, sits under a platform or security team’s ownership, since every product team depends on it and inconsistency there creates risk broadly. Individual MCP servers (CRM, support, knowledge base, data warehouse) are owned by the teams closest to that system’s data and domain logic, following the same pattern as any other well-run platform engineering organization. This split is what lets the CRM team ship a new tool version on their own schedule (Lesson 16’s versioning discipline) without needing platform team involvement, while still inheriting consistent authentication, discovery, and observability for free, and it is also what lets the CRM team’s own canary rollout mistake, in the scenario above, be contained by shared, non-negotiable controls (the confirmation gate) that no individual team’s rollout schedule can bypass.
Where to Go From Here
You have now built, secured, and operated a complete MCP-based enterprise tool ecosystem: protocol fundamentals, a real server with validated tools and resources, authentication and fine-grained authorization, integrations across REST APIs, databases, and SaaS systems, versioning and federation across many servers, defenses against the injection and confused-deputy risks specific to agent-facing infrastructure, connections to Claude, other model providers, and self-hosted open-weight models, and the observability, testing, and CI/CD discipline that keeps all of it reliable in production, plus, in this closing scenario, a concrete demonstration of why no single one of those layers is meant to carry the whole burden alone. The natural next step is applying this architecture to your own organization’s systems, starting with the single highest-value integration and expanding outward using the same patterns, and, as new tools are added over time, deliberately asking of each one: which of this course’s layers actually stops the worst-case misuse of this specific tool, and is that layer something a bug elsewhere in the system could quietly disable.