Once AngusSecurity MCP is connected, you can ask for scan conclusions right in IDE chat: any highs on this check, how to fix a finding, whether the gate will block, whether a report is ready—look up highs and alerts, explain findings, compare two checks, read or download report snapshots; with matching permissions and write on, you can also scan the current repo, image, or artifact. What comes back is a redacted conclusion, not a full raw scan dump into the model.
Main practical scenarios:
Takeaway: Security MCP exposes up to sixteen tools—most query findings, alerts, CVEs, licenses, gates, and reports; with permissions and write on, you can also scan or create a report for a finished check. No suppress of false positives, no secret plaintext, no publish/share. Use a portal-issued user access token for this product.
Console and host wiring: Connect AngusSecurity with MCP in the references. “Which repo holds this coordinate / client setup” is AngusRepo MCP—eight tools, write always off. Here the answer is scan conclusions, CVEs, licenses, gates, and report snapshots. Unified engines and how reports export: replace scanner scripts; how to export scan reports.
Explicitly out of scope: suppress false positives, reveal secret plaintext, change alert status, edit policies, publish/share/delete reports, manage credentials and engines, upload a whole unnamed tree, export engine raw output.
| Contrast | AngusRepo MCP | AngusSecurity MCP |
|---|---|---|
| Surface | Eight read-only tools; cannot scan or create reports | Up to sixteen; with permissions, can scan + create reports |
| Answers | Which repo holds a coordinate, dependency/isolation snapshots, client templates | Findings, CVEs, licenses, gate simulation, report snapshots |
| Does not | Proxy protocol pull, trigger scans | Locate artifact repos, reveal secrets, suppress |
Chat only sees named tools; the server loops back in-process to the existing management API so permissions and audit stay one path.
IDE / Agent
--POST {gateway}/security/mcp--> Boot /mcp
--loopback Bearer--> /api/v1/** (named semantic tools)
A separate Node that re-wraps REST would duplicate policy. Loopback has no generic path parameter, so the model cannot invent the general upload gateway, reveal, or publish routes.
| Item | Stance |
|---|---|
| Transport | Stateless POST ; default/mcp ; via gateway{host}/security/mcp |
| Loopback | Local Security port (default 1811 ); Bearer forwarded as-is;X-Angus-Client-Source: mcp |
| Surface | Registers tools only; no resources / prompts / sampling |
| GM | No new GM resources; visibility follows existing @PPS |
| IDs | Job and finding ids are decimal strings —do not truncate or treat as floats |
| Setting | Effect |
|---|---|
angus.mcp.enabled (ANGUS_MCP_ENABLED ,true when unset) |
false → no endpoint; console / CLI / existing scans keep working |
angus.mcp.write-enabled (true when unset in current release) |
false → list dropssecurity_scan andsecurity_create_report ; queries and downloads do not use this switch |
Rate limit: at most 30 successful calls per account per minute; then rate_limited—wait briefly.
With write on and full related permissions, an analyst or admin should see exactly 16 on tools/list. Viewers see fewer—§4.
| Tool | Permission notes | What it does / easy mistakes |
|---|---|---|
security_scan |
ScanJobs:EXECUTE + write on |
kind :git /image /artifact /files ; one target type per call; returns a job id (jobId ) immediately—wait for the scan to finish before asking for issues or a report.git accepts https only;gitRef is what the user said or the current branch—never guess main . Private targets take a console-savedcredential name , never a token. Named checks go incapabilities ; if omitted, the server expands |
security_issues |
Findings:VIEW +ScanJobs:VIEW |
Grouped by capability; notScanned=true on a row means that check did not run; empty ≠ safe; secret snippets masked |
| Tool | Permission notes | What it does / easy mistakes |
|---|---|---|
security_list_findings |
Findings:VIEW |
At least one filter ( jobId /assetKey /keyword /ruleId , …); list hasno code snippets; empty ≠ safe |
security_explain_finding |
Findings:VIEW ; rule text also needsRulePacks:VIEW |
Rule meaning, remediation, masked snippets; cannot reveal; about five ids per call max |
security_list_jobs |
ScanJobs:VIEW |
For repo/image/artifact use assetKeyword —do not put the URL inkeyword ; do not treat counts as clean unless status isCOMPLETED /PARTIAL |
security_list_alerts |
Alerts:VIEW |
Read alerts only; no status change or assign |
Pagination starts at 1; at most 20 per page.
| Tool | Permission notes | What it does / easy mistakes |
|---|---|---|
security_compare_jobs |
ScanJobs:VIEW |
Fingerprint diff of two completed jobs (added/gone/still there); no new job |
security_lookup_vulnerability |
RulePacks:VIEW |
Local vuln DB; if missing, say the record is absent—do not rewrite as “no vulnerability” |
security_license_summary |
Findings:VIEW |
Visible license rollup for the account; cannot bind a job—usesecurity_issues for one job |
security_risk_summary |
Dashboard:VIEW |
Risk score and posture summary; not the overview’s large lists |
security_simulate_gate |
Policies:VIEW |
Read-only simulation; optional lookbackJobs (max 100); usually hidden from viewer and developer |
| Tool | Permission notes | What it does / easy mistakes |
|---|---|---|
security_report_summary |
Reports:VIEW |
Existing reports; if none READY, say not generated yet; no verify URL or share password |
security_get_report |
Reports:VIEW |
Scope, status, metrics by id; no verify/share password/spec body |
security_compare_reports |
Reports:VIEW |
Compare two report summaries and finding fingerprints |
security_download_report |
Reports:EXECUTE |
Only when the report is ready ( READY );format :JSON /HTML /CSV /PDF /SARIF ; text capped ~64 KB thentruncated ; PDF/archives return filename, bytes, and console path only |
security_create_report |
Reports:EXECUTE + write on |
Finished jobs only; mainly jobId (+ optional name/format); create starts as generating (PENDING )—wait until ready before download , pollsecurity_get_report untilREADY or failure; no publish, share, or open password |
Explicitly not in the list: suppress, reveal, publish, share, delete reports, edit policies, upload a whole unnamed tree, export engine raw output.
A report is a snapshot at generation time and does not rewrite when the next scan finishes—same stance as “how to export scan reports” in the references.
| Role | Write on | Write off |
|---|---|---|
Viewer ( SEC_VIEWER ) |
12 : hassecurity_issues ; no scan, no gate simulate, no report download/create |
Same (12) |
Developer ( SEC_DEVELOPER ) |
13 : viewer +security_scan |
12 |
Analyst / admin ( SEC_ANALYST /SEC_ADMIN ) |
16 | 14 (no scan, no create report) |
If the account lacks permission, the tool does not appear; calling it by name yields permission_denied. MCP does not grant extra access. Try the same action in the console with the same account before blaming MCP.
| Credential | Result |
|---|---|
| Portal-issued user access token (PAT) | Can enter; tool set narrows by role and write switch |
repod_ or tokens from other products (e.g. AngusRepo) |
401 , no tool list |
| OAuth refresh token | 401 |
| No Bearer | 401 (avoid turning auth failure into an in-tool error the model retries blindly) |
Visibility matches what that user sees on /api/v1, same as the console. Personal tokens: avatar → Me (/profile). Use a service account for CI; do not commit a personal session into a repository.
Keep the token in an environment variable; do not commit it:
{
"mcpServers": {
"angus-security": {
"url": "https://<gateway-host>/security/mcp",
"headers": { "Authorization": "Bearer ${ANGUS_SECURITY_TOKEN}" }
}
}
}
Public shape is gateway {host}/security/mcp. A direct private process uses https://<security-host>/mcp (default port 1811; behind a reverse proxy you need not expose that port publicly). Copy the URL from System → MCP in the console.
| Host | Config file (follow each host’s docs) |
|---|---|
| Cursor | Project .cursor/mcp.json or user~/.cursor/mcp.json |
| Claude | claude_desktop_config.json |
| VS Code | Workspace .vscode/mcp.json |
| Codex / Qoder | See that host’s MCP docs |
Stdio-only hosts forward with @anguskit/mcp --product security (reads ANGUS_TOKEN / ANGUS_BASE_URL, not the same names as ANGUS_SECURITY_TOKEN):
{
"mcpServers": {
"angus-security": {
"command": "npx",
"args": ["-y", "@anguskit/mcp", "--product", "security"],
"env": {
"ANGUS_BASE_URL": "https://<gateway-host>",
"ANGUS_TOKEN": "${ANGUS_SECURITY_TOKEN}"
}
}
}
}
ANGUS_BASE_URL is the gateway origin without /security/mcp. Without a product prefix in private deploy, use --endpoint + https://<security-host>/mcp. If the default npm registry lacks the package, the docs suggest https://repo.anguskit.com/npm/npm-public/. Full host table: MCP docs in the references.
Example A: scan, then ask for issues
| Step | Content |
|---|---|
| User asks | Scan this repo for code security and secrets. |
| Should call | security_scan (kind=git , httpsgitUrl ,gitRef =user/current branch, optionalcapabilities ) → latersecurity_issues /security_list_jobs |
| Expected fields | Immediate job id ( jobId , decimal string);after the scan finishes , grouped results; secret snippets masked |
| Must not appear | Guessing main , pasting a PAT in chat, submitting SSHgit@ without converting to https |
Example B: explain an existing finding
| Step | Content |
|---|---|
| User asks | Explain this finding and how to fix it. |
| Should call | security_list_findings (with filters) for the fullid , thensecurity_explain_finding |
| Expected fields | Rule meaning, remediation / fixed version, path/line, maskedsnippet |
| Must not appear | Secret plaintext, suppress/approval, presenting the model’s own patch as the scanner’s conclusion |
Example C: gate and report
| Step | Content |
|---|---|
| User asks | Will this policy block us? Create an HTML report for this finished job. |
| Should call | security_simulate_gate (needsPolicies:VIEW ) → with write on andReports:EXECUTE ,security_create_report → pollsecurity_get_report |
| Expected fields | Simulation creates no new scan; create starts as generating; download only after ready (text may includetruncated ) |
| Must not appear | Viewer/developer forcing gate or create report; treating “generating” as done; publish/share |
After connect, also tools/list against the role table, then smoke-test security_explain_finding on a finding that already exists in the console.
| Shape | Example | vs AngusSecurity (one line) |
|---|---|---|
| Local stdio scan of the workspace | Snyk CLI MCP | Server pulls repo/image/artifact; named files use capped upload |
| Platform search + mutable state | SonarQube MCP | Adopts search and gate simulation; does not change finding status or mount the workspace |
| Artifact intelligence MCP | Sonatype Guide / JFrog Xray | Coordinate ownership is Repo MCP; here: scan conclusions and gates |
| In-process semantic tools | AngusSecurity | Loopback to this process’s REST; suppress/reveal/publish stay off the tool surface |
Comparison explains product trade-offs, not a buying rank. Details follow each vendor’s docs of the day.
Three common failures after connect: the wrong product’s token won’t get in, an empty finding list rewritten as “safe,” and asking for report body while the scan or report is still running—see the table and FAQ below.
| Symptom | Cause | What to do |
|---|---|---|
| Cannot connect | enabled=false / wrong URL / console-host/mcp blocked by site proxy |
Flip the switch; verify gateway /security/mcp ; host mustPOST |
| 401 | Other-product token or repod_ / no Bearer / expired token |
Re-issue a PAT from Me ; refresh the host MCP |
| Few tools / fewer than a coworker | Missing role permissions or write off | Check §4; viewer has no scan; developer has no gate simulate or report download/create |
permission_denied |
Call outside the list or console also denies | Verify the same account in the console; MCP does not widen rights |
| Assistant says it cannot scan this repo | No ScanJobs:EXECUTE , write off, missinggitRef , private repo without credential name |
Enable write; pass https + branch; name the console credential |
| Want to suppress a FP | No matching tool | Dispose in the console (avoids the model turning “accept risk” into an auto-approved suppress) |
| Cannot read secret plaintext | By design | Reveal only in the console |
New report still generating ( PENDING ) |
Report generation is async | Poll security_get_report until ready (READY ) or failure—do not read the body right after create |
| “Downloaded” PDF has no body | Binary stays out of chat | Use filename + consolePath and fetch in the console |
rate_limited |
Over 30 calls/minute | Wait; merge questions |
| Empty finding list | Not scanned, unfinished, or filters missed | Say not scanned / unfinished—do not rewrite as safe |
-32020 |
Custom Mcp-Method /Mcp-Name headers disagree with the JSON body |
Drop the custom headers, or keep them consistent with that request |
No. Explain and alerts keep masks; suppress, reveal, and approval stay in the console. One reason: some suppress scopes auto-approve—if the model frames “accept risk” as a fix, it would write an effective suppress.
Queries need Reports:VIEW. Downloads need Reports:EXECUTE and do not use the write switch. What the write switch removes is security_scan and security_create_report.
CLI and pipelines remain the main path for batch runs and gates; MCP brings the same jobs and findings into IDE chat. Unified engines: replace scanner scripts in the references.
Named tools keep the loopback whitelist small, avoid exposing the whole admin API to the model, and make projection redaction easier.
repod_ connect?
MCP uses this portal’s user access token with the same rights as the console. Treating automation or cross-product tokens as chat identity widens the surface—401 before auth proceeds.
security_license_summary answer “this job”?
It rolls up licenses visible to the account and cannot bind a jobId. For one job’s license issues, use security_issues.
No. Also distinguish: job unfinished, a capability with notScanned=true, and filters that missed. None of those mean the target is safe.
/security/mcp + PAT;