DEV Community

Yigit Konur
Yigit Konur

Posted on • Edited on

Error Handling in MCP TypeScript SDK

This document provides comprehensive documentation of error handling features and patterns in the Model Context Protocol (MCP) TypeScript SDK. The SDK implements a robust error handling system that covers protocol-level errors, OAuth authentication errors, transport errors, and application-level exceptions.

Table of Contents

Core Error Classes

McpError

The McpError class is the primary error type for MCP protocol-level errors. It extends the standard JavaScript Error class with MCP-specific information.

Location: src/types.ts:1461-1470

export class McpError extends Error { constructor( public readonly code: number, message: string, public readonly data?: unknown, ) { super(`MCP error ${code}: ${message}`); this.name = "McpError"; } } 
Enter fullscreen mode Exit fullscreen mode

Properties:

  • code: Numeric error code (from ErrorCode enum)
  • message: Human-readable error description
  • data: Optional additional error information
  • name: Always set to "McpError"

Usage:

import { McpError, ErrorCode } from "@modelcontextprotocol/sdk"; throw new McpError( ErrorCode.InvalidRequest, "Missing required parameter", { parameter: "name" } ); 
Enter fullscreen mode Exit fullscreen mode

OAuthError Hierarchy

A comprehensive set of OAuth-specific error classes that implement RFC 6749 OAuth 2.0 error responses.

Location: src/server/auth/errors.ts

Base Class: OAuthError

export class OAuthError extends Error { static errorCode: string; constructor( message: string, public readonly errorUri?: string ) { super(message); this.name = this.constructor.name; } toResponseObject(): OAuthErrorResponse { const response: OAuthErrorResponse = { error: this.errorCode, error_description: this.message }; if (this.errorUri) { response.error_uri = this.errorUri; } return response; } get errorCode(): string { return (this.constructor as typeof OAuthError).errorCode } } 
Enter fullscreen mode Exit fullscreen mode

Standard OAuth Error Types

  1. InvalidRequestError (invalid_request)

    • Malformed request, missing parameters, or invalid parameter values
  2. InvalidClientError (invalid_client)

    • Client authentication failed
  3. InvalidGrantError (invalid_grant)

    • Authorization grant is invalid, expired, or revoked
  4. UnauthorizedClientError (unauthorized_client)

    • Client not authorized for this grant type
  5. UnsupportedGrantTypeError (unsupported_grant_type)

    • Grant type not supported by authorization server
  6. InvalidScopeError (invalid_scope)

    • Requested scope is invalid or exceeds granted scope
  7. AccessDeniedError (access_denied)

    • Resource owner or authorization server denied the request
  8. ServerError (server_error)

    • Unexpected server condition
  9. TemporarilyUnavailableError (temporarily_unavailable)

    • Server temporarily overloaded or under maintenance
  10. UnsupportedResponseTypeError (unsupported_response_type)

    • Authorization server doesn't support this response type
  11. UnsupportedTokenTypeError (unsupported_token_type)

    • Token type not supported
  12. InvalidTokenError (invalid_token)

    • Access token expired, revoked, or malformed
  13. MethodNotAllowedError (method_not_allowed)

    • HTTP method not allowed (custom extension)
  14. TooManyRequestsError (too_many_requests)

    • Rate limit exceeded (RFC 6585)
  15. InvalidClientMetadataError (invalid_client_metadata)

    • Invalid client metadata (RFC 7591)
  16. InsufficientScopeError (insufficient_scope)

    • Request requires higher privileges

CustomOAuthError

For defining custom error codes:

export class CustomOAuthError extends OAuthError { constructor( private readonly customErrorCode: string, message: string, errorUri?: string ) { super(message, errorUri); } get errorCode(): string { return this.customErrorCode; } } 
Enter fullscreen mode Exit fullscreen mode

Error Registry

All OAuth errors are registered in the OAUTH_ERRORS constant for runtime error parsing:

export const OAUTH_ERRORS = { [InvalidRequestError.errorCode]: InvalidRequestError, [InvalidClientError.errorCode]: InvalidClientError, // ... all other error types } as const; 
Enter fullscreen mode Exit fullscreen mode

JSON-RPC Error Codes

The SDK defines standard JSON-RPC error codes in the ErrorCode enum:

Location: src/types.ts:122-133

export enum ErrorCode { // SDK error codes ConnectionClosed = -32000, RequestTimeout = -32001, // Standard JSON-RPC error codes ParseError = -32700, InvalidRequest = -32600, MethodNotFound = -32601, InvalidParams = -32602, InternalError = -32603, } 
Enter fullscreen mode Exit fullscreen mode

Error Code Categories

  1. SDK-Specific Errors (-32000 to -32099)

    • ConnectionClosed (-32000): Transport connection was closed
    • RequestTimeout (-32001): Request exceeded timeout duration
  2. Standard JSON-RPC Errors (-32600 to -32699)

    • ParseError (-32700): Invalid JSON received
    • InvalidRequest (-32600): JSON-RPC request is invalid
    • MethodNotFound (-32601): Requested method doesn't exist
    • InvalidParams (-32602): Invalid method parameters
    • InternalError (-32603): Internal server error

OAuth Error Handling

Client-Side OAuth Errors

Location: src/client/auth.ts

The SDK provides utilities for handling OAuth errors in client applications:

import { OAuthError, InvalidClientError, InvalidGrantError } from "@modelcontextprotocol/sdk"; // Error handling in OAuth flow try { const token = await exchangeAuthorization(authCode, codeVerifier, metadata); } catch (error) { if (error instanceof InvalidGrantError) { // Handle invalid authorization code console.error("Authorization code is invalid or expired"); } else if (error instanceof InvalidClientError) { // Handle client authentication failure console.error("Client credentials are invalid"); } else if (error instanceof OAuthError) { // Handle other OAuth errors console.error(`OAuth error: ${error.errorCode} - ${error.message}`); } } 
Enter fullscreen mode Exit fullscreen mode

Server-Side OAuth Error Responses

OAuth errors are automatically converted to proper HTTP responses:

try { // OAuth operation } catch (error) { if (error instanceof OAuthError) { const errorResponse = error.toResponseObject(); return new Response(JSON.stringify(errorResponse), { status: 400, headers: { 'Content-Type': 'application/json' } }); } } 
Enter fullscreen mode Exit fullscreen mode

UnauthorizedError

A special client-side error for handling unauthorized access:

export class UnauthorizedError extends Error { constructor(message: string = "Unauthorized") { super(message); this.name = "UnauthorizedError"; } } 
Enter fullscreen mode Exit fullscreen mode

Protocol Error Patterns

Request Handler Error Handling

Location: src/shared/protocol.ts:411-449

The Protocol class implements comprehensive error handling for request processing:

Promise.resolve() .then(() => handler(request, fullExtra)) .then( (result) => { if (abortController.signal.aborted) { return; } return capturedTransport?.send({ result, jsonrpc: "2.0", id: request.id, }); }, (error) => { if (abortController.signal.aborted) { return; } return capturedTransport?.send({ jsonrpc: "2.0", id: request.id, error: { code: Number.isSafeInteger(error["code"]) ? error["code"] : ErrorCode.InternalError, message: error.message ?? "Internal error", }, }); }, ) .catch((error) => this._onerror(new Error(`Failed to send response: ${error}`)), ); 
Enter fullscreen mode Exit fullscreen mode

Key Features:

  • Automatic error code detection and fallback
  • Abort signal handling
  • Transport error isolation
  • Structured error responses

Notification Handler Error Handling

Location: src/shared/protocol.ts:359-367

Promise.resolve() .then(() => handler(notification)) .catch((error) => this._onerror( new Error(`Uncaught error in notification handler: ${error}`), ), ); 
Enter fullscreen mode Exit fullscreen mode

Features:

  • Async error containment
  • Error reporting through onerror callback
  • Non-blocking error handling

Transport Error Handling

Connection Management

Location: src/shared/protocol.ts:331-343

private _onclose(): void { const responseHandlers = this._responseHandlers; this._responseHandlers = new Map(); this._progressHandlers.clear(); this._pendingDebouncedNotifications.clear(); this._transport = undefined; this.onclose?.(); const error = new McpError(ErrorCode.ConnectionClosed, "Connection closed"); for (const handler of responseHandlers.values()) { handler(error); } } 
Enter fullscreen mode Exit fullscreen mode

Connection Closure Handling:

  • All pending requests receive ConnectionClosed error
  • Clean resource cleanup
  • Handler deregistration
  • Optional close callback invocation

WebSocket Error Handling

Location: src/client/websocket.ts

this._ws.onerror = (event) => { const error = event.error ? (event.error as Error) : new Error(`WebSocket error: ${JSON.stringify(event)}`); this.onerror?.(error); }; this._ws.onmessage = (event) => { try { const message = JSON.parse(event.data); this.onmessage?.(message); } catch (error) { this.onerror?.(error as Error); } }; 
Enter fullscreen mode Exit fullscreen mode

Features:

  • WebSocket event error transformation
  • JSON parsing error handling
  • Error callback propagation

Client Error Handling

Initialization Error Handling

Location: src/client/index.ts:135-183

try { const result = await this.request( { method: "initialize", params: { protocolVersion: LATEST_PROTOCOL_VERSION, capabilities: this._capabilities, clientInfo: this._clientInfo, }, }, InitializeResultSchema, options ); if (result === undefined) { throw new Error(`Server sent invalid initialize result: ${result}`); } if (!SUPPORTED_PROTOCOL_VERSIONS.includes(result.protocolVersion)) { throw new Error( `Server's protocol version is not supported: ${result.protocolVersion}`, ); } // ... initialization logic } catch (error) { // Disconnect if initialization fails void this.close(); throw error; } 
Enter fullscreen mode Exit fullscreen mode

Initialization Error Patterns:

  • Automatic disconnection on failure
  • Protocol version validation
  • Result validation
  • Error propagation with cleanup

Capability Validation

protected assertCapability( capability: keyof ServerCapabilities, method: string, ): void { if (!this._serverCapabilities?.[capability]) { throw new Error( `Server does not support ${capability} (required for ${method})`, ); } } 
Enter fullscreen mode Exit fullscreen mode

Tool Call Validation

Location: src/client/index.ts:429-478

async callTool(params: CallToolRequest["params"]) { const result = await this.request( { method: "tools/call", params }, resultSchema, options, ); // Validate tool output schema const validator = this.getToolOutputValidator(params.name); if (validator) { if (!result.structuredContent && !result.isError) { throw new McpError( ErrorCode.InvalidRequest, `Tool ${params.name} has an output schema but did not return structured content` ); } if (result.structuredContent) { try { const isValid = validator(result.structuredContent); if (!isValid) { throw new McpError( ErrorCode.InvalidParams, `Structured content does not match the tool's output schema: ${this._ajv.errorsText(validator.errors)}` ); } } catch (error) { if (error instanceof McpError) { throw error; } throw new McpError( ErrorCode.InvalidParams, `Failed to validate structured content: ${error instanceof Error ? error.message : String(error)}` ); } } } return result; } 
Enter fullscreen mode Exit fullscreen mode

Tool Validation Features:

  • Output schema validation
  • Structured content requirements
  • Error classification and re-throwing
  • AJV integration for JSON Schema validation

Server Error Handling

Elicitation Input Validation

Location: src/server/index.ts:313-349

async elicitInput( params: ElicitRequest["params"], options?: RequestOptions, ): Promise<ElicitResult> { const result = await this.request( { method: "elicitation/create", params }, ElicitResultSchema, options, ); if (result.action === "accept" && result.content) { try { const ajv = new Ajv(); const validate = ajv.compile(params.requestedSchema); const isValid = validate(result.content); if (!isValid) { throw new McpError( ErrorCode.InvalidParams, `Elicitation response content does not match requested schema: ${ajv.errorsText(validate.errors)}`, ); } } catch (error) { if (error instanceof McpError) { throw error; } throw new McpError( ErrorCode.InternalError, `Error validating elicitation response: ${error}`, ); } } return result; } 
Enter fullscreen mode Exit fullscreen mode

Validation Features:

  • Schema-based content validation
  • Error classification and wrapping
  • JSON Schema integration
  • Detailed error messages

Request Lifecycle Error Management

Request Timeout Management

Location: src/shared/protocol.ts:249-292

private _setupTimeout( messageId: number, timeout: number, maxTotalTimeout: number | undefined, onTimeout: () => void, resetTimeoutOnProgress: boolean = false ) { this._timeoutInfo.set(messageId, { timeoutId: setTimeout(onTimeout, timeout), startTime: Date.now(), timeout, maxTotalTimeout, resetTimeoutOnProgress, onTimeout }); } private _resetTimeout(messageId: number): boolean { const info = this._timeoutInfo.get(messageId); if (!info) return false; const totalElapsed = Date.now() - info.startTime; if (info.maxTotalTimeout && totalElapsed >= info.maxTotalTimeout) { this._timeoutInfo.delete(messageId); throw new McpError( ErrorCode.RequestTimeout, "Maximum total timeout exceeded", { maxTotalTimeout: info.maxTotalTimeout, totalElapsed } ); } clearTimeout(info.timeoutId); info.timeoutId = setTimeout(info.onTimeout, info.timeout); return true; } 
Enter fullscreen mode Exit fullscreen mode

Timeout Features:

  • Per-request timeout tracking
  • Progress-based timeout reset
  • Maximum total timeout enforcement
  • Automatic cleanup on completion/error

Request Cancellation

Location: src/shared/protocol.ts:582-601

const cancel = (reason: unknown) => { this._responseHandlers.delete(messageId); this._progressHandlers.delete(messageId); this._cleanupTimeout(messageId); this._transport ?.send({ jsonrpc: "2.0", method: "notifications/cancelled", params: { requestId: messageId, reason: String(reason), }, }) .catch((error) => this._onerror(new Error(`Failed to send cancellation: ${error}`)), ); reject(reason); }; 
Enter fullscreen mode Exit fullscreen mode

Cancellation Features:

  • Clean handler removal
  • Timeout cleanup
  • Cancellation notification to remote peer
  • Promise rejection with reason

AbortSignal Integration

options?.signal?.addEventListener("abort", () => { cancel(options?.signal?.reason); }); 
Enter fullscreen mode Exit fullscreen mode

Timeout and Cancellation

RequestOptions Timeout Configuration

export type RequestOptions = { timeout?: number; // Individual request timeout maxTotalTimeout?: number; // Maximum total time regardless of progress resetTimeoutOnProgress?: boolean; // Reset timeout on progress notifications signal?: AbortSignal; // External cancellation signal onprogress?: ProgressCallback; // Progress notification handler }; 
Enter fullscreen mode Exit fullscreen mode

Progress-Based Timeout Reset

Location: src/shared/protocol.ts:451-474

private _onprogress(notification: ProgressNotification): void { const { progressToken, ...params } = notification.params; const messageId = Number(progressToken); const handler = this._progressHandlers.get(messageId); if (!handler) { this._onerror(new Error(`Received a progress notification for an unknown token: ${JSON.stringify(notification)}`)); return; } const responseHandler = this._responseHandlers.get(messageId); const timeoutInfo = this._timeoutInfo.get(messageId); if (timeoutInfo && responseHandler && timeoutInfo.resetTimeoutOnProgress) { try { this._resetTimeout(messageId); } catch (error) { responseHandler(error as Error); return; } } handler(params); } 
Enter fullscreen mode Exit fullscreen mode

Error Propagation and Recovery

Response Handler Error Processing

Location: src/shared/protocol.ts:476-502

private _onresponse(response: JSONRPCResponse | JSONRPCError): void { const messageId = Number(response.id); const handler = this._responseHandlers.get(messageId); if (handler === undefined) { this._onerror( new Error( `Received a response for an unknown message ID: ${JSON.stringify(response)}`, ), ); return; } this._responseHandlers.delete(messageId); this._progressHandlers.delete(messageId); this._cleanupTimeout(messageId); if (isJSONRPCResponse(response)) { handler(response); } else { const error = new McpError( response.error.code, response.error.message, response.error.data, ); handler(error); } } 
Enter fullscreen mode Exit fullscreen mode

Error Processing Features:

  • Unknown message ID handling
  • Automatic resource cleanup
  • McpError construction from JSON-RPC errors
  • Handler deregistration

Fallback Error Handlers

/** * A handler to invoke for any request types that do not have their own handler installed. */ fallbackRequestHandler?: ( request: JSONRPCRequest, extra: RequestHandlerExtra<SendRequestT, SendNotificationT> ) => Promise<SendResultT>; /** * A handler to invoke for any notification types that do not have their own handler installed. */ fallbackNotificationHandler?: (notification: Notification) => Promise<void>; 
Enter fullscreen mode Exit fullscreen mode

Best Practices

1. Use Specific Error Types

// Good: Specific error types throw new McpError(ErrorCode.InvalidParams, "Missing required field: name"); throw new InvalidClientError("Client authentication failed"); // Avoid: Generic errors throw new Error("Something went wrong"); 
Enter fullscreen mode Exit fullscreen mode

2. Provide Meaningful Error Messages

// Good: Descriptive messages with context throw new McpError( ErrorCode.InvalidRequest, `Tool ${toolName} requires parameter '${paramName}' of type ${expectedType}`, { toolName, paramName, expectedType, receivedValue } ); // Avoid: Vague messages throw new McpError(ErrorCode.InvalidRequest, "Bad request"); 
Enter fullscreen mode Exit fullscreen mode

3. Handle Errors at Appropriate Levels

// Application level - handle business logic errors try { const result = await client.callTool({ name: "calculator", arguments: { a: 1, b: 2 } }); } catch (error) { if (error instanceof McpError && error.code === ErrorCode.MethodNotFound) { console.log("Calculator tool not available, using fallback"); return fallbackCalculation(1, 2); } throw error; // Re-throw unexpected errors } // Transport level - handle connection errors client.onerror = (error) => { console.error("Transport error:", error); // Implement reconnection logic }; client.onclose = () => { console.log("Connection closed, attempting reconnect..."); // Implement reconnection strategy }; 
Enter fullscreen mode Exit fullscreen mode

4. Implement Proper Cleanup

class MyClient { private client: Client; async connect() { try { await this.client.connect(transport); } catch (error) { // Cleanup on connection failure await this.client.close(); throw error; } } async shutdown() { // Always cleanup resources try { await this.client.close(); } catch (error) { console.error("Error during shutdown:", error); } } } 
Enter fullscreen mode Exit fullscreen mode

5. Use AbortSignal for Cancellation

const controller = new AbortController(); // Set timeout for user cancellation setTimeout(() => controller.abort("User cancelled"), 30000); try { const result = await client.callTool( { name: "longRunningTool", arguments: {} }, CallToolResultSchema, { signal: controller.signal } ); } catch (error) { if (error.name === 'AbortError') { console.log("Operation was cancelled"); } else { console.error("Operation failed:", error); } } 
Enter fullscreen mode Exit fullscreen mode

Examples

Complete Error Handling in Client Application

import { Client, McpError, ErrorCode, InvalidClientError, UnauthorizedError } from "@modelcontextprotocol/sdk"; class MCPClientWrapper { private client: Client; private reconnectAttempts = 0; private maxReconnectAttempts = 3; constructor() { this.client = new Client({ name: "MyApp", version: "1.0.0" }); this.setupErrorHandlers(); } private setupErrorHandlers() { this.client.onerror = (error) => { console.error("MCP Client Error:", error); if (error instanceof UnauthorizedError) { this.handleAuthenticationError(); } else if (error instanceof McpError) { this.handleMCPError(error); } else { this.handleGenericError(error); } }; this.client.onclose = () => { console.log("Connection closed"); this.attemptReconnect(); }; } private handleMCPError(error: McpError) { switch (error.code) { case ErrorCode.ConnectionClosed: console.log("Connection lost, will attempt to reconnect"); break; case ErrorCode.RequestTimeout: console.log("Request timed out, consider retrying"); break; case ErrorCode.MethodNotFound: console.log("Method not supported by server"); break; default: console.error(`MCP Error ${error.code}: ${error.message}`); } } private async handleAuthenticationError() { try { await this.refreshAuthentication(); } catch (error) { console.error("Failed to refresh authentication:", error); // Redirect to login or request new credentials } } private handleGenericError(error: Error) { console.error("Generic error:", error.message); // Log to error reporting service } private async attemptReconnect() { if (this.reconnectAttempts >= this.maxReconnectAttempts) { console.error("Max reconnection attempts reached"); return; } this.reconnectAttempts++; const delay = Math.pow(2, this.reconnectAttempts) * 1000; // Exponential backoff console.log(`Attempting reconnection ${this.reconnectAttempts}/${this.maxReconnectAttempts} in ${delay}ms`); setTimeout(async () => { try { await this.connect(); this.reconnectAttempts = 0; // Reset on successful connection } catch (error) { console.error("Reconnection failed:", error); this.attemptReconnect(); } }, delay); } async callToolSafely(toolName: string, args: any) { const maxRetries = 3; let attempt = 0; while (attempt < maxRetries) { try { const result = await this.client.callTool( { name: toolName, arguments: args }, CallToolResultSchema, { timeout: 30000, resetTimeoutOnProgress: true } ); if (result.isError) { throw new Error(`Tool error: ${result.content?.[0]?.text || 'Unknown error'}`); } return result; } catch (error) { attempt++; if (error instanceof McpError) { if (error.code === ErrorCode.RequestTimeout && attempt < maxRetries) { console.log(`Request timed out, retrying (${attempt}/${maxRetries})`); continue; } else if (error.code === ErrorCode.InvalidParams) { // Don't retry parameter errors throw error; } } if (attempt >= maxRetries) { throw error; } // Wait before retry await new Promise(resolve => setTimeout(resolve, 1000 * attempt)); } } } } 
Enter fullscreen mode Exit fullscreen mode

Server Error Handling with OAuth

import { Server, McpError, ErrorCode, OAuthError, InvalidTokenError, InsufficientScopeError } from "@modelcontextprotocol/sdk"; class MCPServerWrapper { private server: Server; constructor() { this.server = new Server( { name: "MyServer", version: "1.0.0" }, { capabilities: { tools: {}, resources: {} }, instructions: "A secure MCP server with OAuth" } ); this.setupRequestHandlers(); } private setupRequestHandlers() { // Tool call handler with authentication this.server.setRequestHandler(CallToolRequestSchema, async (request, extra) => { try { // Verify authentication if (!extra.authInfo?.valid) { throw new InvalidTokenError("Invalid or expired access token"); } // Check authorization scope const requiredScope = this.getRequiredScopeForTool(request.params.name); if (!this.hasScope(extra.authInfo.scopes, requiredScope)) { throw new InsufficientScopeError( `Tool '${request.params.name}' requires scope '${requiredScope}'` ); } // Execute tool const result = await this.executeTool(request.params.name, request.params.arguments); return { content: [{ type: "text", text: JSON.stringify(result) }], isError: false }; } catch (error) { // Convert OAuth errors to tool results if (error instanceof OAuthError) { return { content: [{ type: "text", text: `Authentication error: ${error.message}` }], isError: true }; } // Handle other errors if (error instanceof McpError) { throw error; // Re-throw MCP errors } // Wrap unknown errors throw new McpError( ErrorCode.InternalError, `Tool execution failed: ${error.message}`, { toolName: request.params.name, originalError: error.message } ); } }); // Resource handler with error handling this.server.setRequestHandler(ReadResourceRequestSchema, async (request, extra) => { try { const resource = await this.loadResource(request.params.uri); if (!resource) { throw new McpError( ErrorCode.InvalidParams, `Resource not found: ${request.params.uri}`, { uri: request.params.uri } ); } return { contents: [{ uri: request.params.uri, mimeType: resource.mimeType, text: resource.content }] }; } catch (error) { if (error instanceof McpError) { throw error; } throw new McpError( ErrorCode.InternalError, `Failed to read resource: ${error.message}`, { uri: request.params.uri } ); } }); } private getRequiredScopeForTool(toolName: string): string { const scopeMap = { 'read_files': 'files:read', 'write_files': 'files:write', 'execute_command': 'system:execute' }; return scopeMap[toolName] || 'basic'; } private hasScope(userScopes: string[], requiredScope: string): boolean { return userScopes.includes(requiredScope) || userScopes.includes('admin'); } private async executeTool(name: string, args: any) { // Tool implementation with proper error handling switch (name) { case 'calculator': if (typeof args.a !== 'number' || typeof args.b !== 'number') { throw new McpError( ErrorCode.InvalidParams, "Calculator requires numeric parameters 'a' and 'b'", { providedArgs: args } ); } return { result: args.a + args.b }; default: throw new McpError( ErrorCode.MethodNotFound, `Tool '${name}' not found`, { availableTools: ['calculator'] } ); } } private async loadResource(uri: string) { // Resource loading with error handling try { // Implementation would load actual resource return { content: "Resource content", mimeType: "text/plain" }; } catch (error) { // Re-throw as MCP error with context throw new McpError( ErrorCode.InternalError, `Failed to load resource from ${uri}: ${error.message}`, { uri, error: error.message } ); } } } 
Enter fullscreen mode Exit fullscreen mode

This comprehensive error handling documentation covers all major error scenarios in the MCP TypeScript SDK, from low-level transport errors to high-level application errors, providing developers with the knowledge and patterns needed to build robust MCP applications.

Top comments (0)