Skip to content

fix(server): sanitize internal error details in tool error responses#1830

Open
claygeo wants to merge 1 commit intomodelcontextprotocol:mainfrom
claygeo:fix/sanitize-tool-error-messages
Open

fix(server): sanitize internal error details in tool error responses#1830
claygeo wants to merge 1 commit intomodelcontextprotocol:mainfrom
claygeo:fix/sanitize-tool-error-messages

Conversation

@claygeo
Copy link
Copy Markdown

@claygeo claygeo commented Mar 31, 2026

Summary

Closes #1429

When a tool handler throws an unexpected error, the full error message is sent to the MCP client, potentially leaking sensitive server internals (hostnames, connection strings, stack traces).

This PR:

  • Adds a ToolError class that tool authors can throw when they want a specific message shown to the client
  • Sanitizes all other unhandled errors to "Internal error"
  • Preserves ProtocolError messages (SDK-generated validation errors are safe to expose)

Usage

import { McpServer, ToolError } from '@modelcontextprotocol/server';

server.registerTool('my-tool', {}, async () => {
    // This message WILL be shown to the client
    throw new ToolError('Invalid input: country not supported');

    // This message will NOT be shown — client sees "Internal error"
    throw new Error('DB connection failed at 10.0.0.5:5432');
});

Error handling behavior

Error type Client sees Rationale
ToolError Developer's message Intentional, developer-controlled
ProtocolError SDK message SDK-generated validation, safe to expose
Error "Internal error" May contain sensitive internals
Non-Error throw "Internal error" Unknown, sanitize defensively

Test plan

  • Generic Error is sanitized to "Internal error"
  • ToolError message passes through to client
  • Non-Error throw (string) is sanitized to "Internal error"
  • Existing ProtocolError validation tests still pass (129/129)
  • Task cancellation error sanitized correctly

When a tool handler throws an unexpected error, the full error message
was sent to the MCP client, potentially leaking sensitive server
internals (hostnames, connection strings, stack traces).

Adds a ToolError class that tool authors can throw when they want a
specific message shown to the client. All other unhandled errors are
now sanitized to "Internal error". ProtocolErrors from SDK validation
are still passed through since they contain safe, structured messages.

Closes modelcontextprotocol#1429
@claygeo claygeo requested a review from a team as a code owner March 31, 2026 17:38
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 31, 2026

⚠️ No Changeset found

Latest commit: 89b9adc

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 31, 2026

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/client@1830

@modelcontextprotocol/server

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/server@1830

@modelcontextprotocol/express

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/express@1830

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/fastify@1830

@modelcontextprotocol/hono

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/hono@1830

@modelcontextprotocol/node

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/node@1830

commit: 89b9adc

@km-anthropic
Copy link
Copy Markdown

@claude review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Do not return and expose internal errors to the client as this is a security risk

2 participants