Examples & Tutorials

Real-world examples and comprehensive tutorials for OpenAPI MCP Server integration patterns.

Quick Start Examples

๐Ÿš€ JSONPlaceholder API

Perfect for testing and learning - connects to the public JSONPlaceholder API

# CLI usage
npx @lucid-spark/openapi-mcp-server openapi-mcp-server \
  --api-base-url "https://jsonplaceholder.typicode.com" \
  --openapi-spec "https://jsonplaceholder.typicode.com/openapi.json"
// Library usage
import { OpenAPIServer } from "@lucid-spark/openapi-mcp-server";

const server = new OpenAPIServer({
  apiBaseUrl: "https://jsonplaceholder.typicode.com",
  openApiSpec: "https://jsonplaceholder.typicode.com/openapi.json"
});

await server.start();

๐Ÿ” Basic Authentication

Simple header-based authentication with API keys

# Using environment variables
export API_KEY="your-api-key"
export OPENAPI_SPEC_URL="https://api.example.com/openapi.json"

npx @lucid-spark/openapi-mcp-server openapi-mcp-server \
  --api-base-url "https://api.example.com" \
  --header "Authorization=Bearer $API_KEY"
// Library configuration
const server = new OpenAPIServer({
  apiBaseUrl: "https://api.example.com",
  openApiSpec: process.env.OPENAPI_SPEC_URL,
  headers: {
    "Authorization": `Bearer ${process.env.API_KEY}`,
    "Accept": "application/json"
  }
});

๐ŸŽฏ Filtered Tools

Include only specific endpoints or tags to reduce tool clutter

# Include only user-related endpoints
npx @lucid-spark/openapi-mcp-server openapi-mcp-server \
  --api-base-url "https://api.example.com" \
  --include-tags "users,profiles" \
  --include-operations "GET,POST"
// Programmatic filtering
const server = new OpenAPIServer({
  apiBaseUrl: "https://api.example.com",
  openApiSpec: "./api-spec.yaml",
  includeTags: ["users", "profiles"],
  includeOperations: ["GET", "POST"]
});

Real-World Integration Examples

๐Ÿ“Š GitHub API Integration

Connect to GitHub's REST API for repository management, issue tracking, and more.

CLI Setup

# Create a GitHub personal access token first
export GITHUB_TOKEN="ghp_your_token_here"

npx @lucid-spark/openapi-mcp-server openapi-mcp-server \
  --api-base-url "https://api.github.com" \
  --openapi-spec "https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json" \
  --header "Authorization=Bearer $GITHUB_TOKEN" \
  --header "Accept=application/vnd.github.v3+json" \
  --header "User-Agent=OpenAPI-MCP-Server" \
  --include-tags "repos,issues,pulls"

Claude Desktop Configuration

{
  "mcpServers": {
    "github-api": {
      "command": "npx",
      "args": [
        "@lucid-spark/openapi-mcp-server",
        "openapi-mcp-server",
        "--api-base-url", "https://api.github.com",
        "--openapi-spec", "https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json",
        "--header", "Authorization=Bearer YOUR_GITHUB_TOKEN",
        "--header", "Accept=application/vnd.github.v3+json",
        "--header", "User-Agent=Claude-GitHub-Integration",
        "--include-tags", "repos,issues,pulls"
      ]
    }
  }
}

Library Implementation

import { OpenAPIServer, StaticAuthProvider } from "@lucid-spark/openapi-mcp-server";

const githubServer = new OpenAPIServer({
  apiBaseUrl: "https://api.github.com",
  openApiSpec: "https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json",
  authProvider: new StaticAuthProvider({
    "Authorization": `Bearer ${process.env.GITHUB_TOKEN}`,
    "Accept": "application/vnd.github.v3+json",
    "User-Agent": "OpenAPI-MCP-Server"
  }),
  includeTags: ["repos", "issues", "pulls"],
  name: "github-api-server",
  version: "1.0.0"
});

await githubServer.start();

// Test the connection
const connected = await githubServer.testConnection();
console.log(`GitHub API: ${connected ? 'Connected' : 'Failed'}`);

// Get server statistics
const stats = githubServer.getStats();
console.log(`Generated ${stats.tools.total} tools from GitHub API`);

๐Ÿค– Example Claude Interactions

You: Can you list the repositories in my GitHub account?
Claude: I'll list your GitHub repositories using the GitHub API.
[Uses get-repos-for-authenticated-user tool]
You: Create a new issue in my project repo titled "Feature Request: Dark Mode"
Claude: I'll create that issue for you.
[Uses create-issue tool with repo owner/name, title, and body]

๐Ÿ›๏ธ E-commerce API Integration

Connect to an e-commerce platform for product management and order processing.

OAuth2 Authentication

import { OpenAPIServer, IAuthProvider } from "@lucid-spark/openapi-mcp-server";
import { AxiosError } from "axios";

class EcommerceAuthProvider implements IAuthProvider {
  private accessToken: string;
  private refreshToken: string;
  private clientId: string;
  private clientSecret: string;
  private tokenEndpoint: string;
  private tokenExpiry: Date;

  constructor(config: {
    accessToken: string;
    refreshToken: string;
    clientId: string;
    clientSecret: string;
    tokenEndpoint: string;
    expiresIn: number;
  }) {
    this.accessToken = config.accessToken;
    this.refreshToken = config.refreshToken;
    this.clientId = config.clientId;
    this.clientSecret = config.clientSecret;
    this.tokenEndpoint = config.tokenEndpoint;
    this.tokenExpiry = new Date(Date.now() + config.expiresIn * 1000);
  }

  async getAuthHeaders(): Promise> {
    if (this.isTokenExpiring()) {
      await this.refreshAccessToken();
    }

    return {
      Authorization: `Bearer ${this.accessToken}`,
      "Content-Type": "application/json"
    };
  }

  async handleAuthError(error: AxiosError): Promise {
    if (error.response?.status === 401) {
      try {
        await this.refreshAccessToken();
        return true; // Retry request
      } catch (refreshError) {
        console.error("Token refresh failed:", refreshError);
        return false;
      }
    }
    return false;
  }

  private isTokenExpiring(): boolean {
    const bufferTime = 5 * 60 * 1000; // 5 minutes buffer
    return this.tokenExpiry.getTime() <= (Date.now() + bufferTime);
  }

  private async refreshAccessToken(): Promise {
    const response = await fetch(this.tokenEndpoint, {
      method: "POST",
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
        "Authorization": `Basic ${Buffer.from(`${this.clientId}:${this.clientSecret}`).toString("base64")}`
      },
      body: new URLSearchParams({
        grant_type: "refresh_token",
        refresh_token: this.refreshToken
      })
    });

    if (!response.ok) {
      throw new Error(`Token refresh failed: ${response.statusText}`);
    }

    const data = await response.json();
    this.accessToken = data.access_token;
    
    if (data.refresh_token) {
      this.refreshToken = data.refresh_token;
    }
    
    this.tokenExpiry = new Date(Date.now() + data.expires_in * 1000);
  }
}

// Usage
const authProvider = new EcommerceAuthProvider({
  accessToken: process.env.ECOMMERCE_ACCESS_TOKEN!,
  refreshToken: process.env.ECOMMERCE_REFRESH_TOKEN!,
  clientId: process.env.ECOMMERCE_CLIENT_ID!,
  clientSecret: process.env.ECOMMERCE_CLIENT_SECRET!,
  tokenEndpoint: "https://api.ecommerce.com/oauth/token",
  expiresIn: 3600
});

const ecommerceServer = new OpenAPIServer({
  apiBaseUrl: "https://api.ecommerce.com/v1",
  openApiSpec: "https://api.ecommerce.com/v1/openapi.json",
  authProvider: authProvider,
  includeTags: ["products", "orders", "customers"],
  name: "ecommerce-api"
});

๐Ÿ“ˆ Analytics API Integration

Connect to analytics platforms for data retrieval and reporting.

// Advanced filtering and custom headers
const analyticsServer = new OpenAPIServer({
  apiBaseUrl: "https://api.analytics.com",
  openApiSpec: "./analytics-api-spec.yaml",
  headers: {
    "Authorization": `Token ${process.env.ANALYTICS_API_TOKEN}`,
    "X-Client-Version": "1.0.0",
    "Accept": "application/json"
  },
  // Only include specific endpoints for data retrieval
  includeOperations: ["GET", "POST"],
  includeTags: ["reports", "metrics", "dashboards"],
  // Exclude internal/admin endpoints
  includeTools: [
    "get-daily-metrics",
    "get-user-analytics", 
    "post-custom-report",
    "get-dashboard-data"
  ],
  name: "analytics-server",
  debug: true
});

// Start with error handling
try {
  await analyticsServer.start();
  console.log("Analytics API server started successfully");
  
  const stats = analyticsServer.getStats();
  console.log(`Available tools: ${stats.tools.total}`);
  console.log(`API paths: ${stats.openapi.paths}`);
  
} catch (error) {
  console.error("Failed to start analytics server:", error.message);
  process.exit(1);
}

Advanced Integration Patterns

๐Ÿ”„ Multi-Environment Setup

Manage different API environments (dev, staging, production) with environment-specific configurations.

// config/environments.ts
interface Environment {
  name: string;
  apiBaseUrl: string;
  openApiSpec: string;
  headers: Record;
}

const environments: Record = {
  development: {
    name: "dev-api",
    apiBaseUrl: "https://dev-api.example.com",
    openApiSpec: "https://dev-api.example.com/openapi.json",
    headers: {
      "Authorization": `Bearer ${process.env.DEV_API_TOKEN}`,
      "X-Environment": "development"
    }
  },
  staging: {
    name: "staging-api", 
    apiBaseUrl: "https://staging-api.example.com",
    openApiSpec: "https://staging-api.example.com/openapi.json",
    headers: {
      "Authorization": `Bearer ${process.env.STAGING_API_TOKEN}`,
      "X-Environment": "staging"
    }
  },
  production: {
    name: "prod-api",
    apiBaseUrl: "https://api.example.com",
    openApiSpec: "https://api.example.com/openapi.json", 
    headers: {
      "Authorization": `Bearer ${process.env.PROD_API_TOKEN}`,
      "X-Environment": "production"
    }
  }
};

// server-manager.ts
import { OpenAPIServer } from "@lucid-spark/openapi-mcp-server";

export class MultiEnvironmentManager {
  private servers: Map = new Map();

  async createServer(environment: string): Promise {
    const env = environments[environment];
    if (!env) {
      throw new Error(`Unknown environment: ${environment}`);
    }

    const server = new OpenAPIServer({
      ...env,
      transportType: "http",
      httpPort: this.getPortForEnvironment(environment)
    });

    await server.start();
    this.servers.set(environment, server);
    
    return server;
  }

  async stopServer(environment: string): Promise {
    const server = this.servers.get(environment);
    if (server) {
      await server.stop();
      this.servers.delete(environment);
    }
  }

  private getPortForEnvironment(environment: string): number {
    const basePorts = { development: 3001, staging: 3002, production: 3003 };
    return basePorts[environment] || 3000;
  }
}

// Usage
const manager = new MultiEnvironmentManager();

// Start development server
const devServer = await manager.createServer("development");

// Switch to production for final testing
await manager.stopServer("development");
const prodServer = await manager.createServer("production");

๐ŸŽ›๏ธ Dynamic Configuration Loading

Load OpenAPI specifications and configurations dynamically from various sources.

// config-loader.ts
import { readFile } from "fs/promises";
import { load } from "js-yaml";
import { OpenAPIServer, IOpenAPIServerConfig } from "@lucid-spark/openapi-mcp-server";

export class DynamicConfigLoader {
  static async loadFromFile(configPath: string): Promise {
    try {
      const content = await readFile(configPath, "utf-8");
      
      // Support both JSON and YAML
      const config = configPath.endsWith('.yaml') || configPath.endsWith('.yml') 
        ? load(content) as IOpenAPIServerConfig
        : JSON.parse(content) as IOpenAPIServerConfig;
      
      // Resolve environment variables in config
      return this.resolveEnvironmentVariables(config);
    } catch (error) {
      throw new Error(`Failed to load config from ${configPath}: ${error.message}`);
    }
  }

  static async loadFromUrl(configUrl: string): Promise {
    try {
      const response = await fetch(configUrl);
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }
      
      const config = await response.json();
      return this.resolveEnvironmentVariables(config);
    } catch (error) {
      throw new Error(`Failed to load config from ${configUrl}: ${error.message}`);
    }
  }

  static async loadFromRegistry(serviceName: string): Promise {
    // Example: Service discovery integration
    const registryUrl = process.env.SERVICE_REGISTRY_URL || "http://localhost:8500";
    const response = await fetch(`${registryUrl}/v1/catalog/service/${serviceName}`);
    
    if (!response.ok) {
      throw new Error(`Service ${serviceName} not found in registry`);
    }
    
    const services = await response.json();
    const service = services[0]; // Use first available instance
    
    return {
      apiBaseUrl: `http://${service.ServiceAddress}:${service.ServicePort}`,
      openApiSpec: `http://${service.ServiceAddress}:${service.ServicePort}/openapi.json`,
      name: serviceName,
      headers: {
        "X-Service-Version": service.ServiceMeta?.version || "unknown"
      }
    };
  }

  private static resolveEnvironmentVariables(config: any): any {
    const resolved = JSON.parse(JSON.stringify(config));
    
    const replaceEnvVars = (obj: any): any => {
      if (typeof obj === "string") {
        return obj.replace(/\$\{([^}]+)\}/g, (match, envVar) => {
          return process.env[envVar] || match;
        });
      } else if (Array.isArray(obj)) {
        return obj.map(replaceEnvVars);
      } else if (typeof obj === "object" && obj !== null) {
        const result: any = {};
        for (const [key, value] of Object.entries(obj)) {
          result[key] = replaceEnvVars(value);
        }
        return result;
      }
      return obj;
    };
    
    return replaceEnvVars(resolved);
  }
}

// Example configuration file (config.yaml)
/*
apiBaseUrl: ${API_BASE_URL}
openApiSpec: ${OPENAPI_SPEC_URL}
headers:
  Authorization: "Bearer ${API_TOKEN}"
  X-Client-ID: ${CLIENT_ID}
includeTags:
  - users
  - orders
transportType: stdio
debug: ${DEBUG_MODE:false}
*/

// Usage examples
const configLoader = new DynamicConfigLoader();

// Load from file
const fileConfig = await configLoader.loadFromFile("./config.yaml");
const fileServer = new OpenAPIServer(fileConfig);

// Load from URL
const urlConfig = await configLoader.loadFromUrl("https://config.example.com/api-config.json");
const urlServer = new OpenAPIServer(urlConfig);

// Load from service registry
const registryConfig = await configLoader.loadFromRegistry("user-service");
const registryServer = new OpenAPIServer(registryConfig);

๐Ÿ”Œ Plugin Architecture

Extend the server with custom plugins for specialized functionality.

// plugins/base-plugin.ts
export interface IPlugin {
  name: string;
  version: string;
  initialize(server: OpenAPIServer): Promise;
  beforeRequest?(request: any): Promise;
  afterResponse?(response: any): Promise;
  cleanup?(): Promise;
}

// plugins/logging-plugin.ts
export class LoggingPlugin implements IPlugin {
  name = "logging-plugin";
  version = "1.0.0";
  
  private requestCount = 0;
  private errorCount = 0;

  async initialize(server: OpenAPIServer): Promise {
    console.log(`[${this.name}] Initialized for server: ${server.getStats().openapi.version}`);
  }

  async beforeRequest(request: any): Promise {
    this.requestCount++;
    console.log(`[${this.name}] Request #${this.requestCount}: ${request.method} ${request.url}`);
    return request;
  }

  async afterResponse(response: any): Promise {
    if (response.status >= 400) {
      this.errorCount++;
      console.error(`[${this.name}] Error response: ${response.status} ${response.statusText}`);
    }
    return response;
  }

  getStats() {
    return {
      totalRequests: this.requestCount,
      totalErrors: this.errorCount,
      errorRate: this.requestCount > 0 ? (this.errorCount / this.requestCount) * 100 : 0
    };
  }
}

// plugins/caching-plugin.ts
export class CachingPlugin implements IPlugin {
  name = "caching-plugin";
  version = "1.0.0";
  
  private cache = new Map();
  private ttl: number;

  constructor(ttlMinutes: number = 5) {
    this.ttl = ttlMinutes * 60 * 1000;
  }

  async initialize(server: OpenAPIServer): Promise {
    console.log(`[${this.name}] Cache TTL: ${this.ttl}ms`);
    
    // Clean expired entries every minute
    setInterval(() => this.cleanExpired(), 60000);
  }

  async beforeRequest(request: any): Promise {
    if (request.method === "GET") {
      const cacheKey = this.getCacheKey(request);
      const cached = this.cache.get(cacheKey);
      
      if (cached && cached.expires > Date.now()) {
        console.log(`[${this.name}] Cache hit: ${cacheKey}`);
        request.cachedResponse = cached.data;
      }
    }
    return request;
  }

  async afterResponse(response: any): Promise {
    if (response.status === 200 && response.config?.method === "GET") {
      const cacheKey = this.getCacheKey(response.config);
      this.cache.set(cacheKey, {
        data: response.data,
        expires: Date.now() + this.ttl
      });
      console.log(`[${this.name}] Cached response: ${cacheKey}`);
    }
    return response;
  }

  private getCacheKey(request: any): string {
    return `${request.method}:${request.url}`;
  }

  private cleanExpired(): void {
    const now = Date.now();
    for (const [key, value] of this.cache.entries()) {
      if (value.expires <= now) {
        this.cache.delete(key);
      }
    }
  }
}

// enhanced-server.ts
export class EnhancedOpenAPIServer extends OpenAPIServer {
  private plugins: IPlugin[] = [];

  addPlugin(plugin: IPlugin): void {
    this.plugins.push(plugin);
  }

  async start(): Promise {
    // Initialize plugins
    for (const plugin of this.plugins) {
      await plugin.initialize(this);
    }
    
    // Start the base server
    await super.start();
  }

  async stop(): Promise {
    // Cleanup plugins
    for (const plugin of this.plugins) {
      if (plugin.cleanup) {
        await plugin.cleanup();
      }
    }
    
    await super.stop();
  }

  // Override request handling to apply plugins
  protected async processRequest(request: any): Promise {
    let processedRequest = request;
    
    // Apply beforeRequest hooks
    for (const plugin of this.plugins) {
      if (plugin.beforeRequest) {
        processedRequest = await plugin.beforeRequest(processedRequest);
      }
    }
    
    // Check for cached response
    if (processedRequest.cachedResponse) {
      return processedRequest.cachedResponse;
    }
    
    // Process request normally
    let response = await super.processRequest(processedRequest);
    
    // Apply afterResponse hooks
    for (const plugin of this.plugins) {
      if (plugin.afterResponse) {
        response = await plugin.afterResponse(response);
      }
    }
    
    return response;
  }
}

// Usage
const server = new EnhancedOpenAPIServer({
  apiBaseUrl: "https://api.example.com",
  openApiSpec: "./api-spec.yaml"
});

// Add plugins
server.addPlugin(new LoggingPlugin());
server.addPlugin(new CachingPlugin(10)); // 10-minute cache

await server.start();

Common Use Cases

๐Ÿ“ Content Management

{
  "mcpServers": {
    "cms-api": {
      "command": "npx",
      "args": [
        "@lucid-spark/openapi-mcp-server",
        "openapi-mcp-server",
        "--api-base-url", "https://cms.example.com/api/v1",
        "--openapi-spec", "https://cms.example.com/api/openapi.json",
        "--header", "Authorization=Bearer CMS_TOKEN",
        "--include-tags", "articles,pages,media",
        "--include-operations", "GET,POST,PUT,DELETE"
      ]
    }
  }
}

Enables: Content creation, editing, publishing, media management

๐Ÿ’ฐ Financial Services

{
  "mcpServers": {
    "fintech-api": {
      "command": "npx", 
      "args": [
        "@lucid-spark/openapi-mcp-server",
        "openapi-mcp-server",
        "--api-base-url", "https://api.fintech.com/v2",
        "--openapi-spec", "./fintech-openapi.yaml",
        "--header", "X-API-Key=FINTECH_API_KEY",
        "--header", "Accept=application/json",
        "--include-tags", "accounts,transactions,payments",
        "--include-operations", "GET,POST"
      ]
    }
  }
}

Enables: Account queries, transaction history, payment processing

๐Ÿข CRM Integration

{
  "mcpServers": {
    "crm-api": {
      "command": "npx",
      "args": [
        "@lucid-spark/openapi-mcp-server", 
        "--api-base-url", "https://crm.example.com/api",
        "--openapi-spec", "https://crm.example.com/docs/openapi.json",
        "--header", "Authorization=OAuth OAUTH_TOKEN",
        "--include-tags", "contacts,leads,opportunities,tasks"
      ]
    }
  }
}

Enables: Contact management, lead tracking, opportunity management

๐Ÿ“Š Business Intelligence

{
  "mcpServers": {
    "bi-api": {
      "command": "npx",
      "args": [
        "@lucid-spark/openapi-mcp-server",
        "openapi-mcp-server",
        "--api-base-url", "https://bi.example.com/api/v1",
        "--openapi-spec", "./bi-api-spec.yaml",
        "--header", "Authorization=Bearer BI_TOKEN",
        "--include-tags", "reports,dashboards,metrics",
        "--include-operations", "GET"
      ]
    }
  }
}

Enables: Report generation, dashboard data, KPI monitoring

๐Ÿช E-commerce Platform

{
  "mcpServers": {
    "ecommerce-api": {
      "command": "npx",
      "args": [
        "@lucid-spark/openapi-mcp-server",
        "openapi-mcp-server",
        "--api-base-url", "https://shop.example.com/api",
        "--openapi-spec", "https://shop.example.com/openapi.json",
        "--header", "X-Shop-Token=SHOP_TOKEN",
        "--include-tags", "products,orders,customers,inventory"
      ]
    }
  }
}

Enables: Product management, order processing, customer service

โ˜๏ธ Cloud Infrastructure

{
  "mcpServers": {
    "cloud-api": {
      "command": "npx",
      "args": [
        "@lucid-spark/openapi-mcp-server",
        "openapi-mcp-server",
        "--api-base-url", "https://api.cloudprovider.com/v1",
        "--openapi-spec", "https://api.cloudprovider.com/openapi.json", 
        "--header", "Authorization=Bearer CLOUD_TOKEN",
        "--include-tags", "compute,storage,networking,monitoring"
      ]
    }
  }
}

Enables: Infrastructure management, resource monitoring, cost analysis

Testing & Debugging

๐Ÿงช Testing Your Integration

Connection Testing

// test-connection.ts
import { OpenAPIServer } from "@lucid-spark/openapi-mcp-server";

async function testApiConnection() {
  const server = new OpenAPIServer({
    apiBaseUrl: "https://api.example.com",
    openApiSpec: "./api-spec.yaml",
    headers: {
      "Authorization": `Bearer ${process.env.API_TOKEN}`
    },
    debug: true // Enable debug logging
  });

  try {
    console.log("Testing API connection...");
    const connected = await server.testConnection();
    
    if (connected) {
      console.log("โœ… API connection successful");
      
      // Test server startup
      await server.start();
      console.log("โœ… Server started successfully");
      
      // Get statistics
      const stats = server.getStats();
      console.log(`๐Ÿ“Š Generated ${stats.tools.total} tools`);
      console.log(`๐Ÿ“Š API has ${stats.openapi.paths} paths`);
      
      await server.stop();
      console.log("โœ… Server stopped cleanly");
      
    } else {
      console.error("โŒ API connection failed");
      console.log("Check your API URL and authentication");
    }
    
  } catch (error) {
    console.error("โŒ Error:", error.message);
    
    // Debug information
    if (error.response) {
      console.error(`HTTP ${error.response.status}: ${error.response.statusText}`);
      console.error("Response data:", error.response.data);
    }
  }
}

testApiConnection();

Debug Mode Usage

# Enable debug mode in CLI
npx @lucid-spark/openapi-mcp-server openapi-mcp-server \
  --api-base-url "https://api.example.com" \
  --openapi-spec "./api-spec.yaml" \
  --debug \
  --header "Authorization=Bearer YOUR_TOKEN"

# Debug output will show:
# [DEBUG] Loading OpenAPI spec from: ./api-spec.yaml
# [DEBUG] Found 15 paths with 23 operations
# [DEBUG] Generated 23 endpoint tools + 3 meta tools
# [DEBUG] Starting stdio transport
# [DEBUG] Server ready

Error Handling Patterns

// robust-server.ts
import { OpenAPIServer, isAuthError } from "@lucid-spark/openapi-mcp-server";

class RobustApiServer {
  private server: OpenAPIServer | null = null;
  private retryCount = 0;
  private maxRetries = 3;

  async start() {
    while (this.retryCount < this.maxRetries) {
      try {
        this.server = new OpenAPIServer({
          apiBaseUrl: process.env.API_BASE_URL!,
          openApiSpec: process.env.OPENAPI_SPEC!,
          headers: {
            "Authorization": `Bearer ${process.env.API_TOKEN}`
          },
          debug: process.env.NODE_ENV === "development"
        });

        await this.server.start();
        console.log("๐Ÿš€ Server started successfully");
        this.retryCount = 0; // Reset on success
        return;

      } catch (error) {
        this.retryCount++;
        console.error(`โŒ Attempt ${this.retryCount} failed:`, error.message);

        if (isAuthError(error)) {
          console.error("๐Ÿ”’ Authentication error - check your token");
          break; // Don't retry auth errors
        }

        if (error.message.includes("ENOTFOUND")) {
          console.error("๐ŸŒ Network error - check your connection");
        }

        if (this.retryCount < this.maxRetries) {
          const delay = Math.pow(2, this.retryCount) * 1000; // Exponential backoff
          console.log(`โณ Retrying in ${delay}ms...`);
          await new Promise(resolve => setTimeout(resolve, delay));
        }
      }
    }

    throw new Error("Failed to start server after maximum retries");
  }

  async stop() {
    if (this.server) {
      await this.server.stop();
      this.server = null;
    }
  }

  async healthCheck(): Promise {
    if (!this.server) return false;
    
    try {
      return await this.server.testConnection();
    } catch {
      return false;
    }
  }
}

// Usage
const robustServer = new RobustApiServer();

process.on("SIGINT", async () => {
  console.log("๐Ÿ›‘ Shutting down gracefully...");
  await robustServer.stop();
  process.exit(0);
});

process.on("unhandledRejection", (reason) => {
  console.error("๐Ÿ’ฅ Unhandled rejection:", reason);
  process.exit(1);
});

try {
  await robustServer.start();
} catch (error) {
  console.error("๐Ÿ’€ Failed to start server:", error.message);
  process.exit(1);
}

Best Practices

๐Ÿ” Security

  • Store API tokens in environment variables, never in code
  • Use HTTPS for all API communications
  • Implement token refresh for OAuth2 authentication
  • Validate SSL certificates in production
  • Use least-privilege principles for API access
# Example .env file
API_TOKEN=your_secure_token_here
API_BASE_URL=https://api.example.com
OPENAPI_SPEC_URL=https://api.example.com/openapi.json

โšก Performance

  • Use tool filtering to reduce Claude's tool set
  • Cache OpenAPI specifications when possible
  • Implement request timeouts and retries
  • Use HTTP/2 when available
  • Monitor API rate limits
// Optimized configuration
const config = {
  // ... other config
  includeOperations: ["GET", "POST"], // Limit to needed operations
  includeTags: ["users", "orders"],   // Focus on relevant endpoints
  httpTimeout: 30000,                 // 30-second timeout
  maxRetries: 3                       // Retry failed requests
};

๐Ÿ› ๏ธ Maintainability

  • Use version control for configuration files
  • Document API-specific Claude instructions
  • Test with actual API endpoints before deployment
  • Keep OpenAPI specifications up to date
  • Monitor for breaking API changes
// Version your configurations
const config = {
  name: "my-api-v2",
  version: "2.1.0", 
  // ... rest of config
};

๐Ÿ› Debugging

  • Enable debug mode during development
  • Use structured logging for production
  • Test connection before starting full server
  • Validate configurations programmatically
  • Implement health checks
// Debug helper
if (process.env.NODE_ENV === "development") {
  config.debug = true;
  await server.testConnection();
}