GCA · INTEGRATIONS

    AI Coding Assistant Integration

    How Gadriel Code plugs into AI coding assistants so vulnerable code never lands.

    AI-Coding-Assistant Integration

    How Gadriel Code plugs into AI coding assistants so that vulnerable code never enters git history. This page covers the MCP server and its tool surface, the agentic find→fix→re-validate loop, multi-platform support, and autonomous remediation campaigns.

    Related: Tiered analysis model · Privacy boundary


    1. The model: shift-left to the moment of generation

    Every existing scanner (Snyk, Semgrep, SonarQube) runs after code lands:

    agent writes vulnerable code → commit → batch scan → developer reads report
    → developer types "fix this" → agent rewrites → wait for rescan → repeat
    

    The vulnerability entered git history at step 1 and the developer is a relay.

    Gadriel removes the relay:

    agent writes code → Gadriel validates on save (graph already built)
    → finding surfaced into the agent's live context → agent rewrites
    → Gadriel re-validates and clears the finding
    → every step appended to .security/audit-log.jsonl
    

    The vulnerability never reaches git; the audit log is direct compliance evidence and stays local only (see privacy.md).


    2. The MCP server

    Gadriel ships as an MCP server — JSON-RPC 2.0 over stdio. It is the primary integration surface; any MCP-aware assistant can call its tools during code generation. It runs in-process with the graph engine, so there is no IPC overhead and no network egress.

    Start it:

    gadriel code mcp

    The server speaks the three MCP protocol methods (initialize, tools/list, tools/call) plus direct tool invocation. serverInfo.name is gadriel; the advertised protocolVersion is 2024-11-05. stdio transport is unauthenticated by design (the auth-token field is reserved for a future HTTP/SSE transport).

    Fallback floor. Any assistant that cannot speak MCP can poll .security/findings-current.json (written by gadriel watch). Both mechanisms emit the same finding format.

    2.1 Tool surface

    The registry wires 8 tools (verified in crates/code-security/gadriel-mcp/src/server.rs and crates/code-security/gadriel-mcp/src/tools/):

    ToolPurpose
    validate_bufferScan an unsaved code buffer (SAST + Secrets) and return findings.
    validate_fileScan a saved file on disk (SAST + Secrets) and return findings.
    findings_for_pathRead .security/findings.json and return findings filtered by path.
    fix_findingInvoke the per-pillar reasoning runner for a finding.
    dismiss_false_positiveMark a finding as a false positive (writes an audit-log event).
    submit_ai_findingsSubmit host-agent AI findings for fusion with a prior scan session's deterministic results.
    start_remediation_campaignStart a repo-scale remediation campaign over filtered findings.
    campaign_advanceAdvance a campaign: propose the next fix, or finalize an applied one.

    The MCP server never writes files. fix_finding and campaign_advance return a diff + rationale; the host agent applies every edit and self-reports applied: true. No auto-commit, no auto-git add, ever. A buggy or malicious diff can never be silently committed by Gadriel.

    2.2 The core round-trip

    validate_file / validate_buffer return:

    { "findings": [ ... ], "count": 3, "tier2_request": null }

    fix_finding (params { finding_id, repo_root? }) returns a FixProposal envelope:

    { "status": "...", "runner_id": "...", "finding_id": "CODE-W1-AI-001",
    "diff": "...", "rationale": "...", "iterations_used": 1, "tool_calls": [] }

    The tier2_request field is null unless Tier 2 is explicitly enabled — see §2.4 and tiers.md.


    3. The agentic loop

    The loop the host agent runs during a coding session:

    ┌─────────────────────────────────────────────────────────────┐
    │  assistant generates / edits code                            │
    │        │                                                     │
    │        ▼                                                     │
    │  validate_buffer  (before save — code never lands)          │
    │        │  findings?                                          │
    │        ├── none ──▶ save file ──▶ validate_file (confirm)   │
    │        │                                                     │
    │        └── findings ──▶ fix_finding ──▶ assistant applies   │
    │                              │            the returned diff  │
    │                              ▼                               │
    │                        re-validate ──▶ finding cleared?     │
    │                              │                              │
    │                              └── audit-log.jsonl (local)    │
    └─────────────────────────────────────────────────────────────┘
    

    Because validate_buffer runs on the unsaved buffer, the assistant can correct a vulnerability before the file is written — so vulnerable code never enters the working tree, let alone git. dismiss_false_positive closes the loop for findings the developer judges to be false positives, writing an audit event (and updating the Bayesian model).


    4. Multi-platform support

    Claude Code is the native reference platform — it keeps its dedicated scaffolder in init.rs (full parity: local stdio MCP, real-time hooks, CLAUDE.md rules, skills + commands + subagents). Every other assistant is driven by a data-driven registry (crates/gadriel-cli/src/commands/code/platform/registry.rs).

    4.1 Wiring it up: gadriel code init

    gadriel code init scaffolds the integration. For Claude Code it merges an .mcp.json stanza (deep-merge, never clobbering sibling tools):

    {
    "mcpServers": {
    "gadriel": { "command": "gadriel", "args": ["code", "mcp"] }
    },
    "enabledMcpjsonServers": ["gadriel"]
    }

    For other platforms, init writes the platform-appropriate MCP config, hook config, rules/skills, and slash-command files, using the absolute path to the running gadriel binary (GUI assistants do not inherit the shell PATH). Target platforms may be listed explicitly, auto-detected from marker directories (e.g. .cursor/, .windsurf/, .vscode/, .codex/), or set via [init] platforms in .gadriel.toml.

    4.2 Parity report: gadriel code doctor --platform <name>

    Prints the integration parity manifest — MCP/hooks/rules support and version gates — for one platform:

    gadriel code doctor --platform cursor

    Valid --platform values (run gadriel code doctor --help for the current list):

    claude-code · cursor · windsurf · copilot · codex · jetbrains · claude-desktop · chatgpt · ai-studio

    Platforms fall into three integration classes:

    ClassMeaningExample
    ARepo-editing IDE agent — full tier stackCursor, Windsurf, Copilot/VS Code, Codex, JetBrains
    BLocal desktop chat with stdio MCP — MCP-tools onlyClaude Desktop
    CHosted cloud chat — CI-gate + static report only (no local stdio, no repo FS)ChatGPT, AI Studio

    Per-platform parity notes surfaced by doctor (from the registry):

    PlatformMCP config pathReal-time hooksNotes
    Claude Code.mcp.json (project).claude/settings.jsonfull parity — reference platform
    Cursor.cursor/mcp.json (project).cursor/hooks.jsonnear-full parity
    Windsurf (Cascade).codeium/windsurf/mcp_config.json (global)✓ (blocks, no auto-retry)MCP global-scope; 12 KB rules cap
    Copilot / VS Code.vscode/mcp.json (project)Preview (agent edits)save-scan needs the gadriel-vscode extension
    OpenAI Codex CLI.codex/config.toml (project)apply_patch hook needs Codex CLI ≥ v0.117; no slash commands; 32 KB cap
    JetBrainsprint-and-paste (no CLI-writable MCP)block/squiggle/statusline need the JetBrains plugin
    Claude Desktopclaude_desktop_config.json (global)macOS/Windows only; MCP-tools tier
    ChatGPT / AI StudioCI-gate + static report only

    The CI gate and audit log are platform-agnostic — they work identically regardless of which assistant (or none) is connected.


    5. Autonomous remediation campaigns

    A single fix_finding call fixes one finding. To fix a whole class at repo-scale ("fix all 40 confirmed SQLi findings") without the host agent hand-rolling a 40× loop, Gadriel exposes a stateful two-tool pair.

    5.1 start_remediation_campaign

    Params: a filter (severity[] / pillar[] / scan_type[] / rule_id[] / confidence_tier[]) plus an optional finding-ID allowlist, repo_root, and optional runner_id. It loads findings.json, orders the worklist, persists campaign state to .security/campaigns/<campaign_id>.json, and returns { campaign_id, total, first_batch }.

    Ordering: primary sort by effective_risk(severity, confidence) descending; tiebreak by presence of a materialized attack path, then by ascending path length; findings sharing a file stay adjacent.

    5.2 campaign_advance

    The fix → verify → next loop the host agent calls repeatedly ({ campaign_id, repo_root, applied?, after_hash? }):

    1. First call — reads the next pending item, calls the existing fix_finding propose logic, and returns a diff + rationale.
    2. Host applies the diff, then calls again with applied: true.
    3. Second call — runs verification and updates state, returning the next item or { status: "campaign_complete", summary }.

    Per-item terminal states: fixed, verified, verified_partial, regressed, waived, skipped_no_agent.

    Verification: an instant re-scan via validate_file on the touched file. This is accurate/instant only for Python-SAST + Secrets; for SCA/Container/API or non-Python SAST the item is marked verified_partial (and the summary says so explicitly — no overclaiming).

    Failure handling, all mechanized versions of what a human does:

    • Regression / new finding introducedregressed, never waived, never dropped, surfaced prominently in the summary.
    • Agent unavailable (only Security and Safety pillar agents are authored today; the other 6 fail closed) → skipped_no_agent, continue.
    • Runner can't fix / host declines → mechanized durable waiver in .gadriel-waivers.toml with an auto-populated reason.

    The same discipline holds throughout: campaign_advance never writes files; the host agent applies every diff. The optional per-fix Tier-2 second-opinion gate inherits the never-gate invariant — a negative opinion flags and demotes, it never hard-fails the campaign or auto-reverts (this gate is not yet wired).