@gustavobrunodev/agent-scan
v0.1.0
Published
Security scanning library for AI agent MCP servers and tools
Downloads
150
Maintainers
Readme
@ai-stack/agent-scan
Security scanning library for AI agent MCP servers, tools, and skills. Node.js port of snyk-agent-scan.
Auto-discovers MCP configurations across popular AI coding agents and scans them for prompt injections, tool poisoning, tool shadowing, and other security issues.
Installation
npm install @ai-stack/agent-scanRequires Node.js ≥ 20.
Quick Start
- Get a Snyk API token from https://app.snyk.io/account (API Token → KEY → click to show).
- Set the token as an environment variable:
export SNYK_TOKEN=your-api-token-here - Run a scan:
npx agent-scan
CLI Usage
The CLI binary is agent-scan. All commands support --help for detailed options.
scan (default)
Scan auto-discovered MCP servers and optionally specific config files:
# Auto-discover and scan all agents
agent-scan
# Scan a specific config file
agent-scan scan ~/.vscode/mcp.json
# Scan with skills enabled
agent-scan --skills
# Output as JSON
agent-scan --json
# CI mode — exits with code 1 if issues are found
agent-scan --ciOptions:
| Option | Description | Default |
|--------|-------------|---------|
| --verbose | Enable detailed logging | false |
| --json | Output results as JSON | false |
| --ci | Exit code 1 on findings | false |
| --skills | Also scan agent skills | false |
| --scan-all-users | Scan all users on the machine | false |
| --server-timeout <seconds> | MCP server connection timeout | 10 |
| --print-errors | Show error details and tracebacks | false |
| --print-full-descriptions | Show full tool/prompt descriptions | false |
| --skip-ssl-verify | Disable SSL verification | false |
| --analysis-url <url> | Override the analysis endpoint | Snyk API |
| --verification-H <header...> | Additional headers for the analysis server | — |
| --mcp-oauth-tokens-path <path> | Path to MCP OAuth tokens file | — |
| --control-server <url> | Upload results to a control server | — |
inspect
Print descriptions of tools, prompts, and resources without running analysis:
# Inspect auto-discovered agents
agent-scan inspect
# Inspect a specific config file
agent-scan inspect ~/.cursor/mcp.json
# JSON output
agent-scan inspect --jsonguard
Install or uninstall Agent Guard hooks for supported clients:
# Install hooks for Claude
agent-scan guard install claude --tenant-id <id> --url https://api.snyk.io
# Install hooks for Cursor (managed/admin path)
agent-scan guard install cursor --managed --tenant-id <id>
# Uninstall hooks
agent-scan guard uninstall claude
agent-scan guard uninstall cursormcp-server
Start an MCP server that exposes scanning as tools (experimental):
agent-scan mcp-server --tool --background --scan-interval 1800install-mcp-server
Install agent-scan as an MCP server in a given config file (experimental):
agent-scan install-mcp-server ~/.cursor/mcp.json --tool --backgroundevo
Push scan results to Snyk Evo (interactive — prompts for tenant ID and token):
agent-scan evoProgrammatic API
The library exports functions for integrating scanning into your own tooling:
import {
inspectPipeline,
inspectAnalyzePushPipeline,
clientToInspectFromPath,
getMcpConfigPerClient,
getWellKnownClients,
checkServer,
scanMcpConfigFile,
} from "@ai-stack/agent-scan";Inspect MCP Servers
import { inspectPipeline } from "@ai-stack/agent-scan";
const [results] = await inspectPipeline({
timeout: 10,
tokens: [],
paths: [], // empty = auto-discover
allUsers: false,
scanSkills: false,
});
for (const result of results) {
console.log(result.path, result.servers.length, "servers");
}Full Scan with Analysis
import { inspectAnalyzePushPipeline } from "@ai-stack/agent-scan";
const results = await inspectAnalyzePushPipeline(
{ timeout: 10, tokens: [], paths: [], allUsers: false, scanSkills: false },
{
analysisUrl: "https://api.snyk.io/hidden/mcp-scan/analysis-machine?version=2025-09-02",
additionalHeaders: {},
maxRetries: 3,
skipSslVerify: false,
},
{ controlServers: [], skipSslVerify: false, version: "0.1.0" },
false, // verbose
);
for (const result of results) {
for (const issue of result.issues) {
console.log(`[${issue.code}] ${issue.title}`);
}
}Scan a Specific Config File
import { scanMcpConfigFile } from "@ai-stack/agent-scan";
const results = await scanMcpConfigFile("~/.cursor/mcp.json", { timeout: 10 });List Well-Known Clients
import { getWellKnownClients } from "@ai-stack/agent-scan";
const clients = getWellKnownClients();
for (const client of clients) {
console.log(client.name, client.configPaths);
}Guard Hooks
import { runGuard } from "@ai-stack/agent-scan";
// Install Agent Guard hooks
await runGuard({
guardCommand: "install",
client: "claude",
url: "https://api.snyk.io",
tenantId: "your-tenant-id",
});
// Uninstall
await runGuard({ guardCommand: "uninstall", client: "claude" });Configuration Format
The scanner reads MCP configuration files in the standard format used by AI coding agents:
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["./server.js"],
"env": {
"API_KEY": "..."
}
},
"remote-server": {
"url": "https://example.com/mcp",
"headers": {
"Authorization": "Bearer ..."
}
}
}
}Stdio servers specify command and args. Remote servers specify a url.
Config files are auto-discovered from well-known paths for each agent. You can also pass explicit paths to agent-scan or agent-scan inspect.
Supported Clients
The following AI agents are auto-discovered:
| Agent | macOS | Linux | Windows | |-------|:-----:|:-----:|:-------:| | Windsurf | ✓ | ✓ | ✓ | | Cursor | ✓ | ✓ | ✓ | | VS Code | ✓ | ✓ | ✓ | | Claude Desktop | ✓ | — | ✓ | | Claude Code | ✓ | ✓ | ✓ | | Gemini CLI | ✓ | ✓ | ✓ | | OpenClaw | ✓ | ✓ | ✓ | | Amp | ✓ | ✓ | ✓ | | Kiro | ✓ | ✓ | ✓ | | OpenCode | ✓ | ✓ | ✓ | | Antigravity | ✓ | ✓ | ✓ | | Codex | ✓ | ✓ | — | | Amazon Q | ✓ | ✓ | — |
JSON Output
When using --json, the output is a JSON array of ScanPathResult objects:
[
{
"path": "/home/user/.cursor/mcp.json",
"client": "cursor",
"servers": [
{
"name": "my-server",
"tools": [...],
"prompts": [...],
"resources": [...]
}
],
"issues": [
{
"code": "E001",
"title": "Prompt Injection",
"severity": "high",
"description": "..."
}
],
"errors": []
}
]License
Apache-2.0
