Skip to content

[Audit] MEDIUM: No timeout on MCP tool calls #5

@NickCalabs

Description

@NickCalabs

Severity: MEDIUM

Description

The callTool function in src/tools/registry.ts:115-128 calls MCP tools without any timeout, allowing hung or slow tools to block agent execution indefinitely.

Location

File: src/tools/registry.ts
Line: 127

Problematic Code

return server.client!.callTool(originalName, args);

No timeout is set on the MCP client tool call operation.

Issues

  1. Infinite Hangs: A buggy MCP server can hang forever
  2. Resource Exhaustion: Agent threads blocked waiting for tools
  3. Cascading Failures: One slow tool blocks entire agent run
  4. Poor UX: Users see agents "running" but they're just waiting

Impact

  • Agent runs never complete
  • Database grows with stuck "running" entries
  • Server becomes unresponsive over time
  • No way to recover without restart

Recommendation

Add timeout to tool calls:

export async function callTool(
  toolName: string,
  args?: Record<string, unknown>,
  timeoutMs: number = 60_000, // 60 second default
): Promise<unknown> {
  const { server, originalName } = getServerForTool(toolName);

  // Local handler (no MCP subprocess)
  if (server.localHandlers) {
    const handler = server.localHandlers.get(originalName);
    if (handler) {
      // Wrap in timeout
      return Promise.race([
        handler(args ?? {}),
        new Promise((_, reject) => 
          setTimeout(() => reject(new Error(`Tool call timed out after ${timeoutMs}ms`)), timeoutMs)
        ),
      ]);
    }
  }

  // MCP client call with timeout
  return Promise.race([
    server.client!.callTool(originalName, args),
    new Promise((_, reject) => 
      setTimeout(() => reject(new Error(`MCP tool call timed out after ${timeoutMs}ms`)), timeoutMs)
    ),
  ]);
}

Also consider:

  1. Making timeout configurable per-tool or per-agent
  2. Logging slow tool calls (e.g., >5s) as warnings
  3. Adding metrics for tool call durations

Related Code

  • runner.ts doesn't have explicit timeout handling for tool calls either
  • Only ollama.ts:7 sets OLLAMA_TIMEOUT_MS = 10 * 60 * 1000 for LLM calls

Created by security audit

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions