{"record":{"id":"7a26d172cc1f1111","repo":"microsoft/semantic-kernel","slug":"mcp-server-not-connected-please-call-connect-be","errorCode":null,"errorMessage":"MCP server not connected, please call connect() before using this method.","messagePattern":"MCP server not connected, please call connect\\(\\) before using this method\\.","errorType":"validation","errorClass":"KernelPluginInvalidConfigurationError","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/connectors/mcp.py","lineNumber":610,"sourceCode":"                continue\n            if self._has_mcp_function_name_conflict(\"tool\", tool.name, local_name):\n                continue\n            self._mcp_registered_names[local_name] = (\"tool\", tool.name)\n            func = kernel_function(name=local_name, description=tool.description)(partial(self.call_tool, tool.name))\n            func.__kernel_function_parameters__ = _get_parameter_dicts_from_mcp_tool(tool)\n            setattr(self, local_name, func)\n\n    @abstractmethod\n    def get_mcp_client(self) -> _AsyncGeneratorContextManager[Any, None]:\n        \"\"\"Get an MCP client.\"\"\"\n        pass\n\n    async def call_tool(\n        self, tool_name: str, **kwargs: Any\n    ) -> list[TextContent | ImageContent | BinaryContent | AudioContent | FunctionResultContent | FunctionCallContent]:\n        \"\"\"Call a tool with the given arguments.\"\"\"\n        if not self.session:\n            raise KernelPluginInvalidConfigurationError(\n                \"MCP server not connected, please call connect() before using this method.\"\n            )\n        if not self.load_tools_flag:\n            raise KernelPluginInvalidConfigurationError(\n                \"Tools are not loaded for this server, please set load_tools=True in the constructor.\"\n            )\n        try:\n            return _mcp_call_tool_result_to_kernel_contents(await self.session.call_tool(tool_name, arguments=kwargs))\n        except McpError:\n            raise\n        except Exception as ex:\n            raise FunctionExecutionException(f\"Failed to call tool '{tool_name}'.\") from ex\n\n    async def get_prompt(self, prompt_name: str, **kwargs: Any) -> list[ChatMessageContent]:\n        \"\"\"Call a prompt with the given arguments.\"\"\"\n        if not self.session:\n            raise KernelPluginInvalidConfigurationError(\n                \"MCP server not connected, please call connect() before using this method.\"","sourceCodeStart":592,"sourceCodeEnd":628,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/connectors/mcp.py#L592-L628","documentation":"Thrown by MCPPluginBase.call_tool (mcp.py:610) as a KernelPluginInvalidConfigurationError when self.session is None at call time. The MCP client requires an active, initialized session before any tool invocation; calling call_tool before connect() (or after close()) trips this guard.","triggerScenarios":"Instantiating a plugin and immediately calling call_tool without awaiting connect(); calling after the session was closed; using the plugin outside its async context manager; a failed connect that left session=None.","commonSituations":"Forgetting 'await plugin.connect()' or 'async with plugin:'; reusing a plugin after close(); connect() failed silently upstream; lifecycle bug where call_tool races ahead of connect.","solutions":["Use the async context manager so connect/close are handled: 'async with plugin: await plugin.call_tool(...)'.","Otherwise explicitly 'await plugin.connect()' before any call_tool and do not call after close().","After a failed connect, create a new plugin instance rather than retrying on the same one.","Guard call sites: check plugin.session is not None before calling."],"exampleFix":"# before\nplugin = MCPStdioPlugin(...)\nawait plugin.call_tool(\"foo\", x=1)  # session is None\n\n# after\nasync with MCPStdioPlugin(...) as plugin:\n    await plugin.call_tool(\"foo\", x=1)","handlingStrategy":"validation","validationCode":"async def ensure_connected(plugin) -> None:\n    if plugin.session is None:\n        await plugin.connect()\n    assert plugin.session is not None, \"connect() did not establish a session\"","typeGuard":"def plugin_is_connected(plugin) -> bool:\n    return getattr(plugin, \"session\", None) is not None","tryCatchPattern":"from semantic_kernel.exceptions.kernel_exceptions import KernelPluginInvalidConfigurationError\n\nasync def safe_call_tool(plugin, name, **kw):\n    if plugin.session is None:\n        raise RuntimeError(\"connect the plugin first\")\n    try:\n        return await plugin.call_tool(name, **kw)\n    except KernelPluginInvalidConfigurationError as ex:\n        if \"not connected\" in str(ex):\n            await plugin.connect()\n            return await plugin.call_tool(name, **kw)\n        raise","preventionTips":["Use 'async with plugin:' so connect/close are automatic.","Never call call_tool before connect or after close.","After a failed connect, create a new plugin instance.","Check plugin.session is not None at call sites for defense in depth."],"tags":["mcp","lifecycle","session","call-tool","configuration"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}