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:

  1. Check apiBaseUrl is provided
  2. Verify OpenAPI spec path/URL is accessible
  3. Validate authentication credentials
  4. Run with --debug flag

🔌 Connection Issues

Symptoms:

  • API requests fail
  • "Connection refused" errors
  • Timeout errors

Quick Fixes:

  1. Test API URL manually with curl
  2. Check network connectivity
  3. Verify firewall settings
  4. Test with testConnection() method

🔐 Authentication Errors

Symptoms:

  • 401 Unauthorized errors
  • 403 Forbidden responses
  • Token expiry issues

Quick Fixes:

  1. Verify token/credentials are correct
  2. Check token expiration
  3. Test authentication manually
  4. Implement token refresh logic

🛠️ Tool Generation Issues

Symptoms:

  • No tools generated
  • Unexpected tool count
  • Missing specific endpoints

Quick Fixes:

  1. Check OpenAPI spec validity
  2. Review filtering configuration
  3. Verify spec has operations
  4. Check getStats() output

Common Issues & Solutions

❌ Error: "apiBaseUrl is required"

Error: apiBaseUrl is required in configuration

🔧 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

Error: Failed to load OpenAPI spec from: ./api-spec.yaml

🔧 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

Error: Request failed with status code 401

🔧 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

Error: getaddrinfo ENOTFOUND api.example.com

🔧 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

Warning: No tools generated after applying filters

🔧 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:

  1. Validate JSON syntax with a JSON validator
  2. Restart Claude Desktop after configuration changes
  3. Check Claude Desktop console logs
  4. 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 (--debug flag)
  • 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