Troubleshooting Guide
Common issues, debug techniques, and step-by-step solutions for OpenAPI MCP Server problems.
Quick Diagnosis
Start here for rapid problem identification and common solutions.
🚨 Server Won't Start
Symptoms:
- Error on startup
- Process exits immediately
- Configuration validation fails
Quick Fixes:
- Check
apiBaseUrlis provided - Verify OpenAPI spec path/URL is accessible
- Validate authentication credentials
- Run with
--debugflag
🔌 Connection Issues
Symptoms:
- API requests fail
- "Connection refused" errors
- Timeout errors
Quick Fixes:
- Test API URL manually with curl
- Check network connectivity
- Verify firewall settings
- Test with
testConnection()method
🔐 Authentication Errors
Symptoms:
- 401 Unauthorized errors
- 403 Forbidden responses
- Token expiry issues
Quick Fixes:
- Verify token/credentials are correct
- Check token expiration
- Test authentication manually
- Implement token refresh logic
🛠️ Tool Generation Issues
Symptoms:
- No tools generated
- Unexpected tool count
- Missing specific endpoints
Quick Fixes:
- Check OpenAPI spec validity
- Review filtering configuration
- Verify spec has operations
- Check
getStats()output
Common Issues & Solutions
❌ Error: "apiBaseUrl is required"
🔧 Solution:
The base URL for your API is mandatory. Provide it in configuration:
# CLI
npx @lucid-spark/openapi-mcp-server openapi-mcp-server --api-base-url "https://api.example.com"
// Library
const server = new OpenAPIServer({
apiBaseUrl: "https://api.example.com",
// ... other config
});
❌ OpenAPI Specification Loading Errors
🔧 Solutions:
1. File Path Issues
# Check file exists
ls -la ./api-spec.yaml
# Use absolute path
npx @lucid-spark/openapi-mcp-server openapi-mcp-server \
--api-base-url "https://api.example.com" \
--openapi-spec "/full/path/to/api-spec.yaml"
2. URL Accessibility
# Test URL manually
curl -I "https://api.example.com/openapi.json"
# Check for CORS issues (browser only)
# Try with different content-type headers
3. Format Validation
# Validate YAML syntax
npx js-yaml api-spec.yaml
# Validate JSON syntax
jq . api-spec.json
# Validate OpenAPI spec
npx swagger-cli validate api-spec.yaml
❌ Authentication Token Errors
🔧 Solutions:
1. Verify Token Format
# Test authentication manually
curl -H "Authorization: Bearer YOUR_TOKEN" \
"https://api.example.com/some-endpoint"
# Check token format (Bearer, Basic, API Key, etc.)
# Refer to API documentation for correct format
2. Token Expiry Check
// Decode JWT token (if applicable)
const jwt = require('jsonwebtoken');
const decoded = jwt.decode(token);
console.log('Token expires:', new Date(decoded.exp * 1000));
// Implement refresh logic
class TokenManager {
async refreshIfNeeded() {
if (this.isTokenExpiring()) {
await this.refreshToken();
}
}
}
3. Header Configuration
// Common authentication patterns
const configs = {
bearer: {
headers: { "Authorization": "Bearer YOUR_TOKEN" }
},
apiKey: {
headers: { "X-API-Key": "YOUR_API_KEY" }
},
basic: {
headers: { "Authorization": "Basic " + Buffer.from("user:pass").toString("base64") }
}
};
❌ Network Connection Issues
🔧 Solutions:
1. DNS Resolution
# Test DNS resolution
nslookup api.example.com
dig api.example.com
# Try alternative DNS servers
# 8.8.8.8 (Google), 1.1.1.1 (Cloudflare)
2. Network Connectivity
# Test basic connectivity
ping api.example.com
# Test specific port
telnet api.example.com 443
# Check proxy settings
echo $HTTP_PROXY
echo $HTTPS_PROXY
3. SSL/TLS Issues
# Test SSL certificate
openssl s_client -connect api.example.com:443 -servername api.example.com
# Check certificate validity
curl -I --verbose "https://api.example.com"
❌ Tool Filtering Not Working
🔧 Solutions:
1. Check Filter Configuration
// Debug filter settings
const server = new OpenAPIServer({
// ... config
debug: true // Enable debug output
});
const stats = server.getStats();
console.log("Filter status:", stats.filtering);
2. Validate Tag Names
# List available tags in OpenAPI spec
cat api-spec.yaml | grep -A 5 "tags:"
# Use exact tag names (case-sensitive)
npx @lucid-spark/openapi-mcp-server openapi-mcp-server \
--include-tags "Users,Orders" \ # NOT "users,orders"
# ... other config
3. Operation Validation
// Check which operations exist
const spec = await loadOpenAPISpec("./api-spec.yaml");
const operations = [];
Object.entries(spec.paths).forEach(([path, methods]) => {
Object.keys(methods).forEach(method => {
if (['get', 'post', 'put', 'patch', 'delete'].includes(method)) {
operations.push(method.toUpperCase());
}
});
});
console.log("Available operations:", [...new Set(operations)]);
Debug Techniques
🔍 Enable Debug Mode
Debug mode provides detailed logging for troubleshooting:
CLI Debug Mode
# Enable debug output
npx @lucid-spark/openapi-mcp-server openapi-mcp-server \
--api-base-url "https://api.example.com" \
--openapi-spec "./api-spec.yaml" \
--debug
# Expected debug output:
# [DEBUG] Configuration validated successfully
# [DEBUG] Loading OpenAPI spec from: ./api-spec.yaml
# [DEBUG] Found 15 paths with 23 operations
# [DEBUG] Applying filters: includeTags=[], includeOperations=[]
# [DEBUG] Generated 23 endpoint tools + 3 meta tools
# [DEBUG] Starting stdio transport
# [DEBUG] Server ready and listening
Library Debug Mode
import { OpenAPIServer } from "@lucid-spark/openapi-mcp-server";
const server = new OpenAPIServer({
apiBaseUrl: "https://api.example.com",
openApiSpec: "./api-spec.yaml",
debug: true, // Enable debug mode
// ... other config
});
// Debug information will be logged to console
await server.start();
📊 Connection Testing
Test your API connection before starting the full server:
// connection-test.ts
import { OpenAPIServer } from "@lucid-spark/openapi-mcp-server";
async function testSetup() {
const server = new OpenAPIServer({
apiBaseUrl: "https://api.example.com",
openApiSpec: "./api-spec.yaml",
headers: {
"Authorization": `Bearer ${process.env.API_TOKEN}`
}
});
console.log("🔍 Testing API connection...");
try {
const connected = await server.testConnection();
if (connected) {
console.log("✅ Connection successful");
// Test server initialization
await server.start();
// Get detailed statistics
const stats = server.getStats();
console.log("📊 Server Statistics:");
console.log(` - Total tools: ${stats.tools.total}`);
console.log(` - Endpoint tools: ${stats.tools.endpointTools}`);
console.log(` - Meta tools: ${stats.tools.metaTools}`);
console.log(` - OpenAPI version: ${stats.openapi.version}`);
console.log(` - API paths: ${stats.openapi.paths}`);
console.log(` - API operations: ${stats.openapi.operations}`);
if (stats.filtering?.applied) {
console.log("🎯 Filtering applied:");
console.log(` - Included tags: ${stats.filtering.includedTags?.join(', ') || 'none'}`);
console.log(` - Included operations: ${stats.filtering.includedOperations?.join(', ') || 'all'}`);
}
await server.stop();
console.log("✅ Test completed successfully");
} else {
console.error("❌ Connection failed");
}
} catch (error) {
console.error("❌ Error during testing:", error.message);
// Provide debugging hints
if (error.code === 'ENOTFOUND') {
console.log("💡 Hint: Check the API base URL for typos");
} else if (error.response?.status === 401) {
console.log("💡 Hint: Check your authentication credentials");
} else if (error.response?.status === 404) {
console.log("💡 Hint: OpenAPI spec path might be incorrect");
}
}
}
testSetup();
🕵️ Manual API Testing
Test your API manually to verify it works outside of the MCP server:
Using curl
# Test basic connectivity
curl -I "https://api.example.com"
# Test with authentication
curl -H "Authorization: Bearer YOUR_TOKEN" \
-H "Accept: application/json" \
"https://api.example.com/some-endpoint"
# Test OpenAPI spec endpoint
curl "https://api.example.com/openapi.json" | jq .
# Test with verbose output for debugging
curl -v -H "Authorization: Bearer YOUR_TOKEN" \
"https://api.example.com/some-endpoint"
Using Node.js
// manual-test.js
const https = require('https');
function testApi() {
const options = {
hostname: 'api.example.com',
port: 443,
path: '/some-endpoint',
method: 'GET',
headers: {
'Authorization': `Bearer ${process.env.API_TOKEN}`,
'Accept': 'application/json'
}
};
const req = https.request(options, (res) => {
console.log(`Status: ${res.statusCode}`);
console.log(`Headers:`, res.headers);
let data = '';
res.on('data', (chunk) => data += chunk);
res.on('end', () => {
console.log('Response:', data);
});
});
req.on('error', (error) => {
console.error('Error:', error.message);
});
req.end();
}
testApi();
Performance Troubleshooting
🐌 Slow Server Startup
Possible Causes:
- Large OpenAPI specification
- Network latency loading spec from URL
- Complex authentication setup
- Excessive tool generation
Solutions:
// Optimize configuration
const config = {
apiBaseUrl: "https://api.example.com",
// Cache spec locally instead of fetching from URL
openApiSpec: "./cached-api-spec.yaml", // vs remote URL
// Limit tool generation
includeOperations: ["GET", "POST"], // Only needed operations
includeTags: ["users", "orders"], // Only relevant tags
includeTools: [ // Specific tools only
"get-user",
"create-order",
"get-order-status"
],
// Disable abbreviation for faster processing
disableAbbreviation: true
};
⏱️ Request Timeouts
Solutions:
// Configure timeouts
import { OpenAPIServer } from "@lucid-spark/openapi-mcp-server";
import axios from "axios";
// Configure global axios timeout
axios.defaults.timeout = 30000; // 30 seconds
// Custom HTTP client with retry logic
class RobustApiClient {
constructor(baseUrl, authProvider) {
this.axios = axios.create({
baseURL: baseUrl,
timeout: 30000,
retry: 3,
retryDelay: 1000
});
// Add retry interceptor
this.axios.interceptors.response.use(null, async (error) => {
const config = error.config;
if (!config || !config.retry) return Promise.reject(error);
config.retryCount = config.retryCount || 0;
if (config.retryCount >= config.retry) {
return Promise.reject(error);
}
config.retryCount++;
await new Promise(resolve =>
setTimeout(resolve, config.retryDelay * config.retryCount)
);
return this.axios(config);
});
}
}
🔄 Memory Usage Issues
Monitor Memory Usage:
// memory-monitor.ts
function monitorMemory() {
setInterval(() => {
const usage = process.memoryUsage();
console.log('Memory Usage:');
console.log(` RSS: ${Math.round(usage.rss / 1024 / 1024)} MB`);
console.log(` Heap Used: ${Math.round(usage.heapUsed / 1024 / 1024)} MB`);
console.log(` Heap Total: ${Math.round(usage.heapTotal / 1024 / 1024)} MB`);
console.log(` External: ${Math.round(usage.external / 1024 / 1024)} MB`);
}, 60000); // Every minute
}
// Start monitoring
monitorMemory();
// Garbage collection hints
if (global.gc) {
setInterval(() => {
global.gc();
}, 300000); // Every 5 minutes
}
Claude Desktop Integration Issues
🖥️ Claude Desktop Not Recognizing Server
Check Configuration Location:
# macOS
~/Library/Application Support/Claude/claude_desktop_config.json
# Windows
%APPDATA%\Claude\claude_desktop_config.json
# Linux
~/.config/Claude/claude_desktop_config.json
Validate Configuration Format:
{
"mcpServers": {
"openapi-server": {
"command": "npx",
"args": [
"@lucid-spark/openapi-mcp-server",
"openapi-mcp-server",
"--api-base-url", "https://api.example.com",
"--openapi-spec", "https://api.example.com/openapi.json",
"--header", "Authorization=Bearer YOUR_TOKEN"
]
}
}
}
Debugging Steps:
- Validate JSON syntax with a JSON validator
- Restart Claude Desktop after configuration changes
- Check Claude Desktop console logs
- Test the exact command manually in terminal
🔧 Tools Not Appearing in Claude
Verification Steps:
# Test the exact command from Claude config
npx @lucid-spark/openapi-mcp-server openapi-mcp-server \
--api-base-url "https://api.example.com" \
--openapi-spec "https://api.example.com/openapi.json" \
--header "Authorization=Bearer YOUR_TOKEN" \
--debug
# Look for:
# - "Server ready and listening"
# - Tool count > 0
# - No error messages
Common Fixes:
- Ensure server name is unique in Claude config
- Check that OpenAPI spec has valid operations
- Verify authentication doesn't block tool discovery
- Try with a minimal configuration first
⚡ Performance Issues in Claude
Optimize for Claude:
{
"mcpServers": {
"api-server": {
"command": "npx",
"args": [
"@lucid-spark/openapi-mcp-server",
"openapi-mcp-server",
"--api-base-url", "https://api.example.com",
"--openapi-spec", "./local-spec.yaml",
"--include-operations", "GET,POST",
"--include-tags", "users,orders",
"--disable-abbreviation"
]
}
}
}
This reduces tool count and improves Claude's response time.
Log Analysis
📝 Understanding Log Messages
✅ Successful Startup Logs
[DEBUG] Configuration validated successfully
[DEBUG] Loading OpenAPI spec from: https://api.example.com/openapi.json
[DEBUG] Found 15 paths with 23 operations
[DEBUG] Applying filters: includeTags=["users"], includeOperations=["GET","POST"]
[DEBUG] Generated 12 endpoint tools + 3 meta tools
[DEBUG] Starting stdio transport
[INFO] Server ready and listening
Analysis: Normal startup with 15 tools generated from filtered operations.
⚠️ Warning Logs
[WARN] No operations found for tag: "admin"
[WARN] Tool name abbreviated: "getUserDetailsByIdentifier" → "get-usr-dtls-by-idntfr"
[WARN] Duplicate operationId found: "getUser" - using path for uniqueness
Analysis: Non-critical warnings about filtering and naming.
❌ Error Logs
[ERROR] Failed to load OpenAPI spec: getaddrinfo ENOTFOUND api.example.com
[ERROR] Authentication failed: 401 Unauthorized
[ERROR] Invalid OpenAPI specification: Missing required field 'paths'
Analysis: Critical errors preventing server startup.
🔍 Debug Log Interpretation
Configuration Phase
[DEBUG] Configuration validated successfully
[DEBUG] API Base URL: https://api.example.com
[DEBUG] OpenAPI Spec: ./api-spec.yaml
[DEBUG] Transport: stdio
[DEBUG] Authentication: Static headers
Shows configuration was loaded and validated correctly.
Specification Loading
[DEBUG] Loading OpenAPI spec from: ./api-spec.yaml
[DEBUG] Spec format detected: YAML
[DEBUG] OpenAPI version: 3.0.3
[DEBUG] Found 15 paths with 23 operations
OpenAPI specification was loaded and parsed successfully.
Tool Generation
[DEBUG] Applying filters: includeTags=["users"], includeOperations=[]
[DEBUG] Tool created: get-user (GET /users/{id})
[DEBUG] Tool created: create-user (POST /users)
[DEBUG] Generated 12 endpoint tools + 3 meta tools
Tools are being generated and filtered correctly.
Getting Help
📞 When to Seek Help
- You've tried all troubleshooting steps
- Error messages are unclear or undocumented
- Issue appears to be a bug in the software
- Configuration works elsewhere but not in your environment
📋 Information to Provide
Before reporting an issue, gather:
🔧 Environment Details
- Operating system and version
- Node.js version (
node --version) -
Package version (
npm list @lucid-spark/openapi-mcp-server) - Claude Desktop version (if applicable)
📄 Configuration
- Complete configuration (sanitized of secrets)
- OpenAPI specification (or sample)
- Command line arguments used
- Environment variables (names only)
📊 Debug Output
- Full debug logs (
--debugflag) - Error messages and stack traces
- Server statistics output
- Network test results
🔄 Reproduction Steps
- Minimal config to reproduce issue
- Expected vs actual behavior
- Frequency of the issue
- Recent changes before issue started
📝 Issue Report Template
## Issue Summary
Brief description of the problem
## Environment
- OS: macOS 14.0 / Windows 11 / Ubuntu 22.04
- Node.js: v18.17.0
- Package: @lucid-spark/openapi-mcp-server@1.0.3
- Claude Desktop: 1.0.0 (if applicable)
## Configuration
```json
{
"apiBaseUrl": "https://api.example.com",
"openApiSpec": "./api-spec.yaml",
// ... rest of config (remove secrets)
}
```
## Expected Behavior
What should happen
## Actual Behavior
What actually happens
## Debug Output
```
[DEBUG] logs here...
```
## Steps to Reproduce
1. Step one
2. Step two
3. Observe issue
## Additional Context
Any other relevant information