- What was implemented
- Updated MCPToolResult.data docstring to document the normalisation behaviour, clarifying that MCP 1.4.0 list-format content is normalised to a dict with a "content" key.
- Updated MCPToolAdapter.invoke() success path to normalise MCP 1.4.0 list-format content: when content is a list (as per MCP 1.4.0 spec), it is wrapped as {"content": [...]} so MCPToolResult.data is always dict[str, Any].
- Updated MockMCPTransport.call() to return MCP 1.4.0-compliant list-format content: invoke_results are now wrapped as [{"type": "text", "text": json.dumps(payload)}] instead of the non-standard dict format.
- Added json import to mock_mcp_transport.py to support JSON payload encoding.
- Updated existing mcp_adapter.feature scenario "Invoke a discovered tool successfully" to check for "content" key instead of "id" (since mock now returns MCP 1.4.0 list format).
- Added two new Behave scenarios: "Invoke tool returns MCP 1.4.0 list-format content normalised to dict" and "Invoke tool with MCP 1.4.0 content list stores content items".
- Added corresponding step definitions for the new scenarios.
- All 14,418 existing scenarios continue to pass; 2 new scenarios added; typecheck passes with 0 errors; lint passes.
- Why this approach
- Design decision: Normalize to dict (Option B) to maintain a consistent MCPToolResult.data type of dict[str, Any] and avoid breaking downstream code that accesses result.data["key"].
- Fallback path handles non-standard server responses gracefully, ensuring robustness when servers deviate from MCP 1.4.0 spec.
- Technical approach and affected components
- Core: MCPToolResult data handling and MCPToolAdapter.invoke() logic
- Mocks: mock_mcp_transport.py updated to emit MCP 1.4.0 list-format content
- Tests: updated mcp_adapter.feature expectations; added two Behave scenarios with new step definitions
- Dependencies: added import json to mock_mcp_transport.py
- Verification
- Comprehensive test suites: 14,418 existing scenarios pass
- 2 new scenarios added and pass
- Typechecking: 0 errors
- Linting: passes
ISSUES CLOSED: #2743
Implement MCPToolAdapter to connect to external MCP servers, enumerate
tools, and register them in ToolRegistry with source="mcp". Includes
connect/reconnect/disconnect lifecycle with timeout enforcement, input
validation on invoke, capability inference, Behave/Robot/ASV tests, and
docs/reference/mcp_adapter.md.
ISSUES CLOSED: #159