microsoft/semantic-kernel · error · KernelPluginInvalidConfigurationError

MCP server not connected, please call connect() before using

Error message

MCP server not connected, please call connect() before using this method.

What it means

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.

Source

Thrown at python/semantic_kernel/connectors/mcp.py:610

                continue
            if self._has_mcp_function_name_conflict("tool", tool.name, local_name):
                continue
            self._mcp_registered_names[local_name] = ("tool", tool.name)
            func = kernel_function(name=local_name, description=tool.description)(partial(self.call_tool, tool.name))
            func.__kernel_function_parameters__ = _get_parameter_dicts_from_mcp_tool(tool)
            setattr(self, local_name, func)

    @abstractmethod
    def get_mcp_client(self) -> _AsyncGeneratorContextManager[Any, None]:
        """Get an MCP client."""
        pass

    async def call_tool(
        self, tool_name: str, **kwargs: Any
    ) -> list[TextContent | ImageContent | BinaryContent | AudioContent | FunctionResultContent | FunctionCallContent]:
        """Call a tool with the given arguments."""
        if not self.session:
            raise KernelPluginInvalidConfigurationError(
                "MCP server not connected, please call connect() before using this method."
            )
        if not self.load_tools_flag:
            raise KernelPluginInvalidConfigurationError(
                "Tools are not loaded for this server, please set load_tools=True in the constructor."
            )
        try:
            return _mcp_call_tool_result_to_kernel_contents(await self.session.call_tool(tool_name, arguments=kwargs))
        except McpError:
            raise
        except Exception as ex:
            raise FunctionExecutionException(f"Failed to call tool '{tool_name}'.") from ex

    async def get_prompt(self, prompt_name: str, **kwargs: Any) -> list[ChatMessageContent]:
        """Call a prompt with the given arguments."""
        if not self.session:
            raise KernelPluginInvalidConfigurationError(
                "MCP server not connected, please call connect() before using this method."

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Use the async context manager so connect/close are handled: 'async with plugin: await plugin.call_tool(...)'.
  2. Otherwise explicitly 'await plugin.connect()' before any call_tool and do not call after close().
  3. After a failed connect, create a new plugin instance rather than retrying on the same one.
  4. Guard call sites: check plugin.session is not None before calling.

Example fix

# before
plugin = MCPStdioPlugin(...)
await plugin.call_tool("foo", x=1)  # session is None

# after
async with MCPStdioPlugin(...) as plugin:
    await plugin.call_tool("foo", x=1)
Defensive patterns

Strategy: validation

Validate before calling

async def ensure_connected(plugin) -> None:
    if plugin.session is None:
        await plugin.connect()
    assert plugin.session is not None, "connect() did not establish a session"

Type guard

def plugin_is_connected(plugin) -> bool:
    return getattr(plugin, "session", None) is not None

Try / catch

from semantic_kernel.exceptions.kernel_exceptions import KernelPluginInvalidConfigurationError

async def safe_call_tool(plugin, name, **kw):
    if plugin.session is None:
        raise RuntimeError("connect the plugin first")
    try:
        return await plugin.call_tool(name, **kw)
    except KernelPluginInvalidConfigurationError as ex:
        if "not connected" in str(ex):
            await plugin.connect()
            return await plugin.call_tool(name, **kw)
        raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/7a26d172cc1f1111. Report an issue: GitHub.