JSON-RPC error codes carry semantic meaning that MCP clients use to determine how to display and recover from errors. Using HTTP-style codes (404, 500) instead of JSON-RPC codes (-32601, -32603) causes client error handlers to misclassify failures — a method-not-found error processed as an internal error may suppress retry logic or show the wrong message. CWE-703 (improper check or handling of exceptional conditions) applies: error codes must accurately describe the failure type for clients to respond correctly, especially in automated AI workflows where error classification drives next-step decisions.
High because incorrect error codes cause clients to mishandle failures — retrying internal errors, suppressing user-facing messages, or misrouting recoverable vs. non-recoverable conditions.
Use the standard JSON-RPC error codes. The MCP SDK exports ErrorCode and McpError — use them instead of constructing error objects manually.
// src/errors.ts — structured MCP errors
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'
// In tool handlers:
throw new McpError(ErrorCode.InvalidParams, 'Missing required parameter: query')
// In custom message routers:
const METHOD_NOT_FOUND = -32601
const INVALID_PARAMS = -32602
const INTERNAL_ERROR = -32603
return {
jsonrpc: '2.0',
id: request.id,
error: { code: METHOD_NOT_FOUND, message: `Unknown method: ${request.method}` }
}
Custom server error codes must be in the range -32000 to -32099 — never use HTTP status codes.
ID: mcp-server.error-resilience.structured-errors
Severity: high
What to look for: Count all error responses in the server. Enumerate which use MCP error codes (-32600, -32601, -32602, -32603) vs. generic error messages. Check all error responses in the codebase. JSON-RPC 2.0 defines standard error codes: -32700 (Parse error), -32600 (Invalid Request), -32601 (Method not found), -32602 (Invalid params), -32603 (Internal error). Check that the server uses these codes correctly in error responses. Check that custom error codes (if any) are in the allowed range (-32000 to -32099 for server errors). Check that error responses always include both code (integer) and message (string).
Pass criteria: Error responses use standard JSON-RPC error codes correctly. Custom error codes are in the valid range. Every error response includes code and message. Error codes match the actual error type (e.g., -32601 for unknown methods, not -32600). At least 90% of error responses must use standard JSON-RPC/MCP error codes.
Fail criteria: Non-standard error codes used, error responses missing code or message fields, or incorrect codes for the error type (e.g., using -32700 for invalid params).
Skip (N/A) when: All checks skip when no MCP server is detected.
Do NOT pass when: Error responses return HTTP status codes instead of JSON-RPC error objects, or use non-standard error code numbers.
Cross-reference: For tool-level error handling, see tool-error-catch.
Detail on fail: "Error responses use HTTP-style codes (404, 500) instead of JSON-RPC codes (-32601, -32603). Code '500' is not a valid JSON-RPC error code" or "Error response for unknown method uses code -32600 (Invalid Request) instead of -32601 (Method not found)"
Remediation: Use the correct JSON-RPC error codes:
// src/errors.ts — structured MCP error
throw new McpError(ErrorCode.InvalidParams, "Missing required parameter: query")
// Standard JSON-RPC error codes
const PARSE_ERROR = -32700 // Invalid JSON
const INVALID_REQUEST = -32600 // Not a valid Request object
const METHOD_NOT_FOUND = -32601 // Method does not exist
const INVALID_PARAMS = -32602 // Invalid method parameters
const INTERNAL_ERROR = -32603 // Internal server error
// In error responses
return {
jsonrpc: '2.0',
id: request.id,
error: { code: METHOD_NOT_FOUND, message: `Unknown method: ${request.method}` }
}