
    kKjn$                         d dl Z d dlZd dlmZ d dlmZmZ d dlmZ d dl	m
Z
 d dlmZ d dlmZmZ d dlmZ d d	lmZmZmZmZmZmZmZ d d
lmZ erd dlmZ  ee      Z G d de      Z y)    N)AsyncIterator)TYPE_CHECKINGAny)ClientSession)Unpack)_install_hints)ClientTransportSessionKwargs)FastMCPTransport)	MCPConfigMCPServerTypesRemoteMCPServerStdioMCPServerTransformingRemoteMCPServerTransformingStdioMCPServer_coerce_tool_transform_configs)
get_loggerFastMCPc                       e Zd ZdZddeez  defdZej                  de
e   dee   fd       Zdeded	ej$                  d
z  dej&                  deeedf   f
dZd ZdefdZy
)MCPConfigTransportad  Transport for connecting to one or more MCP servers defined in an MCPConfig.

    This transport provides a unified interface to multiple MCP servers defined in an MCPConfig
    object or dictionary matching the MCPConfig schema. It supports two key scenarios:

    1. If the MCPConfig contains exactly one server, it creates a direct transport to that server.
    2. If the MCPConfig contains multiple servers, it creates a composite client by mounting
       all servers on a single FastMCP instance, with each server's name, by default, used as its mounting prefix.

    In the multiserver case, tools are accessible with the prefix pattern `{server_name}_{tool_name}`
    and resources with the pattern `protocol://{server_name}/path/to/resource`.

    This is particularly useful for creating clients that need to interact with multiple specialized
    MCP servers through a single interface, simplifying client code.

    Examples:
        ```python
        from fastmcp import Client

        # Create a config with multiple servers
        config = {
            "mcpServers": {
                "weather": {
                    "url": "https://weather-api.example.com/mcp",
                    "transport": "http"
                },
                "calendar": {
                    "url": "https://calendar-api.example.com/mcp",
                    "transport": "http"
                }
            }
        }

        # Create a client with the config
        client = Client(config)

        async with client:
            # Access tools with prefixes
            weather = await client.call_tool("weather_get_forecast", {"city": "London"})
            events = await client.call_tool("calendar_list_events", {"date": "2023-06-01"})

            # Access resources with prefixed URIs
            icons = await client.read_resource("weather://weather/icons/sunny")
        ```
    configname_as_prefixc                    t        |t              rt        j                  |      }|| _        || _        g | _        | j                  j                  st        d      t        | j                  j                        dk(  rot        t        | j                  j                  j                                     j                         | _        | j                  j                  | j                         y y )Nz$No MCP servers defined in the config   )
isinstancedictr   	from_dictr   r   _transports
mcpServers
ValueErrorlennextitervaluesto_transport	transportappend)selfr   r   s      q/Users/ahmed/devFolder/Ultron/claude-voice/.venv/lib/python3.12/site-packages/fastmcp/client/transports/config.py__init__zMCPConfigTransport.__init__L   s    fd#((0F,24{{%%CDD t{{%%&!+!$t{{'='='D'D'F"GHUUWDN##DNN3 ,    session_kwargsreturnc                  K   t        | j                  j                        dk(  r; | j                  j                  di |4 d {   }| d d d       d {    y 	 ddlm} |j                  d      } |t           d      }t        j                         4 d {   }| j                  D ]  }|j                          d {     g | _        | j                  j                  j!                         D ]b  \  }	}
	 | j#                  |	|
||       d {   \  }}}| j                  j+                  |       |j-                  || j.                  r|	nd        d | j                  st1        d       t3        |      j                  di |4 d {   }| d d d       d {    d d d       d {    y 7 {7 i# 1 d {  7  sw Y   y xY w# t        $ r$}t        t        j                  d            |d }~ww xY w7 k7 G7 # t$        $ r t&        j)                  d|	d	
       Y >w xY w7 7 # 1 d {  7  sw Y   xY w7 # 1 d {  7  sw Y   y xY ww)Nr   r   r   z!MCP configs with multiple serversread_timeout_seconds	MCPRouternamez,Failed to connect to MCP server %r, skippingT)exc_info)	namespacez!All MCP servers failed to connect)mcp )r"   r   r    r'   connect_sessionfastmcp.server.serverr   ImportErrorr   full_packagegetr   
contextlibAsyncExitStackr   closeitems_create_proxy	Exceptionloggerwarningr(   mountr   ConnectionErrorr   )r)   r-   sessionr   exctimeout	compositestacktr3   server_configr'   _clientproxys                 r*   r8   z"MCPConfigTransport.connect_session[   s8    
 t{{%%&!+5t~~55GGG7 HG	5 !$$%;< GCLk2	,,..%%%ggi &!D'+{{'='='C'C'E#m6:6H6HmWe7 1-Iw   ''	29L9LRVW (F" ##%&IJJF'I6FF    5 /..% HGGGG  	++,OP	 /  
1 !  NNF!% # 
     5 /...s9  AI+G I+	GI+GI+!G '9I+ H!I+$#IH7I HHH A5IH;IH?I*H=+I/I+:I;I+I+GGGI+	H$HHI+IH!H84I7H88I=I?I	II	II+I(II($I+r3   rI   NrK   zFastMCP[Any]c                   K   ddl m} ddlm} d}d}d}	t	        |t
              r:t        j                  |      }
|j                  }|j                  }|j                  }	nZt	        |t              r:t        j                  |      }
|j                  }|j                  }|j                  }	n|j                         }
 ||
|      }|j                          d{    |j                  |
j                         |j                  |j                   d        ||d| 	      }|r&dd
lm} |j'                   |t)        |                   |r|j+                  t-        |      d       |	r|j/                  t-        |	             |
||fS 7 w)a  Create underlying transport, proxy client, and proxy server for a single backend.

        The ProxyClient is connected via the AsyncExitStack *before* being
        passed to create_proxy so the factory sees it as connected and reuses
        the same session for all tool calls (instead of creating fresh copies).

        Returns a tuple of (transport, proxy_client, proxy_server).
        r   )StatefulProxyClient)create_proxyN)r'   rI   T)forcezProxy-r2   )ToolTransform)tagsonly)rU   )fastmcp.server.providers.proxyrQ   r9   rR   r   r   r   r&   toolsinclude_tagsexclude_tagsr   r   
__aenter__push_async_callbackr?   _disconnectfastmcp.server.transformsrT   add_transformr   enablesetdisable)r)   r3   r   rI   rK   rQ   rR   tool_transformsrY   rZ   r'   clientrO   rT   s                 r*   rA   z MCPConfigTransport._create_proxy   sk      	G6 f89&33F;I$llO!..L!..L ;<'44V<I$llO!..L!..L++-I$y'J !!! 	!!)//2!!&"4"4D!A$

 ?<_MN LLc,/dL;MMs<0M1&%''- 	"s   CF
FB2F
c                 b   K   | j                   D ]  }|j                          d {     y 7 w)N)r   r?   )r)   r'   s     r*   r?   zMCPConfigTransport.close   s)     ))I//### *#s   #/-/c                 "    d| j                    dS )Nz<MCPConfigTransport(config='z')>)r   )r)   s    r*   __repr__zMCPConfigTransport.__repr__   s    -dkk]#>>r,   )T)__name__
__module____qualname____doc__r   r   boolr+   r=   asynccontextmanagerr   r
   r   r   r8   strr   datetime	timedeltar>   tupler	   r   rA   r?   rg   r7   r,   r*   r   r      s    ,\4y4/ 4 4 ##4 &} 54	}	%4 $4lG(G( G( ##d*	G(
 ((G( 
^3	4G(R$?# ?r,   r   )!r=   ro   collections.abcr   typingr   r   r6   r   typing_extensionsr   fastmcpr   fastmcp.client.transports.baser	   r
    fastmcp.client.transports.memoryr   fastmcp.mcp_configr   r   r   r   r   r   r   fastmcp.utilities.loggingr   r9   r   rh   rC   r   r7   r,   r*   <module>rz      sR      ) %  $ " I =   1-	H	C? C?r,   