DocsNew Run

Deployment

Principle

The repo is fully platform-agnostic. The Dockerfile is the only deployment contract — no platform-specific config files in the repo. All platform settings live in each platform's dashboard.

Required sidecars

The macp-playground does not run standalone. Before it will boot, two additional services must be reachable:

ServiceWhy it's requiredHow to run it
MACP runtime (gRPC)Agents open their own gRPC channels to the runtime (RFC-MACP-0004 §4). MACP_RUNTIME_ADDRESS must point to a live runtime.See macp-runtime/docs/deployment.md.
auth-service (HTTP)Every agent spawn mints a short-lived JWT via POST /tokens. At startup, PolicyRegistrarService also mints an admin JWT to register scenario policies with the runtime. Missing MACP_AUTH_SERVICE_URL throws INVALID_CONFIG and the service fails startup.docker-compose.dev.yml runs it as a sidecar; in production, deploy the auth-service image alongside the runtime.

The runtime must be configured to accept JWTs minted by the same auth-service — on the runtime set MACP_AUTH_ISSUER, MACP_AUTH_AUDIENCE, and MACP_AUTH_JWKS_URL=<auth-service>/.well-known/jwks.json. For the full JWT-mode setup (supported algorithms, macp_scopes claim shape, JWKS caching) see macp-runtime/docs/getting-started.md § JWT mode.

v0.5.0 runtime changes.

  • A local, no-auth runtime now refuses to start unless MACP_ALLOW_INSECURE=1 is set — the published image no longer bakes it in. The fullstack compose sets it explicitly (also required for plaintext gRPC regardless of auth mode).
  • The default JWT algorithm allowlist is RS256/ES256 (HS256 was removed). This stack uses RS256 throughout, so no action is needed; opting into HS256 would require MACP_AUTH_JWT_ALGS=HS256 on the runtime — don't.
  • The runtime exposes a Prometheus text endpoint via MACP_METRICS_ADDR (e.g. 0.0.0.0:9464) — the fullstack compose maps it out at :9464 as an observability demo surface.
  • Runtime images are published to ghcr.io/multiagentcoordinationprotocol/macp-runtime:{0.5.0,latest}, so no local Rust build is required.

Startup order

auth-service up ↓ runtime up (with MACP_AUTH_JWKS_URL pointing at auth-service) ↓ macp-playground boots ├─ validates MACP_AUTH_SERVICE_URL is set (fails fast otherwise) └─ PolicyRegistrarService.onApplicationBootstrap() ├─ mints admin JWT from auth-service (can_manage_mode_registry) ├─ opens gRPC channel to runtime └─ registers each non-default policy (idempotent) ↓ ready to accept POST /examples/run

If any of these fail, /examples/run will surface AUTH_MINT_FAILED (502) at request time rather than at boot — watch the startup logs for PolicyRegistrarService warnings.

Pipeline

push to main / PR (superseded runs on the same ref are cancelled) │ ├─ lint ESLint + Prettier check + npm audit (non-blocking) ├─ build TypeScript compile ├─ test unit (coverage thresholds, report artifact) + e2e + integration (mock) ├─ python ruff + pytest over agents/ workers │ └─ docker PR → build image only (no registry push) main → build + push to GHCR (:latest + :sha-<commit>) + Trivy vulnerability scan (non-blocking)

Dependency updates are automated by Dependabot (.github/dependabot.yml): weekly PRs for npm (root), pip (agents/), and GitHub Actions versions.

Image Tags

TriggerTagPurpose
Push to main:latestRolling production tag
Push to main:sha-<commit>Immutable, for rollback

Pull requests build the image for validation but do not push it, so the registry only carries images built from main.

Images live at:

ghcr.io/multiagentcoordinationprotocol/macp-playground

Deploying

Point any container platform at the GHCR image. No platform config files needed — configure everything in the platform's dashboard. Remember to deploy the auth-service sidecar in the same network.

Railway

  1. Create a service → set source to Docker Image
  2. Image: ghcr.io/multiagentcoordinationprotocol/macp-playground:latest
  3. Set env vars in the Variables tab

Render

  1. Create a Web Service → type Docker Image
  2. Image: ghcr.io/multiagentcoordinationprotocol/macp-playground:latest
  3. Set env vars in the Environment tab

Fly.io

flyctl apps create macp-playground
flyctl deploy --image ghcr.io/multiagentcoordinationprotocol/macp-playground:latest
flyctl secrets set \
  MACP_RUNTIME_ADDRESS=runtime.internal:50051 \
  MACP_AUTH_SERVICE_URL=http://auth-service.internal:3200

AWS ECS

  1. Create an ECR repo, push the GHCR image (or point the task definition at GHCR directly)
  2. Create ECS cluster + service + task definition referencing the image
  3. Deploy the auth-service alongside as a second task definition in the same cluster + VPC

Any other platform

Any platform that can run a Docker image works. Point it at:

ghcr.io/multiagentcoordinationprotocol/macp-playground:latest

Environment Variables

The table below mirrors AppConfigService (src/config/app-config.service.ts) and .env.example. "Required" means the service either refuses to boot or the relevant feature will fail at request time.

Core HTTP / logging

VariableRequiredDefaultDescription
PORTNo3000HTTP listen port
HOSTNo0.0.0.0HTTP listen host
CORS_ORIGINNohttp://localhost:3000Comma-separated origins (supports * and wildcards)
NODE_ENVNodevelopmentdevelopment enables Swagger at /docs
LOG_LEVELNoinfo
AUTH_API_KEYSNoComma-separated keys guarding the macp-playground HTTP surface

Scenario registry

VariableRequiredDefaultDescription
PACKS_DIRNo/app/packsPath to scenario pack YAML files
REGISTRY_CACHE_TTL_MSNo0Cache TTL; 0 reloads on every request

MACP runtime (gRPC)

VariableRequiredDefaultDescription
MACP_RUNTIME_ADDRESSYes (for runs)(empty)gRPC endpoint every agent dials. Required for /examples/run; if unset, PolicyRegistrarService logs a warning and skips registration.
MACP_RUNTIME_TLSNotrueTLS flag written into each agent's bootstrap. RFC-MACP-0006 §3 requires true in production.
MACP_RUNTIME_ALLOW_INSECURENofalseMust be true when MACP_RUNTIME_TLS=false — local dev only.

auth-service (AUTH-2)

VariableRequiredDefaultDescription
MACP_AUTH_SERVICE_URLYes(empty)Base URL of the auth-service. Startup fails with INVALID_CONFIG if unset.
MACP_AUTH_SERVICE_TIMEOUT_MSNo5000HTTP timeout for POST /tokens.
MACP_AUTH_TOKEN_TTL_SECONDSNo3600TTL requested from auth-service on every mint. Must exceed the agent's gRPC stream lifetime (SDKs bind auth once at stream open). Capped by auth-service MACP_AUTH_MAX_TTL_SECONDS.
MACP_AUTH_SCOPES_JSONNo(empty)Per-sender scope overrides, JSON {"sender":{"can_start_sessions":true,...}}. Deep-merged onto role-derived defaults; explicit null clears a key.

Policy registration

VariableRequiredDefaultDescription
REGISTER_POLICIES_ON_LAUNCHNotrueWhen true, PolicyRegistrarService registers every non-default policy with the runtime at bootstrap. Set to false only in tests or when policies are pre-registered out-of-band.

Read-only registry (v0.5.0, prod-style alternative). A runtime started with MACP_POLICIES_DIR owns its policy registry from disk and rejects RegisterPolicy RPCs with FAILED_PRECONDITION. Mount this repo's ./policies into that directory and set REGISTER_POLICIES_ON_LAUNCH=false to skip the mutation probe entirely. If you leave REGISTER_POLICIES_ON_LAUNCH=true, PolicyRegistrarService detects the read-only registry, stops mutating, and switches to verification — calling getPolicy for each required policy and logging a registered/already/managed_by_runtime/missing/failed summary. Any policy the runtime is missing is logged at ERROR with the <policy_id>.json file to mount (launches referencing it would otherwise fail UNKNOWN_POLICY_VERSION). The fullstack compose ships a commented-out variant of this setup.

Agent workers

VariableRequiredDefaultDescription
AUTO_BOOTSTRAP_EXAMPLE_AGENTSNotrueAuto-resolve agent bindings on /examples/run.
EXAMPLE_AGENT_PYTHON_PATHNopython3Python interpreter for Python workers.
EXAMPLE_AGENT_NODE_PATHNo(process.execPath)Node interpreter for Node workers.
MACP_CANCEL_CALLBACK_HOSTNo127.0.0.1Host each agent binds for the cancel-callback HTTP server. Empty disables.
MACP_CANCEL_CALLBACK_PORT_BASENo0Port base for deterministic per-agent ports; 0 = ephemeral.
MACP_CANCEL_CALLBACK_PATHNo/agent/cancelHTTP path for the cancel-callback server.

GHCR Visibility

If the package is private, set it to Public (simplest), or configure pull credentials in your platform's dashboard.

Rollback

# Use an older immutable tag
ghcr.io/multiagentcoordinationprotocol/macp-playground:sha-abc1234

Or re-tag:

docker pull ghcr.io/…/macp-playground:sha-<old>
docker tag  ghcr.io/…/macp-playground:sha-<old> ghcr.io/…/macp-playground:latest
docker push ghcr.io/…/macp-playground:latest

Local Testing

docker-compose.dev.yml wires the macp-playground to the auth-service sidecar. Start the runtime separately, then:

docker compose -f docker-compose.dev.yml up
curl http://localhost:3000/healthz

For a single-container smoke test without auth-service, the service will refuse to start — that's by design. Run the auth-service first:

# In auth-service/
npm install && npm run build && npm start  # listens on :3200

# In macp-playground/
MACP_AUTH_SERVICE_URL=http://localhost:3200 \
MACP_RUNTIME_ADDRESS=runtime.local:50051 \
docker run -p 3000:3000 --env-file .env macp-playground