Auditing MCP Configurations and AI Agent Rules for Security Risks
Modern developer workflows increasingly rely on AI agent configurations and Model Context Protocol (MCP) servers. Tools like Claude Desktop, Cursor, and Windsurf execute local commands, connect to remote services, and read workspace instructions from files like .cursorrules or claude_desktop_config

Posted on Nov 1 • Originally published at py-forge.com
Modern developer workflows increasingly rely on AI agent configurations and Model Context Protocol (MCP) servers. Tools like Claude Desktop, Cursor, and Windsurf execute local commands, connect to remote services, and read workspace instructions from files like.cursorrules or claude_desktop_config.json.
However, these configuration files can introduce serious security vulnerabilities into your environment:
agentconfig_audit_mcp_and_rules_scanner.py is an audit script designed to inspect MCP configuration files and agent instruction rulebooks to flag these specific security issues.
The tool is self-contained and relies entirely on Python's standard library ( argparse, json, pathlib, re, unicodedata, dataclasses, and shlex ). You do not need to run pip install for any third-party dependencies.
Download the script file and save it to your workspace as agentconfig_audit_mcp_and_rules_scanner.py. Ensure you have Python 3.8 or later installed.
You can display the built-in command options by invoking Python directly:
python agentconfig_audit_mcp_and_rules_scanner.py --help Enter fullscreen mode Exit fullscreen mode To audit an entire workspace for both MCP configurations and rule files (such as.cursorrules, agents.md, and markdown prompts), pass the directory path to the script:
python agentconfig_audit_mcp_and_rules_scanner.py. Enter fullscreen mode Exit fullscreen mode You can also target specific standard system locations where tools like Claude Desktop or Cursor store their MCP definitions:
# Auditing a specific configuration file python agentconfig_audit_mcp_and_rules_scanner.py ~/.cursor/mcp.json Enter fullscreen mode Exit fullscreen mode How It Works The audit tool inspects two main surfaces: structured JSON MCP server configurations and plaintext rule/instruction documents.
When parsing mcpServers configurations, the scanner evaluates command arguments against dangerous system roots and verifies if package runners include immutable version specifications:
# Check Overly Permissive Filesystem Paths if isinstance ( args, list ): for arg in args: if not isinstance ( arg, str ): continue expanded = os. path. expanduser ( arg ) for pat in BROAD_PATH_PATTERNS: if re. match ( pat, arg. strip ()) or re. match ( pat, expanded. strip ()): findings. append ( Finding ( rule_id = " MCP-BROAD-FILESYSTEM-ROOT ", title = f " Overly Broad Filesystem Access in ' { server_name } '", severity = " CRITICAL ", file_path = str ( file_path ), line_number = None, description = ( f " Server ' { server_name } ' is assigned an expansive filesystem path ' { arg } '. " " Agents interacting with this server obtain arbitrary read/write access to user " " home directories or root. " ), evidence = f " arg: { arg } ", remediation = " Scope the server access specifically to a dedicated subproject folder.
", ) ) Enter fullscreen mode Exit fullscreen mode The script monitors paths matching expressions like ^/$, ^/home/?$, ^/Users/?$, ^~$, or root drives on Windows ( ^[A-Za-z]:\\?$ ). If an MCP server is configured to mount those locations, it raises a CRITICAL finding.
Similarly, the scanner evaluates whether npx or uvx executions pin their targets. If an argument lacks @<version> or ==<version>, the tool flags MCP-UNPINNED-SERVER to prevent automatic downstream execution of unpinned packages.
The tool loops through every env key-value pair in each configured server. If a value contains known credential structures (such as GitHub personal access tokens, AWS keys, Slack tokens, or private key headers), or if keys containing TOKEN, KEY, or SECRET hold hardcoded strings longer than 11 characters, it generates an alert:
# Check Plaintext Credentials in 'env' if isinstance ( env, dict ): for env_key, env_val in env. items (): if not isinstance ( env_val, str ): continue # Skip template variables like ${VAR} or $VAR if ( env_val. startswith ( " ${ " ) and env_val. endswith ( " } " )) or env_val. startswith ( " $ " ): continue for regex, label in SECRET_REGEXES: if re. search ( regex, env_val ) or ( any ( s in env_key. upper () for s in ( " TOKEN ", " KEY ", " SECRET ", " PASSWORD ", " AUTH " )) and len ( env_val ) >= 12 ): findings. append ( Finding ( rule_id = " MCP-PLAINTEXT-SECRET ", title = f " Exposed Secret in Server ' { server_name } ' Env ", severity = " CRITICAL ", file_path = str ( file_path ), line_number = None, description = ( f " Environment variable ' { env_key } ' contains a hardcoded plaintext secret ( { label } ). " ), evidence = f " { env_key } = { env_val [: 4 ] }... { env_val [ - 4: ] if len ( env_val ) > 8 else '' } ", remediation = " Extract credentials to the system shell environment or a secure local keyring and reference via variable expansion. ", ) ) break Enter fullscreen mode Exit fullscreen mode If the value uses variable expansion syntax such as ${MY_SECRET} or $MY_SECRET, the scanner treats it as externalized and skips it.
Files like.cursorrules, agents.md, and prompt.txt can contain hidden characters that alter model behavior without being visible in standard text editors. The scanner checks each line for:
While this tool highlights high-risk patterns, it has specific design limitations based directly on its codebase:
Does the scanner transmit any found tokens or file contents to an external server? No. The script runs entirely on your local machine using standard Python modules. It performs no network calls, uploads no telemetry, and outputs findings strictly to your local standard output stream.
Why does the script flag my npx or uvx command as high severity? Commands like npx @modelcontextprotocol/server-filesystem download and run the latest published version by default. If that package is modified or compromised upstream, your agent environment executes that code automatically. The scanner requires pinning a specific version tag (e.g., npx @modelcontextprotocol/server-filesystem@0.1.0 ) to pass without a finding.
Can the scanner automatically redact secrets or remove invisible characters from my files? No. The scanner is an auditing tool, not an in-place mutation tool. It reports the rule ID, offending file path, line evidence, and suggested remediation, leaving actual file modifications to the developer.
Full version and the rest of the toolkit: AgentConfig Audit MCP and rules scanner on PyForge. Product page: https://py-forge.com/products/agentconfig-audit-mcp-and-rules-scanner