MCP Integration¶
Sovereign GRC ships a standalone Model Context Protocol (MCP) server, @defendflow/grc-mcp, that exposes your compliance posture to LLM agents. With it, a model in Claude Desktop (or any MCP-capable client) can read your frameworks, controls, assessments, findings, evidence, testing schedule, vendors and policies — and perform a few clearly-marked mutating actions — by talking to the real API over HTTPS with a customer-managed API key.
The server source lives in the repo at services/grc-mcp/.
How it talks to the API¶
The MCP server is a thin, read-mostly wrapper over the same REST API documented elsewhere in this guide. It authenticates with an API key on the standard header:
There is no X-API-Key header, and API-key requests are exempt from CSRF. The key is scoped (see Integrations and API Keys); a tool only works on endpoints the key's scopes cover. Backend 401/403 responses are surfaced as structured MCP errors rather than masked, so a "not a member of this organization" error is the RBAC layer, not a client bug.
Build¶
This produces dist/index.js, the executable the MCP client launches.
Environment variables¶
The server is configured entirely through env vars:
| Variable | Required | Default | Notes |
|---|---|---|---|
GRC_API_KEY |
yes | — | A DefendFlow API key (sk-...). |
GRC_ORG_ID |
yes | — | Organization UUID (e.g. 00000000-0000-0000-0000-000000000001). |
GRC_BASE_URL |
no | https://demo.defendflow.xyz |
API origin, no trailing slash. |
GRC_TIMEOUT_MS |
no | 30000 |
Per-request timeout in milliseconds. |
If GRC_API_KEY or GRC_ORG_ID is missing, the server prints a clear error to stderr and exits non-zero before connecting.
Getting an API key¶
- Sign in to the GRC app (the demo accepts
demo/demo). - Create a scoped key from the API Keys page, or via the API (the key is shown once):
# Log in (form-data) to get a session token + CSRF cookie
curl -s -c cookies.txt -X POST \
https://demo.defendflow.xyz/api/v1/auth/login \
-F username=demo -F password=demo
# Create the key (state-changing -> needs the CSRF double-submit token)
CSRF=$(grep csrf_token cookies.txt | awk '{print $7}')
curl -s -b cookies.txt -X POST \
"https://demo.defendflow.xyz/api/v1/orgs/<ORG_ID>/api-keys" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "X-CSRF-Token: $CSRF" -H "Content-Type: application/json" \
-d '{"name":"grc-mcp","scopes":["read:*","write:assessments"]}'
# -> response includes "key":"sk-..." (store it; it is not retrievable again)
A read-only read:* key is enough to drive every read tool below. Add write:assessments (and write:evidence) only if you want the model to be able to create assessments, update findings, or request evidence upload URLs.
Claude Desktop configuration¶
Add the server to your claude_desktop_config.json (a copy lives at services/grc-mcp/example-claude-desktop-config.json):
{
"mcpServers": {
"defendflow-grc": {
"command": "node",
"args": ["/absolute/path/to/sovereign-grc/services/grc-mcp/dist/index.js"],
"env": {
"GRC_BASE_URL": "https://demo.defendflow.xyz",
"GRC_API_KEY": "<your sk- api key>",
"GRC_ORG_ID": "00000000-0000-0000-0000-000000000001"
}
}
}
}
Use the absolute path to dist/index.js. Restart Claude Desktop after editing the config; the defendflow-grc tools should then appear in the client.
Tools¶
The server registers 15 tools over stdio. Read tools are advertised with readOnlyHint: true and mutating tools with readOnlyHint: false, so MCP clients can gate them.
Read (safe / idempotent)¶
| Tool | What it does |
|---|---|
list_frameworks |
List all compliance frameworks in the catalog. |
get_framework_controls |
List controls of a framework (optional category filter). |
list_assessments |
List org assessments (framework/status filters, paging). |
get_assessment |
Get one assessment by ID. |
list_findings |
List findings (assessment/control/status/severity filters). |
get_findings_summary |
Aggregate finding counts for the org (optional assessment). |
list_evidence |
List evidence artifacts (assessment/control filters, paging). |
get_evidence_metadata |
Get metadata for one evidence object by object key. |
list_controls_due_and_overdue |
Upcoming + overdue control tests. |
list_control_schedules |
Configured control-testing cadences. |
list_vendors |
List third-party vendors (tier/status filters, paging). |
list_policies |
List policies (status/owner/review_overdue filters, paging). |
Write (mutating — clearly marked)¶
| Tool | What it does |
|---|---|
create_assessment |
Mutating. Create a new assessment against a framework. |
update_finding |
Mutating. Update a finding's status/disposition/notes. |
request_evidence_upload_url |
Mutating. Get a presigned evidence upload URL (does not upload the file — pair with the Integrations PUT + link flow to complete it). |
Example prompts¶
Once the server is wired in, you can ask the model things like:
- "Using the DefendFlow tools, which control tests are past due or coming up in the next two weeks? Group them by framework and flag anything overdue."
- "List our open SOC 2 findings by severity, summarize the critical ones, and tell me which controls they map to."
- "List the frameworks we track, then pull the controls for ISO 27001 and tell me how many we have evidence linked for."
Because the read tools are idempotent and scoped, these are safe to run against production with a read:* key. Mutating prompts (e.g. "create a PCI DSS assessment") require the corresponding write:* scope and will surface a clear scope error otherwise.
Troubleshooting¶
- Server exits immediately —
GRC_API_KEYorGRC_ORG_IDis unset; check stderr. 403 missing required scope— the key lacks the scope for that tool; re-scope it on the API Keys page.403 not a member of this organization— the key resolves to a user without membership forGRC_ORG_ID; this is the backend RBAC layer.- Tools don't appear in Claude Desktop — confirm the
argspath is absolute and points at the builtdist/index.js, then restart the client.