Back to skill

Security audit

Mcp Builder test

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent MCP development guide, but its evaluation harness can send unredacted MCP tool data to Anthropic and call any exposed MCP tool without enforcing read-only limits.

Install only if you will use it in a disposable or least-privileged environment. Do not run the evaluation harness against production MCP servers, broad-scope credentials, private datasets, or sensitive tool outputs unless you accept that tool schemas, questions, tool inputs, tool outputs, summaries, and errors may be sent to Anthropic. Pin dependencies before use and harden any copied HTTP or file-resource examples.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/evaluation.py:83
Finding

Evaluation Harness Does Not Enforce Read-Only Tool Execution

Content
View full analysis
tuple[str, dict[str, Any]]: """Run the agent loop with MCP tools.""" messages = [{"role": "user", "content": question}] response = await asyncio.to_thread( client.messages.create, model=model, max_tokens=4096, system=EVALUATION_PROMPT, messages=messages, tools=tools, ) messages.append({"role": "assistant", "content": response.content}) tool_metrics = {} while response.stop_reason == "tool_use": tool_use = next(block for block in response.content if block.type == "tool_use") tool_name = tool_use.name tool_input = tool_use.input tool_start_ts = time.time() try: tool_result = await connection.call_tool(tool_name, tool_input) tool_response = json.dumps(tool_result) if isinstance(tool_result, (dict, list)) else str(tool_result) except Exception as e: tool_response = f"Error executing tool {tool_name}: {str(e)}\n" tool_response += traceback.format_exc() ``` The connection layer also strips MCP behavioral annotations when exposing tools: ```python async def list_tools(self) -> list[dict[str, Any]]: """Retrieve available tools from the MCP server.""" response = await self.session.list_tools() return [ { "name": tool.name, "description": tool.description, "input_schema": tool.inputSchema, } for tool in response.tools ] async def call_tool(self, tool_name: str, arguments: dict[str, Any]) -> Any: ...[truncated 2051 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/evaluation.py:94
Finding

Sensitive MCP Results and Internal Tracebacks Are Forwarded to an External Model Provider

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
reference/node_mcp_server.md:824
Finding

Reference Streamable HTTP Server Lacks Authentication and Safe Network Binding

Content
View full analysis
{ // Create new transport for each request (stateless, prevents request ID collisions) const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined, enableJsonResponse: true }); res.on('close', () => transport.close()); await server.connect(transport); await transport.handleRequest(req, res, req.body); }); app.listen(3000); ``` The complete example similarly exposes the endpoint without authenticating the caller: ```typescript const app = express(); app.use(express.json()); app.post('/mcp', async (req, res) => { const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined, enableJsonResponse: true }); res.on('close', () => transport.close()); await server.connect(transport); await transport.handleRequest(req, res, req.body); }); const port = parseInt(process.env.PORT || '3000'); app.listen(port, () => { console.error(`MCP server running on http://localhost:${port}/mcp`); }); ``` ### Technical Analysis The examples register an MCP endpoint without authentication or authorization middleware. They also do not validate `Origin` or `Host` headers, enable DNS-rebinding protection, apply request-size limits, or explicitly bind to `127.0.0.1`. Calling `app.listen(3000)` without a hostname commonly listens on all available interfaces. The log message claiming that the server runs on `localhost` does not constrain the actual binding. The earlier environment-variable che ...[truncated 1390 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
reference/python_mcp_server.md:541
Finding

Python Resource Example Is Vulnerable to Directory Traversal

Content
View full analysis
str: '''Expose documents as MCP resources. Resources are useful for static or semi-static data that doesn't require complex parameters. They use URI templates for flexible access. ''' document_path = f"./docs/{name}" with open(document_path, "r") as f: return f.read() ``` ### Technical Analysis The `name` parameter is controlled by the MCP caller and is interpolated directly into a filesystem path. The code performs no canonicalization, validation, or containment check. A value containing traversal components such as `../../` can cause the resolved path to escape the intended `./docs` directory. Absolute paths or platform-specific separators may create equivalent behavior depending on parsing and deployment. The operation remains constrained by the operating-system permissions of the MCP server process, but MCP servers commonly have access to configuration files, environment-related files, source code, and user data. ### Attack Path 1. An attacker identifies the `file://documents/{name}` resource template. 2. The attacker supplies a traversal value such as `../../.env`. 3. The handler creates `./docs/../../.env`. 4. The operating system resolves the traversal outside the document root. 5. The handler opens the file and returns its contents through MCP. ### Impact Assessment A successful attack can disclose any readable file accessible to the server process, potentially including: - Environment and configuration files. - API keys or service credentials stored on disk. - Application source code. - Private keys or tokens. - User documents and internal datasets. Leaked credentials could enable follow-on access to external systems, ...[truncated 49 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/requirements.txt:1
Finding

Unpinned Dependencies and Unversioned Package Execution Create Supply-Chain Risk

Content
View full analysis
=0.39.0 mcp>=1.1.0 ``` The Skill also recommends executing an unversioned npm package: ```markdown - Test with MCP Inspector: `npx @modelcontextprotocol/inspector` ``` The evaluation guide permits fully unpinned installation: ```bash pip install -r scripts/requirements.txt ``` ```bash pip install anthropic mcp ``` ### Technical Analysis The Python requirements specify only minimum versions, allowing installation of any future compatible or incompatible release. The manual installation command imposes no version constraints at all. The `npx @modelcontextprotocol/inspector` command resolves and executes a package version at invocation time. Therefore, the code executed by users can change after the Skill has been reviewed. No lockfile, hash verification, integrity metadata, or exact audited version is provided. This creates a supply-chain exposure and prevents reproducible installation. The audit did not identify evidence that the named packages are currently malicious; the issue is the unsafe dependency policy. ### Attack Path 1. A user follows the Skill’s setup or testing instructions. 2. The package manager resolves the latest package versions allowed by the broad constraints. 3. A future compromised, malicious, or unexpectedly incompatible release is selected. 4. Package installation hooks, imported package code, or the `npx` command executes on the user’s machine. 5. The third-party code runs with the privileges of the user performing the installation or evaluation. ### Impact Assessment A compromised dependency or package release could execute arbitrary code with the invoking user’s privile ...[truncated 467 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (21)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

A description-behavior mismatch is security-relevant because users may trust the skill as a simple development guide while it also drives evaluation workflows that can connect to local or remote MCP servers, execute tools, and interact with external APIs. That hidden operational breadth increases the risk of unexpected network access, tool execution, data exposure, or unintended costs.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 62)May include surrounding context.

md
- [⚡ TypeScript Guide](./reference/node_mcp_server.md) - TypeScript patterns and examples

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 83)May include surrounding context.

md
- [⚡ TypeScript Guide](./reference/node_mcp_server.md) - TypeScript patterns and examples

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 223)May include surrounding context.

md
- [⚡ TypeScript Guide](./reference/node_mcp_server.md) - TypeScript patterns and examples

External Model or Provider Selection

High
Category
Excessive Agency
Confidence
90% confidence
Finding

Skill selects an external model or provider that may use a different account or billing plan than the operator expects. Undisclosed model switches can cause unexpected cost or quota consumption.

Content

Scanner excerpt · reference/evaluation.md (reported line 488)May include surrounding context.

md
optional arguments:
  -h, --help            Show help message
  -t, --transport       Transport type: stdio, sse, or http (default: stdio)
  -m, --model           Claude model to use (default: claude-3-7-sonnet-20250219)
  -o, --output          Output file for report (default: print to stdout)

stdio options:

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · reference/mcp_best_practices.md (reported line 158)May include surrounding context.

md
**OAuth 2.1**:
- Use secure OAuth 2.1 with certificates from recognized authorities
- Validate access tokens before processing requests
- Only accept tokens specifically intended for your server

**API Keys**:

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill instructs the user to create projects, run commands, fetch remote content, and produce evaluation artifacts, yet it declares no explicit tool scope or permissions boundaries. In an agentic environment, missing scope metadata can cause the skill to be invoked with broader capabilities than intended, increasing the chance of unintended file writes or MCP interactions.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
77% confidence
Finding

Using npx @modelcontextprotocol/inspector without a pinned version introduces a supply-chain risk because the latest package version will be resolved at execution time. If the package is compromised or a breaking release is published, users may run unreviewed code in their local environment.

Content

No source excerpt is available for this finding.

Unrestricted Tool Access

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill grants unrestricted tool access without appropriate constraints. An agent with unfettered tool access can perform arbitrary actions including file modification, network requests, and code execution.

Content

Scanner excerpt · reference/evaluation.md (reported line 205)May include surrounding context.

md
After understanding the API and tools, USE the MCP server tools:
- Inspect content using READ-ONLY and NON-DESTRUCTIVE operations ONLY
- Goal: identify specific content (e.g., users, channels, messages, projects, tasks) for creating realistic questions
- Should NOT call any tools that modify state
- Will NOT read the code of the MCP server implementation itself
- Parallelize this step with individual sub-agents pursuing independent explorations
- Ensure each subagent is only performing READ-ONLY, NON-DESTRUCTIVE, and IDEMPOTENT operations

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · reference/node_mcp_server.md (reported line 601)May include surrounding context.

md
mcp = FastMCP("example_mcp")

# Constants
API_BASE_URL = "https://api.example.com/v1"

# Enums
class ResponseFormat(str, Enum):

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · reference/python_mcp_server.md (reported line 353)May include surrounding context.

md
mcp = FastMCP("example_mcp")

# Constants
API_BASE_URL = "https://api.example.com/v1"

# Enums
class ResponseFormat(str, Enum):

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The guide demonstrates use of ctx.elicit to request an API key and ctx.read_resource/file-backed resources without accompanying security guidance on secrets handling, least-privilege access, consent, redaction, or scope restrictions. In a skill intended to teach MCP server authors, omission of those safeguards can propagate insecure implementations that collect credentials in-tool or expose local data through resources.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The example explicitly instructs tools to ask users, in-band, for an API key via ctx.elicit(prompt="Please provide your API key:", input_type="password"). Even with a password input type, normalizing direct secret collection inside tool flows encourages phishing-like UX, mishandling of credentials, and accidental retention in logs, traces, prompts, or downstream calls.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The system prompt explicitly instructs the model to include the inputs and outputs of every tool call in its summary. In an evaluation harness for MCP servers, those tool arguments and results can easily contain credentials, tokens, personal data, proprietary API responses, or sensitive operational details, which are then copied into the generated report and potentially persisted or shared.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

When a tool call fails, the code returns both the exception message and full Python traceback to the model as tool output. That can expose filesystem paths, stack frames, library versions, internal code structure, secrets embedded in errors, or backend details from the MCP server, and the model may then reproduce that information in summaries, feedback, or logs.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The description says to use the skill "when building MCP servers to integrate external APIs or services," which is a wide activation condition without explicit boundaries or negative examples. Because it covers a broad class of development tasks, it may ambiguously trigger for many MCP-related requests beyond the intended scope.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

At L058-L061 the guide says to use only modern register* APIs and explicitly avoid older/manual handler patterns. Later, L865-L871 shows server.notification(...), which is not one of the recommended register* APIs and appears inconsistent with the guide's own stated API direction, creating a documentation-to-code example contradiction within the skill content.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency specifier uses a lower bound only (anthropic>=0.39.0), which makes builds non-reproducible and allows future installs to pull in newer releases with breaking changes or newly introduced security issues. In a security-sensitive skill focused on building MCP servers, dependency drift increases supply-chain risk because the resulting server may silently consume vulnerable or incompatible SDK versions.

Content

Scanner excerpt · scripts/requirements.txt (reported line 1)May include surrounding context.

text
anthropic>=0.39.0
mcp>=1.1.0

Unverifiable Dependency: anthropic has 4 known advisory(ies) (CVE-2026-34450 (Claude SDK for Python has Insecure Default File Permissions in Local Filesystem ); CVE-2026-34452 (Claude SDK for Python: Memory Tool Path Validation Race Condition Allows Sandbox); CVE-2026-34450 (The Claude SDK for Python provides access to the Claude API from Python applicat) +1 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
88% confidence
Finding

The manifest references anthropic without pinning, and the package has known advisories, so it is impossible to verify from this file whether the installed version is affected. While this file alone does not prove exploitation, the inability to constrain to a patched release creates a real supply-chain exposure and weakens vulnerability management.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency specifier mcp>=1.1.0 is unpinned, so installations may resolve to any later version, preventing reproducible builds and making it hard to know which code is actually deployed. This is more concerning here because the skill is explicitly about creating MCP servers, so an unsafe or newly vulnerable MCP SDK release could directly affect generated integrations.

Content

Scanner excerpt · scripts/requirements.txt (reported line 2)May include surrounding context.

text
anthropic>=0.39.0
mcp>=1.1.0

Unverifiable Dependency: mcp has 12 known advisory(ies) (CVE-2025-53366 (MCP Python SDK vulnerability in the FastMCP Server causes validation error, lead); CVE-2025-66416 (Model Context Protocol (MCP) Python SDK does not enable DNS rebinding protection); CVE-2026-52870 (MCP Python SDK: Experimental task handlers allow any client to access and cancel) +9 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The mcp package has multiple known advisories, and because the dependency is not pinned, the manifest does not demonstrate that only patched versions will be installed. Given that this skill is specifically for building MCP servers, uncertainty around the MCP SDK version is more dangerous because any affected release could directly expose generated servers to protocol, validation, or access-control flaws.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.