def call_mcp_tool(self, tool_name: str, params: dict) -> tuple[Optional[str], Optional[str]]:
        """Call an MCP tool via Claude CLI (docker exec)"""
        try:
            # Prepare the MCP initialization and tool call sequence
            init_request = {
                "jsonrpc": "2.0",
                "id": 1,
                "method": "initialize",
                "params": {
                    "protocolVersion": "2024-11-05",
                    "capabilities": {"tools": {}},
                    "clientInfo": {"name": "communication-simulator", "version": "1.0.0"},
                },
            }

            # Send initialized notification
            initialized_notification = {"jsonrpc": "2.0", "method": "notifications/initialized"}

            # Prepare the tool call request
            tool_request = {
                "jsonrpc": "2.0",
                "id": 2,
                "method": "tools/call",
                "params": {"name": tool_name, "arguments": params},
            }

            # Combine all messages
            messages = [json.dumps(init_request), json.dumps(initialized_notification), json.dumps(tool_request)]

            # Join with newlines as MCP expects
            input_data = "\n".join(messages) + "\n"

            # Simulate Claude CLI calling the MCP server via docker exec
            docker_cmd = ["docker", "exec", "-i", self.container_name, "python", "server.py"]

            self.logger.debug(f"Calling MCP tool {tool_name} with proper initialization")

            # Execute the command
            result = subprocess.run(
                docker_cmd, input=input_data, text=True, capture_output=True, timeout=3600  # 1 hour timeout
            )

            if result.returncode != 0:
                self.logger.error(f"Docker exec failed: {result.stderr}")
                return None, None

            # Parse the response - look for the tool call response
            response_data = self._parse_mcp_response(result.stdout, expected_id=2)
            if not response_data:
                return None, None

            # Extract continuation_id if present
            continuation_id = self._extract_continuation_id(response_data)

            return response_data, continuation_id

        except subprocess.TimeoutExpired:
            self.logger.error(f"MCP tool call timed out after 1 hour: {tool_name}")
            return None, None
        except Exception as e:
            self.logger.error(f"MCP tool call failed: {e}")
            return None, None
Call an MCP tool via Claude CLI (docker exec)
simulator_tests/base_test.py