Architecture Guide

Detailed architecture guide including component design, data flow, interface patterns, and extensibility.

Architecture Overview

OpenAPI MCP Server follows a layered, interface-based architecture designed for modularity, type safety, and extensibility. The system is built around clear separation of concerns with well-defined interfaces between components.

Core Design Principles

🏗️ Interface-Based Design

All major components implement well-defined TypeScript interfaces, enabling easy testing, mocking, and extension.

🔧 Modular Architecture

Each component has a single responsibility and can be developed, tested, and maintained independently.

🛡️ Type Safety

Comprehensive TypeScript interfaces ensure compile-time type checking and excellent IDE support.

🔌 Extensibility

Plugin architecture allows for custom authentication providers, transport handlers, and tool filters.

System Layers

🎯 Application Layer

OpenAPIServer
CLI Interface

Orchestrates the entire system, handles MCP protocol, and manages server lifecycle.

🏗️ Core Services Layer

ToolsManager
OpenAPISpecLoader
ApiClient

Core business logic for tool management, OpenAPI processing, and API communication.

🔧 Infrastructure Layer

Transport Handlers
Auth Providers
Configuration System

Infrastructure concerns like networking, authentication, and configuration management.

⚙️ Utilities Layer

Tool ID Generator
Name Generator
Logger

Shared utilities and helper functions used across all layers.

Core Components

🎯 OpenAPIServer

The main orchestrator that coordinates all system components.

class OpenAPIServer {
  private server: Server;              // MCP SDK server
  private specLoader: OpenAPISpecLoader;  // OpenAPI specification handling
  private toolsManager: ToolsManager;     // Tool creation and filtering
  private apiClient: ApiClient;           // HTTP API communication
  private transportHandler: ITransportHandler; // Transport layer

  async start(): Promise;        // Initialize and start server
  async stop(): Promise;         // Graceful shutdown
  getStats(): ServerStats;             // Runtime statistics
}

🔧 OpenAPISpecLoader

Handles loading and parsing OpenAPI specifications from multiple sources.

class OpenAPISpecLoader {
  async loadSpec(source: string, method: SpecInputMethod): Promise;
  getSpec(): OpenAPISpec;              // Parsed specification
  getOperations(): IOperation[];       // All API operations
  getTags(): string[];                 // OpenAPI tags
}

Input Methods:

  • URL: Load from remote HTTP/HTTPS URLs
  • File: Load from local filesystem
  • Stdin: Read from standard input stream
  • Inline: Parse from string content

🛠️ ToolsManager

Creates, filters, and manages MCP tools from OpenAPI operations.

class ToolsManager {
  async loadTools(filter: IToolsFilter): Promise;
  getTools(): ITool[];                 // All loaded tools
  getToolByName(name: string): ITool | undefined;
  listOperations(filter?: any): IOperationSummary[];
  getStats(): ToolStats;               // Tool statistics
}

Tool Modes:

  • All: Load all endpoint tools + meta-tools
  • Dynamic: Load only meta-tools for API exploration
  • Explicit: Load only specified tools

🔗 ApiClient

Executes authenticated HTTP requests to target APIs.

class ApiClient {
  constructor(
    baseUrl: string,
    authProvider?: IAuthProvider,
    headers?: Record
  );
  
  async executeApiCall(params: IApiCallParams): Promise;
  async testConnection(): Promise;
}

Features:

  • Authentication Integration: Static headers or dynamic providers
  • Retry Logic: Automatic retry on authentication errors
  • Parameter Mapping: Maps MCP parameters to HTTP requests
  • Error Handling: Comprehensive error processing

Data Flow

🚀 Startup Flow

1

Configuration Validation

Validate and normalize server configuration

2

Component Initialization

Create and configure core components

3

OpenAPI Loading

Load and parse OpenAPI specification

4

Tool Generation

Create MCP tools from OpenAPI operations

5

Transport Setup

Initialize and start transport layer

🔧 Tool Execution Flow

1

MCP Request

Client sends tools/call request

2

Tool Resolution

Find tool by name and validate parameters

3

Authentication

Get fresh auth headers from provider

4

API Call

Execute HTTP request to target API

5

Response Processing

Format response for MCP client

Interface System

The OpenAPI MCP Server uses comprehensive TypeScript interfaces to ensure type safety and enable extensibility.

🔐 Authentication Interfaces

interface IAuthProvider {
  getAuthHeaders(): Promise>;
  handleAuthError(error: AxiosError): Promise;
}

Enables custom authentication strategies with token refresh and error recovery.

🌐 Transport Interfaces

interface ITransportHandler {
  start(): Promise;
  stop(): Promise;
  getType(): string;
  getStatus(): { type: string; active: boolean };
}

Allows for different transport implementations (stdio, HTTP, WebSocket, etc.).

🛠️ Tool Interfaces

interface ITool extends Tool {
  tags?: string[];           // OpenAPI tags
  method?: string;           // HTTP method
  resourceName?: string;     // Resource identifier
  originalPath?: string;     // OpenAPI path
  toolId?: string;          // Unique tool identifier
}

Extends MCP Tool interface with OpenAPI-specific metadata for filtering and management.

Extensibility Points

🔐 Custom Authentication

Implement the IAuthProvider interface to support any authentication scheme:

class OAuth2Provider implements IAuthProvider {
  async getAuthHeaders() {
    if (this.isTokenExpired()) {
      await this.refreshToken();
    }
    return { Authorization: `Bearer ${this.accessToken}` };
  }

  async handleAuthError(error) {
    if (error.response?.status === 401) {
      await this.refreshToken();
      return true; // Retry request
    }
    return false;
  }
}

🌐 Custom Transports

Extend BaseTransportHandler to support new transport methods:

class WebSocketTransportHandler extends BaseTransportHandler {
  async start() {
    this.wsServer = new WebSocketServer({ port: this.port });
    // WebSocket-specific initialization
  }

  getType(): string {
    return 'websocket';
  }
}

🔧 Custom Tool Filters

Extend tool filtering logic for specialized use cases:

interface IToolsFilter {
  mode: ToolsMode;
  includeTools?: string[];
  includeTags?: string[];
  includeResources?: string[];
  includeOperations?: string[];
  customFilter?: (tool: ITool) => boolean;  // Extension point
}

Performance Considerations

💾 Memory Management

  • Lazy Loading: Tools are generated on-demand during startup
  • Caching: OpenAPI specs and tool metadata are cached in memory
  • Filtering: Early filtering reduces memory footprint for large APIs

⚡ Request Processing

  • Connection Pooling: HTTP client reuses connections
  • Authentication Caching: Auth headers are cached between requests
  • Async Processing: All operations are non-blocking

📊 Scalability

  • Stateless Design: Server can be horizontally scaled
  • HTTP Transport: Supports load balancing and clustering
  • Resource Limits: Configurable limits prevent resource exhaustion

Security Architecture

🔒 Authentication Security

  • No Credential Storage: Credentials are provided at runtime
  • Dynamic Refresh: Tokens can be refreshed automatically
  • Error Isolation: Auth errors don't expose sensitive information

🛡️ Runtime Security

  • Input Validation: All parameters are validated against OpenAPI schemas
  • Request Sanitization: HTTP requests are constructed safely
  • Error Handling: Sensitive information is not leaked in error messages

🌐 Transport Security

  • HTTPS Support: All HTTP communications can use TLS
  • CORS Configuration: Configurable cross-origin policies
  • Rate Limiting: Built-in protection against abuse