CI integration
Add agentgate ci to your pipeline so a rug-pulled tool description or a severe finding fails the build before your agent ever sees it.
Prerequisites in the repo being gated:
- A committed
agentgate.lock(runagentgate locklocally and review it in a PR). - An MCP config the runner can read — pass it explicitly with
--configfor reproducible CI runs.
AgentGate is published on npm as mcp-agentgate (the installed command is still agentgate), so every recipe below is a one-liner with npx mcp-agentgate.
GitHub Actions
Section titled “GitHub Actions”Using the bundled composite action:
name: mcp-gateon: [push, pull_request]
jobs: gate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: wookat/agentgate/packages/action@main with: command: ci args: --config .mcp.json --fail-on high lockfile: agentgate.lockTo surface scan findings in GitHub code scanning, set sarif-file: agentgate.sarif on the action and add:
- uses: github/codeql-action/upload-sarif@v3 if: always() with: sarif_file: agentgate.sarifGitLab CI
Section titled “GitLab CI”mcp-gate: image: node:22 script: - npx mcp-agentgate ci --config .mcp.json --fail-on highCircleCI
Section titled “CircleCI”version: 2.1jobs: mcp-gate: docker: - image: cimg/node:22.17 steps: - checkout - run: name: MCP gate command: npx mcp-agentgate ci --config .mcp.json --fail-on highworkflows: gate: jobs: [mcp-gate]Jenkins
Section titled “Jenkins”pipeline { agent { docker { image 'node:22' } } stages { stage('MCP gate') { steps { sh 'npx mcp-agentgate ci --config .mcp.json --fail-on high' } } }}Azure Pipelines
Section titled “Azure Pipelines”pool: vmImage: ubuntu-lateststeps: - task: UseNode@1 inputs: version: 22.x - script: npx mcp-agentgate ci --config .mcp.json --fail-on high displayName: MCP gate- Pin the config: auto-discovery looks at the runner’s home directory — in CI, always pass
--configpointing at a config committed to the repo. - Choose the threshold deliberately:
--fail-on high(default) blocks on high/critical findings; use--fail-on mediumonce your baseline is clean. - Stdio servers run in CI:
ci/diff/lockconnect to stdio servers to read their live tool surface, so the runner needs any runtimes those servers require (e.g.uvfor Python servers). Restrict with--serverif only some servers matter. - Exit code 2 means the gate itself broke (missing lockfile, unreachable server) — treat it as a failure, don’t mask it.