make_tool previously depended on tool instances in the main process, but the tool instances are no longer available there
To solve this, the tool interface was adjusted to provide static information which is used in the ProcessIsolatedTool wrapper.
I also tried another approach before, where ProcessIsolatedTool would accept tool metadata at init, but this lead to serialization issues that couldn't be easily solved (mcp's FuncMetadata is not serializable, despite being a BaseModel...).
Tests for checking that the wrapped tool instance has the same metadata as the wrapper have been added.
- Updated exception handling in `agent.py` for better error specificity (catching `FileNotFoundError`).
- Added contextual comment for `CONFIG_FILE_DOCKER` in `agent.py`.
- Updated `DOCKER.md` to reflect the new GitHub repository link.
ROOT CAUSE: Asyncio event loop contamination between MCP server and SerenaAgent
was causing intermittent deadlocks. MCP server runs in its own asyncio loop,
but SerenaAgent creates coroutines that leak into the MCP context, leading to
unawaited coroutines and eventual event loop blocking.
SOLUTION: Complete process isolation with clean architecture
Process Isolation Changes:
- Add ProcessIsolatedSerenaAgent wrapper that runs SerenaAgent in separate process
- Implement JSON-RPC based IPC for communication between MCP server and agent
- Add SerenaAgentWorker class to handle requests in the isolated process
- Centralize error handling in _make_request_with_result() helper method
- Use serena_config.tool_timeout instead of hardcoded timeout parameters
Architecture Improvements:
- Define ToolProtocol interface for clean tool contracts
- Implement ProcessIsolatedTool with complete Tool interface (apply + apply_ex)
- Remove hacky make_process_isolated_tool function - use single make_tool path
- Eliminate inheritance abuse - ProcessIsolatedTool implements protocol cleanly
- Preserve full docstring parsing functionality through process boundary
MCP Server Updates:
- Update start_mcp_server() to use process isolation by default
- Maintain backward compatibility with create_mcp_server_and_agent()
- Retrieve tool metadata from isolated process for proper MCP tool creation
- Ensure proper process lifecycle management in server lifespan handlers
Key Benefits:
- Prevents asyncio contamination deadlocks completely
- Maintains full docstring parsing and parameter schema generation
- Clean protocol-based architecture with no inheritance hacks
- Centralized configuration-driven timeout handling
- All tools implement consistent apply_ex interface
- Process isolation is transparent to MCP clients
This fix ensures that MCP symbolic tools no longer create deadlocks
1. Use all gitignore files in SerenaAgent, not just top level
2. Listing and file finding tools now can find all non-ignored files (previously they would only find code files)
3. Read and edit tools will raise an error on attempting to operate on an ignored file or a path outside the project root