Deployment¶
Docker Compose¶
cp .env.example .env
# Fill in store credentials, then add a token:
echo "MCP_HTTP_AUTH_TOKENS=$(openssl rand -base64 32)" >> .env
docker compose up -d --build
curl http://127.0.0.1:3000/healthz
The compose file:
- runs the server over streamable HTTP on port 3000, published on
127.0.0.1only - writes the audit log to the
auditvolume at/data/audit.jsonl - uses a read-only root file system, drops all capabilities, and blocks privilege escalation
To serve several stores, mount a stores file and set WOOCOMMERCE_STORES_FILE (the lines are commented in docker-compose.yml). Keep secrets in .env and reference them with consumerSecretEnv.
Docker image¶
Released images are on the GitHub Container Registry for linux/amd64 and linux/arm64:
docker run -d --name woocommerce-mcp -p 127.0.0.1:3000:3000 \
--env-file .env \
ghcr.io/sadrmanesh/woocommerce-mcp:0.3.2
Use 0.3.2 to pin a release, 0.3 to follow patch releases, or latest. To run the published image with Docker Compose, remove the build: block and set image: ghcr.io/sadrmanesh/woocommerce-mcp:0.3.2.
Or build it yourself from a checkout:
docker build -t woocommerce-mcp .
docker build -t woocommerce-mcp:otel --build-arg OTEL=true . # with the tracing exporter
The image is based on node:22-alpine, runs as the unprivileged node user, exposes port 3000, and defines a health check against /healthz. It defaults to MCP_TRANSPORT=http and MCP_HTTP_HOST=0.0.0.0, so it will not start without authentication configured.
Run it over stdio instead, for a host that launches containers:
{
"mcpServers": {
"woocommerce": {
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT=stdio", "-e", "WOOCOMMERCE_URL", "-e", "WOOCOMMERCE_CONSUMER_KEY", "-e", "WOOCOMMERCE_CONSUMER_SECRET", "ghcr.io/sadrmanesh/woocommerce-mcp:0.3.2"],
"env": {
"WOOCOMMERCE_URL": "https://store.example.com",
"WOOCOMMERCE_CONSUMER_KEY": "ck_...",
"WOOCOMMERCE_CONSUMER_SECRET": "cs_..."
}
}
}
}
Reverse proxy¶
Expose the server only through TLS. A minimal Caddy example:
Then set:
MCP_HTTP_ALLOWED_HOSTS=mcp.example.com
MCP_OAUTH_RESOURCE=https://mcp.example.com/mcp # when using OAuth introspection
Streamable HTTP responses can be server-sent event streams, so disable response buffering in proxies that buffer by default.
Endpoints¶
| Path | Purpose |
|---|---|
MCP_HTTP_PATH (default /mcp) |
MCP streamable HTTP |
/healthz |
Liveness check, returns {"status":"ok","version":"..."} |
/.well-known/oauth-protected-resource<path> |
RFC 9728 metadata, when authentication is on |
Upgrading from 0.1.x¶
Existing single-store variables keep working. Two behaviours changed:
- Write tools now ask for confirmation by default. Clients must call again with
confirm: true, or setWOOCOMMERCE_REQUIRE_CONFIRMATION=falseto restore the old behaviour. MCP_HTTP_HOSTmay now be a non-loopback address when authentication is configured.