Skip to contentAgent? Read agent.txt
All posts
Engineering

Scanning MCP servers in CI: the shift-left pattern for agent security

Pull request scanning catches poisoned tool descriptions before a developer installs them. Here's the 10-line GitHub Action that makes it work.

The Decoy TeamEngineering

Security that only runs on a security team's laptop is security that misses three weeks per hire. If you care about MCP security, the fastest way to raise the floor is to scan every PR that adds or changes an MCP server.

The 10-line action

name: MCP security scan
on: pull_request

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: decoy-run/decoy-scan@v1
        with:
          fail-on: critical

Drop that in .github/workflows/decoy.yml and every PR gets 50+ checks run against any MCP server configs touched. A critical finding fails the build. SARIF output lands in the PR's Security tab.

Why fail-on: critical is the right default

Every scanner has a false-positive ceiling. We tuned decoy-scan's critical bucket to mean "don't merge this" — things like poisoned tool descriptions, unbounded shell-adjacent inputs, and transports that leak credentials. High and medium findings go to the Security tab for review but don't block the merge. If you're just starting, that's the default you want.

You can tighten later. Business-tier teams can ship custom detection rules that enforce org-specific policies (banned capabilities, required descriptions, allowed transports).

What this buys you

A shift-left loop for agent security. Your developers learn what a poisoned tool description looks like because GitHub explained it to them on PR #247, not because a CISO emailed them three weeks later. That's the only way this scales.