Architecture
Overview
The MACP Example Showcase Service is a single NestJS service that intentionally combines three responsibilities for demo simplicity:
- Catalog — browse example scenario packs and their versions
- Compiler — validate user inputs and compile them into control-plane-ready
ExecutionRequestpayloads - Hosting — resolve and bootstrap example agent bindings (manifest-only by default)
This service is a showcase/examples layer used to demonstrate scenarios and sample agents for MACP. It intentionally combines catalog, compilation, and sample agent hosting for simplicity. It is not the production system boundary.
Clean Demo Split
In a production deployment, these three things are separate:
| Concern | Demo (this service) | Production |
|---|---|---|
| Scenario catalog | Example Showcase Service | Scenario Registry |
| Compilation | Example Showcase Service | Scenario Registry or Control Plane |
| Agent hosting | Example Showcase Service | Agent Platform / Runtime |
| Run lifecycle | Control Plane | Control Plane |
| Coordination | MACP Runtime | MACP Runtime |
Module Structure
src/
catalog/ → Pack/scenario listing (read-only)
compiler/ → Input validation (AJV) + template substitution + ExecutionRequest assembly
config/ → Environment-based configuration (global module)
contracts/ → TypeScript interfaces — registry types, launch types, agent types
control-plane/ → HTTP client for the control plane (/runs/validate, /runs)
controllers/ → REST endpoints (health, catalog, launch, examples)
dto/ → Swagger-annotated request/response DTOs
errors/ → AppException, ErrorCode enum, GlobalExceptionFilter
example-agents/ → Hard-coded example agent catalog (fraud, growth, compliance, risk)
runtime/ → Worker runtime: control-plane client + risk-decider worker
hosting/ → Two-phase agent hosting (resolve + attach) + pluggable host providers
launch/ → Launch schema generation + ExampleRunService (full showcase flow)
middleware/ → Correlation ID + request logging
registry/ → File-backed YAML loader + in-memory cache indexRequest Flow
HTTP Request
→ CorrelationIdMiddleware (X-Correlation-ID)
→ RequestLoggerMiddleware (timing/status)
→ Controller
→ Service
→ Registry / Compiler / Hosting
→ Response
→ GlobalExceptionFilter (catches errors)Key Flows
1. Browse Catalog
GET /packs → CatalogService → RegistryIndexService → FileRegistryLoader → YAML files2. Get Launch Schema
GET /packs/:pack/scenarios/:scenario/versions/:version/launch-schema
→ LaunchService
→ Load scenario + optional template
→ Extract schema defaults, merge template defaults
→ Summarize participants with agent previews
→ Return form schema, defaults, runtime hints3. Compile Scenario
POST /launch/compile
→ CompilerService
→ Parse scenarioRef (pack/scenario@version)
→ Load scenario + optional template
→ Merge defaults: schema < template < user inputs
→ Validate inputs against JSON Schema (AJV)
→ Substitute {{ inputs.* }} in context/metadata/kickoff templates
→ Build ExecutionRequest4. Run Example (Full Showcase Flow)
POST /examples/run
→ ExampleRunService
1. Compile (same as above)
2. Resolve agents → HostingService.resolve() → ProcessExampleAgentHostProvider
→ Inject transport identities into ExecutionRequest participants
3. Submit to control plane (optional)
→ ControlPlaneClient.validate() + .createRun()
4. Attach agents → HostingService.attach() → Spawn Python/Node worker processes
→ Workers poll control plane for events, send MACP messages back
5. Return compiled + hostedAgents + controlPlane statusData Flow: Scenario Packs
packs/{pack-slug}/
pack.yaml → PackFile (metadata)
scenarios/{scenario-slug}/{version}/
scenario.yaml → ScenarioVersionFile (inputs schema, launch config, runtime)
templates/
default.yaml → ScenarioTemplateFile (defaults + overrides)
*.yaml → Additional template variantsTemplates override scenario defaults and launch configuration. The merge precedence is:
schema defaults < template defaults < user inputsAgent Hosting Strategy
The example agents use an active process-backed hosting strategy:
- Service resolves agent definitions from a hard-coded catalog (fraud, growth, compliance, risk)
- Transport identities are injected into the ExecutionRequest before submission
- After the control plane creates a run, lightweight Python and Node worker processes are spawned
- Workers poll the control plane for run state and events (
GET /runs/:id/events) - Workers send session-bound MACP messages back via
POST /runs/:id/messages - Each framework is demonstrated: LangGraph (fraud), LangChain (growth), CrewAI (compliance), custom (risk)
- The
InMemoryExampleAgentHostProvideris available as a manifest-only fallback for environments without Python
Caching
RegistryIndexService caches the loaded registry snapshot with a configurable TTL:
REGISTRY_CACHE_TTL_MS=0— reload from disk on every request (development)REGISTRY_CACHE_TTL_MS=60000— cache for 60 seconds (production)
Call invalidate() to force a reload.