High risk. Don't ship without significant remediation.
Scanned 5/1/2026, 4:57:54 AMΒ·Cached resultΒ·Deep ScanΒ·88 rulesΒ·View source βΒ·How we decide β
AIVSS Score
High
Severity Breakdown
0
critical
7
high
3
medium
0
low
MCP Server Information
Findings
This package carries significant security concerns with a D grade and 68/100 safety score, driven primarily by seven high-severity findings centered on prompt injection vulnerabilities and tool poisoning risks. The five prompt injection issues and two tool poisoning findings suggest the server inadequately validates or sanitizes user inputs before processing them, creating potential pathways for attackers to manipulate model behavior or compromise tool execution. While no critical vulnerabilities were identified, the combination of input validation weaknesses and server configuration issues warrants careful review before deployment in production environments.
AIPer-finding remediation generated by bedrock-claude-haiku-4-5 β 10 of 10 findings. Click any finding to read.
Dependencies
@modelcontextprotocol/sdk (2)
Scan Details
Done
Sign in to save scan history and re-scan automatically on new commits.
Building your own MCP server?
Same rules, same LLM judges, same grade. Private scans stay isolated to your account and never appear in the public registry. Required for code your team hasnβt shipped yet.
10 of 10 findings
10 findings
Tool 'brave_web_search' shadows reserved name 'web_search' from search category without server-specific prefix.
Evidence
| 4 | import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; |
| 5 | const WEB_SEARCH_TOOL = { |
| 6 | name: "brave_web_search", |
| 7 | description: "Performs a web search using the Brave Search API, ideal for general queries, news, articles, and online content. " + |
| 8 | "Use this for broad information gathering, recent events, or when you need diverse web sources. " + |
| 9 | "Supports pagination, content filtering, and freshness controls. " + |
| 10 | "Maximum 20 res |
RemediationAI
The tool name 'brave_web_search' collides with the reserved 'web_search' name from the search category, creating namespace ambiguity in MCP tool resolution. Rename the tool to include a server-specific prefix by changing the `name` field in `WEB_SEARCH_TOOL` from 'brave_web_search' to 'brave:web_search' (or similar namespace convention). This explicit prefixing eliminates collision risk and makes the tool's origin unambiguous to callers. Verify by running `npm run build` and confirming the tool list in MCP introspection shows the new prefixed name without conflicts.
Tool 'brave_local_search' uses module-level global BRAVE_API_KEY (read from process.env at line 68) to call Brave Local Search API without consulting caller identity.
Evidence
| 30 | }, |
| 31 | }; |
| 32 | const LOCAL_SEARCH_TOOL = { |
| 33 | name: "brave_local_search", |
| 34 | description: "Searches for local businesses and places using Brave's Local Search API. " + |
| 35 | "Best for queries related to physical locations, businesses, restaurants, services, etc. " + |
| 36 | "Returns detailed information including:\n" + |
RemediationAI
The `brave_local_search` tool handler reads `BRAVE_API_KEY` from module-level scope (initialized at line 68 from `process.env`) and uses it for all requests regardless of caller identity, allowing any caller to consume the shared API quota and credentials. Refactor the tool handler to accept the API key as a request parameter or retrieve it from an MCP-provided resource/credential context (via `server.setRequestHandler()` with caller context), then pass it explicitly to the Brave API call. This change ensures each caller's identity and quota are tracked independently, preventing credential sharing. Test by instantiating two separate MCP clients and verifying their API calls are logged with distinct caller identifiers.
Tool 'brave_web_search' uses module-level global BRAVE_API_KEY (read from process.env at line 68) to call Brave Search API without consulting caller identity.
Evidence
| 11 | inputSchema: { |
| 12 | type: "object", |
| 13 | properties: { |
| 14 | query: { |
| 15 | type: "string", |
| 16 | description: "Search query (max 400 chars, 50 words)" |
| 17 | }, |
RemediationAI
The `brave_web_search` tool handler reads `BRAVE_API_KEY` from module-level scope (initialized at line 68 from `process.env`) and uses it for all requests regardless of caller identity, allowing any caller to consume the shared API quota and credentials. Refactor the tool handler to accept the API key as a request parameter or retrieve it from an MCP-provided resource/credential context (via `server.setRequestHandler()` with caller context), then pass it explicitly to the Brave API call. This change ensures each caller's identity and quota are tracked independently, preventing credential sharing. Test by instantiating two separate MCP clients and verifying their API calls are logged with distinct caller identifiers.
Tool 'brave_local_search' makes undisclosed NETWORK calls to the Brave Local Search API via HTTP(S) requests in the handler.
Evidence
| 29 | required: ["query"], |
| 30 | }, |
| 31 | }; |
| 32 | const LOCAL_SEARCH_TOOL = { |
| 33 | name: "brave_local_search", |
| 34 | description: "Searches for local businesses and places using Brave's Local Search API. " + |
| 35 | "Best for queries related to physical locations, businesses, restaurants, services, etc. " + |
RemediationAI
The `brave_local_search` tool description does not disclose that the handler makes external HTTP(S) network calls to the Brave Local Search API, violating transparency requirements for MCP tools. Add a `_meta` or `capabilities` field to the `LOCAL_SEARCH_TOOL` definition (or update the description) to explicitly declare `"network": true` and document the external dependency. Alternatively, add a comment in the handler function and update the tool schema to include a `capabilities` array with `"network"`. Verify by checking that MCP tool introspection or documentation now clearly lists network access as a capability.
Tool 'brave_web_search' makes undisclosed NETWORK calls to the Brave Search API via HTTP(S) requests in the handler.
Evidence
| 7 | description: "Performs a web search using the Brave Search API, ideal for general queries, news, articles, and online content. " + |
| 8 | "Use this for broad information gathering, recent events, or when you need diverse web sources. " + |
| 9 | "Supports pagination, content filtering, and freshness controls. " + |
| 10 | "Maximum 20 results per request, with offset for pagination. ", |
| 11 | inputSchema: { |
| 12 | type: "object", |
| 13 | properties: { |
RemediationAI
The `brave_web_search` tool description does not disclose that the handler makes external HTTP(S) network calls to the Brave Search API, violating transparency requirements for MCP tools. Add a `_meta` or `capabilities` field to the `WEB_SEARCH_TOOL` definition (or update the description) to explicitly declare `"network": true` and document the external dependency. Alternatively, add a comment in the handler function and update the tool schema to include a `capabilities` array with `"network"`. Verify by checking that MCP tool introspection or documentation now clearly lists network access as a capability.
Tool 'brave_local_search' fetches untrusted local business data from external Brave Local Search API and returns it verbatim to the LLM without provenance delimiters or source attribution markers.
Evidence
| 32 | const LOCAL_SEARCH_TOOL = { |
| 33 | name: "brave_local_search", |
| 34 | description: "Searches for local businesses and places using Brave's Local Search API. " + |
| 35 | "Best for queries related to physical locations, businesses, restaurants, services, etc. " + |
| 36 | "Returns detailed information including:\n" + |
| 37 | "- Business names and addresses\n" + |
| 38 | "- Ratings and review counts\n" + |
RemediationAI
The `brave_local_search` handler returns untrusted external data from the Brave API directly to the LLM without source attribution or provenance markers, allowing the LLM to treat unverified business information as authoritative. Wrap the API response in a structured object that includes explicit source attribution (e.g., `{ source: 'Brave Local Search API', timestamp: ..., results: [...] }`) and prepend each result with a provenance delimiter such as `[SOURCE: Brave Local Search]` in the text. This change ensures the LLM can distinguish external data from verified sources. Test by calling the tool and confirming the response includes source metadata and that each result is clearly marked with its origin.
Tool 'brave_web_search' fetches untrusted web search results from external Brave Search API and returns them verbatim to the LLM without provenance delimiters or source attribution markers.
Evidence
| 8 | "Use this for broad information gathering, recent events, or when you need diverse web sources. " + |
| 9 | "Supports pagination, content filtering, and freshness controls. " + |
| 10 | "Maximum 20 results per request, with offset for pagination. ", |
| 11 | inputSchema: { |
| 12 | type: "object", |
| 13 | properties: { |
| 14 | query: { |
RemediationAI
The `brave_web_search` handler returns untrusted external data from the Brave API directly to the LLM without source attribution or provenance markers, allowing the LLM to treat unverified search results as authoritative. Wrap the API response in a structured object that includes explicit source attribution (e.g., `{ source: 'Brave Search API', timestamp: ..., results: [...] }`) and prepend each result with a provenance delimiter such as `[SOURCE: Brave Search]` in the text. This change ensures the LLM can distinguish external data from verified sources. Test by calling the tool and confirming the response includes source metadata and that each result is clearly marked with its origin.
@modelcontextprotocol/sdk==1.0.1 has 2 known CVEs [HIGH]: GHSA-8r9q-7v3j-jr4g, GHSA-w48q-cv73-mx4w. Upgrade to a patched version.
RemediationAI
The package.json declares a dependency on `@modelcontextprotocol/sdk==1.0.1`, which has 2 known high-severity CVEs (GHSA-8r9q-7v3j-jr4g and GHSA-w48q-cv73-mx4w) that may allow remote code execution or privilege escalation. Update the `@modelcontextprotocol/sdk` dependency in package.json to a patched version (e.g., `^1.1.0` or the latest stable release) that addresses these CVEs. This fix eliminates the known attack surface by applying security patches. Verify by running `npm audit` after the upgrade and confirming that no high-severity vulnerabilities remain for this package.
Package declares an install-time hook (npm postinstall/preinstall/prepare, setup.py cmdclass override, custom setuptools install class, or non-default pyproject build-backend). Anyone installing this package runs the hook. Confirm the hook is necessary and review its contents; prefer shipping a plain library without install-time execution.
Evidence
| 15 | ], |
| 16 | "scripts": { |
| 17 | "build": "tsc && shx chmod +x dist/*.js", |
| 18 | "prepare": "npm run build", |
| 19 | "watch": "tsc --watch" |
| 20 | }, |
| 21 | "dependencies": { |
RemediationAI
The package.json declares a `prepare` script that runs `npm run build` at install time, executing arbitrary code (TypeScript compilation and chmod) whenever the package is installed, creating a supply-chain attack surface. Remove the `prepare` hook from the scripts section and instead document that users must run `npm run build` manually after installation, or move the build step to a CI/CD pipeline that runs before publishing to npm. If pre-built artifacts are necessary, commit the compiled `dist/` directory to the repository and remove the build script entirely. Verify by uninstalling and reinstalling the package (`npm install`) and confirming that no build commands execute automatically.
MCP manifest declares tools but no authentication field is present (none of: auth, authorization, bearer, oauth, mtls, apiKey, api_key, basic, token, authToken). Absence is a weak signal β confirm whether the server relies on network-layer or host-level auth, or declare the real mechanism explicitly so reviewers can audit it.
Evidence
| 1 | # Brave Search MCP Server |
| 2 | |
| 3 | An MCP server implementation that integrates the Brave Search API, providing both web and local search capabilities. |
| 4 | |
| 5 | ## Features |
| 6 | |
| 7 | - **Web Search**: General queries, news, articles, with pagination and freshness controls |
| 8 | - **Local Search**: Find businesses, restaurants, and services with detailed information |
| 9 | - **Flexible Filtering**: Control result types, safety levels, and content freshness |
| 10 | - **Smart Fallbacks**: Local search automatically falls back to web when no re |
RemediationAI
The MCP manifest and README do not declare any authentication or authorization mechanism, making it unclear whether the server enforces access control or relies on network-layer security, hindering security audits. Add an explicit `authentication` or `authorization` section to the README (or MCP manifest if supported) that documents the real security modelβfor example, 'API key authentication via BRAVE_API_KEY environment variable' or 'No per-caller authentication; relies on network-layer firewall rules.' If the server should enforce authentication, implement a bearer token or API key validation in the MCP request handler using `server.setRequestHandler()` with credential extraction. Verify by reviewing the updated documentation and confirming that a security auditor can immediately identify the authentication mechanism without inspecting code.
brave_web_search
brave_local_search