A good MCP pipeline answers: can we prove this artifact speaks MCP correctly before any human points Cursor at it?
Pipeline stages (reference)
lint / typecheck / unit tests
→ contract snapshots (tool names + inputSchema)
→ build immutable artifact (image digest or git SHA package)
→ protocol smoke against that artifact
→ deploy staging
→ smoke staging URL (initialize, tools/list, tools/call, auth fail)
→ manual or automated promote to prod
→ watch tool error rate 30–60 minutes
→ ready to rollback previous digest
Protocol references: lifecycle, tools. Debug aids: Inspector, debugging.
Why MCP CI differs from “normal” API CI
| Normal HTTP API | MCP server |
|---|---|
| OpenAPI often optional in CI | tools/list is the contract agents use |
| 200 OK may be enough | Need initialize + tool execution semantics |
| Clients are your apps | Clients are heterogeneous hosts (Cursor, Claude, VS Code) |
| Breaking field = app deploy | Breaking field = silent agent failures across the company |
Git deploys and mcplambda.yaml
For Git-based deploys on MCPLambda, commit mcplambda.yaml at the repo root so install/build/run/transport are versioned with the code:
build_strategy: npm
install_command: npm ci
build_command: npm run build
run: node dist/index.js
transport: streamable-http
Do not put secrets in the yaml. CI should pass secrets via the platform at deploy time. CLI/API flags override yaml when both are set (yaml docs).
What to test in CI
Unit
- Handler logic with mocked upstreams
- Fail-closed when secrets missing
Contract
- Snapshot tool names
- Snapshot JSON Schema for each tool
- Fail PR on unexpected diffs (versioning)
Protocol smoke
- Start process with prod entrypoint
initialize- Assert
tools/list - Happy-path
tools/call - Invalid call → prefer
isError: truewith readable text (tools error handling) - Remote: unauthenticated call rejected
Stdio hygiene
If testing stdio: fail if stdout is polluted (build server, stdio transport).
Environments
| Env | Secrets | Auto-deploy | Purpose |
|---|---|---|---|
| PR preview (optional) | Non-prod only | Optional | Experimentation |
| Staging | Staging upstream | On merge to main | Smoke + dogfood |
| Production | Prod | Promote only | Customer/team traffic |
Staging credentials must not be able to destroy production data.
Platform GitOps vs CI tests
Auto-rebuild on git push is convenient, but not a substitute for protocol smoke. Prefer:
merge → CI green → deploy staging → smoke → promote prod
If you auto-deploy prod on push, at least require the protocol smoke job as a required check.
Auth for CI bots
- Service account / API token with least privilege
- Scoped to staging project for PR pipelines
- Separate prod promote token held by a protected environment
- Rotate regularly
Align remote auth with Authorization and security best practices (no token passthrough in your server code either).
Post-deploy verification
For 30–60 minutes after promote:
- Tool error rate vs baseline
- Auth failure spike
- p95 latency on critical tools
Product metrics: MCPLambda analytics. Process: observability.
Worked example: Node TypeScript server
PR opened
npm ci && npm test && npm run build
start node dist/index.js (or test harness transport)
protocol smoke script
merge to main
build image OR git deploy sha
mcpl deploy … --name my-mcp-staging
smoke against staging URL
human approve
mcpl deploy … --name my-mcp-prod (or promote pointer)
watch analytics
Release checklist
- Required CI checks include protocol smoke
- Artifact is immutable (SHA/digest recorded)
-
mcplambda.yamlpresent for Git servers - Staging smoked on same transport as prod
-
tools/listdiff reviewed if changed - Rollback artifact known
- On-call knows how to revert
- Destructive tools flagged in change notes
Anti-patterns
- Deploying without
tools/listassertion - Using personal tokens in CI
- One environment for staging and prod
- Shipping tool renames without dual-run
- Ignoring stdio stdout pollution in tests
Worked scenario: Promote only after staging speaks MCP
Your pipeline used to deploy on every merge to main. One Friday deploy changed OAuth audience validation. Every Cursor session got 401s. Rollback took an hour because production was “whatever main built.”
You restructure: merge runs unit + contract + protocol smoke and produces an image digest. Staging auto-deploys that digest. A protected “prod” environment promotes the same digest after a human checks staging smoke. CI uses a staging-only token; prod promote uses a separate secret.
mcplambda.yaml lives in the repo so agents and CI share install/build/run—secrets still come from the platform at deploy time.
Checklist for this topic
- Required checks include protocol smoke
- Artifacts are digests/SHAs, not :latest
- Staging and prod secrets are isolated
- mcplambda.yaml committed for Git servers
- Prod promote is a pointer move to a known digest
- Post-deploy watch window owned by the releaser
Topic-specific failure modes
| Failure | Likely cause | Fix |
|---|---|---|
| Cannot rollback | No immutable artifact | Record digest/SHA every release |
| CI uses human SSO cookie | Convenience auth | Service account token in CI secrets |
| Staging proves nothing | Different transport than prod | Same transport + auth shape |
| Yaml drifts from CI script | Two sources of truth | Single mcplambda.yaml contract |
Related guides
Testing · mcplambda.yaml · Versioning
Sources
- Tools — 2025-11-25
- Lifecycle — 2025-11-25
- Transports — 2025-11-25
- MCP Inspector
- Debugging
- Build an MCP server
- Security Best Practices
- MCPLambda CLI · mcplambda.yaml · deployment strategies