python-sdk
python-sdk copied to clipboard
feat: Add configurable timeout for tool execution
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)