Skip to content

MCP (Model Context Protocol) Integration

Edda provides seamless integration with the Model Context Protocol (MCP), allowing AI assistants like Claude to interact with your durable workflows as long-running tools.

Overview

MCP is a standardized protocol for AI tool integration. Edda's MCP integration automatically converts your durable workflows into MCP-compliant tools that:

  • Start workflows and return instance IDs immediately
  • Check workflow status to monitor progress with completed activity count and suggested poll interval
  • Retrieve results when workflows complete
  • Cancel workflows if running or waiting, with automatic compensation execution

This enables AI assistants to work with long-running processes that may take minutes, hours, or even days to complete, with full control over the workflow lifecycle.

Installation

Install Edda with MCP support:

pip install edda-framework[mcp]

# Or using uv
uv add edda-framework --extra mcp

Quick Start

1. Create an MCP Server

from edda.integrations.mcp import EddaMCPServer
from edda import WorkflowContext, activity

# Create MCP server
server = EddaMCPServer(
    name="Order Service",
    db_url="postgresql://user:pass@localhost/orders",
)

@activity
async def reserve_inventory(ctx: WorkflowContext, items: list[str]):
    # Your business logic here
    return {"reserved": True}

@activity
async def process_payment(ctx: WorkflowContext, amount: float):
    # Payment processing logic
    return {"transaction_id": "txn_123"}

@server.durable_tool(description="Process customer order workflow")
async def process_order(ctx: WorkflowContext, order_id: str, items: list[str]):
    """
    Long-running order processing workflow.

    This workflow reserves inventory, processes payment, and ships the order.
    """
    # Reserve inventory
    await reserve_inventory(ctx, items)

    # Process payment
    await process_payment(ctx, 99.99)

    return {"status": "completed", "order_id": order_id}

2. Deploy the Server

# Deploy with uvicorn (production)
if __name__ == "__main__":
    import uvicorn
    uvicorn.run(server.asgi_app(), host="0.0.0.0", port=8000)
# Run the server
uvicorn your_app:server.asgi_app --host 0.0.0.0 --port 8000

3. Use from MCP Clients (e.g., Claude Desktop)

Add to your MCP client configuration (e.g., Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "order-service": {
      "command": "uvicorn",
      "args": ["your_app:server.asgi_app", "--host", "127.0.0.1", "--port", "8000"],
      "env": {
        "DATABASE_URL": "postgresql://user:pass@localhost/orders"
      }
    }
  }
}

Auto-Generated Tools

Each @durable_tool automatically generates four MCP tools:

1. Main Tool: Start Workflow

Tool Name: process_order
Description: Process customer order workflow

Input: {"order_id": "ORD-123", "items": ["item1", "item2"]}
Output: {
  "content": [{
    "type": "text",
    "text": "Workflow 'process_order' started successfully.\nInstance ID: abc123...\n\nUse 'process_order_status' tool to check progress."
  }],
  "isError": false
}

2. Status Tool: Check Progress

Tool Name: process_order_status
Description: Check status of process_order workflow

Input: {"instance_id": "abc123..."}
Output: {
  "content": [{
    "type": "text",
    "text": "Workflow Status: running\nCurrent Activity: payment:1\nCompleted Activities: 1\nSuggested Poll Interval: 5000ms\nInstance ID: abc123..."
  }],
  "isError": false
}

The status tool provides progress metadata for efficient polling:

  • Completed Activities: Number of activities that have finished
  • Suggested Poll Interval: Recommended wait time before checking again (5000ms for running, 10000ms for waiting)

3. Result Tool: Get Final Result

Tool Name: process_order_result
Description: Get result of process_order workflow (if completed)

Input: {"instance_id": "abc123..."}
Output: {
  "content": [{
    "type": "text",
    "text": "Workflow Result:\n{'status': 'completed', 'order_id': 'ORD-123'}"
  }],
  "isError": false
}

4. Cancel Tool: Stop Workflow

Tool Name: process_order_cancel
Description: Cancel process_order workflow (if running or waiting)

Input: {"instance_id": "abc123..."}
Output: {
  "content": [{
    "type": "text",
    "text": "Workflow 'process_order' cancelled successfully.\nInstance ID: abc123...\nCompensations executed.\n\nThe workflow has been stopped and any side effects have been rolled back."
  }],
  "isError": false
}

The cancel tool:

  • Only works on workflows with status running, waiting_for_event, or waiting_for_timer
  • Automatically executes SAGA compensation transactions to roll back side effects
  • Returns an error for already completed, failed, or cancelled workflows

Advanced Configuration

Authentication

Protect your MCP server with token-based authentication:

def verify_token(token: str) -> bool:
    # Your token verification logic
    return token == "secret-token-123"

server = EddaMCPServer(
    name="Order Service",
    db_url="postgresql://user:pass@localhost/orders",
    token_verifier=verify_token,
)

Clients must include the token in the Authorization header:

Authorization: Bearer secret-token-123

Transactional Outbox Pattern

Enable event-driven architecture with outbox pattern:

server = EddaMCPServer(
    name="Order Service",
    db_url="postgresql://user:pass@localhost/orders",
    outbox_enabled=True,
    broker_url="nats://localhost:4222",
)

MCP Protocol Compliance

Edda's MCP integration follows the MCP Tools specification:

  • JSON-RPC 2.0: All communication uses JSON-RPC 2.0 protocol
  • Content Arrays: Responses include content array with text/image/resource items
  • Error Handling: Errors are reported with isError: true flag
  • Stateless HTTP: Uses MCP's streamable HTTP transport for production deployments

Architecture

┌─────────────────┐
│    MCP Client   │
└────────┬────────┘
         │ JSON-RPC 2.0
         │ (HTTP Transport)
┌─────────────────┐
│  EddaMCPServer  │
│   ┌─────────┐   │
│   │ FastMCP │   │  ← Official MCP SDK
│   └─────────┘   │
│   ┌─────────┐   │
│   │ EddaApp │   │  ← Durable Execution
│   └─────────┘   │
└────────┬────────┘
┌─────────────────┐
│    Database     │
└─────────────────┘

Examples

See the examples/mcp/ directory for complete working examples.