feat(mcp): add toolCallTimeoutMs, timeout/reconnect/error handling

- Add toolCallTimeoutMs to stdio MCP config with 60s default
- tools/call runs under timeout with dedicated Timeout error
- Handle malformed JSON/broken protocol as InvalidResponse
- Reset/reconnect stdio state on child exit or transport drop
- Add tests: slow timeout, invalid JSON response, stdio reconnect
- Verified: cargo test -p runtime 113 passed, clippy clean
This commit is contained in:
YeonGyu-Kim
2026-04-02 18:24:30 +09:00
parent 6e4b0123a6
commit 3b18ce9f3f
4 changed files with 866 additions and 135 deletions

View File

@@ -84,10 +84,13 @@ pub fn mcp_server_signature(config: &McpServerConfig) -> Option<String> {
pub fn scoped_mcp_config_hash(config: &ScopedMcpServerConfig) -> String {
let rendered = match &config.config {
McpServerConfig::Stdio(stdio) => format!(
"stdio|{}|{}|{}",
"stdio|{}|{}|{}|{}",
stdio.command,
render_command_signature(&stdio.args),
render_env_signature(&stdio.env)
render_env_signature(&stdio.env),
stdio
.tool_call_timeout_ms
.map_or_else(String::new, |timeout_ms| timeout_ms.to_string())
),
McpServerConfig::Sse(remote) => format!(
"sse|{}|{}|{}|{}",
@@ -245,6 +248,7 @@ mod tests {
command: "uvx".to_string(),
args: vec!["mcp-server".to_string()],
env: BTreeMap::from([("TOKEN".to_string(), "secret".to_string())]),
tool_call_timeout_ms: None,
});
assert_eq!(
mcp_server_signature(&stdio),