python-sdk icon indicating copy to clipboard operation
python-sdk copied to clipboard

feat: Add configurable timeout for tool execution

Open dgenio opened this issue 1 month ago • 0 comments

Summary

Implements baseline timeout behavior for MCP tool calls to prevent indefinite blocking.

Closes #1374

Changes

Server-Side Timeout

  • Added REQUEST_TIMEOUT error code (-32001) to src/mcp/types.py
  • Added tool_timeout_seconds setting to FastMCP with default of 300 seconds (5 minutes)
  • Wrapped tool execution in anyio.fail_after() to enforce timeouts
  • Error mapping: TimeoutError → McpError with REQUEST_TIMEOUT code

Configuration

  • Constructor parameter: FastMCP(tool_timeout_seconds=60.0)
  • Environment variable: FASTMCP_TOOL_TIMEOUT_SECONDS=120
  • Disable timeout: FastMCP(tool_timeout_seconds=None)

Testing

  • Added 8 comprehensive tests in test_tool_manager.py:
    • Timeout exceeded behavior
    • Fast completion before timeout
    • No timeout (None) behavior
    • Sync and async tool timeouts
    • Context injection compatibility
    • Error differentiation
    • FastMCP setting propagation

Documentation

  • Added "Tool Timeouts" section to README.md
  • Configuration examples and best practices
  • Error handling patterns for clients

Design Decisions

  • Conservative default (300s) to avoid breaking existing tools
  • Nullable timeout allows explicit disabling for long operations
  • Standard error code aligns with TypeScript SDK
  • Environment variable support for deployment flexibility

Client-Side

Client-side timeout handling already exists in BaseSession.send_request() and works correctly with the new server-side timeouts.

Testing

All new tests pass:

pytest tests/server/fastmcp/test_tool_manager.py::TestToolTimeout -v

Linting passes:

ruff check .

Checklist

  • [x] Server-side timeout implementation
  • [x] Configurable via settings and environment variables
  • [x] Proper error code mapping (REQUEST_TIMEOUT)
  • [x] Comprehensive tests added
  • [x] Documentation updated
  • [x] All linting checks pass
  • [x] No changes to client-side (already has timeout support)

dgenio avatar Nov 28 '25 12:11 dgenio