Skip to content

Shell Sentinel 1.4.1 - MCP e2e suite and hung-handshake fix

Latest

Choose a tag to compare

@ibitato ibitato released this 19 Oct 08:36

Highlights

  • Fix: no more orphaned MCP servers on a hung handshake. An MCP server that accepts the connection but never answers initialize used to outlive Shell Sentinel: Strands' MCPClient.stop() only resolves a future awaited after the handshake, so it blocked forever and the stdio subprocess kept running. Every transport now runs inside an anyio CancelScope that MCPManager cancels when the startup deadline expires; the process tree is killed, the client thread ends cleanly and the server is still reported as timeout in the conversation panel and /status.
  • End-to-end test suite for MCP. Offline (tests/e2e/offline/test_mcp_flow.py, part of make test): the real TUI launches a scripted stdio server built on the mcp 2.x SDK plus local HTTP endpoints and verifies tool registration and calls, env_passthrough, tool errors, /status, the startup diagnostics for every failure kind and process cleanup. Live (tests/e2e/live/test_live_mcp_firecrawl.py, make test-e2e-live): the real Firecrawl MCP server is started by the TUI, firecrawl_scrape round-trips through the agent, and each selected provider must pick a Firecrawl tool to read a page (FIRECRAWL_API_KEY + Node.js).

Configuration

No configuration changes. Operators with MCP transports get the fix automatically.

Dependencies

No version changes. anyio (already installed transitively, 4.15.1) is now declared in pyproject.toml because it is imported directly; lockfiles regenerated.

Validation

  • 366 offline tests passed on Python 3.12 (unit, integration, offline e2e including the 6 MCP scenarios); 40 token-spending tests deselected by default
  • Live MCP scenarios passed against Firecrawl with Mistral zai-glm-5-3
  • Ruff, Black, CodeQL and Cursor Bugbot (no findings) clean on the merged PR

See CHANGELOG.md for the complete release notes.