Back to skill

Security audit

mcp-builder

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent MCP-building guide, but its optional evaluation harness can send full MCP tool results and errors to Anthropic and does not strongly constrain remote or tool access.

Install only if you are comfortable using a Claude-based evaluation harness. Run it in an isolated environment, use only test or low-sensitivity MCP servers and credentials, prefer HTTPS remote URLs, avoid passing production authorization headers, and review saved evaluation reports before sharing or committing them because they may contain tool data.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/evaluation.py:116
Finding
Unredacted MCP Tool Results and Exception Tracebacks Are Sent to Anthropic<![CDATA[ ## Vulnerability Details **File Location**: `scripts/evaluation.py:116-144` **Vulnerability Type**: External transmission of potentially sensitive tool output **Risk Level**: Medium ### Vulnerable Code ```python 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() tool_duration = time.time() - tool_start_ts if tool_name not in tool_metrics: tool_metrics[tool_name] = {"count": 0, "durations": []} tool_metrics[tool_name]["count"] += 1 tool_metrics[tool_name]["durations"].append(tool_duration) messages.append({ "role": "user", "content": [{ "type": "tool_result", "tool_use_id": tool_use.id, "content": tool_response, }] }) response = await asyncio.to_thread( client.messages.create, model=model, max_tokens=4096, system=EVALUATION_PROMPT, messages=messages, tools=tools, ) ``` ### Technical Analysis The evaluation harness serializes complete MCP tool results and places them into the conversation sent to the Anthropic API. There is no sensitive-data classification, secret redaction, output-size restriction, or per-result confirmation before transmission. An evaluated MCP server may return private repository content, customer information, internal documents, access tokens, API keys, or other confidential records. If a tool raises an exception, the harness additionally transmits `str(e)` and a complete Python traceback. Exception messages and tracebacks may contain local file paths, req ...[truncated 1875 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Clearly disclose before execution that evaluation questions, tool schemas, tool inputs, tool outputs, and model responses are sent to Anthropic. 2. Require explicit opt-in before transmitting MCP tool results to an external model provider. 3. Redact authorization headers, API keys, bearer tokens, cookies, passwords, private keys, and other common secret formats. 4. Do not send full tracebacks to the model. Log sanitized diagnostics locally and return a generic tool error to the conversation. 5. Apply strict response-size and token limits before adding tool output to `messages`. 6. Add configurable field allowlists or data-classification policies for tools that may return private data. 7. Update the system prompt to state that tool results are untrusted data and that instructions contained inside tool output must not be followed. 8. Provide a local or offline model option for evaluations involving confidential data. 9. Restrict evaluation runs to verified read-only tools rather than relying solely on MCP annotation hints. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/connections.py:86
Finding
Remote MCP Transports Accept Authentication Headers Without Enforcing HTTPS<![CDATA[ ## Vulnerability Details **File Location**: `scripts/connections.py:86-99` **Vulnerability Type**: Plaintext transmission of authentication credentials and MCP data **Risk Level**: Medium ### Vulnerable Code ```python class MCPConnectionSSE(MCPConnection): """MCP connection using Server-Sent Events.""" def __init__(self, url: str, headers: dict[str, str] = None): super().__init__() self.url = url self.headers = headers or {} def _create_context(self): return sse_client(url=self.url, headers=self.headers) class MCPConnectionHTTP(MCPConnection): """MCP connection using Streamable HTTP.""" def __init__(self, url: str, headers: dict[str, str] = None): super().__init__() self.url = url self.headers = headers or {} def _create_context(self): return streamablehttp_client(url=self.url, headers=self.headers) ``` The connection factory at `scripts/connections.py:119-143` verifies only that a URL is present. The CLI at `scripts/evaluation.py:331-332` permits users to supply arbitrary URLs and headers, including authorization tokens. ### Technical Analysis The harness forwards custom HTTP headers directly to the supplied SSE or streamable HTTP URL. It does not parse the URL or require the `https` scheme. Consequently, a user can configure an `http` endpoint while also providing a bearer token or other sensitive headers. Although the documentation examples use HTTPS, this is not enforced by executable code. Plaintext transport allows network observers to read authorization headers, evaluation requests, MCP tool arguments, and MCP tool responses. An active network attacker may also modify tool descriptions or responses before they reach the evaluation agent. Loopback HTTP may be reasonable for local development, but unrestricted plaintext remote transport is broader than necessary for the declared remote evaluation functionality. ### Attack Path 1. A user supplies ...[truncated 1121 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse remote URLs before creating a connection and require the `https` scheme by default. 2. Allow plaintext HTTP only for explicit loopback destinations such as `localhost`, `127.0.0.1`, or `::1`. 3. If non-loopback plaintext transport is required, require an explicit `--allow-insecure-http` option and display a prominent warning. 4. Reject authorization headers and other credential-bearing headers when an insecure transport is selected. 5. Preserve normal TLS certificate and hostname verification; do not add certificate-verification bypasses. 6. Consider destination allowlists for automated or shared evaluation environments. 7. Document the credential and MCP-data exposure risks of remote transports. 8. Add tests confirming that plaintext remote URLs are rejected and that HTTPS URLs remain supported. ]]>

T08 · Insecure Dependencies

Note
Location
scripts/requirements.txt:1
Finding
Third-Party Dependencies Use Unbounded Version Ranges<![CDATA[ ## Vulnerability Details **File Location**: `scripts/requirements.txt:1-2` **Vulnerability Type**: Non-reproducible and insufficiently constrained dependencies **Risk Level**: Low ### Vulnerable Code ```text anthropic>=0.39.0 mcp>=1.1.0 ``` The installation workflow at `reference/evaluation.md:384-392` directs users to install these packages with: ```bash pip install -r scripts/requirements.txt ``` ### Technical Analysis Both dependencies specify only a minimum version. Pip may therefore install any later release available at installation time. The package set can change after the Skill has been audited, and the project provides no lock file or package hashes to verify the exact artifacts being installed. The package names correspond to expected dependencies and there is no evidence of typosquatting, dependency confusion, or an intentionally malicious package. The risk arises from future supply-chain compromise, unexpected breaking changes, or a malicious release becoming eligible under the open-ended constraints. Python package installation can execute package build hooks or install code that later runs with the evaluation harness. Because the harness handles API credentials, starts local MCP subprocesses, and accesses remote services, dependency integrity is security-relevant. ### Attack Path 1. A future eligible release of `anthropic`, `mcp`, or a transitive dependency is compromised or behaves maliciously. 2. A user follows the documented installation command at a later date. 3. Pip resolves the unbounded requirement to the compromised release. 4. Package build or runtime code executes under the user account. 5. The malicious dependency may access environment variables, evaluation data, network credentials, files available to the user, or subprocess configuration. This is a conditional supply-chain path; no currently bundled dependency was demonstrated to be malicious. ### Impact Assessment A compromised dependency would execute with ...[truncated 495 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin direct dependencies to reviewed exact versions. 2. Generate and commit a lock file containing fully resolved transitive dependencies. 3. Use package hashes and install with hash verification, such as pip's `--require-hashes` mode. 4. Perform dependency updates through a controlled review process rather than accepting arbitrary future releases. 5. Run vulnerability and provenance checks when updating the lock file. 6. Install and run the evaluation harness in an isolated virtual environment or container without elevated privileges. 7. Avoid exposing unrelated environment variables or files to the evaluation environment. 8. Document the reviewed Python version and dependency versions to make installation reproducible. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (24)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared purpose presents the skill as a documentation guide, but the detected behavior extends into operational actions such as connecting to live MCP servers, invoking tools, calling an external LLM API, parsing evaluation datasets, and writing reports. This mismatch is dangerous because users may authorize or run the skill under the assumption that it is passive guidance when it can actually trigger network access, data processing, and potentially sensitive external interactions.

Ae1

High
Category
analysis-evasion
Content
- [⚡ TypeScript Implementation Guide](./reference/node_mcp_server.md) - Node/TypeScript-specific best practices and examples
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- [⚡ TypeScript Implementation Guide](./reference/node_mcp_server.md) - Node/TypeScript-specific best practices and examples
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- [⚡ TypeScript Implementation Guide](./reference/node_mcp_server.md) - Node/TypeScript-specific best practices and examples
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- [⚡ TypeScript Implementation Guide](./reference/node_mcp_server.md) - Node/TypeScript-specific best practices and examples
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- [⚡ TypeScript Implementation Guide](./reference/node_mcp_server.md) - Node/TypeScript-specific best practices and examples
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

External Model or Provider Selection

High
Category
Excessive Agency
Content
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:
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.

Credential Access

High
Category
Privilege Escalation
Content
**OAuth 2.1 Implementation:**
- Use secure OAuth 2.1 with certificates from recognized authorities
- Validate access tokens before processing requests
- Only accept tokens specifically intended for your server
- Reject tokens without proper audience claims
- Never pass through tokens received from MCP clients
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding
The skill appears capable of writing files and interacting with MCP-related external capabilities, but it declares no explicit tool scope such as permissions or allowed-tools. That creates an avoidable trust gap: an agent or reviewer cannot easily tell what the skill is permitted to do, increasing the chance of overbroad execution or unintended side effects.

Unrestricted Tool Access

Medium
Category
Excessive Agency
Content
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
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.

Whitespace Padding

Medium
Category
Prompt Injection
Content
The MCP specification defines the following annotations for tools:

| Annotation        | Type    | Default | Description                                                                                                                          |
| ----------------- | ------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `title`           | string  | -       | A human-readable title for the tool, useful for UI display                                                                           |
| `readOnlyHint`    | boolean | false   | If true, indicates the tool does not modify its environment                                                                          |
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
mcp = FastMCP("example_mcp")

# Constants
API_BASE_URL = "https://api.example.com/v1"
CHARACTER_LIMIT = 25000  # Maximum response size in characters

# Enums
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
mcp = FastMCP("example_mcp")

# Constants
API_BASE_URL = "https://api.example.com/v1"
CHARACTER_LIMIT = 25000  # Maximum response size in characters

# Enums
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The guide explicitly demonstrates use of `ctx.elicit(..., input_type="password")` to request an API key from the user, but it provides no accompanying warning about secure credential handling, storage minimization, redaction, or safer alternatives such as environment-based auth. In a skill that teaches MCP server design, this can normalize collecting secrets interactively and lead downstream implementations to mishandle credentials or expose them through logs, memory, traces, or prompt context.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The evaluation prompt explicitly instructs the model to include each tool input and output in its generated summary. Because MCP tools may access external services and return sensitive data, this design causes unnecessary disclosure to Anthropic during processing and then re-exposes that data in the final report without any user warning or minimization. In the context of an MCP evaluation harness, this is more dangerous because the whole purpose is to exercise arbitrary tools, which may handle secrets, personal data, or proprietary API responses.

Ssd 3

Medium
Confidence
98% confidence
Finding
The prompt requires disclosure of full tool inputs and outputs in the summary, which is a direct data-spillage pattern. Any sensitive user input, authentication material, personal data, or confidential API response accessed via MCP tools may be copied into model output and ultimately the report, violating least-privilege and data-minimization principles. This is especially risky in an MCP builder/evaluation context because tool schemas and responses are highly variable and may not be privacy-safe by default.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script forwards raw tool results and full exception tracebacks directly to the external model. This can leak sensitive data from tool responses, internal error details, stack traces, file paths, or credentials embedded in failures to a third-party API, even when those details are not needed to answer the evaluation question. Given this skill's purpose of testing arbitrary MCP servers, the exposure surface is broad and materially increases risk.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The generated report persists model-produced summary and feedback content to disk, and that content may include sensitive tool inputs/outputs because the prompt asked the model to reproduce them. Saving such data without warning or review can create an at-rest leakage channel, especially if reports are shared, committed, or stored in insecure locations. In an evaluation workflow, report artifacts are likely to be retained, amplifying exposure duration.

Intent-Code Divergence

Low
Confidence
98% confidence
Finding
The documentation explicitly states 'Avoid `any`' as a TypeScript best practice, but earlier examples define `makeApiRequest<any>`, `const response: any`, and map over `(user: any)`, and later include `data?: any` and `params?: any`. This is an active contradiction between the guide's stated coding intent and the example code it provides.

Intent-Code Divergence

Low
Confidence
97% confidence
Finding
The checklist says 'No use of `any` type - use `unknown` or proper types instead', yet the guide's own sample tool and shared utility code use `any` in several places. That makes the checklist's stated requirement inconsistent with the actual implementation guidance given elsewhere in the file.

Unpinned Dependencies

Low
Category
Supply Chain
Content
anthropic>=0.39.0
mcp>=1.1.0
Confidence
96% confidence
Finding
The dependency is specified with a lower bound only (`anthropic>=0.39.0`), which makes builds non-reproducible and can pull in different versions over time, including newly introduced vulnerable or breaking releases. In a security-sensitive skill for building MCP servers, this increases supply-chain risk because generated environments may unpredictably install affected SDK versions.

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 an exact version, while advisories exist for that package, so it is impossible to verify from this file whether deployment will install a vulnerable release. This does not prove exploitation by itself, but it creates uncertainty and can result in vulnerable environments being installed depending on resolution time.

Unpinned Dependencies

Low
Category
Supply Chain
Content
anthropic>=0.39.0
mcp>=1.1.0
Confidence
97% confidence
Finding
The `mcp` package is also unpinned (`mcp>=1.1.0`), so installations may resolve to any newer release, including versions with known security issues or incompatible behavior. Because this skill is specifically about creating MCP servers that expose tools to external clients, dependency drift in the core MCP SDK is more dangerous than in a generic application and can directly affect server-side security controls.

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
95% confidence
Finding
The `mcp` dependency has multiple known advisories, and because the manifest does not pin a version, there is no way to determine whether the installed SDK will include one of those flaws. Given that MCP server frameworks often mediate external tool execution and network-facing interactions, uncertainty around the exact `mcp` version materially raises the chance of deploying an exposed server with known weaknesses.

Static analysis

No suspicious patterns detected.