
    i8!                         d dl Z d dlZd dl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 d d	lmZmZ  G d
 de      Zy)    N)AsyncIterator)Any)ClientSession)Unpack)ClientTransportSessionKwargs)FastMCPTransport)	MCPConfigMCPServerTypesRemoteMCPServerStdioMCPServerTransformingRemoteMCPServerTransformingStdioMCPServer)FastMCPcreate_proxyc                       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ee   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      p/Users/bowang/.openclaw/workspace/ChatDev/.venv/lib/python3.12/site-packages/fastmcp/client/transports/config.py__init__zMCPConfigTransport.__init__E   s    fd#((0F,24{{%%CDD t{{%%&!+!$t{{'='='D'D'F"GHUUWDN##DNN3 ,    session_kwargsreturnc                t  K   t        | j                  j                        dk(  r; | j                  j                  di |4 d {   }| d d d       d {    y |j                  d      }t        t           d      }t        j                         4 d {   }| j                  D ]  }|j                          d {     g | _
        	 | j                  j                  j                         D ]a  \  }}| j                  ||||       d {   \  }	}
}| j                  j                  |	       |j                  || j                   r|nd        c 	  t%        |      j                  di |4 d {   }| d d d       d {    d d d       d {    y 7 a7 O# 1 d {  7  sw Y   y xY w7 %7 7 # t"        $ r3 | j                  D ]  }|j                          d {  7    g | _
         w xY w7 7 y# 1 d {  7  sw Y   xY w7 # 1 d {  7  sw Y   y xY ww)Nr   read_timeout_seconds	MCPRoutername)	namespace)mcp )r   r   r   r#   connect_sessiongetr   r   
contextlibAsyncExitStackr   closeitems_create_proxyr$   mountr   	Exceptionr	   )r%   r)   sessiontimeout	compositestacktr/   server_configr#   _clientproxys               r&   r3   z"MCPConfigTransport.connect_sessionT   s    
 t{{%%&!+5t~~55GGG7 HG !$$%;<CLk2	,,..%%%ggi &!D+/;;+A+A+G+G+I'D-6:6H6HmWe7 1-Iw $$++I6OO1D1D$ $  ,J G'I6FF    - /.. HGGGG /  
1  ))A'')OO *#%     - /...s  AH8F&H8	F,H8F)AH8GH8 #H#GH#AG	GAG	!H#;H<H#?HH#H
H#H8 H!!H8)H8,F>2F53F>:H8H#G		+H4G7
5HH#
H#H	HH	H#!H8#H5)H,*H51H8r/   r=   Nr?   c                    K   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       t        |
d|       }|rdd	lm} |j%                   ||             |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   )StatefulProxyClientN)r#   r=   T)forcezProxy-r.   )ToolTransform)tagsonly)rH   )fastmcp.server.providers.proxyrE   r   r   r   r"   toolsinclude_tagsexclude_tagsr   r   
__aenter__push_async_callbackr7   _disconnectr   fastmcp.server.transformsrG   add_transformenablesetdisable)r%   r/   r   r=   r?   rE   tool_transformsrL   rM   r#   clientrC   rG   s                r&   r9   z MCPConfigTransport._create_proxy   s]      	G f89&33F;I$llO!..L!..L ;<'44V<I$llO!..L!..L++-I$y'J !!! 	!!)//2!!&"4"4D!A$

 ?o >?LLc,/dL;MMs<0M1&%'') 	"s   CE>E<B,E>c                 b   K   | j                   D ]  }|j                          d {     y 7 w)N)r   r7   )r%   r#   s     r&   r7   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'   r5   asynccontextmanagerr   r   r   r   r3   strr   datetime	timedeltar6   tupler   r   r   r9   r7   rZ   r2   r(   r&   r   r      s    ,\4y4/ 4 4 ##) &} 5)	}	%) $)VD(D( D( ##d*	D(
 ((D( 
WS\1	2D(L$?# ?r(   r   )r5   rb   collections.abcr   typingr   r1   r   typing_extensionsr   fastmcp.client.transports.baser   r    fastmcp.client.transports.memoryr	   fastmcp.mcp_configr
   r   r   r   r   r   fastmcp.server.serverr   r   r   r2   r(   r&   <module>rl      s:      )   $ I =  8u? u?r(   