Docker Deployment
Dockerfile
Section titled “Dockerfile”Since adtk is a statically compiled Go binary, the Docker image is minimal:
# Build stageFROM golang:1.26-alpine AS builder
WORKDIR /buildCOPY go.mod go.sum ./RUN go mod download
COPY . .RUN CGO_ENABLED=0 GOOS=linux go build \ -ldflags="-s -w" \ -o /adtk ./cmd/adtk
# Runtime stageFROM scratch
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/COPY --from=builder /adtk /adtk
ENTRYPOINT ["/adtk"]CMD ["mcp"]Build and Run
Section titled “Build and Run”# Build the imagedocker build -t adtk .
# Run in stdio mode (for piping to MCP clients)docker run -i --rm \ -e AZURE_DEVOPS_ORG=myorg \ -e AZURE_DEVOPS_PAT=your-pat-here \ adtk mcp
# Run in HTTP modedocker run -d --rm \ -p 8080:8080 \ -e AZURE_DEVOPS_ORG=myorg \ -e AZURE_DEVOPS_PAT=your-pat-here \ --name adtk-server \ adtk mcp --port 8080Docker Compose
Section titled “Docker Compose”For a persistent MCP server deployment:
version: '3.8'
services: adtk: build: . container_name: adtk-mcp restart: unless-stopped ports: - "8080:8080" environment: AZURE_DEVOPS_ORG: ${AZURE_DEVOPS_ORG} AZURE_DEVOPS_PAT: ${AZURE_DEVOPS_PAT} ADTK_ENABLE_WRITES: ${ADTK_ENABLE_WRITES:-false} AZURE_DEVOPS_DISABLED_TOOLS: ${AZURE_DEVOPS_DISABLED_TOOLS:-} command: ["mcp", "--port", "8080"] healthcheck: test: ["CMD", "wget", "--spider", "-q", "http://localhost:8080/health"] interval: 30s timeout: 5s retries: 3Create a .env file alongside:
AZURE_DEVOPS_ORG=myorgAZURE_DEVOPS_PAT=your-pat-hereADTK_ENABLE_WRITES=falseThen run:
docker compose up -dUsing with MCP Clients
Section titled “Using with MCP Clients”Once the HTTP server is running, configure your MCP client to connect:
{ "mcpServers": { "adtk": { "url": "http://localhost:8080/mcp" } }}Security Considerations
Section titled “Security Considerations”- Use Docker secrets or a secrets manager for PAT storage in production
- Run the container as a non-root user if deploying beyond local development
- Restrict network access to the HTTP port as needed
- Set
ADTK_ENABLE_WRITES=falseunless write access is explicitly needed