Mostly safe β a couple of notes worth reading.
Scanned 5/3/2026, 6:29:03 PMΒ·Cached resultΒ·Fast ScanΒ·45 rulesΒ·How we decide β
AIVSS Score
Low
Severity Breakdown
0
critical
11
high
125
medium
0
low
MCP Server Information
Findings
This package carries significant security concerns with a B grade and safety score of 53/100, driven primarily by 64 ansi_escape_injection vulnerabilities and 57 server_configuration issues across 11 high-severity and 125 medium-severity findings. The ansi_escape_injection risks could allow attackers to manipulate terminal output or inject malicious content, while the configuration weaknesses may expose the server to misuse or information disclosure. You should carefully evaluate whether the package's functionality justifies these risks or consider alternatives before installation.
No known CVEs found for this package or its dependencies.
Scan Details
Want deeper analysis?
Fast scan found 26 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.
26 of 26 findings
26 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 | --- |
| 2 | name: migrate-v1-to-v2 |
| 3 | description: Migrate MCP TypeScript SDK code from v1 (@modelcontextprotocol/sdk) to v2 (@modelcontextprotocol/core, /client, /server). Use when a user asks to migrate, upgrade, or port their MCP TypeScript code from v1 to v2. |
| 4 | --- |
| 5 | |
| 6 | # MCP TypeScript SDK: v1 β v2 Migration |
| 7 | |
| 8 | Apply these changes in order: dependencies β imports β API calls β type aliases. |
| 9 | |
| 10 | ## 1. Environment |
| 11 | |
| 12 | - Node.js 20+ required (v18 dropped) |
| 13 | - ESM only (CJS dropped). If the project uses `require()`, conv |
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 | BaseContext, |
| 3 | ClientCapabilities, |
| 4 | CreateMessageRequest, |
| 5 | CreateMessageRequestParamsBase, |
| 6 | CreateMessageRequestParamsWithTools, |
| 7 | CreateMessageResult, |
| 8 | CreateMessageResultWithTools, |
| 9 | ElicitRequestFormParams, |
| 10 | ElicitRequestURLParams, |
| 11 | ElicitResult, |
| 12 | Implementation, |
| 13 | InitializeRequest, |
| 14 | InitializeResult, |
| 15 | JSONRPCRequest, |
| 16 | JsonSchemaType, |
| 17 | jsonSchemaValidator, |
| 18 | ListRootsRequest, |
| 19 | LoggingLevel, |
| 20 | LoggingMessageNotification, |
| 21 | Me |
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 | import { createMcpExpressApp } from '@modelcontextprotocol/express'; |
| 2 | import { NodeStreamableHTTPServerTransport } from '@modelcontextprotocol/node'; |
| 3 | import type { CallToolResult, GetPromptResult, ReadResourceResult } from '@modelcontextprotocol/server'; |
| 4 | import { McpServer } from '@modelcontextprotocol/server'; |
| 5 | import type { Request, Response } from 'express'; |
| 6 | import * as z from 'zod/v4'; |
| 7 | |
| 8 | const getServer = () => { |
| 9 | // Create an MCP server with implementation details |
| 10 | const server = new Mcp |
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 | # `@modelcontextprotocol/fastify` |
| 2 | |
| 3 | Fastify adapters for the MCP TypeScript server SDK. |
| 4 | |
| 5 | This package is a thin Fastify integration layer for [`@modelcontextprotocol/server`](https://github.com/modelcontextprotocol/typescript-sdk/tree/main/packages/server). |
| 6 | |
| 7 | It does **not** implement MCP itself. Instead, it helps you: |
| 8 | |
| 9 | - create a Fastify app with sensible defaults for MCP servers |
| 10 | - add DNS rebinding protection via Host header validation (recommended for localhost servers) |
| 11 | |
| 12 | ## Install |
| 13 | |
| 14 | ```bash |
| 15 | npm |
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 | import { randomUUID } from 'node:crypto'; |
| 2 | |
| 3 | import { createMcpExpressApp } from '@modelcontextprotocol/express'; |
| 4 | import { NodeStreamableHTTPServerTransport } from '@modelcontextprotocol/node'; |
| 5 | import type { CallToolResult } from '@modelcontextprotocol/server'; |
| 6 | import { isInitializeRequest, McpServer } from '@modelcontextprotocol/server'; |
| 7 | import type { Request, Response } from 'express'; |
| 8 | import * as z from 'zod/v4'; |
| 9 | |
| 10 | // Create an MCP server with implementation details |
| 11 | const getServer = () => { |
| 12 | |
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 | # `@modelcontextprotocol/node` |
| 2 | |
| 3 | Node.js adapters for the MCP TypeScript server SDK. |
| 4 | |
| 5 | This package is a thin Node.js integration layer for [`@modelcontextprotocol/server`](https://github.com/modelcontextprotocol/typescript-sdk/tree/main/packages/server). It provides a Streamable HTTP transport that works with Nodeβs `IncomingMessage` / `ServerResponse`. |
| 6 | |
| 7 | For webβstandard runtimes (Cloudflare Workers, Deno, Bun, etc.), use `WebStandardStreamableHTTPServerTransport` from `@modelcontextprotocol/serv |
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 | import { randomUUID } from 'node:crypto'; |
| 2 | |
| 3 | import { createMcpExpressApp } from '@modelcontextprotocol/express'; |
| 4 | import { NodeStreamableHTTPServerTransport } from '@modelcontextprotocol/node'; |
| 5 | import type { ReadResourceResult } from '@modelcontextprotocol/server'; |
| 6 | import { isInitializeRequest, McpServer } from '@modelcontextprotocol/server'; |
| 7 | import type { Request, Response } from 'express'; |
| 8 | |
| 9 | // Helper to register a dynamic resource on a given server instance |
| 10 | const addResource = (server: McpServer |
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 | /** |
| 2 | * SSE Polling Example Server (SEP-1699) |
| 3 | * |
| 4 | * This example demonstrates server-initiated SSE stream disconnection |
| 5 | * and client reconnection with Last-Event-ID for resumability. |
| 6 | * |
| 7 | * Key features: |
| 8 | * - Configures `retryInterval` to tell clients how long to wait before reconnecting |
| 9 | * - Uses `eventStore` to persist events for replay after reconnection |
| 10 | * - Uses `ctx.http?.closeSSE()` callback to gracefully disconnect clients mid-operation |
| 11 | * |
| 12 | * Run with: pnpm tsx src/ssePollingExample.ts |
| 13 | * |
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 | // Run with: pnpm tsx src/elicitationFormExample.ts |
| 2 | // |
| 3 | // This example demonstrates how to use form elicitation to collect structured user input |
| 4 | // with JSON Schema validation via a local HTTP server with SSE streaming. |
| 5 | // Form elicitation allows servers to request *non-sensitive* user input through the client |
| 6 | // with schema-based validation. |
| 7 | // Note: See also elicitationUrlExample.ts for an example of using URL elicitation |
| 8 | // to collect *sensitive* user input via a browser. |
| 9 | |
| 10 | import { randomUUID |
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 | /** |
| 2 | * Simple interactive task server demonstrating elicitation and sampling. |
| 3 | * |
| 4 | * This server demonstrates the task message queue pattern from the MCP Tasks spec: |
| 5 | * - confirm_delete: Uses elicitation to ask the user for confirmation |
| 6 | * - write_haiku: Uses sampling to request an LLM to generate content |
| 7 | * |
| 8 | * Both tools use the "call-now, fetch-later" pattern where the initial call |
| 9 | * creates a task, and the result is fetched via tasks/result endpoint. |
| 10 | */ |
| 11 | |
| 12 | import { randomUUID } from 'node:cryp |
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 | /** |
| 2 | * This file is automatically generated from the Model Context Protocol specification. |
| 3 | * |
| 4 | * Source: https://github.com/modelcontextprotocol/modelcontextprotocol |
| 5 | * Pulled from: https://raw.githubusercontent.com/modelcontextprotocol/modelcontextprotocol/main/schema/draft/schema.ts |
| 6 | * Last updated from commit: 5c25208be86db5033f644a4e0d005e08f699ef3d |
| 7 | * |
| 8 | * DO NOT EDIT THIS FILE MANUALLY. Changes will be overwritten by automated updates. |
| 9 | * To update this file, run: pnpm run fetch:spec-types |
| 10 | |
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
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
| 761 | console.log('Failed to open SSE stream'); |
| 762 | break; |
| 763 | case SdkErrorCode.ClientHttpNotImplemented: |
| 764 | console.log('HTTP request failed'); |
| 765 | break; |
| 766 | } |
| 767 | // Access HTTP status code from error.data if needed |
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
| 451 | console.log('Please try again...'); |
| 452 | continue; |
| 453 | } else { |
| 454 | console.log('Maximum attempts reached. Declining request.'); |
| 455 | return returnResult({ action: 'decline' }); |
| 456 | } |
| 457 | } |
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
| 688 | await transport.handleRequest(req, res, req.body); |
| 689 | } catch (error) { |
| 690 | console.error('Error handling MCP request:', error); |
| 691 | if (!res.headersSent) { |
| 692 | res.status(500).json({ |
| 693 | jsonrpc: '2.0', |
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
| 470 | console.log('Please correct the errors and try again...'); |
| 471 | continue; |
| 472 | } else { |
| 473 | console.log('Maximum attempts reached. Declining request.'); |
| 474 | return returnResult({ action: 'decline' }); |
| 475 | } |
| 476 | } |
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
| 121 | //#region Client_setRequestHandler_sampling |
| 122 | client.setRequestHandler('sampling/createMessage', async request => { |
| 123 | const lastMessage = request.params.messages.at(-1); |
| 124 | console.log('Sampling request:', lastMessage); |
| 125 | |
| 126 | // In production, send messages to your LLM here |
| 127 | return { |
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
| 105 | // Handle the request with existing transport |
| 106 | await transport.handleRequest(req, res, req.body); |
| 107 | } catch (error) { |
| 108 | console.error('Error handling MCP request:', error); |
| 109 | if (!res.headersSent) { |
| 110 | res.status(500).json({ |
| 111 | jsonrpc: '2.0', |
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
| 139 | }); |
| 140 | |
| 141 | app.delete('/mcp', async (req: Request, res: Response) => { |
| 142 | console.log('Received DELETE MCP request'); |
| 143 | res.writeHead(405).end( |
| 144 | JSON.stringify({ |
| 145 | jsonrpc: '2.0', |
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
| 14 | const client = new Client({ name: 'acme-search-client', version: '0.0.0' }); |
| 15 | |
| 16 | client.setNotificationHandler('acme/searchProgress', { params: SearchProgressParams }, params => { |
| 17 | console.log(`[progress] ${params.stage} ${Math.round(params.pct * 100)}%`); |
| 18 | }); |
| 19 | |
| 20 | await client.connect(new StdioClientTransport({ command: 'node', args: ['../server/dist/customMethodExample.js'] })); |
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
| 692 | return; |
| 693 | } |
| 694 | |
| 695 | console.log(`Received session termination request for session ${sessionId}`); |
| 696 | |
| 697 | try { |
| 698 | const transport = transports[sessionId]; |
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
| 286 | } |
| 287 | console.log('\nπ Elicitation (form) Request Received:'); |
| 288 | console.log(`Message: ${request.params.message}`); |
| 289 | console.log(`Related Task: ${request.params._meta?.[RELATED_TASK_META_KEY]?.taskId}`); |
| 290 | console.log(`Task Creation Requested: ${request.params.task ? 'yes' : 'no'}`); |
| 291 | console.log('Requested Schema:'); |
| 292 | console.log(JSON.stringify(request.params.requestedSchema, null, 2)); |
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
| 456 | ```ts source="../examples/client/src/clientGuide.examples.ts#elicitation_handler" |
| 457 | client.setRequestHandler('elicitation/create', async request => { |
| 458 | console.log('Server asks:', request.params.message); |
| 459 | |
| 460 | if (request.params.mode === 'form') { |
| 461 | // Present the schema-driven form to the user |
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
| 287 | console.log('\nπ Elicitation (form) Request Received:'); |
| 288 | console.log(`Message: ${request.params.message}`); |
| 289 | console.log(`Related Task: ${request.params._meta?.[RELATED_TASK_META_KEY]?.taskId}`); |
| 290 | console.log(`Task Creation Requested: ${request.params.task ? 'yes' : 'no'}`); |
| 291 | console.log('Requested Schema:'); |
| 292 | console.log(JSON.stringify(request.params.requestedSchema, null, 2)); |
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
| 512 | } |
| 513 | } |
| 514 | |
| 515 | console.log('Maximum attempts reached. Declining request.'); |
| 516 | return returnResult({ action: 'decline' }); |
| 517 | }); |
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
| 383 | // Handle the request with existing transport |
| 384 | await transport.handleRequest(req, res, req.body); |
| 385 | } catch (error) { |
| 386 | console.error('Error handling MCP request:', error); |
| 387 | if (!res.headersSent) { |
| 388 | res.status(500).json({ |
| 389 | jsonrpc: '2.0', |
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
| 748 | console.log('Failed to open SSE stream'); |
| 749 | break; |
| 750 | case SdkErrorCode.ClientHttpNotImplemented: |
| 751 | console.log('HTTP request failed'); |
| 752 | break; |
| 753 | } |
| 754 | // Access HTTP status code from error.data if needed |
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.
greet