MACP

Adding a Framework Host

This guide explains how to add support for a new agent framework (e.g., AutoGen, Semantic Kernel, OpenAI Agents SDK).

Step 1: Create a Host Adapter

Create src/hosting/adapters/<framework>-host-adapter.ts:

import { AgentHostAdapter, PrepareLaunchInput, PreparedLaunch } from '../contracts/host-adapter.types';
import { AgentFramework, AgentManifest, ManifestValidationResult } from '../contracts/manifest.types';

export class MyFrameworkHostAdapter implements AgentHostAdapter {
  readonly framework: AgentFramework = 'myframework';  // add to AgentFramework union first

  validateManifest(manifest: AgentManifest): ManifestValidationResult {
    const errors: string[] = [];
    // Validate framework-specific requirements
    if (!manifest.frameworkConfig?.myRequiredField) {
      errors.push('frameworkConfig.myRequiredField is required');
    }
    return { valid: errors.length === 0, errors };
  }

  prepareLaunch(input: PrepareLaunchInput): PreparedLaunch {
    const { manifest, bootstrap } = input;
    return {
      command: manifest.host?.python ?? 'python3',
      args: [manifest.entrypoint.value],
      env: {
        ...process.env as Record<string, string>,
        MACP_BOOTSTRAP_FILE: '',
        MACP_CONTROL_PLANE_URL: bootstrap.runtime.baseUrl,
        MACP_FRAMEWORK: 'myframework',
        MACP_PARTICIPANT_ID: bootstrap.participant.participantId,
        MACP_RUN_ID: bootstrap.run.runId,
      },
      cwd: manifest.host?.cwd ?? process.cwd(),
      startupTimeoutMs: manifest.host?.startupTimeoutMs ?? 30000,
    };
  }
}

Step 2: Update the Framework Type

Add your framework to the union in src/hosting/contracts/manifest.types.ts:

export type AgentFramework = 'langgraph' | 'langchain' | 'crewai' | 'custom' | 'myframework';

Step 3: Register the Adapter

In src/hosting/host-adapter-registry.ts, add:

import { MyFrameworkHostAdapter } from './adapters/myframework-host-adapter';

// In constructor:
this.register(new MyFrameworkHostAdapter());

Step 4: Create a Worker Package

Create agents/myframework_worker/ with:

  • __init__.py
  • main.py — entry point that uses the SDK
  • <framework_specific>.py — framework setup (graph, chain, crew, etc.)
  • mappers.py — input/output mappers

Example main.py:

#!/usr/bin/env python3
import sys, os, time
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'sdk', 'python'))

from macp_worker_sdk import load_bootstrap, ControlPlaneClient, MacpMessageBuilder
from macp_worker_sdk.message_builder import extract_proposal_id
from macp_worker_sdk.bootstrap import log_agent

def main() -> int:
    ctx = load_bootstrap()
    client = ControlPlaneClient(ctx)
    builder = MacpMessageBuilder(ctx.run_id, ctx.participant_id, ctx.framework, ctx.participant.agent_id)

    # Your framework logic here
    # ...

    return 0

if __name__ == '__main__':
    raise SystemExit(main())

Step 5: Create a Manifest

Create agents/manifests/my-agent.json:

{
  "id": "my-agent",
  "name": "My Agent",
  "framework": "myframework",
  "entrypoint": {
    "type": "python_file",
    "value": "agents/myframework_worker/main.py"
  },
  "frameworkConfig": {
    "myRequiredField": "value"
  }
}

Step 6: Register in the Agent Catalog

Add an entry to EXAMPLE_AGENT_DEFINITIONS in src/example-agents/example-agent-catalog.service.ts.

Step 7: Add Tests

  • Unit test for the adapter in src/hosting/adapters/adapters.spec.ts
  • Add the agent to an existing scenario or create a new one
  • Run npm test and npm run test:e2e

Key Rules

  1. Never let framework code leak into controllers or compiler — all framework logic stays in adapters and worker packages
  2. All outbound messages must use the MACP envelope format — use MacpMessageBuilder
  3. Workers must poll the control plane — no custom backchannels
  4. Validate manifests before spawn — bad config should fail fast with clear errors
  5. Framework workers must gracefully fall back when framework libraries aren't installed