# MCP Server Reconnection and Timeout Handling in 5ire: Implementation Guide

> Understand 5ire MCP server reconnection and timeout logic. Discover how the codebase ensures resilience with tiered retry strategies and automatic reconnections for seamless operation.

- Repository: [Ironben/5ire](https://github.com/nanbingxyz/5ire)
- Tags: how-to-guide
- Published: 2026-03-07

---

**The 5ire codebase implements a two-layer resilience strategy for MCP (Model Context Protocol) servers: the connection-establishment layer retries failed connections up to 3 times with exponential backoff, while the call-execution layer enforces per-request timeouts and performs a single automatic reconnection before retrying failed RPCs.**

The 5ire repository provides a robust TypeScript implementation for managing MCP server connections in desktop AI applications. Understanding how MCP servers handling reconnection attempts and timeouts is critical for building resilient integrations that survive transient network failures and server restarts without blocking the user interface.

## Connection Establishment with Retry Logic

The foundation of resilience lies in [`src/main/services/mcp-connections-manager.ts`](https://github.com/nanbingxyz/5ire/blob/main/src/main/services/mcp-connections-manager.ts), specifically within the private `#connect` method. This layer manages the lifecycle of TCP and stdio transports while implementing defensive retry patterns against transient startup failures.

### The `#connect` Method Implementation

When activating a new MCP server, the manager first checks existing connection states to prevent duplicate attempts. If no active connection exists, it enters a retry loop designed to handle transient startup failures.

The implementation uses a `for` loop running **up to 3 retries** (`for (let retries = 0; retries < 3; retries++)`). Between attempts, it applies an exponential back‑off strategy by waiting `1000 × retries` milliseconds, creating delays of 0ms, 1s, and 2s respectively.

```typescript
// Simplified logic from src/main/services/mcp-connections-manager.ts
for (let retries = 0; retries < 3; retries++) {
  await new Promise(r => setTimeout(r, 1000 * retries));
  
  try {
    const client = new Client(CLIENT_IMPLEMENTATION, { capabilities: CLIENT_CAPABILITIES });
    const capabilities = await client.connect(this.#transport(server), {});
    // Success: store connection, emit event, break loop
    return;
  } catch (e) {
    connectError = e; // Continue to next retry
  }
}
// After loop: mark connection as error

```

Upon successful connection, the client is stored in the manager’s internal `connections` map with status **`connected`**, and capabilities are negotiated. If all retries exhaust, the status transitions to **`error`** alongside the captured exception message.

## Request Execution with Timeout Protection

Once established, individual RPC calls are protected by [`src/main/mcp.ts`](https://github.com/nanbingxyz/5ire/blob/main/src/main/mcp.ts), which implements timeout enforcement and graceful degradation through the `safeCall` helper and `reconnect` methods.

### The `safeCall` Helper

The `safeCall(clientKey, fn, timeoutMs?)` method wraps every MCP operation, such as `listTools` or `listPrompts`. It first validates the client's existence, then executes the provided function `fn`.

If a `timeoutMs` parameter is provided, `safeCall` races the actual request against a `setTimeout` that rejects with an `invalid_connection` error after the specified duration. This prevents hung servers from freezing the UI indefinitely.

```typescript
// Logic from src/main/mcp.ts
private async safeCall(clientKey: string, fn: () => Promise<any>, timeoutMs?: number) {
  if (!this.clients[clientKey]) throw new Error(`Client ${clientKey} not found`);

  try {
    if (!timeoutMs) return await fn();

    const res = await Promise.race([
      fn(),
      new Promise((_r, reject) =>
        setTimeout(() => reject(new Error("invalid_connection")), timeoutMs)
      ),
    ]);
    return res;
  } catch {
    await this.reconnect(clientKey);
    return fn(); // Second attempt after reconnect
  }
}

```

When any error occurs—including timeouts—`safeCall` invokes `await this.reconnect(clientKey)` to refresh the connection before attempting the operation **one additional time**.

### The `reconnect` Method

The private `reconnect` method in [`src/main/mcp.ts`](https://github.com/nanbingxyz/5ire/blob/main/src/main/mcp.ts) performs surgical connection recovery. It closes the existing client instance, re‑activates the server configuration, and throws any activation errors immediately. This ensures that stale transport handles are discarded before the retry attempt.

## Practical Implementation Examples

### Adding a Server with Automatic Retry

When registering a new MCP server through the store, the connection manager automatically applies the retry logic:

```typescript
import useMCPStore from '@/stores/useMCPStore';

await useMCPStore.getState().addServer({
  id: "my-server",
  transport: "http",
  endpoint: "https://example.com/mcp",
  config: {},
  active: true,
});
// MCPConnectionsManager.#connect retries up to 3 times if unreachable

```

### Executing Calls with Timeout Protection

Standard operations use `safeCall` internally to guarantee responsiveness:

```typescript
import MCP from '@/services/mcp';

const mcp = new MCP();

// Uses LIST_TOOLS_TIMEOUT (≈ 5s) internally via safeCall
const { tools, error } = await mcp.listTools();

if (error) {
  console.error('Failed to fetch tools:', error);
}

```

### Manual Reconnection

For advanced scenarios, explicit reconnection is available:

```typescript
await mcp.reconnect('my-server-key');
// Closes old client and re-activates configuration

```

## Summary

- **Three-attempt retry logic** in [`src/main/services/mcp-connections-manager.ts`](https://github.com/nanbingxyz/5ire/blob/main/src/main/services/mcp-connections-manager.ts) handles initial connection failures with exponential backoff (0ms → 1s → 2s).
- **Connection state tracking** uses explicit statuses (`connected`, `connecting`, `error`) to prevent duplicate connection attempts.
- **Per-call timeouts** via `safeCall` in [`src/main/mcp.ts`](https://github.com/nanbingxyz/5ire/blob/main/src/main/mcp.ts) use `Promise.race` to bound RPC duration and prevent UI blocking.
- **Single automatic reconnection** occurs when requests fail, closing stale clients and re-activating configurations before one final retry.
- **Structured error handling** returns specific error codes like `invalid_connection` and `invalid_response` for programmatic error handling.

## Frequently Asked Questions

### How many times does 5ire retry a failed MCP connection?

The `MCPConnectionsManager` attempts to establish a connection **up to 3 times** before marking the server as errored. This logic resides in the `#connect` method within [`src/main/services/mcp-connections-manager.ts`](https://github.com/nanbingxyz/5ire/blob/main/src/main/services/mcp-connections-manager.ts), with exponential backoff delays between attempts.

### What timeout values does 5ire use for MCP requests?

5ire defines specific timeout constants for different operations, including `CONNECT_TIMEOUT`, `LIST_TOOLS_TIMEOUT`, and `RETRIEVE_PROMPTS_TIMEOUT`. These values are passed to the `safeCall` method in [`src/main/mcp.ts`](https://github.com/nanbingxyz/5ire/blob/main/src/main/mcp.ts), which races the request against a timer that rejects with an `invalid_connection` error upon expiry.

### Does 5ire reconnect automatically when an MCP call fails?

Yes. The `safeCall` implementation automatically invokes `this.reconnect(clientKey)` when any RPC throws an error or times out. After reconnecting, it executes the original function **once more**. If this second attempt fails, the error propagates to the caller.

### Where is the MCP connection state managed in the codebase?

Connection states (`connected`, `connecting`, `error`) are managed in the `MCPConnectionsManager` class at [`src/main/services/mcp-connections-manager.ts`](https://github.com/nanbingxyz/5ire/blob/main/src/main/services/mcp-connections-manager.ts). The high-level RPC wrappers and reconnection logic reside in [`src/main/mcp.ts`](https://github.com/nanbingxyz/5ire/blob/main/src/main/mcp.ts), while type definitions are located in [`src/types/mcp.d.ts`](https://github.com/nanbingxyz/5ire/blob/main/src/types/mcp.d.ts).