Skip to main content

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

FieldTypeDefaultDescription
severitystring"low"Minimum severity to report
formatstring"table"Output format: table, json, sarif
fail-onstring"high"Exit 1 if findings at this level or above
verbosebooleanfalseShow full finding details and remediation
colorbooleantrueEnable ANSI colored output
timeoutnumber30000Per-detector timeout in milliseconds
rules.disabledstring[][]Rule IDs to skip entirely
rules.configobject{}Per-rule configuration overrides
suppressionsarray[]Active suppression rules
pluginsstring[][]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

FieldRequiredDescription
ruleYesRule ID to suppress (e.g., AG-CRD-002)
serverNameNoOnly suppress for this specific server
reasonYesWhy this finding is suppressed (for audit trail)
expiresNoISO 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.

Supported MCP Config Formats

The scanner parses and normalizes configs from all major MCP clients:
FormatExample FileKey Differences
Claude Desktopclaude_desktop_config.json{ mcpServers: { ... } }
Claude Code.mcp.json{ mcpServers: { ... } }
Cursor.cursor/mcp.json{ mcpServers: { ... } }
VS Code.vscode/mcp.json{ servers: { ... } } or { mcpServers: { ... } }
Zedsettings.jsonMCP config nested under lsp settings
Windsurfmcp_config.json{ mcpServers: { ... } }
Genericmcp.jsonAuto-detected format
YAMLmcp.yamlYAML 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]);