Skip to main content
Glama
mcp-secret-sentinel

mcp-secret-sentinel

scan_directory

Read-onlyIdempotent

Recursively scans a directory tree for exposed secrets, honoring Git ignore rules and skipping binaries, caches, lockfiles, and oversized files to detect leaks before committing.

Instructions

Recursively scan a directory tree for exposed secrets.

Inside a git repository the file list comes from git (tracked files plus untracked files no .gitignore excludes), so every ignore rule is honoured. Always skips .git, node_modules, virtualenvs, caches, dist, build, minified bundles, lockfiles, binaries, files over 5 MB and the paths the project's .secret-sentinel.toml excludes.

Args: path: Absolute path to the directory to scan. max_files: Stop after scanning this many files (default 500). max_findings: List at most this many findings, most severe first (default 200, 0 = no limit).

Returns: The standard redacted findings report; finding paths are relative to the scanned root, using forward slashes.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "path": "<path>"
    },
    "name": "scan_directory"
  }
}

Input Schema

NameRequiredDescriptionDefault
pathYes
max_filesNo
max_findingsNo

Output Schema

NameRequiredDescriptionDefault
cleanYes
summaryYes
findingsYes
baselinedNo
top_filesNo
truncatedNo
suppressedNo
files_scannedYes
total_findingsNo
counts_by_patternNo
counts_by_severityNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv0.3.0
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$defs": {
      +    "FileCount": {
      +      "properties": {
      +        "file": {
      +          "title": "File",
      +          "type": "string"
      +        },
      +        "findings": {
      +          "title": "Findings",
      +          "type": "integer"
      +        }
      +      },
      +      "required": [
      +        "file",
      +        "findings"
      +      ],
      +      "title": "FileCount",
      +      "type": "object"
      +    },
      +    "Finding": {
      +      "properties": {
      +        "advice": {
      +          "title": "Advice",
      +          "type": "string"
      +        },
      +        "commit": {
      +          "anyOf": [
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "title": "Commit"
      +        },
      +        "file": {
      +          "title": "File",
      +          "type": "string"
      +        },
      +        "line": {
      +          "title": "Line",
      +          "type": "integer"
      +        },
      +        "pattern": {
      +          "title": "Pattern",
      +          "type": "string"
      +        },
      +        "redacted": {
      +          "title": "Redacted",
      +          "type": "string"
      +        },
      +        "severity": {
      +          "enum": [
      +            "critical",
      +            "high",
      +            "medium"
      +          ],
      +          "title": "Severity",
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "file",
      +        "line",
      +        "pattern",
      +        "severity",
      +        "redacted",
      +        "advice"
      +      ],
      +      "title": "Finding",
      +      "type": "object"
      +    }
      +  },
      +  "properties": {
      +    "baselined": {
      +      "anyOf": [
      +        {
      +          "type": "integer"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "title": "Baselined"
      +    },
      +    "clean": {
      +      "title": "Clean",
      +      "type": "boolean"
      +    },
      +    "counts_by_pattern": {
      +      "anyOf": [
      +        {
      +          "additionalProperties": {
      +            "type": "integer"
      +          },
      +          "type": "object"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "title": "Counts By Pattern"
      +    },
      +    "counts_by_severity": {
      +      "anyOf": [
      +        {
      +          "additionalProperties": {
      +            "type": "integer"
      +          },
      +          "type": "object"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "title": "Counts By Severity"
      +    },
      +    "files_scanned": {
      +      "title": "Files Scanned",
      +      "type": "integer"
      +    },
      +    "findings": {
      +      "items": {
      +        "$ref": "#/$defs/Finding"
      +      },
      +      "title": "Findings",
      +      "type": "array"
      +    },
      +    "summary": {
      +      "title": "Summary",
      +      "type": "string"
      +    },
      +    "suppressed": {
      +      "anyOf": [
      +        {
      +          "type": "integer"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "title": "Suppressed"
      +    },
      +    "top_files": {
      +      "anyOf": [
      +        {
      +          "items": {
      +            "$ref": "#/$defs/FileCount"
      +          },
      +          "type": "array"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "title": "Top Files"
      +    },
      +    "total_findings": {
      +      "anyOf": [
      +        {
      +          "type": "integer"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "title": "Total Findings"
      +    },
      +    "truncated": {
      +      "anyOf": [
      +        {
      +          "type": "boolean"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "title": "Truncated"
      +    }
      +  },
      +  "required": [
      +    "clean",
      +    "findings",
      +    "files_scanned",
      +    "summary"
      +  ],
      +  "title": "ScanReport",
      +  "type": "object"
      +}
  2. First observedv0.2.0

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, and the description adds substantive behavior on top: git-derived file enumeration honoring .gitignore, an explicit skip list (.git, node_modules, venvs, caches, dist, build, minified bundles, lockfiles, binaries, >5 MB, .secret-sentinel.toml exclusions). It also discloses truncation semantics and ordering of findings, which an agent cannot infer from annotations alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose, then a well-structured Args/Returns block. The skip-list sentence is dense but each item earns its place; only minor trimming would improve it.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given three parameters, real filesystem traversal complexity, and an output schema that already defines the report shape, the description covers everything an agent needs: scope, ignore/skip rules, git awareness, truncation limits, and finding-path conventions. Nothing material is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the parameter burden and it does: path is documented as an absolute directory path, max_files as a stop-after cap with default 500, and max_findings as a list cap with default 200 where 0 means unlimited and results are most-severe-first. This meaningfully exceeds the bare typed schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource+scope: 'Recursively scan a directory tree for exposed secrets.' This clearly separates it from siblings like scan_file, scan_text, scan_git_staged, and list_patterns, which an agent can distinguish without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The scope ('recursively ... directory tree', git-aware file listing) makes the intended use case obvious and implicitly routes file/text/git-index scanning to siblings. However, it never explicitly names an alternative or states when not to use it, so it stops short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.