MACP

Framework Hosting Design

Overview

The MACP Example Showcase Service uses a framework-neutral hosting architecture that allows heterogeneous agent frameworks (LangGraph, LangChain, CrewAI, custom) to participate in the same MACP run through a unified control-plane contract.

Architecture

POST /examples/run
  → CompilerService.compile()          [framework-agnostic]
  → HostingService.resolve()           [materializes agent metadata]
  → ControlPlaneClient.validate()      [standard MACP contract]
  → ControlPlaneClient.createRun()     [standard MACP contract]
  → HostingService.attach()            [launches framework workers]
    → ProcessExampleAgentHostProvider
      → HostAdapterRegistry.get(framework)
      → ManifestValidator.validate(manifest)
      → AgentHostAdapter.prepareLaunch()
      → LaunchSupervisor.launch()

Key Boundaries

Compiler stays framework-agnostic

The compiler produces ExecutionRequest payloads with participants, runtime metadata, kickoff messages, and policy. It never references LangGraph, LangChain, or CrewAI.

Hosting layer owns framework integration

All framework-specific launch logic lives in src/hosting/adapters/. Each adapter implements AgentHostAdapter:

interface AgentHostAdapter {
  readonly framework: AgentFramework;
  validateManifest(manifest: AgentManifest): ManifestValidationResult;
  prepareLaunch(input: PrepareLaunchInput): PreparedLaunch;
}

Control plane remains the only message ingress/egress

Workers communicate exclusively through the control plane HTTP API:

  • POST /runs/:id/messages — send MACP messages
  • GET /runs/:id/events — poll for run events
  • GET /runs/:id — check run status

Bootstrap contract

Every worker receives a stable BootstrapPayload via a temp JSON file (MACP_BOOTSTRAP_FILE):

{
  "run": { "runId": "...", "traceId": "..." },
  "participant": { "participantId": "...", "role": "..." },
  "runtime": { "baseUrl": "...", "messageEndpoint": "...", "eventsEndpoint": "..." },
  "execution": { "scenarioRef": "...", "ttlMs": 300000, ... },
  "session": { "context": { ... }, "participants": [ ... ] },
  "agent": { "manifest": { ... }, "framework": "langgraph", "frameworkConfig": { ... } }
}

Component Map

ComponentPathPurpose
Host Adapter Interfacesrc/hosting/contracts/host-adapter.types.tsFramework adapter contract
Manifest Typessrc/hosting/contracts/manifest.types.tsTyped manifest schema
Bootstrap Typessrc/hosting/contracts/bootstrap.types.tsBootstrap payload contract
LangGraph Adaptersrc/hosting/adapters/langgraph-host-adapter.tsLangGraph manifest validation + launch prep
LangChain Adaptersrc/hosting/adapters/langchain-host-adapter.tsLangChain manifest validation + launch prep
CrewAI Adaptersrc/hosting/adapters/crewai-host-adapter.tsCrewAI manifest validation + launch prep
Custom Adaptersrc/hosting/adapters/custom-host-adapter.tsNode/Python custom worker support
Adapter Registrysrc/hosting/host-adapter-registry.tsMaps framework → adapter
Manifest Validatorsrc/hosting/manifest-validator.tsPre-spawn validation
Launch Supervisorsrc/hosting/launch-supervisor.tsProcess lifecycle management
Python Worker SDKagents/sdk/python/macp_worker_sdk/Shared Python SDK for workers
Node Worker SDKagents/sdk/node/Shared Node SDK for workers

Framework Workers

AgentFrameworkWorker PathManifest
Fraud AgentLangGraphagents/langgraph_worker/agents/manifests/fraud-agent.json
Growth AgentLangChainagents/langchain_worker/agents/manifests/growth-agent.json
Compliance AgentCrewAIagents/crewai_worker/agents/manifests/compliance-agent.json
Risk AgentCustom (Node)src/example-agents/runtime/risk-decider.worker.tsagents/manifests/risk-agent.json

Each worker gracefully falls back when its framework library is not installed, preserving the same MACP message contract.