Mostly safe โ a couple of notes worth reading.
Scanned 5/3/2026, 6:28:14 PMยทCached resultยทFast Scanยท45 rulesยทHow we decide โ
AIVSS Score
Low
Severity Breakdown
0
critical
13
high
384
medium
15
low
MCP Server Information
Findings
This package presents significant security concerns with a B grade and 42/100 safety score, driven primarily by 242 server configuration issues and 106 ansi escape injection vulnerabilities that could enable output manipulation attacks. The 13 high-severity findings, combined with 384 medium-severity issues spanning resource exhaustion, readiness problems, and one vulnerable dependency, suggest the package requires substantial hardening before production use. Installation should be deferred until these configuration and injection vulnerabilities are addressed.
No known CVEs found for this package or its dependencies.
Scan Details
Want deeper analysis?
Fast scan found 33 findings using rule-based analysis. Upgrade for LLM consensus across 5 judges, AI-generated remediation, and cross-file taint analysis.
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.
Showing 1โ30 of 33 findings
33 findings
File invokes the MCP `sampling/createMessage` capability without passing a `maxTokens` / `max_tokens` cap. The MCP spec has the *client* perform the LLM call on the server's behalf, so an uncapped request bills the end user (or hits provider limits silently). Always pass an explicit cap. TS: await server.createMessage({ messages, maxTokens: 1024, ... }) Python: await session.create_message(messages=[...], max_tokens=1024) Distinct from MCP-084 (denial-of-wallet), which targets the server's
Evidence
| 1 | # Sampling Example Server |
| 2 | |
| 3 | This example demonstrates how to create an MCP server that uses sampling to request LLM completions from connected clients. |
| 4 | |
| 5 | ## Features |
| 6 | |
| 7 | This server includes three example tools that use sampling: |
| 8 | |
| 9 | 1. **analyze-sentiment** - Analyzes text sentiment using the client's LLM |
| 10 | 2. **summarize-text** - Summarizes text using the client's LLM |
| 11 | 3. **translate-text** - Translates text to another language using the client's LLM |
| 12 | |
| 13 | ## Running the Server |
| 14 | |
| 15 | ```bash |
| 16 | # Development mode (wi |
Remediation
TS: pass `maxTokens` to `server.createMessage({...})` or include it in the params of a raw `sampling/createMessage` JSON-RPC request. Python: pass `max_tokens=` to `session.create_message(...)`. Derive the cap from the user's per-call budget; do not default to "unset" expecting the client to enforce a sane ceiling.
File invokes the MCP `sampling/createMessage` capability without passing a `maxTokens` / `max_tokens` cap. The MCP spec has the *client* perform the LLM call on the server's behalf, so an uncapped request bills the end user (or hits provider limits silently). Always pass an explicit cap. TS: await server.createMessage({ messages, maxTokens: 1024, ... }) Python: await session.create_message(messages=[...], max_tokens=1024) Distinct from MCP-084 (denial-of-wallet), which targets the server's
Evidence
| 1 | import type { |
| 2 | CreateMessageRequest, |
| 3 | CreateMessageResult, |
| 4 | ElicitRequestFormParams, |
| 5 | ElicitRequestURLParams, |
| 6 | ElicitResult, |
| 7 | Notification, |
| 8 | } from "@modelcontextprotocol/sdk/types.js"; |
| 9 | import React, { |
| 10 | createContext, |
| 11 | useCallback, |
| 12 | useContext, |
| 13 | useEffect, |
| 14 | useMemo, |
| 15 | useRef, |
| 16 | useState, |
| 17 | type ReactNode, |
| 18 | } from "react"; |
| 19 | import { Logger } from "../logging.js"; |
| 20 | import type { StorageProvider } from "./storage/StorageProvider.js"; |
| 21 | import type { UseMcpOptions, UseMcpResult } from "./types. |
Remediation
TS: pass `maxTokens` to `server.createMessage({...})` or include it in the params of a raw `sampling/createMessage` JSON-RPC request. Python: pass `max_tokens=` to `session.create_message(...)`. Derive the cap from the user's per-call budget; do not default to "unset" expecting the client to enforce a sane ceiling.
File mounts an HTTP route that handles MCP `tools/list` (Express / Fastify / FastAPI / Flask) but the route โ and the router it sits behind โ has no auth middleware applied. An anonymous client can enumerate every tool the server exposes, scope the attack surface, and (if `tools/call` shares the route) invoke them. Apply auth at the route or router level: Express `passport.authenticate(...)` / a `requireAuth`-style middleware, FastAPI `Depends(get_current_user)` or `Depends(verify_jwt)`, Flask
Evidence
| 1 | from __future__ import annotations |
| 2 | |
| 3 | import inspect |
| 4 | import logging |
| 5 | import os |
| 6 | import time |
| 7 | import weakref |
| 8 | from datetime import UTC, datetime |
| 9 | from typing import TYPE_CHECKING, Any, cast |
| 10 | |
| 11 | import mcp.server.lowlevel.server as lowlevel |
| 12 | import mcp.server.session as mcp_session |
| 13 | from mcp.server.fastmcp import FastMCP |
| 14 | from mcp.types import ( |
| 15 | AnyFunction, |
| 16 | CallToolRequest, |
| 17 | CompleteRequest, |
| 18 | Completion, |
| 19 | GetPromptRequest, |
| 20 | Icon, |
| 21 | ListPromptsRequest, |
| 22 | ListResourcesRequest, |
| 23 | ListTo |
Remediation
Apply auth middleware at the route or router level: - Express / Fastify / Koa: `passport.authenticate(...)`, `requireAuth`, `verifyToken`, or an equivalent JWT middleware applied via `router.use(authMw)` or as a per-route handler. - FastAPI: `Depends(get_current_user)`, `OAuth2PasswordBearer`, `HTTPBearer`, or `verify_jwt` dependency. - Flask: `@login_required`, `@auth_required`, `@jwt_required`, or call `verify_jwt_in_request()` in the handler. Mounting MCP behind a s
File mounts an HTTP route that handles MCP `tools/list` (Express / Fastify / FastAPI / Flask) but the route โ and the router it sits behind โ has no auth middleware applied. An anonymous client can enumerate every tool the server exposes, scope the attack surface, and (if `tools/call` shares the route) invoke them. Apply auth at the route or router level: Express `passport.authenticate(...)` / a `requireAuth`-style middleware, FastAPI `Depends(get_current_user)` or `Depends(verify_jwt)`, Flask
Evidence
| 1 | # Architecture |
| 2 | |
| 3 | Understanding how mcp-use servers are structured under the hood. |
| 4 | |
| 5 | --- |
| 6 | |
| 7 | ## Server Structure |
| 8 | |
| 9 | mcp-use is **built on top of the Hono web framework**. When you create an `MCPServer`, you get: |
| 10 | |
| 11 | ```typescript |
| 12 | const server = new MCPServer({ |
| 13 | name: "my-server", |
| 14 | version: "1.0.0" |
| 15 | }); |
| 16 | ``` |
| 17 | |
| 18 | The server instance has three key components: |
| 19 | |
| 20 | ### 1. `server.app` - Hono Instance |
| 21 | |
| 22 | The underlying Hono web application that handles HTTP routing and middleware. |
| 23 | |
| 24 | ```typescript |
| 25 | // Add custom HTTP route |
Remediation
Apply auth middleware at the route or router level: - Express / Fastify / Koa: `passport.authenticate(...)`, `requireAuth`, `verifyToken`, or an equivalent JWT middleware applied via `router.use(authMw)` or as a per-route handler. - FastAPI: `Depends(get_current_user)`, `OAuth2PasswordBearer`, `HTTPBearer`, or `verify_jwt` dependency. - Flask: `@login_required`, `@auth_required`, `@jwt_required`, or call `verify_jwt_in_request()` in the handler. Mounting MCP behind a s
File mounts an HTTP route that handles MCP `tools/list` (Express / Fastify / FastAPI / Flask) but the route โ and the router it sits behind โ has no auth middleware applied. An anonymous client can enumerate every tool the server exposes, scope the attack surface, and (if `tools/call` shares the route) invoke them. Apply auth at the route or router level: Express `passport.authenticate(...)` / a `requireAuth`-style middleware, FastAPI `Depends(get_current_user)` or `Depends(verify_jwt)`, Flask
Evidence
| 1 | # Architecture |
| 2 | |
| 3 | Understanding how mcp-use servers are structured under the hood. |
| 4 | |
| 5 | --- |
| 6 | |
| 7 | ## Server Structure |
| 8 | |
| 9 | mcp-use is **built on top of the Hono web framework**. When you create an `MCPServer`, you get: |
| 10 | |
| 11 | ```typescript |
| 12 | const server = new MCPServer({ |
| 13 | name: "my-server", |
| 14 | version: "1.0.0" |
| 15 | }); |
| 16 | ``` |
| 17 | |
| 18 | The server instance has three key components: |
| 19 | |
| 20 | ### 1. `server.app` - Hono Instance |
| 21 | |
| 22 | The underlying Hono web application that handles HTTP routing and middleware. |
| 23 | |
| 24 | ```typescript |
| 25 | // Add custom HTTP route |
Remediation
Apply auth middleware at the route or router level: - Express / Fastify / Koa: `passport.authenticate(...)`, `requireAuth`, `verifyToken`, or an equivalent JWT middleware applied via `router.use(authMw)` or as a per-route handler. - FastAPI: `Depends(get_current_user)`, `OAuth2PasswordBearer`, `HTTPBearer`, or `verify_jwt` dependency. - Flask: `@login_required`, `@auth_required`, `@jwt_required`, or call `verify_jwt_in_request()` in the handler. Mounting MCP behind a s
File mounts an HTTP route that handles MCP `tools/list` (Express / Fastify / FastAPI / Flask) but the route โ and the router it sits behind โ has no auth middleware applied. An anonymous client can enumerate every tool the server exposes, scope the attack surface, and (if `tools/call` shares the route) invoke them. Apply auth at the route or router level: Express `passport.authenticate(...)` / a `requireAuth`-style middleware, FastAPI `Depends(get_current_user)` or `Depends(verify_jwt)`, Flask
Evidence
| 1 | # Architecture |
| 2 | |
| 3 | Understanding how mcp-use servers are structured under the hood. |
| 4 | |
| 5 | --- |
| 6 | |
| 7 | ## Server Structure |
| 8 | |
| 9 | mcp-use is **built on top of the Hono web framework**. When you create an `MCPServer`, you get: |
| 10 | |
| 11 | ```typescript |
| 12 | const server = new MCPServer({ |
| 13 | name: "my-server", |
| 14 | version: "1.0.0" |
| 15 | }); |
| 16 | ``` |
| 17 | |
| 18 | The server instance has three key components: |
| 19 | |
| 20 | ### 1. `server.app` - Hono Instance |
| 21 | |
| 22 | The underlying Hono web application that handles HTTP routing and middleware. |
| 23 | |
| 24 | ```typescript |
| 25 | // Add custom HTTP route |
Remediation
Apply auth middleware at the route or router level: - Express / Fastify / Koa: `passport.authenticate(...)`, `requireAuth`, `verifyToken`, or an equivalent JWT middleware applied via `router.use(authMw)` or as a per-route handler. - FastAPI: `Depends(get_current_user)`, `OAuth2PasswordBearer`, `HTTPBearer`, or `verify_jwt` dependency. - Flask: `@login_required`, `@auth_required`, `@jwt_required`, or call `verify_jwt_in_request()` in the handler. Mounting MCP behind a s
MCP tool returns a hyperlink whose URL interpolates a runtime variable. Two render surfaces: markdown `[text](URL)` and HTML `<a href="URL">`. When the host renders the link, the user may click โ exfiltration, phishing, or click-tracking. Unlike MCP-220 (markdown image, auto-fetched at render time), hyperlinks fire on user click โ but the same threat model applies: never put untrusted data in the destination URL. Hard-code the URL or validate against a per-tool allow-list before interpolation.
Evidence
| 1 | import { |
| 2 | Dialog, |
| 3 | DialogContent, |
| 4 | DialogHeader, |
| 5 | DialogTitle, |
| 6 | } from "@/client/components/ui/dialog"; |
| 7 | import type { McpServer } from "mcp-use/react"; |
| 8 | import { Copy } from "lucide-react"; |
| 9 | import { copyToClipboard } from "@/client/utils/clipboard"; |
| 10 | import { toast } from "sonner"; |
| 11 | import { Button } from "./ui/button"; |
| 12 | import { Tooltip, TooltipContent, TooltipTrigger } from "./ui/tooltip"; |
| 13 | import { JSONDisplay } from "./shared/JSONDisplay"; |
| 14 | import { |
| 15 | getConfiguredServerAlias, |
| 16 | getServerDispla |
Remediation
Hard-code the URL, or validate against a per-tool allow-list before interpolation. If user input must shape the link, keep the destination URL static and put the variable in the visible link text only.
MCP tool returns a hyperlink whose URL interpolates a runtime variable. Two render surfaces: markdown `[text](URL)` and HTML `<a href="URL">`. When the host renders the link, the user may click โ exfiltration, phishing, or click-tracking. Unlike MCP-220 (markdown image, auto-fetched at render time), hyperlinks fire on user click โ but the same threat model applies: never put untrusted data in the destination URL. Hard-code the URL or validate against a per-tool allow-list before interpolation.
Evidence
| 1 | import { Badge } from "@/client/components/ui/badge"; |
| 2 | import { Button } from "@/client/components/ui/button"; |
| 3 | import { |
| 4 | DropdownMenu, |
| 5 | DropdownMenuContent, |
| 6 | DropdownMenuItem, |
| 7 | DropdownMenuTrigger, |
| 8 | } from "@/client/components/ui/dropdown-menu"; |
| 9 | import { NotFound } from "@/client/components/ui/not-found"; |
| 10 | import { MESH_PANEL_FINE_OVERLAY_NOISE_DATA_URL } from "@/client/components/ui/random-gradient-background"; |
| 11 | import { MeshGradient } from "@paper-design/shaders-react"; |
| 12 | import { |
| 13 | Tooltip, |
| 14 | T |
Remediation
Hard-code the URL, or validate against a per-tool allow-list before interpolation. If user input must shape the link, keep the destination URL static and put the variable in the visible link text only.
MCP tool returns content marked as HTML (`{type: "html"}`, `Content-Type: text/html`, or `mimeType: "text/html"`) with no sanitiser on the same code path. The host renders HTML directly โ anything tainted in the body becomes a script execution / markup-injection vector. Pipe the body through `DOMPurify.sanitize()` (TS), `bleach.clean()` (Python), `lxml.html.clean.Cleaner`, or `sanitize_html` before returning. Better: return `{type: "text"}` / `text/plain` and let the host escape. Distinct from
Evidence
| 1 | /** |
| 2 | * MCP Endpoint Mounting |
| 3 | * |
| 4 | * Main orchestration function for mounting MCP endpoints at /mcp and /sse. |
| 5 | * Uses a single native SDK transport instance to handle all sessions. |
| 6 | */ |
| 7 | |
| 8 | import type { Context, Hono as HonoType } from "hono"; |
| 9 | import { join } from "node:path"; |
| 10 | import { Telemetry } from "../../telemetry/telemetry-node.js"; |
| 11 | import { generateLandingPage } from "../landing.js"; |
| 12 | import type { SessionData, StreamManager } from "../sessions/index.js"; |
| 13 | import { |
| 14 | FileSystemSessionStore, |
| 15 | In |
Remediation
Sanitise the HTML body before return. Prefer `DOMPurify.sanitize(body)` (TS, plenty of MCP servers already bundle it for resource rendering) or `bleach.clean(body, tags=ALLOWED_TAGS, strip=True)` (Python). Even better: return `{type: "text"}` / `Content-Type: text/plain` and let the host's markdown renderer handle escape. HTML output is rarely needed for tool results.
MCP tool returns content marked as HTML (`{type: "html"}`, `Content-Type: text/html`, or `mimeType: "text/html"`) with no sanitiser on the same code path. The host renders HTML directly โ anything tainted in the body becomes a script execution / markup-injection vector. Pipe the body through `DOMPurify.sanitize()` (TS), `bleach.clean()` (Python), `lxml.html.clean.Cleaner`, or `sanitize_html` before returning. Better: return `{type: "text"}` / `text/plain` and let the host escape. Distinct from
Evidence
| 1 | --- |
| 2 | title: "Building ChatGPT Apps" |
| 3 | description: "Understanding ChatGPT widget flows and how mcp-use simplifies widget development" |
| 4 | icon: "openai" |
| 5 | --- |
| 6 | |
| 7 | <Info> |
| 8 | ChatGPT now supports **MCP Apps**. For new projects, use [Creating MCP Apps Server](/typescript/server/creating-mcp-apps-server) to build widgets that work with both ChatGPT and MCP Apps clients. |
| 9 | </Info> |
| 10 | |
| 11 | # Building ChatGPT Apps with Widgets |
| 12 | |
| 13 | <Info> |
| 14 | **Widget Protocol Options**: This guide focuses on **ChatGPT Apps SDK** specifically. For th |
Remediation
Sanitise the HTML body before return. Prefer `DOMPurify.sanitize(body)` (TS, plenty of MCP servers already bundle it for resource rendering) or `bleach.clean(body, tags=ALLOWED_TAGS, strip=True)` (Python). Even better: return `{type: "text"}` / `Content-Type: text/plain` and let the host's markdown renderer handle escape. HTML output is rarely needed for tool results.
MCP tool returns content marked as HTML (`{type: "html"}`, `Content-Type: text/html`, or `mimeType: "text/html"`) with no sanitiser on the same code path. The host renders HTML directly โ anything tainted in the body becomes a script execution / markup-injection vector. Pipe the body through `DOMPurify.sanitize()` (TS), `bleach.clean()` (Python), `lxml.html.clean.Cleaner`, or `sanitize_html` before returning. Better: return `{type: "text"}` / `text/plain` and let the host escape. Distinct from
Evidence
| 1 | <div align="center" style="margin: 0 auto; max-width: 80%;"> |
| 2 | <picture> |
| 3 | <source media="(prefers-color-scheme: dark)" srcset="./packages/mcp-use/static/logo_white.svg"> |
| 4 | <source media="(prefers-color-scheme: light)" srcset="./packages/mcp-use/static/logo_black.svg"> |
| 5 | <img alt="mcp use logo" src="./packages/mcp-use/static/logo_white.svg" width="80%" style="margin: 20px auto;"> |
| 6 | </picture> |
| 7 | </div> |
| 8 | |
| 9 | <h1 align="center">mcp-use: The Complete TypeScript Framework for Model Context Protocol</ |
Remediation
Sanitise the HTML body before return. Prefer `DOMPurify.sanitize(body)` (TS, plenty of MCP servers already bundle it for resource rendering) or `bleach.clean(body, tags=ALLOWED_TAGS, strip=True)` (Python). Even better: return `{type: "text"}` / `Content-Type: text/plain` and let the host's markdown renderer handle escape. HTML output is rarely needed for tool results.
MCP tool returns content marked as HTML (`{type: "html"}`, `Content-Type: text/html`, or `mimeType: "text/html"`) with no sanitiser on the same code path. The host renders HTML directly โ anything tainted in the body becomes a script execution / markup-injection vector. Pipe the body through `DOMPurify.sanitize()` (TS), `bleach.clean()` (Python), `lxml.html.clean.Cleaner`, or `sanitize_html` before returning. Better: return `{type: "text"}` / `text/plain` and let the host escape. Distinct from
Evidence
| 1 | import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; |
| 2 | import { fsHelpers, isDeno } from "./runtime.js"; |
| 3 | |
| 4 | /** |
| 5 | * Typed CallToolResult that constrains the structuredContent property |
| 6 | * to match a specific type T. Used for output schema validation. |
| 7 | * T must be a record type (object) to match the SDK's CallToolResult interface. |
| 8 | * |
| 9 | * Note: |
| 10 | * Properties are listed explicitly instead of using `extends Omit<CallToolResult, "structuredContent">` |
| 11 | * to avoid breaking type inference. |
Remediation
Sanitise the HTML body before return. Prefer `DOMPurify.sanitize(body)` (TS, plenty of MCP servers already bundle it for resource rendering) or `bleach.clean(body, tags=ALLOWED_TAGS, strip=True)` (Python). Even better: return `{type: "text"}` / `Content-Type: text/plain` and let the host's markdown renderer handle escape. HTML output is rarely needed for tool results.
Auth material (token / session / JWT / API key) is stored in `localStorage` or `sessionStorage`. Both are JS-readable from any script in the same origin โ a single XSS leaks the credential, and no `HttpOnly` cookie option exists for these stores. Move auth material to an `HttpOnly; Secure; SameSite=Lax` cookie set by the server. If you must keep it client-side, use the in-memory store of an SPA framework and accept the cost of re-auth on tab refresh.
Evidence
| 166 | "mcp-inspector-llm-config", |
| 167 | JSON.stringify(newLlmConfig) |
| 168 | ); |
| 169 | localStorage.setItem( |
| 170 | "mcp-inspector-auth-config", |
| 171 | JSON.stringify(newAuthConfig) |
| 172 | ); |
Remediation
Set credentials via an `HttpOnly; Secure; SameSite=Lax` cookie from the server. Cookie-based sessions are immune to XSS read-out (they're not exposed to JS) and add CSRF as the only remaining concern (see MCP-235). If you must keep tokens client-side, hold them in memory only (SPA store / closure variable). Accept the re-auth cost on tab refresh as the trade-off.
motion is 1 edit from popular 'emotion' โ possible typosquat
Remediation
Typosquat: verify you meant the popular package. If so, correct the spelling; if you truly intended the less-common name, suppress with an inline waiver. Stale release: check whether the package has a maintained fork or successor. If no patched release exists, vendor the code or migrate to an active alternative before the unmaintained code accrues unfixed CVEs.
Dockerfile never sets a non-root `USER` directive, so the CMD runs as root by default. Any RCE or library-level vulnerability exploited inside this container gets full privileges (MCP Top-10 R3). Add `USER <non-root>` before CMD / ENTRYPOINT in the final stage โ e.g. `USER 1000`, `USER nobody`, or `USER nonroot` on distroless.
Evidence
| 1 | FROM node:20-alpine |
| 2 | |
| 3 | # Specify the version variable (defaults to latest) |
| 4 | ARG VERSION=latest |
| 5 | |
| 6 | WORKDIR /app |
| 7 | |
| 8 | # Cache bust by checking the latest version from npm |
| 9 | # This layer will be invalidated when a new version is published |
| 10 | RUN npm view @mcp-use/inspector version |
| 11 | |
| 12 | # Install the inspector package from npm |
| 13 | RUN npm install -g @mcp-use/inspector@${VERSION} |
| 14 | |
| 15 | # Set production environment |
| 16 | ENV NODE_ENV=production |
| 17 | |
| 18 | # Expose 8080 (standard alternative HTTP port for production) |
| 19 | # Note: The actual port is |
Remediation
Create and switch to a non-root user before the CMD / ENTRYPOINT: RUN adduser --system --uid 1000 app USER 1000 Or reuse the base image's shipped non-root account (e.g. `USER nobody`, `USER nonroot` on distroless). Multi-stage builds only need the USER directive in the final stage.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 56 | agent.setTags(["test-tag-1", "test-tag-2"]); |
| 57 | |
| 58 | console.log("๐ฌ Running agent query..."); |
| 59 | const result = await agent.run({ |
| 60 | prompt: `Hello, you are a tester can you please answer the follwing questions: |
| 61 | - Which resources do you have access to? |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 120 | const terminalElicitation: OnElicitationCallback = async (params) => { |
| 121 | if (params.mode === "url") { |
| 122 | console.log(`Visit: ${params.url}`); |
| 123 | return { action: "accept" }; |
| 124 | } |
| 125 | const input = await promptTerminal(params.message, params.requestedSchema); |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 551 | // Custom middleware |
| 552 | server.use('/api/*', async (c, next) => { |
| 553 | console.log(`${c.req.method} ${c.req.path}`) |
| 554 | await next() |
| 555 | }) |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 187 | currentToolCall = event.name; |
| 188 | console.log(`\n๐ง Tool started: ${event.name}`); |
| 189 | if (event.data?.input) { |
| 190 | console.log(` Input: ${JSON.stringify(event.data.input)}`); |
| 191 | } |
| 192 | break; |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 317 | { |
| 318 | clientInfo: { name: "my-app", version: "1.0.0" }, |
| 319 | onElicitation: async (params) => acceptWithDefaults(params), |
| 320 | onNotification: (n) => console.log(n.method, n.params), |
| 321 | // onSampling: optional; see Sampling docs |
| 322 | } |
| 323 | ); |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 40 | // Set up elicitation handler |
| 41 | client.setRequestHandler(ElicitRequestSchema, async (request: any) => { |
| 42 | console.log("\n๐ฅ Received elicitation request:"); |
| 43 | console.log(" Mode:", request.params.mode || "form"); |
| 44 | console.log(" Message:", request.params.message); |
| 45 | |
| 46 | if (request.params.mode === "url") { |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 111 | // Find and select the request immediately |
| 112 | const request = pendingRequests.find((r) => r.id === requestId); |
| 113 | if (request) { |
| 114 | console.log( |
| 115 | "[ElicitationTab] Selecting request from event:", |
| 116 | requestId |
| 117 | ); |
| 118 | setSelectedRequest(request); |
| 119 | setTimeout(() => { |
| 120 | const requestElement = document.getElementById( |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 162 | const query = `What's the current time and date? Also create a simple text file with today's date.`; |
| 163 | |
| 164 | console.log(`๐ Query: ${query}\n`); |
| 165 | console.log("๐ Streaming fine-grained events...\n"); |
| 166 | |
| 167 | try { |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 46 | // Register notification handler |
| 47 | session.on("notification", async (notification) => { |
| 48 | console.log(`Received: ${notification.method}`, notification.params); |
| 49 | }); |
| 50 | ``` |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 9 | * ```typescript |
| 10 | * // Log all tool calls |
| 11 | * server.use('mcp:tools/call', async (ctx, next) => { |
| 12 | * console.log(`Calling tool: ${ctx.params.name}`); |
| 13 | * const result = await next(); |
| 14 | * return result; |
| 15 | * }); |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 69 | }); |
| 70 | |
| 71 | try { |
| 72 | console.log("๐ Running query with custom config...\n"); |
| 73 | const result = await agent.run("What files are in this directory?"); |
| 74 | |
| 75 | console.log("\nโ Result:"); |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 104 | }>; |
| 105 | const requestId = customEvent.detail.requestId; |
| 106 | |
| 107 | console.log("[SamplingTab] Custom navigate event received:", requestId); |
| 108 | |
| 109 | // Find and select the request immediately |
| 110 | const request = pendingRequests.find((r) => r.id === requestId); |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 18 | try { |
| 19 | listener(...args); |
| 20 | } catch (e) { |
| 21 | console.error("Error in event listener:", e); |
| 22 | } |
| 23 | }); |
| 24 | } |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 980 | if (stored && window.openai) { |
| 981 | window.openai.widgetState = JSON.parse(stored); |
| 982 | } |
| 983 | } catch (err) {} |
| 984 | }, 0); |
| 985 | })(); |
| 986 | </script> |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 246 | # This catches non-McpError exceptions, like a direct httpx timeout |
| 247 | # but in the most cases this won't happen. It's for safety. |
| 248 | try: |
| 249 | await raw_test_client.__aexit__(None, None, None) |
| 250 | except Exception: |
| 251 | pass |
| 252 | raise init_error |
| 253 | |
| 254 | # Exception from the inner try is propagated here and in |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 31 | json_str = json_str.replace("\\'", "'") |
| 32 | json_str = json_str.replace("\\\\", "\\") |
| 33 | try: |
| 34 | return json.loads(json_str) |
| 35 | except json.JSONDecodeError: |
| 36 | pass |
| 37 | |
| 38 | return None |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 168 | if isinstance(content, dict | list): |
| 169 | try: |
| 170 | formatted = json.dumps(content, indent=2) |
| 171 | return Markdown(f"```json\n{formatted}\n```", code_theme=CODE_THEME) |
| 172 | except (TypeError, ValueError): |
| 173 | pass |
| 174 | |
| 175 | # If it already has markdown code blocks, render as is |
| 176 | if "```" in content_str: |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 108 | # Put response in queue |
| 109 | try: |
| 110 | self.response_queue.put_nowait(response) |
| 111 | except asyncio.QueueFull: |
| 112 | pass # Ignore if queue is already full |
| 113 | |
| 114 | # Return success page |
| 115 | if response.code: |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
my-app
my-server
+1 more โ click to filter
get_weather