Skip to content

Use MCP for AI-assisted vulnerability triage

Connect your own MCP-capable AI agent to Craftifact vulnerability findings. You control autonomy across three levels: recommendations, reviewable drafts, or deliberate direct-write mode.

Quick path

  1. Use a Pro or Team instance where the MCP interface is enabled.
  2. Create an API token or robot token with the narrow repository permissions your agent needs.
  3. Decide which repository or exact subjects the agent should inspect before the first run; all-repository triage may be rejected.
  4. Add the Craftifact MCP endpoint to an agent or MCP client that supports remote MCP over HTTP, such as Codex or Claude Code.
  5. Start with recommend_only; move to draft_proposals only after you trust the workflow.
  6. Enable direct_write only for deliberately approved workflows and review the resulting suppressions regularly.

What the interface does

Craftifact exposes an MCP endpoint at INSTANCE_URL/mcp. It is an interface for your own AI agent; Craftifact does not run an AI model for you and does not perform triage automatically. The agent authenticates with the access token you provide, sees only repositories allowed by that scope, and can use tools for vulnerability queues, suppressions, and triage proposals. The main advantage of this design is that the agent can combine Craftifact findings with context from the workstation where it runs, such as local source code, build files, or the current branch. That lets it judge more accurately which vulnerabilities matter in your actual repository and which likely do not; an artifact repository alone cannot make that comparison.

Modes

Use the mode query parameter to control autonomy across three levels:

  • recommend_only: read queues, prompts, and redundancy checks. This is the default and most conservative mode.
  • draft_proposals: also lets the agent create draft triage proposals that a human can review.
  • direct_write: also lets the agent create vulnerability suppressions directly when the token has the required permission.

For most teams, draft_proposals is the best working mode. It keeps the output reviewable without limiting the agent to read-only recommendations. direct_write fits clearly bounded workflows when you review the resulting suppressions regularly in Findings -> Suppressions.

Direct-write suppressions

Use the direct-write endpoint form only for deliberately approved workflows:

direct_write MCP endpoint
https://packages.example.com/mcp?mode=direct_write

Run the first session interactively. Non-interactive MCP hosts may cancel tool calls before you can approve the repository reads or writes, so validate the queue, token scope, and approval prompts before automating the workflow.

In direct_write, the agent must call check_vulnerability_suppression before create_vulnerability_suppression with the exact intended findings and scope. Each suppression creation needs:

  • scope_kind: one of the supported suppression scopes, such as repository, artifact, or oci_repo.
  • scope_key: the concrete scope identifier. Repository scope uses repository:<name>. Artifact scope uses artifact:<uuid> or an OCI digest scope.
  • expires_at: an ISO 8601 datetime in the future.
  • justification: a concise stored reason, limited to 256 characters.

Keep longer rationale, advisory notes, and local-code evidence in the agent’s final report. For OCI artifact suppressions, use oci_digest:sha256:<digest> as the canonical scope key. Agents may also send raw sha256:<digest> for scope_kind="artifact"; Craftifact normalizes it to oci_digest:sha256:<digest>.

OCI subject names are not always available. When a work item has no subject name, use the returned digest, subject.oci_locations, or subject.display_label, for example OCI digest sha256:..., as the stable identifier in prompts, reports, and suppression review notes.

For exact vulnerability triage on a subject, call the work-item tool with repository plus one of artifact_id or oci_digest. For OCI tags shown in the UI, resolve the tag to its digest first, then pass that digest as oci_digest. The q parameter searches finding, package, and scanner-target text; it is not the preferred way to select an OCI image tag or version.

Token requirements

Create an API token or robot token for the repositories the agent may inspect. For personal triage sessions, a narrowly scoped API token is often a good fit. For shared or repeatable automation, a dedicated robot token can be cleaner. Regardless of token type, the agent acts on behalf of the person running the session, and that person remains responsible for the decision. For read-only triage, grant repository read access plus findings read access. For draft proposals or direct suppressions, grant the findings suppression permission only on repositories where the agent is allowed to prepare or apply that action.

Avoid unnecessarily broad scopes. If a token is intended for one repository or one incident, keep the scope that narrow and rotate it when the session is done.

Set up a remote MCP client

Any agent or MCP client that supports remote MCP over HTTP with configurable headers can use the Craftifact endpoint. Pass the access token through an environment variable or secret store, not through committed files.

Example: Codex

Add the MCP server to your Codex config:

~/.codex/config.toml
[mcp_servers.craftifact-vulnerability-triage]
url = "https://packages.example.com/mcp?mode=recommend_only"
bearer_token_env_var = "CRAFTIFACT_MCP_TOKEN"

Replace INSTANCE_HOST with the domain where your Craftifact instance is reachable. For example, if you open Craftifact at https://craftifact.example.com/, use craftifact.example.com in the snippets.

Then start Codex from the source checkout you want the agent to inspect:

Codex first run (Bash)
read -rsp "Craftifact MCP token: " CRAFTIFACT_MCP_TOKEN
printf "\n"
export CRAFTIFACT_MCP_TOKEN
codex --no-alt-screen -s workspace-write -a on-request

This keeps the token out of shell history and out of the Codex config file. If you already keep the token in a secret manager or environment variable, set CRAFTIFACT_MCP_TOKEN from that source instead, without printing the value.

For the first run, prefer interactive Codex so you can approve MCP tool calls and see which repositories the agent reads. Non-interactive Codex runs need MCP tool calls to be allowed up front; otherwise the host may cancel the calls before the agent can read the queue. For proposal review, change the URL to ?mode=draft_proposals. For direct suppressions, change the URL to ?mode=direct_write only after the workflow and token scope have been approved. Keep repository names and expected boundaries in AGENTS.md so the agent knows which findings to inspect and when to stop for human review.

Give the agent an explicit triage task, not only a queue listing task:

Triage prompt
Use the Craftifact vulnerability triage MCP in recommend_only mode.
Scope the work to these repositories or exact subjects: REPOSITORY_OR_SUBJECT_NAMES.
For OCI image subjects, resolve the tag to a digest first, then call the work-item tool with repository and oci_digest.
List open unsuppressed findings for those targets only.
For each high or important finding, open the advisory URL, inspect local source and build files for reachable use of the affected package or feature, and explain whether the finding is applicable.
Cite finding IDs, packages, versions, repository or subject, priority, severity, advisory evidence, and local evidence.
Recommend remediation first, or the narrowest safe suppression scope when remediation is not the right immediate action.
Do not create suppressions unless the MCP server is in direct_write mode and the evidence clearly supports the decision.
In direct_write mode, first call check_vulnerability_suppression with the exact intended scope. Keep stored justification under 256 characters and put longer rationale in the final report.

Example: Claude Code

Add the same remote MCP endpoint to your Claude Code project or user settings. Use recommend_only first, then draft_proposals after you have checked the prompt and token scope.

.claude/settings.json
{
  "mcpServers": {
    "craftifact-vulnerability-triage": {
      "url": "https://packages.example.com/mcp?mode=recommend_only",
      "headers": {
        "Authorization": "Bearer ${CRAFTIFACT_MCP_TOKEN}"
      }
    }
  }
}

Claude Code supports headers on remote MCP servers; the example above uses that path directly. If you are using a different client without configurable headers, use the mcp-remote fallback below and provide the authorization header there.

mcp-remote fallback

Use mcp-remote when your agent expects a local stdio MCP server or when your chosen client does not offer configurable HTTP headers for remote MCP.

mcp-remote
npx mcp-remote https://packages.example.com/mcp?mode=recommend_only \
  --header "Authorization: Bearer ${CRAFTIFACT_MCP_TOKEN}"

Pin the mcp-remote version in shared automation if reproducibility matters. Do not let the fallback command fetch packages directly from public registries in environments where package installs must go through Craftifact proxies.

Safe use

Treat agent triage as decision support. Ask it to cite the finding IDs, affected packages, target environments, priority signals, and the suppression scope it proposes. Also require evidence from the advisory and from local code or build files before accepting a suppression recommendation. Good suppressions explain why the affected code path is unreachable or irrelevant for the concrete artifact, not merely that a scanner reported a low probability issue. Before accepting a proposal or using direct_write, verify that the scope is no broader than needed and that the justification explains the current risk decision.

For recurring findings, prefer draft proposals with explicit expiry dates. If you enable direct_write for a tightly scoped incident or a well-understood routine workflow, use short expiry windows and review the suppression ledger afterwards in Findings -> Suppressions. Call check_vulnerability_suppression before each direct suppression and keep justification within the 256-character storage limit. Put fuller reasoning in the report, not in the stored suppression field.

Troubleshooting

If an all-repository queue request is rejected, ask the agent to provide repository or use a sufficiently specific q query. Craftifact may require narrower MCP queries so an agent does not read more findings than it needs for the current triage task. If the UI shows an OCI tag such as namespace:tag, resolve it to a digest and call the work-item tool with repository and oci_digest; do not rely on q to match the tag. If an OCI subject has no name, use the returned digest, subject.oci_locations, or subject.display_label as the stable identifier.