MCP
MCP Troubleshooting Guide
Comprehensive guide to debugging and fixing common Model Context Protocol issues. Find solutions to errors, connection problems, and implementation challenges.
Common Errors & Solutions
MCP error -32001: Request timed out
Symptoms:
- • Server fails to respond within timeout period
- • Long-running operations getting interrupted
- • Intermittent connection failures
Common Causes:
- • Server startup taking too long
- • Network connectivity issues
- • Resource-intensive operations blocking the server
Solutions:
Increase timeout duration:
// In claude_desktop_config.json
{
"mcpServers": {
"myserver": {
"command": "node",
"args": ["server.js"],
"timeout": 30000 // Increase from default 10s to 30s
}
}
}Optimize server startup:
// Defer heavy initialization
class MCPServer {
constructor() {
// Quick initialization only
this.server = new Server({ name: 'myserver' });
}
async start() {
// Heavy operations after server starts
await this.loadDatabase();
await this.initializeCache();
}
}MCP error -32000: Connection closed
Symptoms:
- • Server disconnects unexpectedly
- • Cannot establish initial connection
- • Connection drops during operation
Common Causes:
- • Server process crashed
- • Authentication failure
- • Protocol version mismatch
Solutions:
Check server logs:
// Enable detailed logging
const server = new Server({
name: 'myserver',
version: '1.0.0',
});
// Log to stderr (captured by host)
console.error('Server starting...');
server.onerror = (error) => {
console.error('Server error:', error);
};Verify protocol compatibility:
// package.json
{
"dependencies": {
"@modelcontextprotocol/sdk": "^0.5.0" // Use latest stable
}
}Headers Already Sent (SSE Transport)
Symptoms:
- • Cannot set headers after streaming starts
- • Authentication failures with SSE
- • CORS errors in browser
Common Causes:
- • Trying to send headers after SSE stream initialized
- • Incorrect middleware ordering
- • Missing pre-flight handling
Solutions:
Set headers before SSE initialization:
app.get('/sse', (req, res) => {
// Set all headers first
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Access-Control-Allow-Origin', '*');
// Check auth before starting stream
if (!isAuthenticated(req)) {
res.status(401).end();
return;
}
// Now safe to start SSE
res.write('data: connected\n\n');
});Working Directory Issues
Symptoms:
- • File not found errors
- • Relative paths not working
- • Different behavior in development vs production
Common Causes:
- • Undefined working directory in claude_desktop_config.json
- • Relative path resolution differences
- • Environment-specific path issues
Solutions:
Always use absolute paths:
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Use absolute paths
const configPath = join(__dirname, 'config.json');
const dataDir = join(__dirname, '../data');Set explicit working directory:
// claude_desktop_config.json
{
"mcpServers": {
"myserver": {
"command": "node",
"args": ["server.js"],
"cwd": "/absolute/path/to/server"
}
}
}Environment Variable Access
Symptoms:
- • Missing API keys or tokens
- • Configuration not loading
- • Different behavior across environments
Common Causes:
- • Limited environment variable inheritance
- • Security restrictions on variable access
- • Platform-specific variable handling
Solutions:
Explicitly pass environment variables:
// claude_desktop_config.json
{
"mcpServers": {
"myserver": {
"command": "node",
"args": ["server.js"],
"env": {
"API_KEY": "your-api-key",
"DATABASE_URL": "postgresql://...",
"NODE_ENV": "production"
}
}
}
}Debugging Steps
1
Enable Verbose Logging
Turn on detailed logging to see what's happening
Actions:
- Add console.error() statements (not console.log())
- Log server lifecycle events
- Track request/response flow
- Monitor resource usage
Example:
// Comprehensive logging setup
class MCPServer {
constructor() {
console.error('[INIT] Server initializing...');
this.server = new Server({
name: 'debug-server',
version: '1.0.0'
});
this.server.onerror = (error) => {
console.error('[ERROR]', error);
};
// Log all requests
this.server.setRequestHandler('*', async (request, next) => {
console.error('[REQUEST]', request.method, request.params);
try {
const result = await next();
console.error('[RESPONSE]', result);
return result;
} catch (error) {
console.error('[ERROR]', error);
throw error;
}
});
}
}2
Use MCP Inspector
Test your server with the official debugging tool
Actions:
- Install MCP Inspector globally
- Connect to your server
- Test each tool/resource individually
- Verify request/response formats
Example:
# Install MCP Inspector
npm install -g @modelcontextprotocol/inspector
# Run your server
node server.js
# In another terminal, start inspector
mcp-inspector
# Connect to your server and test3
Isolate the Problem
Narrow down where the issue occurs
Actions:
- Test with minimal server implementation
- Remove tools one by one
- Check with different transport methods
- Verify in different environments
Example:
// Minimal test server
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const server = new Server({
name: 'test-server',
version: '1.0.0',
});
// Single test tool
server.setRequestHandler('tools/list', async () => ({
tools: [{
name: 'test',
description: 'Test tool',
inputSchema: { type: 'object' }
}]
}));
server.setRequestHandler('tools/call', async (request) => ({
content: [{ type: 'text', text: 'Test response' }]
}));
const transport = new StdioServerTransport();
await server.connect(transport);4
Check External Dependencies
Verify all external services and dependencies
Actions:
- Test API endpoints independently
- Verify database connections
- Check file system permissions
- Validate network connectivity
Example:
// Test dependencies before server start
async function validateDependencies() {
try {
// Test database
await db.query('SELECT 1');
console.error('[OK] Database connected');
// Test API
const response = await fetch(API_ENDPOINT);
if (!response.ok) throw new Error('API unavailable');
console.error('[OK] API accessible');
// Test file access
await fs.access(CONFIG_PATH);
console.error('[OK] Config file accessible');
} catch (error) {
console.error('[FAIL] Dependency check:', error);
process.exit(1);
}
}Platform-Specific Issues
Windows
Path separator problems
Use path.join() or path.sep instead of hardcoded slashes
Process spawn errors
Use shell: true option or full executable paths
Permission issues
Run as administrator or check file permissions
macOS
Security warnings
Code sign your server or allow in System Preferences
Port access restrictions
Use ports above 1024 or grant specific permissions
Linux
Missing dependencies
Install required system packages (build-essential, etc.)
SELinux restrictions
Configure SELinux policies or use appropriate contexts
Quick Debugging Checklist
- ✓ Check server logs in stderr (not stdout)
- ✓ Verify MCP SDK version compatibility
- ✓ Test with MCP Inspector tool
- ✓ Use absolute paths for all file references
- ✓ Explicitly pass required environment variables
- ✓ Validate all external dependencies
- ✓ Check transport-specific requirements