Skip to content

Connect Semgrep to Claude: Audit Policies & Manage Deployments

Learn how to build a managed MCP server for Semgrep, connect it to Claude, and orchestrate automated security scans, triage workflows, and policy management.

Nachi Raman Nachi Raman · · 10 min read

If you need to connect Semgrep to Claude to automate SAST finding triage, audit organization-wide security policies, or orchestrate agent deployments, you need a Model Context Protocol (MCP) server. This server acts as the translation layer between Claude's function calls and Semgrep's complex REST API. You can either build and maintain this infrastructure yourself, or use a managed integration platform like Truto to dynamically generate a secure, authenticated MCP server URL. If your team uses ChatGPT, check out our guide on connecting Semgrep to ChatGPT or explore our broader architectural overview on connecting Semgrep to AI Agents.

Giving a Large Language Model (LLM) read and write access to a sensitive code security ecosystem like Semgrep is an engineering challenge. You must handle token lifecycles, safely expose destructive operations, map massive nested JSON schemas to MCP tool definitions, and deal with Semgrep's explicit rate limits and async polling patterns. Every time Semgrep updates its enterprise API, you have to rewrite your server code, redeploy, and test the integration.

This guide breaks down exactly how to use Truto to generate a secure, managed MCP server for Semgrep, connect it natively to Claude, and execute complex security engineering workflows using natural language.

The Engineering Reality of the Semgrep API

A custom MCP server is essentially a self-hosted API proxy layer. While the open MCP standard provides a predictable way for models to discover tools, the reality of implementing it against Semgrep's API is painful. You are not just integrating a standard CRUD API; you are interacting with an enterprise security platform built on top of complex protobuf schemas.

If you decide to build a custom MCP server for Semgrep, you own the entire API lifecycle. Here are the specific architectural challenges you will face:

Optimistic Concurrency and State Versions Unlike basic APIs where a simple PUT or PATCH updates a resource, Semgrep enforces strict optimistic concurrency on consequential endpoints like detection and remediation policies. If Claude wants to apply a new detection policy bundle, it cannot just send the payload. It must first fetch the current policy to retrieve the state_version, and then explicitly pass that value in the If-Match header on the subsequent update request. If the header is missing, the API throws a 428 Precondition Required. If the state has changed in the interim, it throws a 409 Conflict. Exposing this to an LLM requires an abstraction layer that explicitly instructs the model on how to handle these headers, otherwise the agent will get stuck in error loops.

Asynchronous Jobs and Task Tokens Operations involving large datasets in Semgrep—such as generating a Software Bill of Materials (SBOM) or triggering AI-powered SAST fix jobs—do not return immediate results. Instead, they return a 202 Accepted response containing a task_token_jwt. To get the actual data, the client must poll a separate Tasks endpoint (list_all_semgrep_tasks) with that JWT until the job status reads complete. Your custom MCP server has to register both the initiation and polling endpoints as distinct tools, and strictly define the schemas so Claude understands it has to wait and query again.

Protobuf-Backed Nested Data Structures Many of Semgrep's modern endpoints (v2) are backed by complex upstream protobuf definitions (e.g., protos.projects.v1.BulkApplyRepoUpdateResponse). When an LLM attempts to construct a request body, it struggles with deeply nested, obscure object structures. Truto handles this by using documentation-driven tool generation. Rather than dumping raw endpoints to Claude, Truto parses specific query_schema and body_schema records to map these flat inputs into the nested arrays Semgrep actually requires.

Explicit Rate Limit Management A critical factual note on architecture: Truto does not automatically retry, throttle, or apply backoff logic when an API returns a 429 Too Many Requests. Instead, Truto acts as a transparent proxy. When Semgrep rate-limits a request, Truto passes that 429 directly back to the caller. However, Truto normalizes Semgrep's upstream rate limit information into standardized HTTP headers per the IETF spec (ratelimit-limit, ratelimit-remaining, ratelimit-reset). It is strictly the responsibility of your LLM orchestration layer (like LangGraph) or the MCP client to read the ratelimit-reset header, pause execution, and retry the function call.

Creating the Semgrep MCP Server

Truto derives MCP tools dynamically from the integration's internal resource definitions and human-readable documentation. If an endpoint does not have a documentation record defining its description and schema, it is intentionally excluded from the MCP server. This acts as a strict quality gate to prevent Claude from hallucinating payloads for undocumented endpoints.

Each generated MCP server is scoped to a single integrated Semgrep account. The resulting URL contains a cryptographic token authenticating the server without requiring further configuration.

You can create the MCP server in two ways.

Method 1: Via the Truto UI

If you prefer a visual interface, you can generate the MCP URL directly from your dashboard:

  1. Navigate to the integrated account page for your Semgrep connection in the Truto dashboard.
  2. Click the MCP Servers tab.
  3. Click Create MCP Server.
  4. Select your desired configuration (e.g., specify a name, allowed operations like read or write, and set an expiration date if needed).
  5. Copy the generated MCP server URL. This URL holds the hashed token used for authentication.

Method 2: Via the API

For teams embedding MCP generation into automated onboarding flows, you can create the server programmatically. Truto checks your account plan limits and validates that your requested configuration matches at least one available tool before provisioning the Cloudflare KV records and database entries.

const response = await fetch('https://api.truto.one/integrated-account/<semgrep_account_id>/mcp', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${TRUTO_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: "Semgrep SecOps Agent",
    config: {
      methods: ["read", "write", "custom"], // Filter operations
      tags: ["vulnerabilities", "policies"] // Scope to specific domains
    },
    expires_at: "2026-12-31T23:59:59Z" // Optional TTL for the server
  })
});
 
const mcpServer = await response.json();
console.log(mcpServer.url); 
// Returns: https://api.truto.one/mcp/a1b2c3d4e5f6...

Connecting the MCP Server to Claude

Once you have your Truto MCP URL, you need to register it with your LLM client so it can run the initialization handshake (initialize), list the tools (tools/list), and execute them (tools/call) using JSON-RPC 2.0.

Option A: Via the UI (Claude / ChatGPT)

If you are using enterprise AI chat interfaces that support native remote MCP connectors:

  • For Claude: Go to SettingsIntegrationsAdd MCP Server. Paste the Truto URL and click Add. Claude will immediately query the endpoints and populate the available tools.
  • For ChatGPT: Go to SettingsConnectorsAdd Custom Connector (requires Developer Mode enabled on Pro/Enterprise plans). Paste the Truto URL and label it (e.g., "Semgrep Tools").

Option B: Via Manual Config File (Claude Desktop)

For local development or testing with Claude Desktop, you modify your local configuration file. Because Truto provides a remote HTTP endpoint and Claude Desktop expects local execution commands, you utilize the official @modelcontextprotocol/server-sse bridge. This command-line utility wraps Truto's remote endpoint and pipes the Server-Sent Events (SSE) stream back into Claude's standard I/O.

Add this to your claude_desktop_config.json:

{
  "mcpServers": {
    "semgrep_production": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-sse",
        "https://api.truto.one/mcp/<your_truto_token>"
      ]
    }
  }
}

Restart Claude Desktop. The application will execute the npx command, connect to Truto, and pull the complete list of curated Semgrep operations.

Hero Tools for Semgrep

When Claude lists the tools available on the Truto MCP server, it receives dynamically generated definitions. Truto automatically builds snake_case names (e.g., list_all_semgrep_deployment_findings), injects explicit instructions for handling cursor-based pagination, and flattens query and body schemas into a single namespace.

Here are 6 high-leverage "hero" tools available out-of-the-box.

1. List Deployment Findings

Tool Name: list_all_semgrep_deployment_findings

This is the core visibility tool. It fetches vulnerabilities across code, supply chain, and AI-powered scans for a specific deployment. The response includes severity, confidence intervals, triaged status, and specific lines of code.

"Claude, pull the critical supply chain findings for our primary deployment slug. Filter for findings that have not been triaged and flag any that have a high confidence score."

2. Create AI Fix Job

Tool Name: create_a_semgrep_issue_fix_job

This powerful tool triggers Semgrep's AI workflow to analyze a specific SAST issue, generate a secure fix, and automatically open a pull request against the underlying repository.

"Review the SQL injection finding (ID: 88472) on the main branch. Trigger an automated AI fix job for this issue and report back with the task execution status."

3. Bulk Update Findings

Tool Name: semgrep_deployment_findings_bulk_update

Allows Claude to triage issues at scale. This tool accepts a payload matching finding filters and applies triage state updates (e.g., marking false positives or setting ignore rules) to all matching vulnerabilities in a single operation.

"I've reviewed the 15 low-severity hardcoded secret findings tied to the testing directory. Execute a bulk update to mark their triage state as 'ignored' and add the comment 'Test environment artifacts'."

4. Manage Detection Policies

Tool Name: semgrep_deployment_detection_policies_bulk_update

This tool applies a detection policy bundle to a product in the deployment. Crucially, the Truto schema explicitly defines the need for the If-Match header. Claude must first read the policy, extract the state_version, and pass it into this tool to enforce optimistic concurrency.

"Fetch the current detection policy for our deployment. Add the new rule for identifying insecure direct object references (IDOR) to the bundle, grab the state_version, and apply the update."

5. Generate SBOM Asynchronously

Tool Name: create_a_semgrep_deployment_sbom_async

Starts the background generation of a Software Bill of Materials (SBOM) for a deployment. Because this is a heavy task, the tool immediately returns a task_token_jwt rather than the finished document.

"Initiate an SBOM export for the production deployment. Return the task token JWT so we can monitor the build progress."

6. Poll Task Status

Tool Name: list_all_semgrep_tasks

Used in tandem with async tools like the SBOM export. Claude passes the task_token_jwt into this tool to check if the background task is queued, running, or complete.

"Take the task token from the previous step and check the status. If it's complete, output the final result. If it's still running, let me know to check back later."

(Note: This is just a curated selection of high-leverage endpoints. For the exhaustive list of supported Semgrep operations, schemas, and required parameters, review the Semgrep integration page.)

Workflows in Action

MCP tools become transformative when Claude chains them together to automate multi-step engineering tasks. Here are two concrete scenarios showing exactly how the LLM orchestrates Semgrep tools.

Scenario 1: Automated Triage and Remediation

User Prompt:

"Check our main deployment for any new, untriaged high-severity SAST findings. For each finding, trigger an automated fix job and output a summary of the PRs being generated."

Agent Execution Sequence:

  1. list_all_semgrep_deployment_findings: Claude queries the deployment, applying filters for severity: "HIGH" and triage_state: "unresolved".
  2. Analysis: Claude evaluates the resulting JSON array, isolating the internal id fields for the newly discovered vulnerabilities.
  3. create_a_semgrep_issue_fix_job: For each id, Claude calls the fix job tool, passing the deployment_id and issue_id. It captures the response confirming the AI engine has queued the PR generation.
  4. Result: Claude writes back a summary table listing the file paths, rule names, and confirmation that the fix workflows have been initiated.
sequenceDiagram
    participant User as User
    participant Agent as Claude (MCP Client)
    participant Proxy as Truto MCP Server
    participant Upstream as "Upstream API (Semgrep)"

    User->>Agent: "Find untriaged HIGH severity issues..."
    Agent->>Proxy: tools/call (list_all_semgrep_deployment_findings)
    Proxy->>Upstream: GET /api/v1/deployments/{id}/findings
    Upstream-->>Proxy: Returns finding JSON array
    Proxy-->>Agent: Returns normalized findings
    
    loop For each finding ID
        Agent->>Proxy: tools/call (create_a_semgrep_issue_fix_job)
        Proxy->>Upstream: POST /api/v1/deployments/{id}/findings/{issue_id}/fix
        Upstream-->>Proxy: 200 OK (Job Queued)
        Proxy-->>Agent: Returns job status
    end
    
    Agent-->>User: Outputs summary of queued PRs

Scenario 2: Synchronized SBOM Generation

User Prompt:

"We need an updated SBOM for compliance. Please trigger the generation for deployment ID 4452. Poll the status until it's finished, then give me the location of the final export."

Agent Execution Sequence:

  1. create_a_semgrep_deployment_sbom_async: Claude triggers the export by supplying the deployment_id.
  2. Token Extraction: Semgrep returns a 202 Accepted with a task_token_jwt. Claude parses this token.
  3. list_all_semgrep_tasks: Claude passes the JWT into the task polling tool. If the status reads RUNNING, Claude uses its internal system prompt logic to wait.
  4. Repeat Polling: Claude invokes the polling tool again. Once the status reads COMPLETED, it extracts the result object.
  5. Result: Claude informs the user that the SBOM is ready and provides the necessary download coordinates or metadata.

Security and Access Control

Connecting an autonomous agent to your core security scanning infrastructure requires rigid access constraints. Truto's MCP architecture enforces security at the token layer, meaning the underlying integration credentials are never exposed to the LLM.

When provisioning a Semgrep MCP server via Truto, you have four critical control levers:

  • Method Filtering (config.methods): Restrict the entire server to specific HTTP verbs. Setting methods: ["read"] ensures Claude can list findings and read policies, but explicitly blocks destructive create, update, or delete operations.
  • Tag Filtering (config.tags): Scope the server to specific operational domains. By specifying tags: ["policies"], Truto will filter out all user management and deployment tooling, strictly limiting the agent to policy administration endpoints.
  • Expiration (expires_at): Ideal for temporary auditing or contractor access. You can provide an ISO datetime string; once that time is reached, Truto automatically cleans up the Cloudflare KV entries and destroys the server via a Durable Object alarm.
  • Dual Authentication (require_api_token_auth): For enterprise environments where the MCP URL might be logged or visible, setting this flag to true forces the calling client to pass a valid Truto API session token as a secondary layer of authentication.

Wrapping Up

Giving AI models direct, unmediated access to sprawling enterprise platforms like Semgrep typically involves weeks of studying protobuf schemas, managing token infrastructure, and dealing with optimistic concurrency headers. By relying on dynamically generated MCP servers, you eliminate the entire integration maintenance lifecycle.

Truto derives the MCP tooling directly from Semgrep's API documentation, meaning as Semgrep evolves, your tools evolve automatically. You bypass the point-to-point code, normalize rate limit errors to the IETF standard, and ensure that Claude only executes actions against the curated endpoints you explicitly authorize.

FAQ

How do I handle Semgrep API rate limits with Claude?
Truto does not absorb or automatically retry rate limit errors. It passes HTTP 429s directly to Claude, normalizing the upstream rate limit data into standard IETF headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset). Your LLM client or agent orchestration layer is responsible for implementing retry and backoff logic.
Can I restrict the Semgrep MCP server to read-only access?
Yes. When generating the MCP server via Truto, you can pass a configuration object with specific method filters, such as methods: ["read"]. This ensures Claude can only perform GET and LIST operations, blocking destructive actions like deleting policies or closing findings.
How does Claude handle Semgrep's asynchronous SBOM exports?
When Claude triggers an asynchronous job like an SBOM export, Semgrep returns a 202 Accepted status with a task_token_jwt. Claude must then use the list_all_semgrep_tasks tool to poll the endpoint with that JWT until the job completes and returns the result.
Does Truto cache my Semgrep vulnerability data?
No. Truto operates as a real-time proxy API layer. Tool calls from Claude are executed directly against the native Semgrep REST API. Truto normalizes the schema and pagination but does not persist the underlying finding or vulnerability data in its own databases.

More from our Blog