{
  "type": "guide",
  "id": "scan-agent-written-code-with-semgrep-mcp",
  "title": "Scan agent-written code for vulnerabilities with the Semgrep MCP server",
  "summary": "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.",
  "author": "Agentica Author",
  "tags": [
    "security",
    "static-analysis",
    "sast",
    "mcp",
    "coding-agents",
    "claude-code",
    "cursor",
    "code-review"
  ],
  "published": "2026-10-28",
  "last_verified": "2026-10-28",
  "difficulty": "beginner",
  "time_estimate": "20 min",
  "entries": [
    "semgrep-mcp",
    "sonarqube-mcp-server",
    "snyk-agent-scan",
    "claude-code",
    "cursor",
    "vscode-agents",
    "codex-cli",
    "kiro",
    "mcp-python-sdk",
    "trailofbits-skills"
  ],
  "links": {
    "html": "https://indexagentica.com/guides/scan-agent-written-code-with-semgrep-mcp/",
    "markdown": "https://indexagentica.com/guides/scan-agent-written-code-with-semgrep-mcp.md",
    "json": "https://indexagentica.com/api/longform/guides/scan-agent-written-code-with-semgrep-mcp.json",
    "source": "https://github.com/Drudley/indexagentica/blob/main/content-long/guides/scan-agent-written-code-with-semgrep-mcp.md"
  },
  "status": "published",
  "prerequisites": [
    "Python 3 with pip, or Homebrew (to install the Semgrep CLI)",
    "An MCP client: Claude Code, Cursor, VS Code with Copilot, Codex CLI, Kiro or your own",
    "Optional: a Semgrep AppSec Platform account and token for the findings and supply-chain tools"
  ],
  "entries_detail": [
    {
      "id": "semgrep-mcp",
      "name": "Semgrep MCP (Semgrep Guardian)",
      "summary": "Semgrep's MCP server, now shipped in the semgrep CLI (`semgrep mcp`) and bundled as Semgrep Guardian plugins to scan agent-written code for vulnerabilities.",
      "url": "https://indexagentica.com/entries/semgrep-mcp/",
      "json": "https://indexagentica.com/api/entries/semgrep-mcp.json"
    },
    {
      "id": "sonarqube-mcp-server",
      "name": "SonarQube MCP Server",
      "summary": "SonarSource's official MCP server: agents query SonarQube Cloud or Server issues, quality gates, hotspots and metrics, and analyze code snippets.",
      "url": "https://indexagentica.com/entries/sonarqube-mcp-server/",
      "json": "https://indexagentica.com/api/entries/sonarqube-mcp-server.json"
    },
    {
      "id": "snyk-agent-scan",
      "name": "Snyk Agent Scan",
      "summary": "Security scanner that discovers agent components on your machine (agents, MCP servers, skills) and scans them for prompt injections and vulnerabilities.",
      "url": "https://indexagentica.com/entries/snyk-agent-scan/",
      "json": "https://indexagentica.com/api/entries/snyk-agent-scan.json"
    },
    {
      "id": "claude-code",
      "name": "Claude Code",
      "summary": "Anthropic's agentic coding tool that reads your codebase, edits files, runs commands and integrates with dev tools; available in terminal, IDE, desktop and browser.",
      "url": "https://indexagentica.com/entries/claude-code/",
      "json": "https://indexagentica.com/api/entries/claude-code.json"
    },
    {
      "id": "cursor",
      "name": "Cursor",
      "summary": "AI code editor and coding agent with Agent mode, Rules, Skills, MCP servers and a CLI.",
      "url": "https://indexagentica.com/entries/cursor/",
      "json": "https://indexagentica.com/api/entries/cursor.json"
    },
    {
      "id": "vscode-agents",
      "name": "VS Code Agents (agent mode)",
      "summary": "Agent mode in Visual Studio Code: an agent finds relevant code, edits across files and runs checks in your workspace while you review the changes.",
      "url": "https://indexagentica.com/entries/vscode-agents/",
      "json": "https://indexagentica.com/api/entries/vscode-agents.json"
    },
    {
      "id": "codex-cli",
      "name": "OpenAI Codex CLI",
      "summary": "OpenAI's lightweight open-source coding agent that runs in your terminal.",
      "url": "https://indexagentica.com/entries/codex-cli/",
      "json": "https://indexagentica.com/api/entries/codex-cli.json"
    },
    {
      "id": "kiro",
      "name": "Kiro",
      "summary": "Agentic engineering environment that turns prompts into executable specs and builds across large codebases with parallel agents.",
      "url": "https://indexagentica.com/entries/kiro/",
      "json": "https://indexagentica.com/api/entries/kiro.json"
    },
    {
      "id": "mcp-python-sdk",
      "name": "MCP Python SDK",
      "summary": "Official Python SDK for building Model Context Protocol servers and clients.",
      "url": "https://indexagentica.com/entries/mcp-python-sdk/",
      "json": "https://indexagentica.com/api/entries/mcp-python-sdk.json"
    },
    {
      "id": "trailofbits-skills",
      "name": "Trail of Bits Skills",
      "summary": "Trail of Bits' plugin marketplace of agent skills for security research, vulnerability detection, testing and audit workflows.",
      "url": "https://indexagentica.com/entries/trailofbits-skills/",
      "json": "https://indexagentica.com/api/entries/trailofbits-skills.json"
    }
  ],
  "related": [
    {
      "type": "guide",
      "id": "add-mcp-servers-to-claude-code",
      "title": "Add MCP servers to Claude Code",
      "url": "https://indexagentica.com/guides/add-mcp-servers-to-claude-code/",
      "json": "https://indexagentica.com/api/longform/guides/add-mcp-servers-to-claude-code.json"
    },
    {
      "type": "guide",
      "id": "test-your-mcp-server",
      "title": "Test your MCP server with in-process tests and Inspector CI checks",
      "url": "https://indexagentica.com/guides/test-your-mcp-server/",
      "json": "https://indexagentica.com/api/longform/guides/test-your-mcp-server.json"
    },
    {
      "type": "guide",
      "id": "test-an-agent-for-prompt-injection",
      "title": "Test a tool-using agent for prompt injection with AgentDojo",
      "url": "https://indexagentica.com/guides/test-an-agent-for-prompt-injection/",
      "json": "https://indexagentica.com/api/longform/guides/test-an-agent-for-prompt-injection.json"
    },
    {
      "type": "guide",
      "id": "run-untrusted-code-in-a-sandbox",
      "title": "Run agent-generated code safely in a sandbox",
      "url": "https://indexagentica.com/guides/run-untrusted-code-in-a-sandbox/",
      "json": "https://indexagentica.com/api/longform/guides/run-untrusted-code-in-a-sandbox.json"
    },
    {
      "type": "comparison",
      "id": "coding-agent-harnesses",
      "title": "Terminal coding agents compared",
      "url": "https://indexagentica.com/compare/coding-agent-harnesses/",
      "json": "https://indexagentica.com/api/longform/compare/coding-agent-harnesses.json"
    },
    {
      "type": "comparison",
      "id": "llm-red-teaming-tools",
      "title": "Open-source red-teaming tools for LLM apps and agents",
      "url": "https://indexagentica.com/compare/llm-red-teaming-tools/",
      "json": "https://indexagentica.com/api/longform/compare/llm-red-teaming-tools.json"
    }
  ],
  "sources": [
    {
      "title": "Semgrep Guardian / MCP server README (semgrep repo, cli/src/semgrep/mcp)",
      "url": "https://github.com/semgrep/semgrep/blob/develop/cli/src/semgrep/mcp/README.md",
      "accessed": "2026-10-28"
    },
    {
      "title": "semgrep/mcp (archived standalone repo, deprecation notice)",
      "url": "https://github.com/semgrep/mcp",
      "accessed": "2026-10-28"
    },
    {
      "title": "PyPI: semgrep",
      "url": "https://pypi.org/project/semgrep/",
      "accessed": "2026-10-28"
    },
    {
      "title": "SonarQube MCP Server README",
      "url": "https://github.com/SonarSource/sonarqube-mcp-server",
      "accessed": "2026-10-28"
    },
    {
      "title": "SonarQube MCP Server license (Sonar Source-Available License v1.0)",
      "url": "https://github.com/SonarSource/sonarqube-mcp-server/blob/master/LICENSE",
      "accessed": "2026-10-28"
    },
    {
      "title": "Codex: Model Context Protocol (config.toml mcp_servers)",
      "url": "https://developers.openai.com/codex/mcp",
      "accessed": "2026-10-28"
    }
  ],
  "front_matter": {
    "id": "scan-agent-written-code-with-semgrep-mcp",
    "type": "guide",
    "title": "Scan agent-written code for vulnerabilities with the Semgrep MCP server",
    "summary": "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.",
    "description": "A hands-on guide to the Semgrep MCP server, which moved from the archived semgrep/mcp repo into the main Semgrep CLI as the `mcp` subcommand (packaged as Semgrep Guardian plugins for Claude Code and Cursor). We installed semgrep 1.182.1 from PyPI on 2026-10-28, connected to `semgrep mcp` over stdio with the MCP Python SDK, listed its seven tools and scanned a small Python file. It covers client configs, the tools, a custom-rule scan, two gotchas (semgrep_scan needs absolute paths and fails with metrics off; the custom-rule tool needs relative paths), and where SonarQube's MCP server is the better fit.",
    "author": "Agentica Author",
    "difficulty": "beginner",
    "time_estimate": "20 min",
    "prerequisites": [
      "Python 3 with pip, or Homebrew (to install the Semgrep CLI)",
      "An MCP client: Claude Code, Cursor, VS Code with Copilot, Codex CLI, Kiro or your own",
      "Optional: a Semgrep AppSec Platform account and token for the findings and supply-chain tools"
    ],
    "tags": [
      "security",
      "static-analysis",
      "sast",
      "mcp",
      "coding-agents",
      "claude-code",
      "cursor",
      "code-review"
    ],
    "entries": [
      "semgrep-mcp",
      "sonarqube-mcp-server",
      "snyk-agent-scan",
      "claude-code",
      "cursor",
      "vscode-agents",
      "codex-cli",
      "kiro",
      "mcp-python-sdk",
      "trailofbits-skills"
    ],
    "related": [
      "add-mcp-servers-to-claude-code",
      "test-your-mcp-server",
      "test-an-agent-for-prompt-injection",
      "run-untrusted-code-in-a-sandbox",
      "coding-agent-harnesses",
      "llm-red-teaming-tools"
    ],
    "sources": [
      {
        "title": "Semgrep Guardian / MCP server README (semgrep repo, cli/src/semgrep/mcp)",
        "url": "https://github.com/semgrep/semgrep/blob/develop/cli/src/semgrep/mcp/README.md",
        "accessed": "2026-10-28"
      },
      {
        "title": "semgrep/mcp (archived standalone repo, deprecation notice)",
        "url": "https://github.com/semgrep/mcp",
        "accessed": "2026-10-28"
      },
      {
        "title": "PyPI: semgrep",
        "url": "https://pypi.org/project/semgrep/",
        "accessed": "2026-10-28"
      },
      {
        "title": "SonarQube MCP Server README",
        "url": "https://github.com/SonarSource/sonarqube-mcp-server",
        "accessed": "2026-10-28"
      },
      {
        "title": "SonarQube MCP Server license (Sonar Source-Available License v1.0)",
        "url": "https://github.com/SonarSource/sonarqube-mcp-server/blob/master/LICENSE",
        "accessed": "2026-10-28"
      },
      {
        "title": "Codex: Model Context Protocol (config.toml mcp_servers)",
        "url": "https://developers.openai.com/codex/mcp",
        "accessed": "2026-10-28"
      }
    ],
    "last_verified": "2026-10-28",
    "published": "2026-10-28"
  },
  "markdown": "\nCoding 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](https://indexagentica.com/entries/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.\n\n## 1. Know where the server lives now\n\nThe 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:\n\n```bash\npython3 -m pip install semgrep    # or: brew install semgrep\nsemgrep --version                 # we used 1.182.1\nsemgrep mcp --help\n```\n\n`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`.\n\nSemgrep 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.\n\n## 2. Connect your agent\n\n**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.\n\n**Any client, plain MCP route.** If you just want the tools, point the client at the subcommand:\n\n```bash\n# Claude Code\nclaude mcp add semgrep -- semgrep mcp\n```\n\n```json\n// VS Code: .vscode/mcp.json   (Kiro: .kiro/settings/mcp.json uses \"mcpServers\")\n{\n  \"servers\": {\n    \"semgrep\": { \"command\": \"semgrep\", \"args\": [\"mcp\"] }\n  }\n}\n```\n\n```toml\n# Codex CLI: ~/.codex/config.toml\n[mcp_servers.semgrep]\ncommand = \"semgrep\"\nargs = [\"mcp\"]\n```\n\nTo use the AppSec Platform tools, run `semgrep login` or set `SEMGREP_APP_TOKEN` in the server's environment. [Add MCP servers to Claude Code](https://indexagentica.com/guides/add-mcp-servers-to-claude-code/) covers scopes and config files in more detail.\n\n## 3. The tools\n\nWhen we connected over stdio with the [MCP Python SDK](https://indexagentica.com/entries/mcp-python-sdk/), the server (v1.182.1) listed seven tools:\n\n| Tool | What it does | Needs a Semgrep account |\n|---|---|---|\n| `semgrep_scan` | Scans files by **absolute path** with Semgrep's default rules and returns JSON findings | No |\n| `semgrep_scan_with_custom_rule` | Scans code content you pass in with a YAML rule you pass in | No |\n| `semgrep_rule_schema` | Returns the rule schema, so the agent can write valid custom rules | No |\n| `get_abstract_syntax_tree` | Returns a file's AST as JSON | No |\n| `get_supported_languages` | Lists supported languages | No |\n| `semgrep_scan_supply_chain` | Scans a workspace's dependencies for known-vulnerable packages | Yes (Supply Chain) |\n| `semgrep_findings` | Fetches existing findings from the Semgrep AppSec Platform | Yes |\n\n## 4. Try a scan\n\nWe scanned this file:\n\n```python\nimport subprocess, sqlite3\ndef run(cmd):\n    return subprocess.call(cmd, shell=True)\ndef find(db, name):\n    return db.execute(\"SELECT * FROM users WHERE name = '%s'\" % name).fetchall()\n```\n\n`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).\n\nA 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:\n\n```yaml\nrules:\n- id: sql-string-format\n  languages: [python]\n  severity: ERROR\n  message: SQL built with string formatting; use parameters\n  pattern: $DB.execute(\"...\" % $X)\n```\n\nWith `{\"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.\n\nTo 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.\n\n## 5. Two gotchas we hit\n\n- **Paths.** `semgrep_scan` takes absolute paths to files on disk and reads them itself. `semgrep_scan_with_custom_rule` is the opposite: it takes content and rejects absolute paths with `Untrusted path must be relative`. Pass a relative name such as `app.py`.\n- **Metrics off breaks the default scan.** With `SEMGREP_SEND_METRICS=off`, `semgrep_scan` failed with *\"Cannot run scan with auto config when metrics are off\"*. The tool has no parameter for picking a ruleset, so either allow Semgrep's metrics for that server or use `semgrep_scan_with_custom_rule` with your own rules. Check Semgrep's docs on what metrics send before you decide.\n\nAlso 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.\n\n## 6. When SonarQube's MCP server fits better\n\n[SonarQube MCP Server](https://indexagentica.com/entries/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.\n\nUse 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.\n\n## Scope\n\nStatic 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](https://indexagentica.com/guides/test-an-agent-for-prompt-injection/). To check the MCP servers and skills installed on a machine, see [Snyk Agent Scan](https://indexagentica.com/entries/snyk-agent-scan/). And run code an agent wrote but you haven't reviewed in a sandbox ([Run untrusted code in a sandbox](https://indexagentica.com/guides/run-untrusted-code-in-a-sandbox/)).\n",
  "raw": "---\nid: scan-agent-written-code-with-semgrep-mcp\ntype: guide\ntitle: Scan agent-written code for vulnerabilities with the Semgrep MCP server\nsummary: \"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.\"\ndescription: \"A hands-on guide to the Semgrep MCP server, which moved from the archived semgrep/mcp repo into the main Semgrep CLI as the `mcp` subcommand (packaged as Semgrep Guardian plugins for Claude Code and Cursor). We installed semgrep 1.182.1 from PyPI on 2026-10-28, connected to `semgrep mcp` over stdio with the MCP Python SDK, listed its seven tools and scanned a small Python file. It covers client configs, the tools, a custom-rule scan, two gotchas (semgrep_scan needs absolute paths and fails with metrics off; the custom-rule tool needs relative paths), and where SonarQube's MCP server is the better fit.\"\nauthor: Agentica Author\ndifficulty: beginner\ntime_estimate: 20 min\nprerequisites:\n  - \"Python 3 with pip, or Homebrew (to install the Semgrep CLI)\"\n  - \"An MCP client: Claude Code, Cursor, VS Code with Copilot, Codex CLI, Kiro or your own\"\n  - \"Optional: a Semgrep AppSec Platform account and token for the findings and supply-chain tools\"\ntags: [security, static-analysis, sast, mcp, coding-agents, claude-code, cursor, code-review]\nentries: [semgrep-mcp, sonarqube-mcp-server, snyk-agent-scan, claude-code, cursor, vscode-agents, codex-cli, kiro, mcp-python-sdk, trailofbits-skills]\nrelated: [add-mcp-servers-to-claude-code, test-your-mcp-server, test-an-agent-for-prompt-injection, run-untrusted-code-in-a-sandbox, coding-agent-harnesses, llm-red-teaming-tools]\nsources:\n  - title: \"Semgrep Guardian / MCP server README (semgrep repo, cli/src/semgrep/mcp)\"\n    url: https://github.com/semgrep/semgrep/blob/develop/cli/src/semgrep/mcp/README.md\n    accessed: 2026-10-28\n  - title: \"semgrep/mcp (archived standalone repo, deprecation notice)\"\n    url: https://github.com/semgrep/mcp\n    accessed: 2026-10-28\n  - title: \"PyPI: semgrep\"\n    url: https://pypi.org/project/semgrep/\n    accessed: 2026-10-28\n  - title: \"SonarQube MCP Server README\"\n    url: https://github.com/SonarSource/sonarqube-mcp-server\n    accessed: 2026-10-28\n  - title: \"SonarQube MCP Server license (Sonar Source-Available License v1.0)\"\n    url: https://github.com/SonarSource/sonarqube-mcp-server/blob/master/LICENSE\n    accessed: 2026-10-28\n  - title: \"Codex: Model Context Protocol (config.toml mcp_servers)\"\n    url: https://developers.openai.com/codex/mcp\n    accessed: 2026-10-28\nlast_verified: 2026-10-28\npublished: 2026-10-28\n---\n\nCoding 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](https://indexagentica.com/entries/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.\n\n## 1. Know where the server lives now\n\nThe 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:\n\n```bash\npython3 -m pip install semgrep    # or: brew install semgrep\nsemgrep --version                 # we used 1.182.1\nsemgrep mcp --help\n```\n\n`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`.\n\nSemgrep 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.\n\n## 2. Connect your agent\n\n**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.\n\n**Any client, plain MCP route.** If you just want the tools, point the client at the subcommand:\n\n```bash\n# Claude Code\nclaude mcp add semgrep -- semgrep mcp\n```\n\n```json\n// VS Code: .vscode/mcp.json   (Kiro: .kiro/settings/mcp.json uses \"mcpServers\")\n{\n  \"servers\": {\n    \"semgrep\": { \"command\": \"semgrep\", \"args\": [\"mcp\"] }\n  }\n}\n```\n\n```toml\n# Codex CLI: ~/.codex/config.toml\n[mcp_servers.semgrep]\ncommand = \"semgrep\"\nargs = [\"mcp\"]\n```\n\nTo use the AppSec Platform tools, run `semgrep login` or set `SEMGREP_APP_TOKEN` in the server's environment. [Add MCP servers to Claude Code](https://indexagentica.com/guides/add-mcp-servers-to-claude-code/) covers scopes and config files in more detail.\n\n## 3. The tools\n\nWhen we connected over stdio with the [MCP Python SDK](https://indexagentica.com/entries/mcp-python-sdk/), the server (v1.182.1) listed seven tools:\n\n| Tool | What it does | Needs a Semgrep account |\n|---|---|---|\n| `semgrep_scan` | Scans files by **absolute path** with Semgrep's default rules and returns JSON findings | No |\n| `semgrep_scan_with_custom_rule` | Scans code content you pass in with a YAML rule you pass in | No |\n| `semgrep_rule_schema` | Returns the rule schema, so the agent can write valid custom rules | No |\n| `get_abstract_syntax_tree` | Returns a file's AST as JSON | No |\n| `get_supported_languages` | Lists supported languages | No |\n| `semgrep_scan_supply_chain` | Scans a workspace's dependencies for known-vulnerable packages | Yes (Supply Chain) |\n| `semgrep_findings` | Fetches existing findings from the Semgrep AppSec Platform | Yes |\n\n## 4. Try a scan\n\nWe scanned this file:\n\n```python\nimport subprocess, sqlite3\ndef run(cmd):\n    return subprocess.call(cmd, shell=True)\ndef find(db, name):\n    return db.execute(\"SELECT * FROM users WHERE name = '%s'\" % name).fetchall()\n```\n\n`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).\n\nA 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:\n\n```yaml\nrules:\n- id: sql-string-format\n  languages: [python]\n  severity: ERROR\n  message: SQL built with string formatting; use parameters\n  pattern: $DB.execute(\"...\" % $X)\n```\n\nWith `{\"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.\n\nTo 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.\n\n## 5. Two gotchas we hit\n\n- **Paths.** `semgrep_scan` takes absolute paths to files on disk and reads them itself. `semgrep_scan_with_custom_rule` is the opposite: it takes content and rejects absolute paths with `Untrusted path must be relative`. Pass a relative name such as `app.py`.\n- **Metrics off breaks the default scan.** With `SEMGREP_SEND_METRICS=off`, `semgrep_scan` failed with *\"Cannot run scan with auto config when metrics are off\"*. The tool has no parameter for picking a ruleset, so either allow Semgrep's metrics for that server or use `semgrep_scan_with_custom_rule` with your own rules. Check Semgrep's docs on what metrics send before you decide.\n\nAlso 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.\n\n## 6. When SonarQube's MCP server fits better\n\n[SonarQube MCP Server](https://indexagentica.com/entries/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.\n\nUse 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.\n\n## Scope\n\nStatic 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](https://indexagentica.com/guides/test-an-agent-for-prompt-injection/). To check the MCP servers and skills installed on a machine, see [Snyk Agent Scan](https://indexagentica.com/entries/snyk-agent-scan/). And run code an agent wrote but you haven't reviewed in a sandbox ([Run untrusted code in a sandbox](https://indexagentica.com/guides/run-untrusted-code-in-a-sandbox/)).\n",
  "html": "<p>Coding agents write a lot of code quickly, and they repeat the same insecure patterns people do: <code>shell=True</code>, 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. <a href=\"/entries/semgrep-mcp/\">Semgrep MCP</a> puts Semgrep&#39;s scanner behind MCP tools so the agent can scan what it just wrote and fix it before you see the diff.</p>\n<h2>1. Know where the server lives now</h2>\n<p>The standalone <code>semgrep/mcp</code> repository (and its <code>semgrep-mcp</code> PyPI package and <code>ghcr.io/semgrep/mcp</code> image) is archived. The server now ships inside the Semgrep CLI as a subcommand:</p>\n<pre><code class=\"language-bash\">python3 -m pip install semgrep    # or: brew install semgrep\nsemgrep --version                 # we used 1.182.1\nsemgrep mcp --help</code></pre>\n<p><code>semgrep mcp</code> speaks stdio by default (it looks like it hangs; that&#39;s expected) or Streamable HTTP with <code>-t streamable-http</code>, which listens on <code>127.0.0.1:8000/mcp</code> (<code>-p</code> changes the port). There is also a Docker route: <code>docker run -i --rm semgrep/semgrep semgrep mcp -t stdio</code>.</p>\n<p>Semgrep also sells this as <strong>Semgrep Guardian</strong>: 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.</p>\n<h2>2. Connect your agent</h2>\n<p><strong>Claude Code, plugin route</strong> (per the README): run <code>/plugin</code>, go to <strong>Discover</strong>, install <strong>Semgrep</strong>, then run <code>/setup-semgrep-plugin</code>, which also installs the CLI. <strong>Cursor:</strong> add Semgrep from the Cursor Plugin Marketplace, run <code>/setup-semgrep-plugin</code>, then restart.</p>\n<p><strong>Any client, plain MCP route.</strong> If you just want the tools, point the client at the subcommand:</p>\n<pre><code class=\"language-bash\"># Claude Code\nclaude mcp add semgrep -- semgrep mcp</code></pre>\n<pre><code class=\"language-json\">// VS Code: .vscode/mcp.json   (Kiro: .kiro/settings/mcp.json uses &quot;mcpServers&quot;)\n{\n  &quot;servers&quot;: {\n    &quot;semgrep&quot;: { &quot;command&quot;: &quot;semgrep&quot;, &quot;args&quot;: [&quot;mcp&quot;] }\n  }\n}</code></pre>\n<pre><code class=\"language-toml\"># Codex CLI: ~/.codex/config.toml\n[mcp_servers.semgrep]\ncommand = &quot;semgrep&quot;\nargs = [&quot;mcp&quot;]</code></pre>\n<p>To use the AppSec Platform tools, run <code>semgrep login</code> or set <code>SEMGREP_APP_TOKEN</code> in the server&#39;s environment. <a href=\"/guides/add-mcp-servers-to-claude-code/\">Add MCP servers to Claude Code</a> covers scopes and config files in more detail.</p>\n<h2>3. The tools</h2>\n<p>When we connected over stdio with the <a href=\"/entries/mcp-python-sdk/\">MCP Python SDK</a>, the server (v1.182.1) listed seven tools:</p>\n<table><thead><tr><th scope=\"col\">Tool</th><th scope=\"col\">What it does</th><th scope=\"col\">Needs a Semgrep account</th></tr></thead><tbody><tr><td><code>semgrep_scan</code></td><td>Scans files by <strong>absolute path</strong> with Semgrep&#39;s default rules and returns JSON findings</td><td>No</td></tr><tr><td><code>semgrep_scan_with_custom_rule</code></td><td>Scans code content you pass in with a YAML rule you pass in</td><td>No</td></tr><tr><td><code>semgrep_rule_schema</code></td><td>Returns the rule schema, so the agent can write valid custom rules</td><td>No</td></tr><tr><td><code>get_abstract_syntax_tree</code></td><td>Returns a file&#39;s AST as JSON</td><td>No</td></tr><tr><td><code>get_supported_languages</code></td><td>Lists supported languages</td><td>No</td></tr><tr><td><code>semgrep_scan_supply_chain</code></td><td>Scans a workspace&#39;s dependencies for known-vulnerable packages</td><td>Yes (Supply Chain)</td></tr><tr><td><code>semgrep_findings</code></td><td>Fetches existing findings from the Semgrep AppSec Platform</td><td>Yes</td></tr></tbody></table>\n<h2>4. Try a scan</h2>\n<p>We scanned this file:</p>\n<pre><code class=\"language-python\">import subprocess, sqlite3\ndef run(cmd):\n    return subprocess.call(cmd, shell=True)\ndef find(db, name):\n    return db.execute(&quot;SELECT * FROM users WHERE name = &#39;%s&#39;&quot; % name).fetchall()</code></pre>\n<p><code>semgrep_scan</code> with <code>{&quot;code_files&quot;: [{&quot;path&quot;: &quot;/abs/path/app.py&quot;}]}</code> returned three findings: <code>python.lang.security.audit.subprocess-shell-true</code> (line 3), <code>python.lang.security.audit.formatted-sql-query</code> (line 5) and <code>python.sqlalchemy.security.sqlalchemy-execute-raw-query</code> (line 5).</p>\n<p>A custom rule works the same way. The agent can call <code>semgrep_rule_schema</code> first, then pass a rule like this together with the file content:</p>\n<pre><code class=\"language-yaml\">rules:\n- id: sql-string-format\n  languages: [python]\n  severity: ERROR\n  message: SQL built with string formatting; use parameters\n  pattern: $DB.execute(&quot;...&quot; % $X)</code></pre>\n<p>With <code>{&quot;code_files&quot;: [{&quot;path&quot;: &quot;app.py&quot;, &quot;content&quot;: &quot;...&quot;}], &quot;rule&quot;: &quot;&lt;the YAML&gt;&quot;}</code> it reported one finding on line 5. Custom rules are a good fit for project conventions (&quot;never call our internal <code>unsafe_eval</code>&quot;) that no public ruleset knows about.</p>\n<p>To make the agent actually use the tools, say so in your agent instructions (for example in <code>AGENTS.md</code> or <code>CLAUDE.md</code>): <em>after editing code, run <code>semgrep_scan</code> on every changed file and fix ERROR findings before finishing.</em> Guardian&#39;s hooks do this for you in Claude Code and Cursor.</p>\n<h2>5. Two gotchas we hit</h2>\n<ul><li><strong>Paths.</strong> <code>semgrep_scan</code> takes absolute paths to files on disk and reads them itself. <code>semgrep_scan_with_custom_rule</code> is the opposite: it takes content and rejects absolute paths with <code>Untrusted path must be relative</code>. Pass a relative name such as <code>app.py</code>.</li><li><strong>Metrics off breaks the default scan.</strong> With <code>SEMGREP_SEND_METRICS=off</code>, <code>semgrep_scan</code> failed with <em>&quot;Cannot run scan with auto config when metrics are off&quot;</em>. The tool has no parameter for picking a ruleset, so either allow Semgrep&#39;s metrics for that server or use <code>semgrep_scan_with_custom_rule</code> with your own rules. Check Semgrep&#39;s docs on what metrics send before you decide.</li></ul>\n<p>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.</p>\n<h2>6. When SonarQube&#39;s MCP server fits better</h2>\n<p><a href=\"/entries/sonarqube-mcp-server/\">SonarQube MCP Server</a> solves a different part of the problem. Semgrep MCP is a local scanner the agent runs on fresh code. SonarQube&#39;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 <code>analyze_code_snippet</code>. It needs a SonarQube token (<code>SONARQUBE_TOKEN</code> plus <code>SONARQUBE_ORG</code> or <code>SONARQUBE_URL</code>) and runs from the <code>sonarsource/sonarqube-mcp</code> container. Its license is the Sonar Source-Available License v1.0, not an open-source one. Semgrep&#39;s CLI is LGPL-2.1.</p>\n<p>Use Semgrep MCP when you want a fast check inside the agent loop with no server. Use SonarQube&#39;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.</p>\n<h2>Scope</h2>\n<p>Static analysis finds known bug patterns in code. It doesn&#39;t tell you whether the agent itself can be manipulated. For that, see <a href=\"/guides/test-an-agent-for-prompt-injection/\">Test a tool-using agent for prompt injection</a>. To check the MCP servers and skills installed on a machine, see <a href=\"/entries/snyk-agent-scan/\">Snyk Agent Scan</a>. And run code an agent wrote but you haven&#39;t reviewed in a sandbox (<a href=\"/guides/run-untrusted-code-in-a-sandbox/\">Run untrusted code in a sandbox</a>).</p>"
}
