Correctness: MCP RPC calls use blocking I/O in async context #79

Open
opened 2026-05-11 13:48:50 +00:00 by thabeta · 0 comments
Owner

Severity: Critical

Location

crates/hero_aibroker_lib/src/mcp.rscall_method()

Finding

The MCP JSON-RPC client uses synchronous std::io writes in an async context:

async fn call_method(&self, method: &str, params: Option<Value>) -> Result<Value, McpError> {
    // ...
    let request_str = serde_json::to_string(&request)?;
    let mut stdout = self.stdout.lock().unwrap();
    write!(stdout, "Content-Length: {}\r\n\r\n{}", len, request_str)?;  // BLOCKING
    stdout.flush()?;  // BLOCKING
    // ...
    let mut reader = BufReader::new(self.stdout.lock().unwrap());  // BLOCKING read
    // ...
}```

## Impact
- Blocks the tokio runtime thread during I/O
- Concurrent MCP calls serialize on the Mutex
- Under load, this can starve the async executor

## Recommendation
- Use `tokio::sync::Mutex` instead of `std::sync::Mutex`
- Use `tokio::io` async read/write
- Or offload blocking I/O to `tokio::task::spawn_blocking()`
## Severity: Critical ## Location `crates/hero_aibroker_lib/src/mcp.rs` — `call_method()` ## Finding The MCP JSON-RPC client uses synchronous `std::io` writes in an `async` context: ```rust async fn call_method(&self, method: &str, params: Option<Value>) -> Result<Value, McpError> { // ... let request_str = serde_json::to_string(&request)?; let mut stdout = self.stdout.lock().unwrap(); write!(stdout, "Content-Length: {}\r\n\r\n{}", len, request_str)?; // BLOCKING stdout.flush()?; // BLOCKING // ... let mut reader = BufReader::new(self.stdout.lock().unwrap()); // BLOCKING read // ... }``` ## Impact - Blocks the tokio runtime thread during I/O - Concurrent MCP calls serialize on the Mutex - Under load, this can starve the async executor ## Recommendation - Use `tokio::sync::Mutex` instead of `std::sync::Mutex` - Use `tokio::io` async read/write - Or offload blocking I/O to `tokio::task::spawn_blocking()`
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_aibroker#79
No description provided.