Index Agentica

Scan agent-written code for vulnerabilities with the Semgrep MCP server

Give a coding agent a deterministic security scanner. Install the Semgrep CLI, run its built-in MCP server (`semgrep mcp`), wire it into Claude Code, Cursor, VS Code, Codex or Kiro, and call semgrep_scan and custom-rule scans. Includes two gotchas we hit, and when SonarQube's MCP server fits better.

Type
Guide
Author
Agentica Author
Published
Last verified
Difficulty
beginner
Time
20 min

Prerequisites

Coding agents write a lot of code quickly, and they repeat the same insecure patterns people do: shell=True, SQL built with string formatting, hard-coded secrets. A model reviewing its own output is not a reliable check. A static analyzer is deterministic: the same code gives the same findings every time. Semgrep MCP puts Semgrep's scanner behind MCP tools so the agent can scan what it just wrote and fix it before you see the diff.

1. Know where the server lives now

The standalone semgrep/mcp repository (and its semgrep-mcp PyPI package and ghcr.io/semgrep/mcp image) is archived. The server now ships inside the Semgrep CLI as a subcommand:

python3 -m pip install semgrep    # or: brew install semgrep
semgrep --version                 # we used 1.182.1
semgrep mcp --help

semgrep mcp speaks stdio by default (it looks like it hangs; that's expected) or Streamable HTTP with -t streamable-http, which listens on 127.0.0.1:8000/mcp (-p changes the port). There is also a Docker route: docker run -i --rm semgrep/semgrep semgrep mcp -t stdio.

Semgrep also sells this as Semgrep Guardian: a plugin that bundles the MCP server with hooks and skills, scans every file an agent writes with Semgrep Code, Supply Chain and Secrets, and prompts the agent to regenerate code until the scan is clean or you dismiss the finding.

2. Connect your agent

Claude Code, plugin route (per the README): run /plugin, go to Discover, install Semgrep, then run /setup-semgrep-plugin, which also installs the CLI. Cursor: add Semgrep from the Cursor Plugin Marketplace, run /setup-semgrep-plugin, then restart.

Any client, plain MCP route. If you just want the tools, point the client at the subcommand:

# Claude Code
claude mcp add semgrep -- semgrep mcp
// VS Code: .vscode/mcp.json   (Kiro: .kiro/settings/mcp.json uses "mcpServers")
{
  "servers": {
    "semgrep": { "command": "semgrep", "args": ["mcp"] }
  }
}
# Codex CLI: ~/.codex/config.toml
[mcp_servers.semgrep]
command = "semgrep"
args = ["mcp"]

To use the AppSec Platform tools, run semgrep login or set SEMGREP_APP_TOKEN in the server's environment. Add MCP servers to Claude Code covers scopes and config files in more detail.

3. The tools

When we connected over stdio with the MCP Python SDK, the server (v1.182.1) listed seven tools:

ToolWhat it doesNeeds a Semgrep account
semgrep_scanScans files by absolute path with Semgrep's default rules and returns JSON findingsNo
semgrep_scan_with_custom_ruleScans code content you pass in with a YAML rule you pass inNo
semgrep_rule_schemaReturns the rule schema, so the agent can write valid custom rulesNo
get_abstract_syntax_treeReturns a file's AST as JSONNo
get_supported_languagesLists supported languagesNo
semgrep_scan_supply_chainScans a workspace's dependencies for known-vulnerable packagesYes (Supply Chain)
semgrep_findingsFetches existing findings from the Semgrep AppSec PlatformYes

4. Try a scan

We scanned this file:

import subprocess, sqlite3
def run(cmd):
    return subprocess.call(cmd, shell=True)
def find(db, name):
    return db.execute("SELECT * FROM users WHERE name = '%s'" % name).fetchall()

semgrep_scan with {"code_files": [{"path": "/abs/path/app.py"}]} returned three findings: python.lang.security.audit.subprocess-shell-true (line 3), python.lang.security.audit.formatted-sql-query (line 5) and python.sqlalchemy.security.sqlalchemy-execute-raw-query (line 5).

A custom rule works the same way. The agent can call semgrep_rule_schema first, then pass a rule like this together with the file content:

rules:
- id: sql-string-format
  languages: [python]
  severity: ERROR
  message: SQL built with string formatting; use parameters
  pattern: $DB.execute("..." % $X)

With {"code_files": [{"path": "app.py", "content": "..."}], "rule": "<the YAML>"} it reported one finding on line 5. Custom rules are a good fit for project conventions ("never call our internal unsafe_eval") that no public ruleset knows about.

To make the agent actually use the tools, say so in your agent instructions (for example in AGENTS.md or CLAUDE.md): after editing code, run semgrep_scan on every changed file and fix ERROR findings before finishing. Guardian's hooks do this for you in Claude Code and Cursor.

5. Two gotchas we hit

Also note the server logs that it initializes tracing at startup. If outbound telemetry from developer machines is a concern, check that with Semgrep before you roll it out.

6. When SonarQube's MCP server fits better

SonarQube MCP Server solves a different part of the problem. Semgrep MCP is a local scanner the agent runs on fresh code. SonarQube's server connects the agent to a SonarQube Cloud or Server project you already analyze: it can search issues and security hotspots, read quality-gate status, coverage, duplications and dependency risks, change issue status, and analyze a single file with analyze_code_snippet. It needs a SonarQube token (SONARQUBE_TOKEN plus SONARQUBE_ORG or SONARQUBE_URL) and runs from the sonarsource/sonarqube-mcp container. Its license is the Sonar Source-Available License v1.0, not an open-source one. Semgrep's CLI is LGPL-2.1.

Use Semgrep MCP when you want a fast check inside the agent loop with no server. Use SonarQube's when your team already gates merges on SonarQube and you want the agent to see and fix the same issues. They can run side by side.

Scope

Static analysis finds known bug patterns in code. It doesn't tell you whether the agent itself can be manipulated. For that, see Test a tool-using agent for prompt injection. To check the MCP servers and skills installed on a machine, see Snyk Agent Scan. And run code an agent wrote but you haven't reviewed in a sandbox (Run untrusted code in a sandbox).

Directory entries in this guide

Related

Sources

Machine-readable