Podcast Title

Author Name

0:00
0:00
Album Art

The MCP Hub Explained in 5 Minutes: Singleton Pattern & Initialization

By 10xdev team August 16, 2025

In a previous article, we reviewed the Model Context Protocol (MCP), its benefits for GenAI applications, and the reasoning behind building an MCP client. In this article, we will begin a deep dive into the MCPHub class implementation, focusing on the design pattern and the initialize function.

Why an 'MCP Hub'?

When structuring the client, file naming conventions are important for clarity. While names like index.ts are common, MCPHub.ts is more descriptive and accurate. It effectively communicates the file's purpose.

The MCPHub.ts file can be broken down into three distinct parts:

  1. Interfaces: Defined at the top of the file to enable strong typing and validation.
  2. Main MCPHub Class: The core logic for managing connections.
  3. Singleton Export: A single, exported instance of the class.

This structure is why we refer to it as a "Hub." All MCP server connections are managed from this single instance, and the application communicates with MCP servers exclusively through it. This centralizes all MCP-related configuration and state. Using the USB analogy, if MCP servers are USB sticks, the MCPHub is the port on our computer that manages them all.

Dissecting the MCP Hub Class

The class contains several methods that can be grouped into various logical sections.

Available Methods

  • Constructor & Singleton:
    • constructor()
    • getInstance()
  • Initialization:
    • initialize()
  • Server Connection Management:
    • connectServer()
    • disconnectServer()
    • reconnectServer()
  • Tool and Resource Operations:
    • callTool()
    • listTools()
    • listResources()
  • Connection Status & Info:
    • listConnections()
    • getConnection()
  • Event Handling:
    • onStatusChange()
    • broadcastStatusChange()

Let's examine the top of the class and the initialize method.

export class MCPHub {
    private connections: Map<string, MCPConnection> = new Map();
    private statusListeners: StatusListener[] = [];
    private isInitialized: boolean = false;
    private config: MCPConfig | null = null;
    private static instance: MCPHub;

    // ... methods
}

The class declares a few private properties: - connections: A Map where the key is the server name and the value is an MCPConnection object holding the state for that connection (e.g., connected, connecting, disconnected). - statusListeners: An array to manage listeners for connection state changes. - isInitialized: A boolean flag to track the initialization status. - config: An object holding the MCP configuration, typed as MCPConfig. - instance: The static property for the Singleton pattern.

The Singleton Design Pattern

The MCPHub is implemented as a Singleton to ensure only one instance exists throughout the application. This is enforced by a private constructor.

private constructor() {
    // Private constructor to prevent direct instantiation
}

Attempting to create a new instance directly will result in an error, ensuring the single-instance principle is maintained.

// This will cause a compile-time error
const hub = new MCPHub(); 

Instead, the class provides a static getInstance method. This method creates the instance if it doesn't exist or returns the existing one.

public static getInstance(): MCPHub {
    if (!MCPHub.instance) {
        MCPHub.instance = new MCPHub();
    }
    return MCPHub.instance;
}

This instance is then created and exported at the bottom of the file for use throughout the application.

The Initialization Process

The initialize method is an asynchronous function that returns a Promise<void>. Its primary job is to connect all the servers defined in the configuration.

public async initialize(config?: MCPConfig): Promise<void> {
    // ...
    const mcpConfig = await this.loadMCPConfig();
    // ...
}

The process begins by calling loadMCPConfig(). If no servers are configured, it sets isInitialized to true and logs a warning.

Loading the Configuration

The loadMCPConfig function is responsible for reading the configuration from the file system. A typical configuration file, let's call it mcp-config.js, follows a specific format.

Here is an example of what the configuration structure looks like:

// mcp-config.js
export const mcpConfig = {
  "mcp_servers": {
    "server-one": {
      "command": "npx",
      "args": [
        "some-mcp-server-package",
        "-y" 
      ],
      "name": "Server One Name"
    },
    "server-two": {
      "command": "python",
      "args": [
        "path/to/server.py"
      ],
      "name": "Server Two Name"
    }
  }
};

The loadMCPConfig function attempts to: 1. Read from File: It reads the config file from a predefined path. 2. Parse and Validate: If successful, it parses the content. Since the file is already a JavaScript object, it validates it against a predefined schema (MCPFileConfigSchema) to ensure it conforms to the expected structure. These schemas are defined in a separate schemas.ts file to keep all core MCP schemas in one place. 3. Fetch from Database: If the file is missing, inaccessible, or fails validation, the function can be extended to fetch the configuration from a database as a fallback. 4. Return Configuration: Finally, the function returns the validated configuration from the cache, file, or database.

The servers included in the example configuration are chosen specifically because they don't require an API key, allowing them to work out of the box without needing personal access tokens. You can find more public servers in the official Model Context Protocol repositories.

This covers the initial setup and initialization logic of the MCPHub. In the next article, we will explore the functions for managing server connections: connectServer, disconnectServer, and reconnectServer.

Join the 10xdev Community

Subscribe and get 8+ free PDFs that contain detailed roadmaps with recommended learning periods for each programming language or field, along with links to free resources such as books, YouTube tutorials, and courses with certificates.

Recommended For You

Up Next