# How ChatMCP Integrates with MCP Servers: Transport Protocols Explained

> Discover how ChatMCP integrates with MCP servers using StdIO, SSE, Streamable HTTP, and InMemory transport protocols for local and remote communication. Learn more now.

- Repository: [刀刀/chatmcp](https://github.com/daodao97/chatmcp)
- Tags: deep-dive
- Published: 2026-02-28

---

**ChatMCP integrates with MCP servers through a flexible plugin architecture that supports four distinct transport protocols—StdIO, SSE, Streamable HTTP, and InMemory—enabling both local process communication and remote HTTP-based interactions via the Model Context Protocol (MCP).**

ChatMCP, developed by daodao97/chatmcp, treats MCP servers as dynamic plugins that extend functionality through the Model Context Protocol (MCP) JSON-RPC API. The application manages server configurations via [`mcp_server.json`](https://github.com/daodao97/chatmcp/blob/main/mcp_server.json) and automatically selects appropriate transport protocols based on server type definitions, implementing a modular communication layer defined in `lib/mcp/mcp.dart`.

## Understanding ChatMCP MCP Server Architecture

### Server Configuration and Provider Model

Each MCP server is defined in [`assets/mcp_server.json`](https://github.com/daodao97/chatmcp/blob/main/assets/mcp_server.json) (managed by **McpServerProvider** in `lib/provider/mcp_server_provider.dart`). The JSON structure specifies:

```json
{
  "name": "My Server",
  "type": "sse",
  "command": "https://example.com/mcp",
  "args": [],
  "env": {},
  "tools": []
}

```

The `type` field determines which transport protocol ChatMCP uses to establish communication. Valid values are `stdio`, `sse`, `streamable`, and `inmemory`.

### The Initialization Entry Point

When users select a server, ChatMCP invokes **`initializeMcpServer`** from `lib/mcp/mcp.dart` (lines 11-75). This function:

1. Parses the configuration into a **ServerConfig** model (`lib/mcp/models/server.dart`)
2. Instantiates the appropriate **McpClient** implementation based on the `type` value
3. Establishes the transport connection and performs the MCP handshake

## Supported Transport Protocols in ChatMCP

ChatMCP implements four transport protocols through dedicated client classes, each optimized for specific deployment scenarios.

### StdIO Transport for Local Processes

The **StdIO** protocol (`type: "stdio"`) uses the **StdioClient** class (`lib/mcp/stdio/stdio_client.dart`). This transport spawns a local process using the `command` field as an executable path and communicates via standard input/output streams. This approach is ideal for local Python or Node.js MCP servers launched via package managers like `uvx` or `npx`.

### SSE Transport for HTTP Streaming

The **SSE** protocol (`type: "sse"`) utilizes **SSEClient** (`lib/mcp/sse/sse_client.dart`). This implementation:

- Opens an HTTP **Server-Sent Events** connection to the URL specified in `command`
- Listens for an `endpoint` event from the server to determine the POST target
- Transmits JSON-RPC requests to the revealed endpoint
- Implements exponential back-off reconnection (max 5 attempts) via `SSEClient._connect` (lines 85-118) and `SSEClient._scheduleReconnection`

### Streamable HTTP with Asynchronous Support

The **Streamable** protocol (`type: "streamable"`) employs **StreamableClient** (`lib/mcp/streamable/streamable_client.dart`). This hybrid approach:

- Sends JSON-RPC requests via standard HTTP POST
- Handles **202 Accepted** responses by initiating SSE streams for asynchronous server messages
- Supports token-based resumption through `StreamableClient._scheduleReconnection`

### InMemory Transport for Embedded Tools

The **InMemory** protocol (`type: "inmemory"`) uses **InMemoryClient** (`lib/mcp/inmemory/client.dart`). This transport loads embedded mock servers entirely within the Dart application, requiring no network connectivity or external processes. This mode powers built-in tools like mathematical functions or testing scenarios.

## The McpClient Interface and Communication Flow

All transport implementations share a common contract defined in `lib/mcp/client/mcp_client_interface.dart`:

```dart
Future<void> initialize();
Future<JSONRPCMessage> sendInitialize();
Future<JSONRPCMessage> sendToolList();
Future<JSONRPCMessage> sendToolCall(...);
Future<JSONRPCMessage> sendMessage(...);
Future<void> dispose();

```

### Standard MCP Workflow

Every connection follows this sequence:

1. **Transport Initialization** — `initialize()` establishes the physical connection (process spawn, HTTP connection, or memory instantiation)
2. **MCP Handshake** — `sendInitialize()` performs protocol negotiation
3. **Tool Discovery** — `sendToolList()` retrieves available callable tools from the server
4. **Execution** — `sendToolCall()` dispatches JSON-RPC requests; responses return through the same client instance
5. **Cleanup** — `dispose()` releases resources and terminates connections

## Configuring and Connecting to MCP Servers

### JSON Configuration Example

Define your MCP server in [`assets/mcp_server.json`](https://github.com/daodao97/chatmcp/blob/main/assets/mcp_server.json):

```json
{
  "my-sse-server": {
    "name": "My SSE Server",
    "type": "sse",
    "command": "https://api.example.com/mcp",
    "args": [],
    "env": {},
    "tools": []
  }
}

```

### Programmatic Server Initialization

Connect to a configured server in Dart:

```dart
final config = await provider.getServerConfig('my-sse-server');
final client = await initializeMcpServer(config);
await client.initialize();
await client.sendInitialize();
final toolList = await client.sendToolList();

```

### Executing Tools

Call remote tools using the unified interface:

```dart
final response = await client.sendToolCall(
  name: 'search',
  arguments: {'query': 'flutter documentation'},
);
print(response.result);

```

This method works identically across **StdIO**, **SSE**, and **Streamable** transports.

### Handling Asynchronous Messages

Monitor connection state for SSE and Streamable protocols:

```dart
client.processStateStream.listen((state) {
  if (state.type == ProcessStateType.running) {
    // Connection ready for message exchange
  }
});

```

## Summary

- ChatMCP treats MCP servers as plugins configured via [`mcp_server.json`](https://github.com/daodao97/chatmcp/blob/main/mcp_server.json) and managed by **McpServerProvider**.
- Four transport protocols are supported: **StdIO** (local processes), **SSE** (HTTP streaming), **Streamable** (HTTP POST with optional SSE), and **InMemory** (embedded).
- The **`initializeMcpServer`** function in `lib/mcp/mcp.dart` routes to appropriate **McpClient** implementations based on the `type` field.
- All transports share the **McpClient** interface, providing consistent methods for initialization, tool discovery, and execution.
- SSE and Streamable clients implement automatic reconnection with exponential back-off for resilient remote connections.

## Frequently Asked Questions

### What transport protocol should I use for a local Python MCP server?

Use **StdIO** transport. Set `"type": "stdio"` in your configuration and specify the Python executable or `uvx` command in the `command` field. The **StdioClient** spawns the process and communicates directly through stdin/stdout streams, making it ideal for local development environments.

### How does ChatMCP handle reconnection when an SSE server drops?

The **SSEClient** implementation in `lib/mcp/sse/sse_client.dart` includes `SSEClient._scheduleReconnection`, which implements exponential back-off retry logic with a maximum of 5 attempts. The client automatically re-establishes the HTTP connection and resynchronizes the JSON-RPC endpoint when network connectivity returns.

### Can ChatMCP connect to MCP servers without network access?

Yes. Use **InMemory** transport by setting `"type": "inmemory"`. The **InMemoryClient** loads the server logic directly within the Dart application, requiring no external network connection or separate process. This is ideal for built-in utilities like mathematical calculation tools or offline testing scenarios.

### What authentication mechanisms does ChatMCP support for MCP connections?

ChatMCP automatically adds **OAuth Bearer** tokens and custom headers when OAuth configuration is present in the server definition. The `ServerConfig` model includes an `oauth` field that, when populated, injects authentication headers into all HTTP-based transports (SSE and Streamable) before establishing connections.