Our MCP implementation uses JSON-RPC 2.0 error format for all error conditions. Every error response contains structured information for programmatic handling.
Standard Error Structure
{
"jsonrpc": "2.0",
"id": "request-123",
"error": {
"code": -32602,
"message": "Invalid params",
"data": {
"details": "Missing required parameter 'name'",
"parameter": "name",
"received": {}
}
}
}
Error Components
Field | Type | Description |
---|
code | integer | Standard JSON-RPC error code |
message | string | Human-readable error description |
data | object | Additional error context (optional) |
Standard Error Codes
JSON-RPC Protocol Errors
Code | Name | Meaning | Common Causes |
---|
-32700 | Parse error | Invalid JSON | Malformed request body |
-32600 | Invalid Request | Invalid JSON-RPC | Missing required fields |
-32601 | Method not found | Unknown method | Typo in method name |
-32602 | Invalid params | Bad parameters | Wrong parameter types |
-32603 | Internal error | Server error | Unexpected server failure |
MCP-Specific Error Codes
Code | Name | Meaning | Recovery Strategy |
---|
-32000 | Authentication | Auth failure | Refresh token, reinitialize |
-32001 | Resource not found | Missing resource | Verify resource exists |
-32002 | Tool not found | Unknown tool | Check available tools |
Detailed Error Examples
Authentication Errors
Expired Token:
{
"jsonrpc": "2.0",
"id": "tools-list-123",
"error": {
"code": -32000,
"message": "Authentication failed",
"data": {
"error": "Token expired",
"expires_at": "2024-01-15T10:30:00Z",
"refresh_required": true
}
}
}
Invalid Session:
{
"jsonrpc": "2.0",
"id": "resource-read-456",
"error": {
"code": -32000,
"message": "Authentication failed",
"data": {
"error": "Invalid session ID",
"session_id": "invalid_session_123",
"reinitialize_required": true
}
}
}
Parameter Validation Errors
Missing Required Parameter:
{
"jsonrpc": "2.0",
"id": "tool-call-789",
"error": {
"code": -32602,
"message": "Invalid params",
"data": {
"parameter": "name",
"error": "Missing required parameter",
"expected": "string",
"received": null
}
}
}
Invalid Parameter Type:
{
"jsonrpc": "2.0",
"id": "resource-read-101",
"error": {
"code": -32602,
"message": "Invalid params",
"data": {
"parameter": "uri",
"error": "Invalid parameter type",
"expected": "string",
"received": "number",
"value": 123
}
}
}
Tool Not Found:
{
"jsonrpc": "2.0",
"id": "tool-call-404",
"error": {
"code": -32002,
"message": "Tool not found",
"data": {
"tool_name": "nonexistent_tool",
"available_tools": ["get_contacts", "create_deal", "update_person"],
"suggestion": "Check available tools with tools/list method"
}
}
}
Resource Not Found:
{
"jsonrpc": "2.0",
"id": "resource-read-404",
"error": {
"code": -32001,
"message": "Resource not found",
"data": {
"uri": "pipedrive://invalid/resource",
"error": "Resource does not exist or access denied",
"available_resources": [
"pipedrive://deals/schema",
"pipedrive://contacts/list"
]
}
}
}
Rate Limiting Errors
Rate Limit Exceeded:
{
"jsonrpc": "2.0",
"id": "ping-rate-limited",
"error": {
"code": -32000,
"message": "Request rate limit exceeded",
"data": {
"type": "rate_limit_exceeded",
"retry_after": 60,
"limit": 10,
"remaining": 0,
"reset_time": 1642248660
}
}
}
Error Recovery Strategies
Authentication Recovery
- Token Refresh: Use refresh token to obtain new access token
- Re-authentication: Redirect user through OAuth flow
- Session Reinitialize: Call
initialize
method with new token
Example Recovery Flow:
async function handleAuthError(error) {
if (error.code === -32000) {
if (error.data?.refresh_required) {
// Attempt token refresh
const newToken = await refreshAccessToken();
return retryWithNewToken(newToken);
}
if (error.data?.reinitialize_required) {
// Reinitialize session
await initializeMCPSession();
return retryOriginalRequest();
}
}
throw error; // Unrecoverable auth error
}
Rate Limiting Recovery
Exponential Backoff:
async function handleRateLimit(error) {
if (error.code === -32000 && error.data?.type === "rate_limit_exceeded") {
const retryAfter = error.data.retry_after || 60;
// Wait for retry period
await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
// Retry original request
return retryOriginalRequest();
}
throw error;
}
Fallback to Available Options:
async function handleResourceError(error) {
if (error.code === -32001 || error.code === -32002) {
const available =
error.data?.available_tools || error.data?.available_resources;
if (available && available.length > 0) {
// Suggest alternative or prompt user to select
return suggestAlternatives(available);
}
}
throw error;
}
Error Prevention
Client-Side Validation:
function validateToolCall(toolName, arguments) {
if (!toolName || typeof toolName !== "string") {
throw new Error("Tool name must be a non-empty string");
}
if (arguments && typeof arguments !== "object") {
throw new Error("Tool arguments must be an object");
}
return true;
}
Session Management
Session Health Checks:
class MCPSession {
async ensureValidSession() {
try {
await this.ping();
} catch (error) {
if (error.code === -32000) {
// Session invalid, reinitialize
await this.initialize();
} else {
throw error;
}
}
}
}
Request ID Management
Unique ID Generation:
class RequestIDManager {
constructor() {
this.usedIds = new Set();
}
generateUniqueId() {
let id;
do {
id = `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
} while (this.usedIds.has(id));
this.usedIds.add(id);
return id;
}
markCompleted(id) {
this.usedIds.delete(id);
}
}
Error Monitoring
Error Logging
Structured Error Logging:
function logMCPError(error, context) {
const logEntry = {
timestamp: new Date().toISOString(),
error_code: error.code,
error_message: error.message,
error_data: error.data,
request_id: context.requestId,
method: context.method,
session_id: context.sessionId,
user_id: context.userId,
};
console.error("MCP Error:", JSON.stringify(logEntry));
// Send to monitoring service
sendToMonitoring(logEntry);
}
Error Metrics
Track these error metrics for monitoring:
- Error Rate: Percentage of requests resulting in errors
- Error Types: Distribution of error codes
- Recovery Success: Rate of successful error recovery
- Session Health: Session initialization and failure rates
Best Practices
Error Handling Principles
- Graceful Degradation: Provide fallback functionality when possible
- User-Friendly Messages: Convert technical errors to user-readable messages
- Retry Logic: Implement appropriate retry strategies with backoff
- State Recovery: Maintain application state consistency during errors
Implementation Guidelines
- Always Check Error Codes: Don’t rely only on HTTP status codes
- Use Error Data: Leverage additional context in error
data
field
- Implement Timeouts: Set reasonable timeouts for all requests
- Log Context: Include request context in error logs
Testing Error Scenarios
Test these error conditions:
- Network failures and timeouts
- Authentication token expiration
- Rate limit exceeded scenarios
- Invalid parameter combinations
- Resource/tool availability changes
This comprehensive error handling approach ensures robust, reliable integration with our MCP server implementation.