Documentation Index
Fetch the complete documentation index at: https://docs.igrisecurity.com/llms.txt
Use this file to discover all available pages before exploring further.
Configuration
The Igris Scanner supports extensive configuration for scanner behavior, rule management, and suppression of known false positives.
Scanner Configuration (.igrisrc)
Place an .igrisrc file in your project root. The CLI searches the current directory and all ancestors.
{
"severity": "medium",
"format": "table",
"fail-on": "high",
"verbose": false,
"color": true,
"timeout": 30000,
"rules": {
"disabled": ["AG-VER-004", "AG-AUDIT-002"],
"config": {}
},
"suppressions": [],
"plugins": []
}
Options
| Field | Type | Default | Description |
|---|
severity | string | "low" | Minimum severity to report |
format | string | "table" | Output format: table, json, sarif |
fail-on | string | "high" | Exit 1 if findings at this level or above |
verbose | boolean | false | Show full finding details and remediation |
color | boolean | true | Enable ANSI colored output |
timeout | number | 30000 | Per-detector timeout in milliseconds |
rules.disabled | string[] | [] | Rule IDs to skip entirely |
rules.config | object | {} | Per-rule configuration overrides |
suppressions | array | [] | Active suppression rules |
plugins | string[] | [] | Paths to custom detector plugins |
Suppressions
Suppressions mark findings as acknowledged without fixing them. Suppressed findings still appear in results but are flagged as suppressed: true and don’t affect the exit code.
{
"suppressions": [
{
"rule": "AG-CRD-002",
"serverName": "dev-server",
"reason": "Test credential — not used in production",
"expires": "2026-12-31"
},
{
"rule": "AG-VER-004",
"reason": "Semver ranges acceptable for dev dependencies"
}
]
}
Suppression Fields
| Field | Required | Description |
|---|
rule | Yes | Rule ID to suppress (e.g., AG-CRD-002) |
serverName | No | Only suppress for this specific server |
reason | Yes | Why this finding is suppressed (for audit trail) |
expires | No | ISO 8601 date — suppression auto-expires after this date |
Disabling Rules
To permanently skip certain rules, add their IDs to the disabled list:
{
"rules": {
"disabled": [
"AG-VER-004",
"AG-AUDIT-002",
"AG-AUDIT-004"
]
}
}
You can also use the --disable CLI flag:
igris scan --disable AG-VER-004,AG-AUDIT-002
Rule IDs support prefix matching — AG-CRD disables all credential scanner rules.
The scanner parses and normalizes configs from all major MCP clients:
| Format | Example File | Key Differences |
|---|
| Claude Desktop | claude_desktop_config.json | { mcpServers: { ... } } |
| Claude Code | .mcp.json | { mcpServers: { ... } } |
| Cursor | .cursor/mcp.json | { mcpServers: { ... } } |
| VS Code | .vscode/mcp.json | { servers: { ... } } or { mcpServers: { ... } } |
| Zed | settings.json | MCP config nested under lsp settings |
| Windsurf | mcp_config.json | { mcpServers: { ... } } |
| Generic | mcp.json | Auto-detected format |
| YAML | mcp.yaml | YAML variant of any of the above |
All formats are normalized to the internal McpConfig structure before scanning, so detectors work identically regardless of which client created the config.
MCP Server Config Fields
Each server entry can contain:
{
// Process-based server (stdio transport)
command?: string, // Executable path
args?: string[], // Command arguments
env?: Record<string, string>, // Environment variables
// Network-based server (SSE/HTTP transport)
url?: string, // Server URL
transport?: "stdio" | "sse" | "streamable-http",
// Tool definitions (from tools/list or manual)
tools?: Array<{
name: string,
description: string,
inputSchema: object
}>,
// Security configurations
oauth?: {
clientId: string,
clientSecret: string,
scopes: string[],
redirectUri: string,
pkce: boolean
},
rateLimit?: {
maxRequests: number,
windowMs: number
},
logging?: {
enabled: boolean,
destination: string,
level: string,
rotation: boolean
},
// Docker-specific
docker?: {
image: string,
tag: string,
volumes: string[], // "host:container[:ro]"
privileged: boolean,
capabilities: string[],
network: string
},
// Permission constraints
permissions?: {
allowedPaths: string[],
networkAccess: boolean,
runAsRoot: boolean,
sudo: boolean
}
}
Programmatic API
Use the Igris Scanner as a library in your own tools:
import {
Scanner,
getAllDetectors,
parseConfigFile,
TableFormatter,
JsonFormatter,
} from "@igris/scanner";
// Parse a config file
const config = await parseConfigFile("~/.claude/claude_desktop_config.json");
// Create scanner with all detectors
const scanner = new Scanner(getAllDetectors(), {
severityFilter: "medium",
failOn: "high",
disabledRules: ["AG-VER-004"],
});
// Run scan
const result = await scanner.scan(config);
// Output
console.log(`Score: ${result.score}/10 (Grade: ${result.grade})`);
console.log(`Findings: ${result.findings.length}`);
// Format output
const formatter = new TableFormatter();
console.log(formatter.format(result));
// Check if should fail
if (shouldFail(result, "high")) {
process.exit(1);
}
Custom Detectors
Implement the Detector interface to add custom rules:
import type { Detector, DetectorMeta, Finding, McpConfig } from "@igris/scanner";
const myDetector: Detector = {
meta: {
id: "my-detector",
name: "My Custom Detector",
description: "Checks for company-specific requirements",
rules: [
{
id: "MY-001",
severity: "high",
title: "Missing required label",
description: "All MCP servers must have a team label",
},
],
},
async detect(config: McpConfig): Promise<Finding[]> {
const findings: Finding[] = [];
// Your detection logic here
return findings;
},
};
// Use with scanner
const scanner = new Scanner([...getAllDetectors(), myDetector]);