jeevesagent.mcp.client
======================

.. py:module:: jeevesagent.mcp.client

.. autoapi-nested-parse::

   Per-server MCP client wrapping ``mcp.ClientSession`` lifetime.

   The ``mcp`` SDK is imported lazily inside :meth:`MCPClient.connect`.
   Tests can bypass the real connection entirely by passing a
   ``session=`` kwarg whose object exposes the methods we use:
   ``initialize()``, ``list_tools()``, ``call_tool(name, args)``.



Classes
-------

.. autoapisummary::

   jeevesagent.mcp.client.MCPClient


Module Contents
---------------

.. py:class:: MCPClient(spec: jeevesagent.mcp.spec.MCPServerSpec, *, session: Any | None = None)

   One client per MCP server. Holds the live ``ClientSession``.


   .. py:method:: aclose() -> None
      :async:


      Tear down the session and underlying transport.



   .. py:method:: call_tool(name: str, args: dict[str, Any]) -> Any
      :async:


      Invoke ``name`` with ``args``. Returns the SDK's CallToolResult.



   .. py:method:: connect() -> None
      :async:


      Open the transport and initialise the session.

      No-op if already connected (or a fake session was injected at
      construction time).



   .. py:method:: list_tools() -> list[Any]
      :async:


      Return whatever the SDK gave us — a list of tool descriptors.

      Each descriptor has ``name``, ``description``, ``inputSchema``.
      We don't translate to :class:`ToolDef` here — the registry does
      that, since it also assigns names with disambiguation.



   .. py:property:: is_connected
      :type: bool



   .. py:property:: name
      :type: str



   .. py:property:: spec
      :type: jeevesagent.mcp.spec.MCPServerSpec



