Skip to content

Tool execution hard-limited to 120s due to AI SDK streamText default stepMs timeout #25509

Closed

Description

@tanbro

Summary

All tool executions (bash, MCP, built-in tools) are hard-limited to 120 seconds, regardless of any timeout configuration. This is caused by the Vercel AI SDK's streamText() default timeout.stepMs value of 120000 (120s), which wraps the entire step including tool execution.

Root Cause

In packages/opencode/src/session/llm.ts, the streamText() call does not pass a timeout parameter:

return streamText({
  // ... other params
  // ⚠️ no `timeout` parameter
})

The AI SDK defaults timeout.stepMs to 120000ms, which means any tool execution exceeding 120 seconds will be killed with:

The operation timed out.

Why experimental.mcp_timeout doesn't help

OpenCode exposes experimental.mcp_timeout in config and passes it to the MCP SDK's callTool():

// packages/opencode/src/mcp/index.ts — convertMcpTool()
client.callTool(
  { name: mcpTool.name, arguments: args },
  CallToolResultSchema,
  {
    resetTimeoutOnProgress: true,
    timeout,  // ← from experimental.mcp_timeout
  },
)

However, this timeout is set on the inner MCP SDK layer. The outer AI SDK streamText timeout (stepMs: 120000) triggers first, making experimental.mcp_timeout completely ineffective for values > 120s.

Call chain

streamText(timeout defaults to { stepMs: 120000 })
  └─ tool execution (bash, MCP, all tools)
       └─ convertMcpTool() → callTool(timeout: experimental.mcp_timeout)
            └─ MCP SDK setTimeout (never reached if stepMs fires first)

Steps to Reproduce

  1. Configure experimental.mcp_timeout: 3600000 in opencode.jsonc
  2. Have an MCP server with a tool that takes >120 seconds (e.g., PDF ingestion with OCR)
  3. Run opencode and invoke the long-running MCP tool
  4. After 120 seconds, the tool is killed with The operation timed out.

Alternatively, with a simple bash test:

opencode run -m <model> "execute a python script that sleeps for 200 seconds"

After 120 seconds: bash tool terminated command after exceeding timeout 120000 ms

Expected Behavior

  • experimental.mcp_timeout (or a new config option) should control the effective tool execution timeout
  • Long-running MCP tools (PDF parsing, OCR, etc.) should be able to run beyond 120 seconds

Suggested Fix

In packages/opencode/src/session/llm.ts, pass the timeout to streamText():

const toolTimeout = cfg.experimental?.mcp_timeout ?? 120_000

return streamText({
  // ... existing params
  timeout: { stepMs: toolTimeout },
})

Environment

  • OpenCode: v1.14.31 (latest as of 2026-05-02)
  • AI SDK: Vercel AI SDK (streamText)
  • OS: Linux (Debian 13), Windows 11

Activity

  1. github-actions commented on May 3, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    If any of these cover the same root cause you've identified, please consider cross-referencing or closing in favor of the existing issue.

  2. tanbro commented on May 4, 2026

    @tanbro
    Author

    OPENCODE_EXPERIMENTAL_BASH_DEFAULT_TIMEOUT_MS and experimental.mcp.timeout solved the problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions