Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.agentfront.dev/llms.txt

Use this file to discover all available pages before exploring further.

MCP Error Codes

export const MCP_ERROR_CODES = {
  UNAUTHORIZED: -32001,          // Missing credentials
  RESOURCE_NOT_FOUND: -32002,    // Resource not found
  FORBIDDEN: -32003,             // Invalid/insufficient credentials
  INVALID_REQUEST: -32600,       // Invalid request
  METHOD_NOT_FOUND: -32601,      // Method not found
  INVALID_PARAMS: -32602,        // Invalid parameters
  INTERNAL_ERROR: -32603,        // Internal server error
  PARSE_ERROR: -32700,           // Parse error
} as const;

Error Hierarchy

McpError (abstract)
├── PublicMcpError (safe to expose to clients)
│   ├── ToolNotFoundError
│   ├── ResourceNotFoundError
│   ├── InvalidInputError
│   ├── UnauthorizedError
│   ├── RateLimitError
│   └── ...

└── InternalMcpError (hide details from clients)
    ├── ToolExecutionError
    ├── ResourceReadError
    ├── InvalidOutputError
    └── ...

Base Error Classes

McpError (Abstract)

Base class for all MCP-related errors.
abstract class McpError extends Error {
  readonly errorId: string;           // Unique ID for tracking
  abstract isPublic: boolean;         // Expose details to clients?
  abstract statusCode: number;        // HTTP status code
  abstract code: string;              // Error code

  abstract getPublicMessage(): string;
  getInternalMessage(): string;
  toMcpError(isDevelopment?: boolean): McpErrorResponse;
}

PublicMcpError

Errors safe to expose to clients (validation errors, not found, etc.).
class PublicMcpError extends McpError {
  readonly isPublic = true;

  constructor(message: string, code?: string, statusCode?: number);
}

InternalMcpError

Errors that should NOT expose details (server errors, unexpected failures).
class InternalMcpError extends McpError {
  readonly isPublic = false;
  readonly statusCode = 500;

  getPublicMessage(): string {
    return `Internal FrontMCP error. Contact support with ID: ${this.errorId}`;
  }
}

Error Categories

Tool Errors

ToolNotFoundError, ToolExecutionError

Resource Errors

ResourceNotFoundError, ResourceReadError

Validation Errors

InvalidInputError, InvalidOutputError

Auth Errors

UnauthorizedError, AuthorizationRequiredError

Agent Errors

AgentNotFoundError, AgentExecutionError

Rate Limit Errors

RateLimitError, QuotaExceededError

Usage Patterns

Throwing Errors

import { ToolNotFoundError, InvalidInputError } from '@frontmcp/sdk';

@Tool({ name: 'my_tool', inputSchema: { id: z.string() } })
class MyTool extends ToolContext {
  async execute(input: { id: string }) {
    if (!input.id) {
      throw new InvalidInputError('ID is required');
    }

    const item = await this.get(Service).find(input.id);
    if (!item) {
      throw new ToolNotFoundError('my_tool');
    }

    return item;
  }
}

Using fail()

@Tool({ name: 'my_tool', inputSchema: {} })
class MyTool extends ToolContext {
  async execute(input) {
    if (!valid) {
      this.fail(new InvalidInputError('Validation failed'));
      // Never reaches here - fail() throws
    }
  }
}

Error with Details

throw new InvalidInputError('Validation failed', {
  field: 'email',
  reason: 'Invalid format',
});

Custom toJsonRpcError

Some errors override toJsonRpcError() for custom data:
class ResourceNotFoundError extends PublicMcpError {
  toJsonRpcError() {
    return {
      code: MCP_ERROR_CODES.RESOURCE_NOT_FOUND,
      message: this.getPublicMessage(),
      data: { uri: this.uri },
    };
  }
}

Error Properties

PropertyTypeDescription
errorIdstringUnique ID for tracking (auto-generated)
isPublicbooleanWhether to expose message to clients
statusCodenumberHTTP status code equivalent
codestringError code for categorization
mcpErrorCodenumberJSON-RPC error code (optional)

Best Practices

Use Specific Error Classes

// Good
throw new ToolNotFoundError('my_tool');
throw new InvalidInputError('Email is required');

// Avoid
throw new Error('Tool not found');

Preserve Original Errors

try {
  await externalService.call();
} catch (error) {
  throw new ToolExecutionError('my_tool', error);
}

Don’t Expose Internal Details

// InternalMcpError hides message from clients
throw new InternalMcpError('Database connection failed: timeout after 30s');
// Client sees: "Internal FrontMCP error. Contact support with ID: err_abc123"

Use Error IDs for Tracking

try {
  // operation
} catch (error) {
  if (error instanceof McpError) {
    logger.error('Operation failed', {
      errorId: error.errorId,
      code: error.code,
    });
  }
  throw error;
}

Import

import {
  MCP_ERROR_CODES,
  McpError,
  PublicMcpError,
  InternalMcpError,
  ToolNotFoundError,
  ToolExecutionError,
  ResourceNotFoundError,
  ResourceReadError,
  InvalidInputError,
  InvalidOutputError,
  UnauthorizedError,
  RateLimitError,
  // ... more
} from '@frontmcp/sdk';