Skip to main content

Self-Hosting the Developer MCP

For teams that want to run their own MCP server instance instead of using the hosted endpoint at dev-mcp.waxell.dev.

Docker​

Build and run the MCP server as a standalone container:

# From the agentforge repo root
docker build -f docker/developer-mcp/Dockerfile -t waxell-dev-mcp .

docker run -p 8004:8004 \
-e WAXELL_DEV_TRANSPORT=sse \
-e WAXELL_DEV_API_URL=https://app.your-domain.com \
waxell-dev-mcp

The server starts in SSE mode on port 8004 with a health check at /health.

Docker Compose​

services:
developer-mcp:
build:
context: .
dockerfile: docker/developer-mcp/Dockerfile
ports:
- "8004:8004"
environment:
WAXELL_DEV_TRANSPORT: "sse"
WAXELL_DEV_API_URL: "https://app.your-domain.com"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8004/health"]
interval: 10s
timeout: 5s
retries: 3

Terraform (AWS Fargate)​

The agentforge repo includes a Terraform module that deploys the MCP server to ECS Fargate with ALB routing.

What it provisions​

  • ECS Fargate task — ARM64 architecture, configurable CPU/memory
  • ECS service — with load balancer integration and health check grace period
  • ALB target group — routes dev-mcp.{domain} to port 8004
  • ALB listener rule — HTTPS termination at the ALB, HTTP to the container
  • ECR repository — for storing Docker images with scan-on-push
  • CloudWatch Logs — log group with developer-mcp stream prefix

Key files​

FilePurpose
terraform/modules/ecs/developer-mcp-task.tfECS task definition and service
terraform/modules/alb/main.tfALB target group and listener rule
terraform/main.tfECR repository and module wiring
terraform/modules/ecs/variables.tfCPU, memory, image, and target group variables

Configuration​

The Terraform module accepts these variables:

VariableDescription
developer_mcp_imageECR image URI (e.g., 123456789.dkr.ecr.us-west-2.amazonaws.com/waxell-dev-developer-mcp:latest)
developer_mcp_cpuCPU units for the Fargate task
developer_mcp_memoryMemory in MB for the Fargate task
developer_mcp_target_group_arnARN of the ALB target group
domainYour domain (creates dev-mcp.{domain} ALB rule)

Environment variables set on the task​

environment = [
{ name = "WAXELL_DEV_API_URL", value = "https://app.${var.domain}" },
{ name = "WAXELL_DEV_TRANSPORT", value = "sse" },
{ name = "WAXELL_DEV_HOST", value = "0.0.0.0" },
{ name = "WAXELL_DEV_PORT", value = "8004" },
]

Note: WAXELL_DEV_API_KEY is intentionally not set on the task. In SSE mode, each connected client sends their own API key via the Authorization header.

Connecting Clients to Your Instance​

Point your MCP client at your self-hosted SSE endpoint:

{
"mcpServers": {
"waxell": {
"type": "sse",
"url": "https://dev-mcp.your-domain.com/sse",
"headers": {
"Authorization": "Bearer wax_sk_your_key_here"
}
}
}
}

Health Check​

The server exposes a GET /health endpoint that returns:

{"status": "ok", "service": "waxell-dev-mcp"}

This is used by Docker health checks, ALB target group health checks, and ECS service stability monitoring.