I am not a native English speaker; this article was translated by AI.
With the Model Context Protocol (MCP) becoming widely adopted, attaching multiple local or remote MCP servers to an agent runtime is standard practice.
In real workloads, however, running multiple MCP servers quickly exposes a fragility issue:
You have five MCP servers in your configuration. Four core local tools for filesystem and terminal work are healthy, but an optional third-party translation or web search server times out or fails due to a local dependency mismatch.
The entire agent runtime panics during initialization. You cannot even ask basic questions or edit local files.
A non-essential auxiliary plugin crash shouldn’t take down the entire core session.
To resolve this, we introduced concurrent startup isolation and graceful degradation for MCP services.
flowchart TD
subgraph Config[MCP Service Criticality]
C1[Critical: Local Filesystem & Terminal]
C2[Optional: Remote Knowledge & Search]
end
subgraph Startup[Concurrent Isolation Sandbox]
C1 --> T1[Tokio Task 1: Critical Service, Strict Validation]
C2 --> T2[Tokio Task 2: Isolated 3s Timeout]
C2 --> T3[Tokio Task 3: Isolated 3s Timeout]
end
subgraph Outcome[Aggregation & Dynamic Degradation]
T1 -->|Success| R[Dynamic Tool Registry]
T2 -->|Timeout / Error| D[Log Diagnostic Warning, Don't Block]
T3 -->|Success| R
D -.->|Filter Unavailable Tools| R
R --> S[Session Launches Cleanly / UI Notice: Degraded Mode]
end
Config --> Startup
1. What Was Wrong With the Legacy Flow? #
Many MCP clients initialize servers via a simple sequential loop:
// Fragile serial loop
for server_config in mcp_servers {
// If any connect or list_tools call fails, the entire setup returns Err
let client = McpClient::connect(&server_config).await?;
let tools = client.list_tools().await?;
registered_tools.extend(tools);
}The flaws are obvious:
- Cumulative startup latency: Total startup time is the sum of every server’s handshake. A single slow server stalling for 5 seconds delays the whole agent by 5 seconds.
- Missing fault isolation: Core filesystem tools and auxiliary search tools share the same lifecycle. An external timeout escalates into a fatal crash.
2. The Solution #
The revised flow focuses on three changes:
1. Explicitly Distinguish Critical from Optional Services #
We added a criticality flag to the configuration schema:
{
"mcpServers": {
"filesystem": {
"command": "agent-mcp-fs",
"required": true
},
"web_search": {
"command": "uvx",
"args": ["mcp-server-duckduckgo"],
"required": false,
"timeout_ms": 3000
}
}
}required: true(Critical): Tools the agent cannot function without. Failures will cleanly abort with a clear error.required: false(Optional, Default): Auxiliary enhancements. Failures trigger circuit-breaking without affecting the main session.
2. Concurrent Probing with Isolated Timeouts #
Using Tokio, each MCP server is probed in a dedicated asynchronous task (tokio::spawn) wrapped in a tokio::time::timeout:
- All servers handshake concurrently. Cold startup latency is bounded by the slowest individual server rather than their cumulative sum.
- If an optional server fails to connect within 3 seconds or crashes, the error is caught and marked as
Degradedrather than bubbling up.
3. Dynamic Tool Filtering and UI Awareness #
Once all probing tasks settle:
- Successfully initialized tools are registered into the session context.
- Tools from degraded servers are filtered out, preventing the model from hallucinating broken calls.
- A lightweight notification informs the frontend which optional plugin failed, while keeping the main chat fully operational.
3. Takeaway #
With startup isolation in place, even if network access is spotty or an MCP plugin config is broken, the agent’s core capabilities launch in sub-seconds.
Plugin systems that depend on external environments must design for failure. An issue in an optional feature should never break core tool availability.