@agentsid/scanner 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +205 -0
  2. package/action/action.yml +42 -0
  3. package/action/index.mjs +179 -0
  4. package/docs/state-of-agent-security-2026.md +377 -0
  5. package/examples/security-scan.yml +57 -0
  6. package/package.json +37 -0
  7. package/reports/aashari-mcp-server-atlassian-confluence.json +110 -0
  8. package/reports/aashari-mcp-server-atlassian-jira.json +138 -0
  9. package/reports/aashari-mcp-server-aws-sso.json +122 -0
  10. package/reports/agentdeskai-browser-tools-mcp.json +361 -0
  11. package/reports/ahmetkca-mcp-server-postgres.json +43 -0
  12. package/reports/aiondadotcom-mcp-ssh.json +166 -0
  13. package/reports/apify-actors-mcp-server.json +43 -0
  14. package/reports/azure-mcp.json +43 -0
  15. package/reports/boilerplate-mcp-tool.json +43 -0
  16. package/reports/browserstack-mcp-server.json +43 -0
  17. package/reports/canvas-mcp-server.json +43 -0
  18. package/reports/canvas-mcp-tool.json +43 -0
  19. package/reports/chrome-devtools-mcp.json +300 -0
  20. package/reports/chrome-local-mcp.json +222 -0
  21. package/reports/claude-flow-mcp.json +43 -0
  22. package/reports/cloudflare-mcp-server.json +43 -0
  23. package/reports/code-canvas-server.json +43 -0
  24. package/reports/cognitionai-metabase-mcp-server.json +43 -0
  25. package/reports/composio-mcp.json +43 -0
  26. package/reports/contentful-mcp-server.json +43 -0
  27. package/reports/dbhub.json +43 -0
  28. package/reports/desktop-commander.json +43 -0
  29. package/reports/dynatrace-oss-dynatrace-mcp-server.json +43 -0
  30. package/reports/e2b-mcp-server.json +67 -0
  31. package/reports/eslint-mcp.json +51 -0
  32. package/reports/european-parliament-mcp-server.json +1467 -0
  33. package/reports/exa-mcp-server.json +74 -0
  34. package/reports/executeautomation-playwright-mcp-server.json +418 -0
  35. package/reports/fast-kit-spec-kit.json +43 -0
  36. package/reports/felores-airtable-mcp-server.json +43 -0
  37. package/reports/figma-mcp.json +103 -0
  38. package/reports/forestadmin-mcp-server.json +43 -0
  39. package/reports/fullrun-mcp.json +43 -0
  40. package/reports/gemini-mcp-tool.json +43 -0
  41. package/reports/gitlab-mcp-agent-server.json +186 -0
  42. package/reports/grackle-ai-mcp.json +43 -0
  43. package/reports/heroku-mcp-server.json +333 -0
  44. package/reports/hisma-server-puppeteer.json +93 -0
  45. package/reports/hubspot-mcp-server.json +43 -0
  46. package/reports/hyper-mcp-shell.json +59 -0
  47. package/reports/iflow-mcp-server-github.json +327 -0
  48. package/reports/jpisnice-shadcn-ui-mcp-server.json +149 -0
  49. package/reports/jsonresume-mcp.json +43 -0
  50. package/reports/mapbox-mcp-server.json +43 -0
  51. package/reports/mcp-framework.json +43 -0
  52. package/reports/mcp-from-openapi.json +43 -0
  53. package/reports/mcp-handler.json +43 -0
  54. package/reports/mcp-proxy.json +43 -0
  55. package/reports/mcp-server-docker.json +59 -0
  56. package/reports/mcp-server-github-gist.json +108 -0
  57. package/reports/mcp-server-google-calendar.json +43 -0
  58. package/reports/mcp-server-jira-cloud.json +43 -0
  59. package/reports/mcp-server-kubernetes.json +43 -0
  60. package/reports/mcp-server-slack.json +411 -0
  61. package/reports/mcp-server-sqlite-npx.json +43 -0
  62. package/reports/mcp-server.json +43 -0
  63. package/reports/mcp-starter.json +59 -0
  64. package/reports/mcp-tool-lint.json +43 -0
  65. package/reports/mcporter.json +43 -0
  66. package/reports/mcptoolshop-mcp-tool-registry.json +43 -0
  67. package/reports/microsoft-devbox-mcp.json +43 -0
  68. package/reports/mobilenext-mobile-mcp.json +214 -0
  69. package/reports/modelcontextprotocol-server-brave-search.json +43 -0
  70. package/reports/modelcontextprotocol-server-everything.json +165 -0
  71. package/reports/modelcontextprotocol-server-fetch.json +43 -0
  72. package/reports/modelcontextprotocol-server-filesystem.json +259 -0
  73. package/reports/modelcontextprotocol-server-github.json +391 -0
  74. package/reports/modelcontextprotocol-server-memory.json +117 -0
  75. package/reports/modelcontextprotocol-server-postgres.json +43 -0
  76. package/reports/modelcontextprotocol-server-puppeteer.json +101 -0
  77. package/reports/modelcontextprotocol-server-sequential-thinking.json +67 -0
  78. package/reports/mongodb-mcp-server.json +43 -0
  79. package/reports/mseep-linear-mcp-server.json +43 -0
  80. package/reports/mseep-mcp-server-sqlite-npx.json +43 -0
  81. package/reports/n8n-mcp.json +123 -0
  82. package/reports/notepost-mcp.json +43 -0
  83. package/reports/notionhq-notion-mcp-server.json +220 -0
  84. package/reports/nx-mcp.json +59 -0
  85. package/reports/obsidian-mcp-server.json +43 -0
  86. package/reports/opengraph-io-mcp.json +130 -0
  87. package/reports/payloadcms-plugin-mcp.json +43 -0
  88. package/reports/peac-mappings-mcp.json +43 -0
  89. package/reports/playwright-mcp.json +236 -0
  90. package/reports/puppeteer-mcp-server.json +43 -0
  91. package/reports/railway-mcp-server.json +194 -0
  92. package/reports/razorpay-blade-mcp.json +182 -0
  93. package/reports/rekog-mcp-nest.json +43 -0
  94. package/reports/remotion-mcp.json +51 -0
  95. package/reports/rollbar-mcp-server.json +43 -0
  96. package/reports/sap-ux-fiori-mcp-server.json +80 -0
  97. package/reports/sentry-mcp-server.json +43 -0
  98. package/reports/server-filesystem.json +43 -0
  99. package/reports/server-memory.json +43 -0
  100. package/reports/shortcut-mcp.json +43 -0
  101. package/reports/supabase-mcp-server-supabase.json +43 -0
  102. package/reports/tavily-mcp.json +79 -0
  103. package/reports/thelord-mcp-server-docker-npx.json +43 -0
  104. package/reports/tyk-technologies-api-to-mcp.json +43 -0
  105. package/reports/tyk-technologies-tyk-dashboard-mcp.json +43 -0
  106. package/reports/ui5-mcp-server.json +157 -0
  107. package/reports/upstash-context7-mcp.json +82 -0
  108. package/reports/vantasdk-vanta-mcp-server.json +43 -0
  109. package/reports/winor30-mcp-server-datadog.json +43 -0
  110. package/reports/wonderwhy-er-desktop-commander.json +43 -0
  111. package/reports/xzxzzx-bilibili-mcp.json +58 -0
  112. package/src/grader.mjs +66 -0
  113. package/src/index.mjs +108 -0
  114. package/src/reporter.mjs +158 -0
  115. package/src/rules.mjs +363 -0
  116. package/src/scanner.mjs +208 -0
@@ -0,0 +1,377 @@
1
+ # The State of MCP Server Security — 2026
2
+
3
+ **An empirical analysis of 100 Model Context Protocol servers**
4
+
5
+ AgentsID Research · March 2026
6
+
7
+ ---
8
+
9
+ ## Abstract
10
+
11
+ In an audit of 100 MCP (Model Context Protocol) server packages — including the "gold standard" reference implementations maintained by Anthropic and Microsoft — every vendor-maintained server that exposed tools received a failing grade (F). Across the broader ecosystem, 71% of servers scored F. Zero scored A. We identified 893 total findings across 41 servers exposing 485 tools, including 163 instances of a novel vulnerability class we term "hallucination-based vulnerabilities" (HBVs) — security weaknesses unique to LLM-driven tool execution where vague or ambiguous tool definitions cause the language model to over-privilege, misroute, or behave unpredictably. Our scanner identifies the exact structural preconditions — unbounded string parameters, missing schema validation, vague scope boundaries — that led to the RCE-class CVEs disclosed against MCP servers in early 2026 (CVE-2025-68143, CVE-2025-68144, CVE-2025-9611). These findings demonstrate that the MCP specification is vulnerable by default: the protocol prioritizes developer flexibility over the schema strictness and semantic validation required for safe autonomous operation, and its own reference implementations confirm that insecurity is the path of least resistance.
12
+
13
+ ---
14
+
15
+ ## 1. Introduction
16
+
17
+ The Model Context Protocol (MCP), introduced by Anthropic in November 2024 and adopted by OpenAI, Google, Microsoft, and Amazon, has become the de facto standard for connecting AI agents to external tools. As of March 2026, the MCP ecosystem has over 97 million monthly SDK downloads and more than 5,200 registered servers.
18
+
19
+ MCP solves a real problem: it standardizes how AI models discover and call tools. But the protocol's security model is minimal by design. The MCP specification delegates authentication to the transport layer, provides no mechanism for per-tool authorization, defines no standard for agent identity, and includes no audit log format.
20
+
21
+ The result is an ecosystem where AI agents have unrestricted access to every tool a server exposes. An agent connecting to a database MCP server can SELECT and DROP with equal ease. An agent with a shell MCP server can `ls` and `rm -rf /` without distinction.
22
+
23
+ This report quantifies the scope of that problem.
24
+
25
+ ### 1.1 Prior Work
26
+
27
+ Previous security analyses of MCP servers include the Astrix Security state of MCP security report (2025), which found that 88% of MCP servers require credentials and only 8.5% use OAuth. Qualys TotalAI identified MCP servers as "the new shadow IT" for AI in March 2026. Individual vulnerability disclosures (CVE-2025-6514, the Postmark MCP supply chain attack) have demonstrated specific attack vectors. However, no prior study has systematically scanned a large sample of MCP servers against a standardized security framework, and no prior work has identified hallucination-based vulnerabilities as a distinct security category.
28
+
29
+ ### 1.2 Contributions
30
+
31
+ This report makes three contributions:
32
+
33
+ 1. **Empirical data**: Security analysis of 100 MCP server packages, with detailed findings across 41 servers exposing 485 tools.
34
+ 2. **Novel vulnerability class**: Identification and taxonomy of hallucination-based vulnerabilities — security issues that arise from the interaction between tool definitions and LLM reasoning, rather than from code-level flaws.
35
+ 3. **Security grading framework**: A reproducible methodology for evaluating MCP server security across six categories.
36
+
37
+ ---
38
+
39
+ ## 2. Methodology
40
+
41
+ ### 2.1 Scanner Design
42
+
43
+ We built an automated scanner (open-source, available at github.com/stevenkozeniesky02/agentsid-scanner) that connects to MCP servers via the stdio transport protocol, performs the standard MCP handshake (initialize → notifications/initialized → tools/list), and analyzes the returned tool definitions.
44
+
45
+ The scanner evaluates seven categories of security risk:
46
+
47
+ | Category | What It Checks |
48
+ |----------|---------------|
49
+ | **Injection** | 11 prompt injection patterns in tool descriptions |
50
+ | **Permissions** | Tool names classified by risk level (destructive, execution, financial, credential) |
51
+ | **Validation** | Input schema completeness and constraint enforcement |
52
+ | **Auth** | Authentication indicators in the tool surface |
53
+ | **Secrets** | Potential credential exposure in tool outputs |
54
+ | **Output** | Unfiltered sensitive data in responses |
55
+ | **Hallucination** | 7 classes of LLM-reasoning vulnerabilities (see Section 4) |
56
+
57
+ ### 2.2 Grading Scale
58
+
59
+ Each server starts at 100 points. Deductions are applied per finding:
60
+
61
+ | Severity | Deduction |
62
+ |----------|-----------|
63
+ | CRITICAL | -25 |
64
+ | HIGH | -15 |
65
+ | MEDIUM | -8 |
66
+ | LOW | -3 |
67
+
68
+ Letter grades: A (90-100), B (75-89), C (60-74), D (40-59), F (0-39). The floor is 0.
69
+
70
+ ### 2.3 Sample Selection
71
+
72
+ We scanned 100 MCP server packages from the npm registry, selected by:
73
+ - The top 50 MCP-related packages by GitHub stars
74
+ - The top 50 results for npm searches across "mcp server", "mcp tool", "mcp agent", and "model context protocol"
75
+ - Deduplication by package name
76
+
77
+ Of these 100, 41 (41%) successfully exposed tool definitions via the stdio transport. The remaining 59 required API keys, external service authentication, or specific runtime configurations that prevented tool enumeration.
78
+
79
+ **The Visibility Gap**: This 41% scan rate is itself a critical finding. 59% of MCP servers are opaque to independent security review — there is no standardized health-check endpoint, no unauthenticated tool-listing capability, and no way for a security researcher (or a developer evaluating a server) to assess the tool surface before connecting an agent. The ecosystem is not just insecure — it is unauditable. This opacity should be addressed in the MCP specification through a mandatory, unauthenticated `/tools/list` introspection endpoint.
80
+
81
+ ### 2.4 Limitations and Design Decisions
82
+
83
+ **Static analysis, not runtime analysis.** The scanner analyzes tool definitions (names, descriptions, schemas), not runtime behavior. A tool that validates input internally would not receive credit for that validation in our scan. Some servers may have security features not visible through tool definitions.
84
+
85
+ **Sample scope.** The sample is limited to npm packages accessible via npx. Python-only, Go-only, and private MCP servers are not included. The 100 packages were selected by popularity (stars, download rank), not randomly — this means our sample skews toward the most visible and presumably best-maintained servers, which makes the results more damning, not less.
86
+
87
+ **Injection detection uses regex, not semantic analysis.** Our current detection engine utilizes 11 regex-based patterns for known injection strings. We acknowledge that regex is a sieve — a sophisticated attacker will not write "ignore previous instructions" but rather embed adversarial intent in natural-sounding phrasing that static patterns cannot catch. However, as the first large-scale audit of over 100 MCP servers, this baseline establishes a vulnerability floor. If 11 simple patterns find issues in 1% of servers, semantic analysis will find substantially more. Future iterations (v2) will incorporate LLM-based "judge" evaluation to detect semantic bypasses that static analysis misses.
88
+
89
+ **HBV-4 (short descriptions) as a vulnerability, not a linting issue.** While short descriptions may traditionally be viewed as a documentation concern, in agentic workflows they represent semantic vulnerabilities. When a tool like `puppeteer_navigate` provides only 17 characters of context, the LLM is forced to rely on internal priors to guess parameter structure and intent. This creates non-deterministic runtime behavior — the same tool invoked by Claude, GPT, and Gemini may produce three different parameter sets. In production-grade agents, non-deterministic tool invocation is an unacceptable risk.
90
+
91
+ **We grade against a standard that does not yet exist.** The MCP specification currently prioritizes developer flexibility over security hardening. This audit intentionally grades against an advanced security posture — mandatory bounded schemas, explicit required fields, scoped tool descriptions — that the protocol does not yet mandate. If vendors made schemas strict and descriptions precise, tools might become harder for LLMs to use casually. We believe that trade-off is correct: an agent that fails safely is better than one that executes unpredictably. By grading against this standard, we expose the systemic validation gap where protocol flexibility actively facilitates agentic failure modes.
92
+
93
+ **The `browser_press_key` false positive.** Our dangerous-tool-name regex flagged `browser_press_key` as credential_access because the name contains "key." This is a false positive — the tool presses keyboard keys, not cryptographic keys. We include this transparently as an example of where regex-based name classification breaks down, and as motivation for the semantic analysis planned in v2. Notably, this single false positive did not drive Playwright's F grade — 24 schema validation failures did. The grading algorithm is weighted toward schema integrity over naming heuristics.
94
+
95
+ ---
96
+
97
+ ## 3. Results
98
+
99
+ ### 3.1 Overall Findings
100
+
101
+ | Metric | Value |
102
+ |--------|-------|
103
+ | Packages scanned | 100 |
104
+ | Servers with tool definitions | 41 |
105
+ | Total tools analyzed | 485 |
106
+ | Average tools per server | 11.8 |
107
+ | Total findings | 893 |
108
+ | Average findings per server | 21.8 |
109
+
110
+ ### 3.2 Grade Distribution
111
+
112
+ | Grade | Count | Percentage |
113
+ |-------|-------|------------|
114
+ | A (90-100) | 0 | 0% |
115
+ | B (75-89) | 2 | 5% |
116
+ | C (60-74) | 3 | 7% |
117
+ | D (40-59) | 7 | 17% |
118
+ | F (0-39) | 29 | 71% |
119
+
120
+ **71% of MCP servers scored F. No server scored A.**
121
+
122
+ The two B-grade servers were single-tool servers with minimal attack surface (1 tool each). The three C-grade servers had 1-2 tools with basic schema validation. Every server with more than 5 tools scored D or F.
123
+
124
+ **The Protocol-Level Ceiling**: These grades do not reflect developer incompetence. Under the current MCP specification, it is structurally difficult to achieve an A grade because the protocol provides no standard fields for per-tool authorization, agent identity declaration, or audit metadata. Server authors cannot implement what the specification does not define. The F grades are a measurement of the protocol's security gap, not individual developer failure. Even the official reference implementations — built by the MCP specification authors themselves — scored F, confirming that the problem is systemic.
125
+
126
+ ### 3.3 Findings by Severity
127
+
128
+ | Severity | Count | Percentage |
129
+ |----------|-------|------------|
130
+ | Critical | 18 | 2% |
131
+ | High | 82 | 9% |
132
+ | Medium | 625 | 70% |
133
+ | Low | 168 | 19% |
134
+
135
+ ### 3.4 Findings by Category
136
+
137
+ | Category | Count | Percentage | Description |
138
+ |----------|-------|------------|-------------|
139
+ | Validation | 543 | 61% | Missing or incomplete input schemas |
140
+ | Hallucination | 163 | 18% | LLM-reasoning vulnerabilities |
141
+ | Permissions | 91 | 10% | Dangerous tools without access controls |
142
+ | Auth | 35 | 4% | Missing authentication indicators |
143
+ | Output | 30 | 3% | Unfiltered sensitive output |
144
+ | Secrets | 20 | 2% | Potential credential exposure |
145
+ | Injection | 11 | 1% | Prompt injection in tool descriptions |
146
+
147
+ ### 3.5 Notable Servers
148
+
149
+ | Server | Tools | Score | Findings | Notes |
150
+ |--------|-------|-------|----------|-------|
151
+ | GitHub MCP (Anthropic) | 26 | F (0) | 45 | 9 HBVs, 9 uncontrolled mutations, 0/26 validated |
152
+ | European Parliament MCP | 61 | F (0) | 204 | 121 hallucination findings. Government server. |
153
+ | Playwright MCP (Microsoft) | 22 | F (0) | 28 | Browser automation with no input validation |
154
+ | Heroku MCP | 33 | F (0) | 42 | Cloud deployment tools unrestricted |
155
+ | Chrome DevTools MCP | 29 | F (0) | 37 | Browser control without permissions |
156
+ | Notion MCP (official) | 22 | F (0) | 26 | Document management unrestricted |
157
+ | Railway MCP | 14 | F (0) | 22 | Infrastructure deployment unrestricted |
158
+ | Filesystem MCP (official) | 14 | F (0) | 31 | File system access without boundaries |
159
+ | Memory MCP (official) | 9 | F (2) | 11 | 3 delete tools with zero controls |
160
+ | Slack MCP | 20 | F (0) | - | Messaging with no per-tool auth |
161
+
162
+ Three of the servers listed above are official reference implementations from the MCP specification authors. Their F grades indicate that the security gap is systemic, not a matter of individual developer negligence.
163
+
164
+ ### 3.6 Gold Standard Audit: Vendor-Maintained Servers
165
+
166
+ To test whether the ecosystem's F-grade trend reflects community inexperience or a deeper structural problem, we conducted targeted scans of the most widely-used, vendor-maintained MCP servers — the reference implementations that developers treat as examples of how to build MCP servers correctly.
167
+
168
+ | Server | Maintainer | Tools | Grade | Validation | Permissions | Hallucination |
169
+ |--------|-----------|-------|-------|------------|-------------|---------------|
170
+ | **@modelcontextprotocol/server-github** | Anthropic | 26 | **F (0)** | F (0/26 validated) | F (9 mutation/deploy tools uncontrolled) | F (9 HBVs) |
171
+ | **@modelcontextprotocol/server-filesystem** | Anthropic | 14 | **F (0)** | F (0/14 validated) | B | D (4 HBVs, 2 HIGH) |
172
+ | **@playwright/mcp** | Microsoft | 22 | **F (0)** | F (0/22 validated) | B | — |
173
+ | **@notionhq/notion-mcp-server** | Notion | 22 | **F (0)** | F (0/22 validated) | A | — |
174
+ | **@modelcontextprotocol/server-puppeteer** | Anthropic | 7 | **F (21)** | D | — | A (1 short desc) |
175
+ | **@modelcontextprotocol/server-memory** | Anthropic | 9 | **F (0)** | B | F (3 delete tools, zero controls) | A |
176
+ | **@modelcontextprotocol/server-everything** | Anthropic | 13 | **F (0)** | F | — | — |
177
+
178
+ **Every vendor-maintained MCP server that exposed tools scored F.** Five of seven Anthropic-maintained servers — built by the authors of the MCP specification — scored F.
179
+
180
+ The most critical result is `@modelcontextprotocol/server-github`, Anthropic's official GitHub integration. It exposes 26 tools including `push_files` (classified as deployment risk), `create_or_update_file`, `fork_repository`, and `merge_pull_request` — all without input validation, per-tool permissions, or scope boundaries. Nine tools triggered hallucination-based vulnerabilities because their descriptions reference files, accounts, and repositories without specifying which ones the agent is allowed to touch. An agent connected to this server with a GitHub PAT can push to any repository, merge any PR, and fork any project the token has access to, with no tool-level guardrails.
181
+
182
+ These findings are not theoretical. In early 2026, the related `@modelcontextprotocol/server-git` was disclosed with CVE-2025-68143 (path traversal) and CVE-2025-68144 (argument injection) — both resulting from unbounded string parameters in git tool inputs. Our scanner identifies exactly the structural precursors to these RCE-class vulnerabilities: tools accepting arbitrary strings with no length limits, no pattern constraints, and no scope boundaries. The CVEs are the consequence; the unbounded schemas are the cause.
183
+
184
+ Microsoft's `@playwright/mcp` exposes 22 browser automation tools — navigate, evaluate JavaScript, upload files, press keys, run arbitrary code — with zero schema validation on any tool. Every string parameter is unbounded. An agent prompted with adversarial input could use `browser_evaluate` to execute arbitrary JavaScript in the context of any authenticated session the browser holds. This aligns with CVE-2025-9611 (DNS rebinding/CSRF in Playwright MCP), where the server's lack of input validation enabled cross-origin exploitation. Microsoft's defense — that the server was for "intended local usage" — underscores the problem: the "intended usage" of an MCP server is whatever the LLM can be prompted to do, and without schema constraints, there is no boundary between intended and adversarial use.
185
+
186
+ These are not obscure community projects. These are the servers that Anthropic links from the MCP documentation, that Microsoft ships with Playwright, that Notion provides as their official integration. They are the templates that thousands of developers copy. If the gold standard scores F, the ecosystem built on top of it has no foundation.
187
+
188
+ **The implication is structural, not incidental.** Even with perfect credentials — the problem Astrix Security's 2025 report identified — these servers remain fully vulnerable to tool-level exploitation. Transport-layer OAuth does not help when the tool surface is unbounded. Credential security and tool-level security are orthogonal problems, and the ecosystem has addressed neither.
189
+
190
+ ---
191
+
192
+ ## 4. Hallucination-Based Vulnerabilities: A Novel Vulnerability Class
193
+
194
+ ### 4.1 Definition
195
+
196
+ Hallucination-based vulnerabilities (HBVs) are security weaknesses that arise from the interaction between tool definitions and LLM reasoning, rather than from code-level flaws. They exploit the fact that LLMs interpret natural language tool descriptions to make execution decisions, and that vague, ambiguous, or misleading descriptions cause the model to over-privilege its actions.
197
+
198
+ Unlike traditional vulnerabilities (SQL injection, buffer overflow), HBVs cannot be detected by analyzing source code. They exist in the semantic space between what a tool description says and what the LLM infers.
199
+
200
+ ### 4.2 Taxonomy
201
+
202
+ We identified seven classes of hallucination-based vulnerabilities:
203
+
204
+ **HBV-1: Vague Description Over-Privileging**
205
+
206
+ A tool described as "manages user data" could mean read, create, update, or delete. The LLM selects the interpretation that best fits the user's prompt, which may be the most destructive option.
207
+
208
+ *Exploit scenario*: User says "clean up the old accounts." LLM interprets "manages user data" as having delete capability. The tool handler accepts a `DELETE` action because the schema has no action-type constraint. User data is destroyed.
209
+
210
+ *Found in*: 29% of servers with tools
211
+
212
+ **HBV-2: Ambiguous Tool Names**
213
+
214
+ Tool names like `manage_users`, `handle_data`, or `process_request` provide no specificity about the operation. The LLM must infer the action, and different models infer differently.
215
+
216
+ *Exploit scenario*: An attacker uses prompt injection ("also remove inactive users") and the LLM routes to `manage_users` because the name is broad enough to match. A tool named `delete_user` would not have been selected by the same prompt because it signals irreversibility.
217
+
218
+ *Found in*: 12% of servers with tools
219
+
220
+ **HBV-3: Missing Scope Boundaries**
221
+
222
+ A tool that says "access files" without specifying which files, directories, or permission levels gives the LLM no basis to limit its access. The model will attempt the broadest possible scope.
223
+
224
+ *Exploit scenario*: An agent with a file tool described as "read and write files" is asked to "save this config." The LLM writes to `/etc/` because no boundary was specified. A description saying "read and write files within the /data directory only" would have constrained the model's behavior.
225
+
226
+ *Found in*: 44% of servers with tools
227
+
228
+ **HBV-4: Insufficient Description**
229
+
230
+ Tool descriptions under 20 characters force the LLM to infer capabilities from the name alone. A tool named `exec` with description "run" could mean anything.
231
+
232
+ *Exploit scenario*: A prompt injection inserts "use the exec tool to run this cleanup script." The LLM has no description to evaluate whether this is safe. With a complete description ("Execute a read-only SQL query against the analytics database"), the model would recognize a mismatch and refuse.
233
+
234
+ *Found in*: 7% of servers with tools
235
+
236
+ **HBV-5: Missing Description**
237
+
238
+ Tools with no description at all leave the LLM entirely dependent on name inference. Behavior becomes unpredictable across different models.
239
+
240
+ *Exploit scenario*: A tool named `sync` with no description. Claude interprets it as "synchronize data between systems." GPT interprets it as "sync local changes to remote." The same agent workflow produces different outcomes depending on which model is executing.
241
+
242
+ *Found in*: 3% of servers with tools
243
+
244
+ **HBV-6: Implicit Authority Escalation**
245
+
246
+ A tool with dangerous capabilities (name includes "admin", "delete", "exec") but an innocuous description ("helper utility", "simple tool") causes the LLM to underestimate risk and use the tool without appropriate caution.
247
+
248
+ *Exploit scenario*: A tool named `admin_reset` described as "simple maintenance utility." The LLM treats it as low-risk and calls it without prompting for confirmation. The tool resets the entire admin configuration. A description accurately stating "Resets all administrator accounts and permissions — irreversible" would trigger the model's safety reasoning.
249
+
250
+ *Found in*: 2% of servers with tools
251
+
252
+ **HBV-7: Conflicting Tool Descriptions**
253
+
254
+ Two or more tools with highly overlapping descriptions (>60% word overlap) cause the LLM to choose between them unpredictably. The wrong choice may execute a destructive operation when a read-only operation was intended.
255
+
256
+ *Exploit scenario*: `list_directory` ("List files and folders in a directory") and `list_directory_with_sizes` ("List files and folders in a directory with their sizes"). 92% overlap. The LLM may route a "show me the files" prompt to either tool non-deterministically. If one returns metadata that includes file permissions or ownership, it leaks information the user didn't request. This is a semantic race condition unique to LLM-driven tool selection.
257
+
258
+ *Found in*: 10% of servers with tools
259
+
260
+ ### 4.3 Impact
261
+
262
+ 163 hallucination-based vulnerabilities were found across 41 servers (4.0 per server average). One server — the European Parliament MCP server — contained 121 HBVs across 61 tools, primarily due to vague descriptions and missing scope boundaries on government data access tools.
263
+
264
+ HBVs are particularly dangerous because:
265
+ 1. They are invisible to traditional security scanners (SAST, DAST)
266
+ 2. They are non-deterministic — the same tool definition may behave differently across LLM models
267
+ 3. They cannot be fixed by patching code — they require rewriting tool descriptions
268
+ 4. They compound: a vague description + missing scope boundary + large tool surface = unpredictable agent behavior at scale
269
+
270
+ ---
271
+
272
+ ## 5. Analysis
273
+
274
+ ### 5.1 The Validation Crisis
275
+
276
+ 61% of all findings were input validation issues — tools accepting arbitrary input with no schema constraints, no string length limits, no pattern validation, and no required fields.
277
+
278
+ This matters because MCP tools receive their arguments from the LLM, which constructs them from natural language. Without schema validation, the tool handler must defend against every possible input the model might generate, including adversarial inputs from prompt injection attacks.
279
+
280
+ ### 5.2 The Permission Vacuum
281
+
282
+ 10% of findings related to permission gaps — destructive, financial, or privilege-escalation tools exposed without any access control mechanism.
283
+
284
+ The MCP specification provides no standard for per-tool authorization. A server can declare tools, but it cannot declare which agents should be allowed to call which tools. This means every connected agent has access to every tool, regardless of its role, trust level, or the human who authorized it.
285
+
286
+ ### 5.3 The Authentication Gap
287
+
288
+ 35 servers (85%) showed no authentication-related tools or indicators. While the MCP specification now includes an OAuth 2.1 authorization framework (added March 2025), adoption is minimal. Most servers authenticate at the transport level (if at all) and make no distinction between authenticated agents.
289
+
290
+ ### 5.4 Scale Correlates with Risk
291
+
292
+ Every server with more than 5 tools scored D or F. Tool count strongly correlates with security grade:
293
+
294
+ | Tool Count | Average Score | Average Grade |
295
+ |------------|--------------|---------------|
296
+ | 1-2 | 65 | C |
297
+ | 3-5 | 28 | F |
298
+ | 6-20 | 3 | F |
299
+ | 20+ | 0 | F |
300
+
301
+ This suggests that MCP server authors do not scale their security practices with their tool surface. Adding the 6th tool is the inflection point where security degrades catastrophically.
302
+
303
+ ---
304
+
305
+ ## 6. Recommendations
306
+
307
+ ### For MCP Server Authors
308
+
309
+ 1. **Validate all inputs** with complete schemas — required fields, string length limits, pattern constraints, and enum restrictions.
310
+ 2. **Write specific tool descriptions** — "Read a single file by path from the /data directory" not "access files." Avoid vague verbs (manage, handle, process).
311
+ 3. **Split ambiguous tools** — replace `manage_users` with `list_users`, `create_user`, `delete_user`. Each tool should do one thing.
312
+ 4. **Add scope boundaries** to descriptions — specify which directories, databases, or resources a tool can access.
313
+ 5. **Differentiate overlapping tools** — if two tools sound similar, clarify the distinction in both descriptions.
314
+
315
+ ### For the MCP Specification
316
+
317
+ 1. **Define a per-tool authorization standard** — the specification should include a mechanism for mapping agent identity to tool permissions, not just transport-level authentication.
318
+ 2. **Require input schema validation** — tool definitions without complete input schemas should be flagged as non-compliant.
319
+ 3. **Standardize audit log format** — every tool call should produce a structured audit entry with agent identity, tool name, parameters, result, and timestamp.
320
+ 4. **Add agent identity to the protocol** — agents should have verifiable identities, not just transport-level sessions.
321
+ 5. **Define delegation semantics** — when an agent spawns a sub-agent, the specification should define how permissions narrow.
322
+
323
+ ### For Developers Using MCP Servers
324
+
325
+ 1. **Scan before you connect** — run `npx @agentsid/scanner` against any MCP server before giving your agent access to it.
326
+ 2. **Add per-tool permissions** — use middleware (e.g., AgentsID Guard) to restrict which tools each agent can call.
327
+ 3. **Audit tool calls** — log every tool call with the agent identity, not just the action.
328
+ 4. **Review tool descriptions** — the description your LLM reads is the description it acts on. Vague descriptions are security vulnerabilities.
329
+
330
+ ---
331
+
332
+ ## 7. Conclusion
333
+
334
+ The MCP ecosystem is growing fast — 97 million monthly SDK downloads, 5,200+ servers, adoption by every major AI company. But our scan of 100 MCP server packages reveals a security posture that is, to put it directly, failing.
335
+
336
+ 71% of servers that exposed tools scored F on security. Zero scored A. The average server had 21.8 security findings. And a new class of vulnerability — hallucination-based vulnerabilities — accounts for 18% of all findings, a risk category that didn't exist before LLM-driven tool execution.
337
+
338
+ The gold standard audit makes the case definitive. Every vendor-maintained MCP server that exposed tools — including five of seven Anthropic reference implementations — scored F. The servers that the MCP specification authors ship as examples, that developers copy as templates, and that enterprises deploy as integrations are structurally vulnerable. The CVEs have already started arriving (CVE-2025-68143, CVE-2025-68144, CVE-2025-9611), and our scanner identifies the exact preconditions that made them possible.
339
+
340
+ The MCP specification has made significant progress on transport-level security (OAuth 2.1, PKCE). But transport-level authentication is orthogonal to tool-level security. An agent authenticated with a 2048-bit RSA key can still pass `rm -rf /` through an unbounded string parameter. OAuth does not validate tool inputs. PKCE does not enforce scope boundaries. The protocol has no answer for the per-tool authorization problem: which agent can call which tool, with what parameters, under what conditions, and who knows about it.
341
+
342
+ The MCP specification is **vulnerable by default**. It allows — and through its reference implementations, actively encourages — empty schemas, unbounded inputs, and vague tool descriptions. These are not oversights by individual developers; they are design choices in the protocol that make insecurity the path of least resistance. Schema strictness and semantic validation must move from optional best practice to protocol-level mandatory requirements.
343
+
344
+ Until the ecosystem addresses identity, permissions, and audit at the tool level — not just the transport level — MCP servers will remain the most under-secured component of the AI agent stack.
345
+
346
+ ---
347
+
348
+ ## Methodology Reproducibility
349
+
350
+ The scanner, grading methodology, and all 100 scan reports are open-source and publicly available:
351
+
352
+ - **Scanner**: github.com/stevenkozeniesky02/agentsid-scanner
353
+ - **Scan data**: github.com/stevenkozeniesky02/agentsid-scanner/tree/master/reports
354
+ - **Scanner methodology**: Documented in src/rules.mjs, src/grader.mjs
355
+
356
+ To reproduce any scan: `npx @agentsid/scanner -- npx <package-name>`
357
+
358
+ ---
359
+
360
+ ## Appendix C: Reference Implementation
361
+
362
+ The recommendations in Sections 6.1–6.3 are not theoretical. We built open-source tooling that implements each one, both to validate the recommendations and to provide a starting point for the ecosystem.
363
+
364
+ | Recommendation | Implementation | Status |
365
+ |----------------|---------------|--------|
366
+ | Per-tool authorization standard (§6.2.1) | **AgentsID Permission Specification** — 14 constraint types (schedule, rate limit, data classification, budget, sequence, session, risk score, IP allowlist, chain depth, cooldown, anomaly detection, approval gates) for defining what an agent can do at tool-level granularity. Open RFC at agentsid.dev/spec. | Published, open for comment |
367
+ | Input schema validation (§6.2.2) | **AgentsID Security Scanner** — the tool used to produce this report. Evaluates tool schemas, descriptions, injection patterns, and hallucination-based vulnerabilities. | Open-source: github.com/stevenkozeniesky02/agentsid-scanner |
368
+ | Audit log format (§6.2.3) | **Tamper-evident audit chain** — SHA-256 hash chain with agent identity, tool name, parameters, result, and timestamp per entry. Implemented in the AgentsID platform. | In production |
369
+ | Agent identity (§6.2.4) | **HMAC-SHA256 self-validating tokens** — agents receive tokens that encode identity and delegation chain without requiring a central lookup on every call. | In production |
370
+ | Delegation semantics (§6.2.5) | **Scope-narrowing delegation protocol** — parent agents can delegate subsets of their permissions to child agents, with cascading revocation. Children cannot escalate beyond parent scope. | In production |
371
+ | Middleware for per-tool permissions (§6.3.2) | **AgentsID Guard** — 50-tool MCP server across 16 categories (shell, files, database, git, HTTP, secrets, containers, cloud). Every tool call validated against per-agent permission rules before execution. | Open-source: npm @agentsid/guard |
372
+
373
+ All source code, the permission specification, and the scanner are available at **agentsid.dev**. The intent is not to promote a product but to demonstrate that the recommendations in this report are implementable today — and to give the ecosystem a concrete starting point rather than another list of aspirations.
374
+
375
+ ---
376
+
377
+ *This report was produced by AgentsID Research. Data collected March 29, 2026. For questions, contact research@agentsid.dev.*
@@ -0,0 +1,57 @@
1
+ # .github/workflows/security-scan.yml
2
+ #
3
+ # Drop this into any MCP server repo to get automatic security
4
+ # scans on every pull request. The scanner grades your server
5
+ # and comments on the PR with findings.
6
+ #
7
+ # Usage:
8
+ # 1. Copy this file to .github/workflows/security-scan.yml
9
+ # 2. Update the server-command to match your MCP server
10
+ # 3. Push — the scan runs on every PR
11
+ #
12
+ # Learn more: https://github.com/stevenkozeniesky02/agentsid-scanner
13
+
14
+ name: MCP Security Scan
15
+
16
+ on:
17
+ pull_request:
18
+ branches: [main, master]
19
+
20
+ permissions:
21
+ contents: read
22
+ pull-requests: write
23
+
24
+ jobs:
25
+ security-scan:
26
+ name: AgentsID Security Scan
27
+ runs-on: ubuntu-latest
28
+
29
+ steps:
30
+ - uses: actions/checkout@v4
31
+
32
+ - uses: actions/setup-node@v4
33
+ with:
34
+ node-version: '20'
35
+
36
+ - name: Install dependencies
37
+ run: npm ci
38
+
39
+ - name: Run AgentsID Security Scanner
40
+ uses: stevenkozeniesky02/agentsid-scanner@master
41
+ with:
42
+ # Option 1: Scan by starting your MCP server
43
+ server-command: 'node src/index.mjs'
44
+
45
+ # Option 2: Scan a remote server
46
+ # server-url: 'https://your-mcp-server.com/mcp'
47
+
48
+ # Option 3: Scan tool definitions from a JSON file
49
+ # tool-definitions: 'src/tools.json'
50
+
51
+ # Fail the PR if grade is below C
52
+ fail-on: 'C'
53
+
54
+ # Post results as a PR comment
55
+ comment: 'true'
56
+ env:
57
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@agentsid/scanner",
3
+ "version": "0.1.0",
4
+ "description": "Security scanner for MCP servers. Grades authentication, permissions, input validation, and tool safety. The Lighthouse of agent security.",
5
+ "type": "module",
6
+ "main": "src/index.mjs",
7
+ "bin": {
8
+ "agentsid-scan": "./src/index.mjs"
9
+ },
10
+ "scripts": {
11
+ "start": "node src/index.mjs",
12
+ "test": "node src/test.mjs"
13
+ },
14
+ "keywords": [
15
+ "mcp",
16
+ "security",
17
+ "scanner",
18
+ "audit",
19
+ "ai-agents",
20
+ "vulnerability",
21
+ "agentsid",
22
+ "mcp-server",
23
+ "authentication",
24
+ "permissions",
25
+ "github-action"
26
+ ],
27
+ "license": "MIT",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/stevenkozeniesky02/agentsid-scanner"
31
+ },
32
+ "dependencies": {
33
+ "@modelcontextprotocol/sdk": "^1.0.0",
34
+ "@actions/core": "^1.10.0",
35
+ "@actions/github": "^6.0.0"
36
+ }
37
+ }
@@ -0,0 +1,110 @@
1
+ {
2
+ "scanner": {
3
+ "name": "agentsid-scanner",
4
+ "version": "0.1.0"
5
+ },
6
+ "scannedAt": "2026-03-29T18:08:12.627Z",
7
+ "server": {
8
+ "name": "@aashari/mcp-server-atlassian-confluence",
9
+ "version": "3.3.0"
10
+ },
11
+ "toolCount": 5,
12
+ "grade": {
13
+ "overall": "F",
14
+ "score": 0,
15
+ "categories": {
16
+ "injection": "A",
17
+ "permissions": "B",
18
+ "validation": "C",
19
+ "auth": "B",
20
+ "secrets": "C"
21
+ }
22
+ },
23
+ "summary": {
24
+ "CRITICAL": 0,
25
+ "HIGH": 4,
26
+ "MEDIUM": 6,
27
+ "LOW": 0,
28
+ "INFO": 0
29
+ },
30
+ "riskProfile": {
31
+ "read_only": 0,
32
+ "mutation": 0,
33
+ "destructive": 1,
34
+ "execution": 0,
35
+ "privilege": 0,
36
+ "financial": 0
37
+ },
38
+ "findings": [
39
+ {
40
+ "category": "injection",
41
+ "severity": "MEDIUM",
42
+ "tool": "conf_get",
43
+ "rule": "excessive_description_length",
44
+ "detail": "Tool description is 1242 chars — unusually long, may contain hidden instructions"
45
+ },
46
+ {
47
+ "category": "permissions",
48
+ "severity": "HIGH",
49
+ "tool": "conf_delete",
50
+ "rule": "dangerous_tool_destructive",
51
+ "detail": "Tool \"conf_delete\" classified as destructive — requires permission controls"
52
+ },
53
+ {
54
+ "category": "validation",
55
+ "severity": "MEDIUM",
56
+ "tool": "conf_get",
57
+ "rule": "unbounded_strings",
58
+ "detail": "String parameters without length limits or pattern validation in tool \"conf_get\""
59
+ },
60
+ {
61
+ "category": "validation",
62
+ "severity": "MEDIUM",
63
+ "tool": "conf_post",
64
+ "rule": "unbounded_strings",
65
+ "detail": "String parameters without length limits or pattern validation in tool \"conf_post\""
66
+ },
67
+ {
68
+ "category": "validation",
69
+ "severity": "MEDIUM",
70
+ "tool": "conf_put",
71
+ "rule": "unbounded_strings",
72
+ "detail": "String parameters without length limits or pattern validation in tool \"conf_put\""
73
+ },
74
+ {
75
+ "category": "validation",
76
+ "severity": "MEDIUM",
77
+ "tool": "conf_patch",
78
+ "rule": "unbounded_strings",
79
+ "detail": "String parameters without length limits or pattern validation in tool \"conf_patch\""
80
+ },
81
+ {
82
+ "category": "validation",
83
+ "severity": "MEDIUM",
84
+ "tool": "conf_delete",
85
+ "rule": "unbounded_strings",
86
+ "detail": "String parameters without length limits or pattern validation in tool \"conf_delete\""
87
+ },
88
+ {
89
+ "category": "auth",
90
+ "severity": "HIGH",
91
+ "tool": "*",
92
+ "rule": "no_auth_tools",
93
+ "detail": "Server exposes no authentication-related tools — may accept unauthenticated connections"
94
+ },
95
+ {
96
+ "category": "secrets",
97
+ "severity": "HIGH",
98
+ "tool": "conf_get",
99
+ "rule": "potential_secret_exposure",
100
+ "detail": "Tool \"conf_get\" may expose secrets in its output based on description"
101
+ },
102
+ {
103
+ "category": "secrets",
104
+ "severity": "HIGH",
105
+ "tool": "conf_post",
106
+ "rule": "potential_secret_exposure",
107
+ "detail": "Tool \"conf_post\" may expose secrets in its output based on description"
108
+ }
109
+ ]
110
+ }