
    k7i                        S SK r S SKrS SKrS SKrS SKrS SKrS SKrS SKrS SKJ	r	  S SK
Jr  S SKJrJrJrJrJrJr  S SKrS SKrS SKrS SKJrJr  S SKJrJrJrJrJr  S SKJ r   S SK!J"r"  S S	K#J$r$  S S
K%J&r'  S SK(J)r)  S SK*J+r+  S SK,J-r-  S SK.J/r/J0r0  S SK1r1S SK2J3r3  S SK4J5r5  S SK6J7r7J8r8  S SK9J:r:  S S
K;J&r&  S SK<J=r=  S SK>J?r?  \=" \@5      rA\" SSS9rB/ SQrC " S S\/SS9rD " S S\ R                  5      rF " S S\F5      rG " S  S!\F5      rH " S" S#\F5      rI " S$ S%\F5      rJS&\KS'\L\K   S(\M\K\K4   S-  S)\KS-  S*\\-  S-  S+\DS,\R                  S-\R                  S.\R                  \   4S/ jrP " S0 S1\J5      rQ " S2 S3\J5      rR " S4 S5\J5      rS " S6 S7\J5      rT " S8 S9\J5      rU " S: S;\J5      rV " S< S=\F5      rW\R                  S>\&\'-  S?\	S   4S@ j5       rY " SA SB\F5      rZ\SC\BS?\B4SD j5       r[\SC\&S?\W4SE j5       r[\SC\'S?\W4SF j5       r[\SC\7S?\Z4SG j5       r[\SC\M\K\4   S?\Z4SH j5       r[\SC\-S?\H\I-  4SI j5       r[\SC\KS?\Q\S-  \H-  \I-  4SJ j5       r[\SC\S?\Q\S-  4SK j5       r[SC\F\&-  \'-  \--  \-  \7-  \M\K\4   -  \K-  S?\F4SL jr[g)M    N)AsyncIterator)Path)AnyLiteralTextIOTypeVarcastoverload)ClientSessionStdioServerParameters)ElicitationFnTListRootsFnT
LoggingFnTMessageHandlerFnTSamplingFnT)
sse_client)stdio_client)streamablehttp_client)FastMCP)McpHttpClientFactory)#create_client_server_memory_streams)AnyUrl)	TypedDictUnpack)
BearerAuth)OAuth)	MCPConfiginfer_transport_type_from_url)get_http_headers)
get_logger)UVEnvironmentClientTransportTClientTransport)bound)r#   FastMCPStdioTransportFastMCPTransportNodeStdioTransportNpxStdioTransportPythonStdioTransportSSETransportStdioTransportStreamableHttpTransportUvStdioTransportUvxStdioTransportinfer_transportc                       \ rS rSr% Sr\R                  S-  \S'   \S-  \S'   \	S-  \S'   \
S-  \S'   \S-  \S'   \S-  \S	'   \R                  R                  S-  \S
'   Srg)SessionKwargs?   z8Keyword arguments for the MCP ClientSession constructor.Nread_timeout_secondssampling_callbacklist_roots_callbacklogging_callbackelicitation_callbackmessage_handlerclient_info )__name__
__module____qualname____firstlineno____doc__datetime	timedelta__annotations__r   r   r   r   r   mcptypesImplementation__static_attributes__r:       S/home/james-whalen/.local/lib/python3.13/site-packages/fastmcp/client/transports.pyr1   r1   ?   sb    B",,t33"T))%,, 4''(4//&--))D00rG   r1   F)totalc                       \ rS rSrSr\R                  \R                  S\	\
   S\\   4S j5       5       rS\4S jrS rS\R$                  \S	   -  \-  S
-  4S jrSrg
)r#   K   z
Abstract base class for different MCP client transport mechanisms.

A Transport is responsible for establishing and managing connections
to an MCP server, and providing a ClientSession within an async context.

session_kwargsreturnc                   #    [         e7f)a  
Establishes a connection and yields an active ClientSession.

The ClientSession is *not* expected to be initialized in this context manager.

The session is guaranteed to be valid only within the scope of the
async context manager. Connection setup and teardown are handled
within this context.

Args:
    **session_kwargs: Keyword arguments to pass to the ClientSession
                      constructor (e.g., callbacks, timeouts).

Yields:
    A mcp.ClientSession instance.
)NotImplementedErrorselfrL   s     rH   connect_sessionClientTransport.connect_sessionT   s     * "!s   	c                 6    SU R                   R                   S3$ )N<>)	__class__r;   rQ   s    rH   __repr__ClientTransport.__repr__l   s    4>>**+1--rG   c                    #    g7f)zClose the transport.Nr:   rX   s    rH   closeClientTransport.closep   s     s   authoauthNc                      Ub  [        S5      eg )Nz$This transport does not support auth)
ValueErrorrQ   r^   s     rH   	_set_authClientTransport._set_auths   s    CDD rG   r:   )r;   r<   r=   r>   r?   abcabstractmethod
contextlibasynccontextmanagerr   r1   r   r   rR   strrY   r\   httpxAuthr   rc   rF   r:   rG   rH   r#   r#   K   s     	## &} 5	}	% $ ,.# .#Eejj77+;;cADH ErG   c                   v    \ rS rSrSrS\\-  4S jr\R                  S\
\   S\\   4S j5       rS\4S jrS	rg
)WSTransportx   zGTransport implementation that connects to an MCP server via WebSockets.urlc                 .   [         R                  R                  (       a  [        R                  " S[
        SS9  [        U[        5      (       a  [        U5      n[        U[        5      (       a  UR                  S5      (       d  [        S5      eXl        g )NzwWSTransport is a deprecated MCP transport and will be removed in a future version. Use StreamableHttpTransport instead.   )
stacklevelwszInvalid WebSocket URL provided.)fastmcpsettingsdeprecation_warningswarningswarnDeprecationWarning
isinstancer   ri   
startswithra   ro   )rQ   ro   s     rH   __init__WSTransport.__init__{   sm    00MM J"
 c6""c(C#s##3>>$+?+?>??rG   rL   rM   c                  #     SSK Jn  U" U R                  5       IS h  vN nUu  pV[	        XV40 UD6 IS h  vN nU7v   S S S 5      IS h  vN   S S S 5      IS h  vN   g ! [         a  n[        S5      UeS nAff = f Na NJ N7! , IS h  vN  (       d  f       NL= f NC! , IS h  vN  (       d  f       g = f7f)Nr   )websocket_clientzxThe websocket transport is not available. Please install fastmcp[websockets] or install the websockets package manually.)mcp.client.websocketr   ImportErrorro   r   )rQ   rL   r   e	transportread_streamwrite_streamsessions           rH   rR   WSTransport.connect_session   s     	= $DHH--(1%K$-;   .--  	 K	
 .    .---s   B>A$ B>BB>B$BB$BB$BB$B>B"B>$
A?.A::A??B>B$B$B	BB	B$"B>$B;*B-+B;7B>c                 "    SU R                    S3$ )Nz<WebSocketTransport(url='')>ro   rX   s    rH   rY   WSTransport.__repr__   s    *488*C88rG   r   N)r;   r<   r=   r>   r?   ri   r   r|   rg   rh   r   r1   r   r   rR   rY   rF   r:   rG   rH   rm   rm   x   sU    QC&L  ## &} 5	}	% $"9# 9rG   rm   c                   4   \ rS rSrSr    SS\\-  S\\\4   S-  S\R                  \
S   -  \-  S-  S\R                  \-  \-  S-  S	\S-  4
S
 jjrS\R                  \
S   -  \-  S-  4S jr\R&                  S\\   S\\   4S j5       rS\4S jrSrg)r*      zOTransport implementation that connects to an MCP server via Server-Sent Events.Nro   headersr^   r_   sse_read_timeouthttpx_client_factoryc                    [        U[        5      (       a  [        U5      n[        U[        5      (       a  UR                  S5      (       d  [	        S5      eXl        U=(       d    0 U l        U R                  U5        XPl        [        U[        [        -  5      (       a  [        R                  " [        U5      S9nX@l        g )Nhttpz$Invalid HTTP/S URL provided for SSE.secondsrz   r   ri   r{   ra   ro   r   rc   r   intfloatr@   rA   r   rQ   ro   r   r^   r   r   s         rH   r|   SSETransport.__init__   s     c6""c(C#s##3>>&+A+ACDD
 }"t$8!&e44'11%@P:QR 0rG   c                     US:X  a  [        U R                  5      nO [        U[        5      (       a  [	        U5      nXl        g Nr_   r   ro   rz   ri   r   r^   rb   s     rH   rc   SSETransport._set_auth   2    7??Dc""d#D	rG   rL   rM   c                  #    0 n[        5       U R                  -  US'   U R                  b  U R                  R                  5       US'   UR	                  S5      b<  [        [        R                  UR	                  S5      5      nUR                  5       US'   U R                  b  U R                  US'   [        U R                  4SU R                  0UD6 IS h  vN nUu  pV[        XV40 UD6 IS h  vN nU7v   S S S 5      IS h  vN   S S S 5      IS h  vN   g  NC N, N! , IS h  vN  (       d  f       N.= f N%! , IS h  vN  (       d  f       g = f7fNr   r   r3   timeoutr   r^   )r   r   r   total_secondsgetr	   r@   rA   r   r   ro   r^   r   )rQ   rL   client_kwargsr3   r   r   r   r   s           rH   rR   SSETransport.connect_session   s3     )+
 $4#5#Di    ,040E0E0S0S0UM,-45A#'""N$6$67M$N$  (<'I'I'KM)$$$0484M4MM01dhhHTYYH-HHI(1%K$-;   IHH    IHHHs   CEDED?2D3D?6D#<D?D!D?ED=ED?!D?#D:	)D,*D:	6D?=E?EEEEc                 "    SU R                    S3$ )Nz<SSETransport(url='r   r   rX   s    rH   rY   SSETransport.__repr__   s    $TXXJc22rG   r^   r   r   r   ro   NNNNr;   r<   r=   r>   r?   ri   r   dictrj   rk   r   r@   rA   r   r   r   r|   rc   rg   rh   r   r1   r   r   rR   rY   rF   r:   rG   rH   r*   r*      s    Y
 *.;?DH<@16\1 c3h$&1 jj77++c1D8	1
 #,,u4s:TA1 3T912ejj77+;;cADH  ## &} 5	}	% $<3# 3rG   r*   c                   4   \ rS rSrSr    SS\\-  S\\\4   S-  S\R                  \
S   -  \-  S-  S\R                  \-  \-  S-  S	\S-  4
S
 jjrS\R                  \
S   -  \-  S-  4S jr\R&                  S\\   S\\   4S j5       rS\4S jrSrg)r,      zUTransport implementation that connects to an MCP server via Streamable HTTP Requests.Nro   r   r^   r_   r   r   c                    [        U[        5      (       a  [        U5      n[        U[        5      (       a  UR                  S5      (       d  [	        S5      eXl        U=(       d    0 U l        U R                  U5        XPl        [        U[        [        -  5      (       a  [        R                  " [        U5      S9nX@l        g )Nr   z0Invalid HTTP/S URL provided for Streamable HTTP.r   r   r   s         rH   r|    StreamableHttpTransport.__init__   s     c6""c(C#s##3>>&+A+AOPP
 }"t$8!&e44'11%@P:QR 0rG   c                     US:X  a  [        U R                  5      nO [        U[        5      (       a  [	        U5      nXl        g r   r   rb   s     rH   rc   !StreamableHttpTransport._set_auth  r   rG   rL   rM   c                L  #    0 n[        5       U R                  -  US'   U R                  b  U R                  US'   UR                  S5      b  UR                  S5      US'   U R                  b  U R                  US'   [        U R                  4SU R                  0UD6 IS h  vN nUu  pEn[        XE40 UD6 IS h  vN nU7v   S S S 5      IS h  vN   S S S 5      IS h  vN   g  ND N, N! , IS h  vN  (       d  f       N.= f N%! , IS h  vN  (       d  f       g = f7fr   )	r   r   r   r   r   r   ro   r^   r   )rQ   rL   r   r   r   r   _r   s           rH   rR   'StreamableHttpTransport.connect_session  s#     )+
 $4#5#Di    ,040E0EM,-45A'5'9'9:P'QM)$$$0484M4MM01(HH

 
 
 +4(Kq$-;  
 
 
   
 
 
 
s   B!D$#C($D$'D
=C*>D
C.D
C,D
D$"D#D$*D
,D
.D	4C75D	D
D$
D!DD!D$c                 "    SU R                    S3$ )Nz<StreamableHttpTransport(url='r   r   rX   s    rH   rY    StreamableHttpTransport.__repr__(  s    /z==rG   r   r   r   r:   rG   rH   r,   r,      s    _
 *.;?DH<@16\1 c3h$&1 jj77++c1D8	1
 #,,u4s:TA1 3T912ejj77+;;cADH  ## &} 5	}	% $>># >rG   r,   c                       \ rS rSrSr    SS\S\\   S\\\4   S-  S\S-  S\S-  S	\	\
-  S-  4S
 jjr\R                  S\\   S\\   4S j5       rS\\   S\S-  4S jrS rS rS rS\4S jrSrg)r+   i,  z
Base transport for connecting to an MCP server via subprocess with stdio.

This is a base class that can be subclassed for specific command-based
transports like Python, Node, Uvx, etc.
Ncommandargsenvcwd
keep_alivelog_filec                     Xl         X l        X0l        X@l        Uc  SnXPl        X`l        SU l        SU l        [        R                  " 5       U l
        [        R                  " 5       U l        g)a  
Initialize a Stdio transport.

Args:
    command: The command to run (e.g., "python", "node", "uvx")
    args: The arguments to pass to the command
    env: Environment variables to set for the subprocess
    cwd: Current working directory for the subprocess
    keep_alive: Whether to keep the subprocess alive between connections.
               Defaults to True. When True, the subprocess remains active
               after the connection context exits, allowing reuse in
               subsequent connections.
    log_file: Optional path or file-like object where subprocess stderr will
           be written. Can be a Path or TextIO object. Defaults to sys.stderr
           if not provided. When a Path is provided, the file will be created
           if it doesn't exist, or appended to if it does. When set, server
           errors will be written to this file instead of appearing in the console.
NT)r   r   r   r   r   r   _session_connect_taskanyioEvent_ready_event_stop_event)rQ   r   r   r   r   r   r   s          rH   r|   StdioTransport.__init__4  sX    6 	J$ .226!KKM ;;=rG   rL   rM   c                  #     U R                   " S0 UD6I S h  vN   [        [        U R                  5      7v   U R                  (       d  U R                  5       I S h  vN   g [        R                  S5        g  Na N! U R                  (       d  U R                  5       I S h  vN    f [        R                  S5        f = f7f)Nz6Stdio transport has keep_alive=True, not disconnectingr:   )connectr	   r   r   r   
disconnectloggerdebugrP   s     rH   rR   StdioTransport.connect_session]  s     	W,,0000}dmm44??oo'''UV 1 ( ??oo'''UVsI   CA? A;!A? $CA= C;A? =C?%C$B'%CCc                 .  #    U R                   b  g [        R                  " 5       n[        R                  " [	        U R
                  U R                  U R                  U R                  U R                  UU R                  U R                  US9	5      U l         U R                  R                  5       I S h  vN   U R                   R                  5       (       a  U R                   R                  5       nUb  UeUI S h  vN U l        U R                  $  N] N7f)N)	r   r   r   r   r   rL   ready_event
stop_eventsession_future)r   asyncioFuturecreate_task_stdio_transport_connect_taskr   r   r   r   r   r   r   waitdone	exceptionr   )rQ   rL   r   r   s       rH   r   StdioTransport.connectj  s      )8?8H %00)YYHHHH- --++-

 $$&&& ""$$**446I$,,}} 	' -s%   B1D3D4AD;D<DDc                    #    U R                   c  g U R                  R                  5         U R                   I S h  vN   S U l         [        R                  " 5       U l        [        R                  " 5       U l        g  N@7fN)r   r   setr   r   r   rX   s    rH   r   StdioTransport.disconnect  sd     % 	      " ;;=!KKM 	!s   8A=A;AA=c                 @   #    U R                  5       I S h  vN   g  N7fr   )r   rX   s    rH   r\   StdioTransport.close  s     oos   c                 x    U R                   R                  5       (       d  U R                   R                  5         gg)zcEnsure that we send a disconnection signal to the transport task if we are being garbage collected.N)r   is_setr   rX   s    rH   __del__StdioTransport.__del__  s.    &&((  " )rG   c                 j    SU R                   R                   SU R                   SU R                   S3$ )NrU   z
(command='z', args=z)>)rW   r;   r   r   rX   s    rH   rY   StdioTransport.__repr__  s3    ''(
4<<.SUV	
rG   )
r   r   r   r   r   r   r   r   r   r   r   )r;   r<   r=   r>   r?   ri   listr   boolr   r   r|   rg   rh   r   r1   r   r   rR   r   r   r\   r   rY   rF   r:   rG   rH   r+   r+   ,  s     &*"&)-')') 3i') #s(^d"	')
 4Z') 4K') -$&')R ##
W &} 5
W	}	%
W $
W! &} 5!		!F* #

# 
rG   r+   r   r   r   r   r   rL   r   r   r   c	           
      (  #     [         R                  " 5        ISh  vN n	 [        U UUUS9n
Uc  [        R                  nO8[        U[        5      (       a!  U	R                  UR                  S5      5      nOUnU	R                  [        XS95      I Sh  vN nUu  pUR                  U	R                  [        X40 UD65      I Sh  vN 5        [        R                  S5        UR                  5         UR!                  5       I Sh  vN   [        R                  S5        SSS5      ISh  vN   g GN N Np N1! [        R                  S5        f = f N(! , ISh  vN  (       d  f       g= f! ["         a    UR                  5         e f = f7f)zA standalone connection task for a stdio transport. It is not a part of the StdioTransport class
to ensure that the connection task does not hold a reference to the Transport object.N)r   r   r   r   a)errlogzStdio transport connectedzStdio transport disconnected)rg   AsyncExitStackr   sysstderrrz   r   enter_contextopenenter_async_contextr   
set_resultr   r   r   r   r   	Exception)r   r   r   r   r   rL   r   r   r   stackserver_paramslog_file_handler   r   r   s                  rH   r   r     s\    ',,..%!= 5#	! #&)jjO$//&+&9&9(--:L&MO '/O"'";"; G# 	 -6)))33%kR>R  89! !oo''' ;<E /.."
 ( ;<E /...F  s   FE3 D4E3 EA3D=D71D=D9
	A D=	D;
D=E#E3 .E/E3 3F4E3 7D=9D=;D==EEE3 E0E" E0,E3 /F0E3 3FFc                      ^  \ rS rSrSrSSS\R                  SS4S\\-  S\	\   S-  S\
\\4   S-  S\S-  S\S	\S-  S
\\-  S-  4U 4S jjjrSrU =r$ )r)   i  z%Transport for running Python scripts.Nscript_pathr   r   r   
python_cmdr   r   c           	      P  > [        U5      R                  5       nUR                  5       (       d  [        SU 35      e[	        U5      R                  S5      (       d  [        SU 35      e[	        U5      /nU(       a  UR                  U5        [        T	U ]%  UUUUUUS9  Xl
        g)a  
Initialize a Python transport.

Args:
    script_path: Path to the Python script to run
    args: Additional arguments to pass to the script
    env: Environment variables to set for the subprocess
    cwd: Current working directory for the subprocess
    python_cmd: Python command to use (default: "python")
    keep_alive: Whether to keep the subprocess alive between connections.
               Defaults to True. When True, the subprocess remains active
               after the connection context exits, allowing reuse in
               subsequent connections.
    log_file: Optional path or file-like object where subprocess stderr will
           be written. Can be a Path or TextIO object. Defaults to sys.stderr
           if not provided. When a Path is provided, the file will be created
           if it doesn't exist, or appended to if it does. When set, server
           errors will be written to this file instead of appearing in the console.
Script not found: .pyNot a Python script: r   r   r   r   r   r   Nr   resolveis_fileFileNotFoundErrorri   endswithra   extendsuperr|   r   )
rQ   r   r   r   r   r   r   r   	full_argsrW   s
            rH   r|   PythonStdioTransport.__init__  s    : ;'//1""$$#&8$FGG;((//4[MBCC%&	T"! 	 	
 'rG   r   )r;   r<   r=   r>   r?   r   
executableri   r   r   r   r   r   r|   rF   __classcell__rW   s   @rH   r)   r)     s    /
 "&%).."&)-/'4Z/' 3i$/' #s(^d"	/'
 4Z/' /' 4K/' -$&/' /'rG   r)   c                      ^  \ rS rSrSr     SS\\-  S\\   S-  S\\\4   S-  S\S-  S\	S-  S	\\
-  S-  4U 4S
 jjjrSrU =r$ )r%   i  z<Transport for running FastMCP servers using the FastMCP CLI.Nr   r   r   r   r   r   c           	        > [        U5      R                  5       nUR                  5       (       d  [        SU 35      e[	        U5      R                  S5      (       d  [        SU 35      e[        TU ]!  SS[	        U5      /UUUUS9  Xl	        g )Nr   r   r   rt   runr   )
r   r   r   r   ri   r   ra   r  r|   r   )rQ   r   r   r   r   r   r   rW   s          rH   r|   FastMCPStdioTransport.__init__  s     ;'//1""$$#&8$FGG;((//4[MBCC[)*! 	 	
 'rG   r  )NNNNNr;   r<   r=   r>   r?   ri   r   r   r   r   r   r|   rF   r  r  s   @rH   r%   r%     s    F
 "&%)"&)-'4Z' 3i$' #s(^d"	'
 4Z' 4K' -$&' 'rG   r%   c                      ^  \ rS rSrSr      SS\\-  S\\   S-  S\\\4   S-  S\S-  S\S	\	S-  S
\\
-  S-  4U 4S jjjrSrU =r$ )r'   i4  z&Transport for running Node.js scripts.Nr   r   r   r   node_cmdr   r   c           	      P  > [        U5      R                  5       nUR                  5       (       d  [        SU 35      e[	        U5      R                  S5      (       d  [        SU 35      e[	        U5      /nU(       a  UR                  U5        [        T	U ]%  UUUUUUS9  Xl
        g)a  
Initialize a Node transport.

Args:
    script_path: Path to the Node.js script to run
    args: Additional arguments to pass to the script
    env: Environment variables to set for the subprocess
    cwd: Current working directory for the subprocess
    node_cmd: Node.js command to use (default: "node")
    keep_alive: Whether to keep the subprocess alive between connections.
               Defaults to True. When True, the subprocess remains active
               after the connection context exits, allowing reuse in
               subsequent connections.
    log_file: Optional path or file-like object where subprocess stderr will
           be written. Can be a Path or TextIO object. Defaults to sys.stderr
           if not provided. When a Path is provided, the file will be created
           if it doesn't exist, or appended to if it does. When set, server
           errors will be written to this file instead of appearing in the console.
r   .jszNot a JavaScript script: r   Nr   )
rQ   r   r   r   r   r  r   r   r  rW   s
            rH   r|   NodeStdioTransport.__init__7  s    : ;'//1""$$#&8$FGG;((//8FGG%&	T"! 	 	
 'rG   r  )NNNnodeNNr  r  s   @rH   r'   r'   4  s    0
 "&%)"&)-/'4Z/' 3i$/' #s(^d"	/'
 4Z/' /' 4K/' -$&/' /'rG   r'   c                      ^  \ rS rSrSr        SS\S\\   S-  S\S\S-  S\S-  S	\\   S-  S
\S-  S\	\\4   S-  S\S-  4U 4S jjjr
SrU =r$ )r-   ii  z/Transport for running commands via the uv tool.Nr   r   moduleproject_directorypython_versionwith_packageswith_requirementsenv_varsr   c
                   > U(       a#  UR                  5       (       d  [        SU 35      e[        UUUUS S9n
/ nU
R                  5       (       a  S/nU(       a  UR	                  SU/5        U(       a  UR	                  S[        U5      /5        U=(       d    /  H  nUR	                  SU/5        M     U(       a  UR	                  S[        U5      /5        OS/nU(       a  UR                  S5        U(       d  / nUR	                  U/UQ5        S nU(       d  U(       aK  [        R                  R                  5       nU(       a  [        U5      US	'   U(       a  UR                  U5        [        TU ]1  S
UUS U	S9  g )NProject directory not found: )pythondependenciesrequirementsprojecteditabler  --pythonz--directory--withz--with-requirementsz--moduleUV_PROJECT_DIRuvr   r   r   r   r   )existsNotADirectoryErrorr!   _must_run_with_uvr  ri   appendosenvironcopyupdater  r|   )rQ   r   r   r  r  r  r  r  r  r   
env_configuv_argspkgr   rW   s                 rH   r|   UvStdioTransport.__init__l  so    %6%=%=%?%?$/0A/BC 
 #!&*%

   '')) gG
N;< s3D/EFG %**#/ +  5s;L7MNO gGNN:&D'$'( &*(**//#C (+,=(>$%

8$! 	 	
rG   r:   )NFNNNNNN)r;   r<   r=   r>   r?   ri   r   r   r   r   r|   rF   r  r  s   @rH   r-   r-   i  s    9
 "&)-%)*.)-*."&I
I
 3i$I
 	I

  $;I
 d
I
 Cy4'I
  $;I
 sCx.4'I
 4KI
 I
rG   r-   c                      ^  \ rS rSrSr       SS\S\\   S-  S\S-  S\S-  S\\   S-  S	\S-  S
\\\4   S-  S\S-  4U 4S jjjr	Sr
U =r$ )r.   i  z0Transport for running commands via the uvx tool.N	tool_name	tool_argsr  r  r  from_packager  r   c	                   > U(       a,  [        U5      R                  5       (       d  [        SU 35      e/ n	U(       a  U	R                  SU/5        U(       a  U	R                  SU/5        U=(       d    /  H  n
U	R                  SU
/5        M     U	R	                  U5        U(       a  U	R                  U5        SnU(       a/  [
        R                  R                  5       nUR                  U5        [        TU ])  SU	UUUS9  Xl        g)a  
Initialize a Uvx transport.

Args:
    tool_name: Name of the tool to run via uvx
    tool_args: Arguments to pass to the tool
    project_directory: Project directory (for package resolution)
    python_version: Python version to use
    with_packages: Additional packages to include
    from_package: Package to install the tool from
    env_vars: Additional environment variables
    keep_alive: Whether to keep the subprocess alive between connections.
               Defaults to True. When True, the subprocess remains active
               after the connection context exits, allowing reuse in
               subsequent connections.
r  r"  z--fromr#  Nuvxr&  )r   r'  r(  r  r*  r+  r,  r-  r.  r  r|   r4  )rQ   r4  r5  r  r  r  r6  r  r   uvx_argsr1  r   rW   s               rH   r|   UvxStdioTransport.__init__  s    8 T*;%<%C%C%E%E$/0A/BC 
 !OOZ89OOX|45 &B&COOXsO, ' 		"OOI&%)**//#CJJx !! 	 	
 (rG   )r4  )NNNNNNNr;   r<   r=   r>   r?   ri   r   r   r   r|   rF   r  r  s   @rH   r.   r.     s    :
 '+(,%)*.#'*."&;(;( 9t#;( :	;(
 d
;( Cy4';( Dj;( sCx.4';( 4K;( ;(rG   r.   c                   ~   ^  \ rS rSrSr     SS\S\\   S-  S\S-  S\\\4   S-  S\S	\S-  4U 4S
 jjjr	Sr
U =r$ )r(   i  z0Transport for running commands via the npx tool.Npackager   r  r  use_package_lockr   c                   > [         R                  " S5      c  [        S5      eU(       a,  [        U5      R	                  5       (       d  [        SU 35      e/ nU(       a  UR                  S5        UR                  U5        U(       a  UR                  U5        SnU(       a/  [        R                  R                  5       nUR                  U5        [        T	U ]5  SUUUUS9  Xl        g)a8  
Initialize an Npx transport.

Args:
    package: Name of the npm package to run
    args: Arguments to pass to the package command
    project_directory: Project directory with package.json
    env_vars: Additional environment variables
    use_package_lock: Whether to use package-lock.json (--prefer-offline)
    keep_alive: Whether to keep the subprocess alive between connections.
               Defaults to True. When True, the subprocess remains active
               after the connection context exits, allowing reuse in
               subsequent connections.
npxNzCommand 'npx' not foundr  z--prefer-offliner&  )shutilwhichra   r   r'  r(  r*  r  r+  r,  r-  r.  r  r|   r=  )
rQ   r=  r   r  r  r>  r   npx_argsr   rW   s
            rH   r|   NpxStdioTransport.__init__  s    0 <<&677 T*;%<%C%C%E%E$/0A/BC 
 OO./ 	 OOD! **//#CJJx !! 	 	
 rG   )r=  )NNNTNr;  r  s   @rH   r(   r(     sy    :
 "&(,*.!%"&88 3i$8 :	8
 sCx.4'8 8 4K8 8rG   r(   c                   ~    \ rS rSrSrSS\\-  S\4S jjr\	R                  S\\   S\\   4S j5       rS\4S	 jrS
rg)r&   i7  aH  In-memory transport for FastMCP servers.

This transport connects directly to a FastMCP server instance in the same
Python process. It works with both FastMCP 2.x servers and FastMCP 1.0
servers from the low-level MCP SDK. This is particularly useful for unit
tests or scenarios where client and server run in the same runtime.
rC   raise_exceptionsc                     Xl         X l        g)z=Initialize a FastMCPTransport from a FastMCP server instance.N)serverrF  )rQ   rC   rF  s      rH   r|   FastMCPTransport.__init__@  s      0rG   rL   rM   c           
       ^ ^^	#    [        5        IS h  vN u  nnUu  pEUu  mm	[        R                  " 5        IS h  vN n[        T R                  S9 IS h  vN   UR                  U UU	4S j5         [        SUUS.UD6 IS h  vN nU7v   S S S 5      IS h  vN   UR                  R                  5         S S S 5      IS h  vN   S S S 5      IS h  vN   S S S 5      IS h  vN   g  N N N Nj NW! , IS h  vN  (       d  f       Nl= f! UR                  R                  5         f = f Nh! , IS h  vN  (       d  f       N}= f Nt! , IS h  vN  (       d  f       N= f N! , IS h  vN  (       d  f       g = f7f)NrH  c                     > T R                   R                  R                  TTT R                   R                  R                  5       T R                  S9$ )N)rF  )rH  _mcp_serverr  create_initialization_optionsrF  )rQ   server_readserver_writes   rH   <lambda>2FastMCPTransport.connect_session.<locals>.<lambda>Z  sD    DKK3377#$//MMO)-)>)>	 8 rG   )r   r   r:   )	r   r   create_task_group_enter_server_lifespanrH  
start_soonr   cancel_scopecancel)
rQ   rL   client_streamsserver_streamsclient_readclient_writetgclient_sessionrO  rP  s
   `       @@rH   rR    FastMCPTransport.connect_sessionI  s&     788 =
(6%K(6%K ''))R&dkk::-,  $/%1  )    (,,    OO**,' ;: *) 988 *:        OO**,' ;::: *))) 9888s2  FC.F&E+C0E+EC2
ED37D	C4
DC8	DC6
D#D3=ED1	EE+EE+F(E))F0E+2E4D6D8D>D?DDD.	.D31E3E
9D<:E
EE+E&	EE&	"E+)F+F1E42F>Fc                 6    SU R                   R                   S3$ )Nz<FastMCPTransport(server='r   )rH  namerX   s    rH   rY   FastMCPTransport.__repr__l  s    +DKK,<,<+=SAArG   )rF  rH  N)F)r;   r<   r=   r>   r?   r   FastMCP1Serverr   r|   rg   rh   r   r1   r   r   rR   ri   rY   rF   r:   rG   rH   r&   r&   7  sb    1Gn4 1 1 ## - &} 5 -	}	% - $ -DB# BrG   r&   rH  rM   c                   #    [        U [        5      (       a/  U R                  5        ISh  vN   S7v   SSS5      ISh  vN   gS7v   g N  N! , ISh  vN  (       d  f       g= f7f)z`Enters the server's lifespan context for FastMCP servers and does nothing for FastMCP 1 servers.N)rz   r   _lifespan_managerrK  s    rH   rT  rT  p  sD     
 &'""++-- .-- 	 .---sC   *A+AA+AA+AA+A+A(AA($A+c                       \ rS rSrSrSS\\-  S\4S jjr\	R                  S\\   S\\   4S j5       rS	 rS\4S
 jrSrg)MCPConfigTransporti|  a  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 multi-server 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
    from fastmcp.utilities.mcp_config import MCPConfig

    # 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                 :   SSK Jn  [        U[        5      (       a  [        R
                  " U5      nXl        / U l        [        U R                  R                  5      S:X  a  [        S5      e[        U R                  R                  5      S:X  ao  [        [        U R                  R                  R                  5       5      5      R                  5       U l        U R                  R!                  U R                  5        g ["        R$                  " S5      n["        [&           " US9U l        U" U R                  5       HC  u  pEnU R                  R!                  U5        U R(                  R+                  XR(       a  UOS S9  ME     [-        U R(                  S9U l        g )	Nr   )$mcp_config_to_servers_and_transportsz$No MCP servers defined in the config   	MCPRouter)r`  )prefixrC   )fastmcp.utilities.mcp_configrj  rz   r   r   	from_dictrg  _underlying_transportslen
mcpServersra   nextitervaluesto_transportr   r*  r   generate_namer   _composite_servermountr&   )rQ   rg  rh  rj  r`  rH  r   s          rH   r|   MCPConfigTransport.__init__  s<   Ufd##((0F=?# t{{%%&!+CDD ''(A-!$t{{'='='D'D'F"GHUUWDN''..t~~> ((5D%,S\t%<D"+O,'i ++229=&&,,>4t - 	, .$2H2HIDNrG   rL   rM   c                   #    U R                   R                  " S0 UD6 IS h  vN nU7v   S S S 5      IS h  vN   g  N N! , IS h  vN  (       d  f       g = f7f)Nr:   )r   rR   )rQ   rL   r   s      rH   rR   "MCPConfigTransport.connect_session  s;      >>11CNCCwM DCCCCCs@   !A>AAAA A AAA	AAc                 f   #    U R                    H  nUR                  5       I S h  vN   M     g  N	7fr   )rq  r\   )rQ   r   s     rH   r\   MCPConfigTransport.close  s(     44I//### 5#s   #1/
1c                 "    SU R                    S3$ )Nz<MCPConfigTransport(config='r   rg  rX   s    rH   rY   MCPConfigTransport.__repr__  s    -dkk]#>>rG   )ry  rq  rg  r   N)T)r;   r<   r=   r>   r?   r   r   r   r|   rg   rh   r   r1   r   r   rR   r\   ri   rY   rF   r:   rG   rH   rf  rf  |  si    -^Jy4/ J JB ## &} 5	}	% $$?# ?rG   rf  r   c                     g r   r:   r   s    rH   r/   r/         FIrG   c                     g r   r:   r  s    rH   r/   r/     s    =@rG   c                     g r   r:   r  s    rH   r/   r/     s    DGrG   c                     g r   r:   r  s    rH   r/   r/     s    ADrG   c                     g r   r:   r  s    rH   r/   r/     r  rG   c                     g r   r:   r  s    rH   r/   r/     s     .1rG   c                     g r   r:   r  s    rH   r/   r/     s    
 rG   c                     g r   r:   r  s    rH   r/   r/     s    SVrG   c                 (   [        U [        5      (       a  U $ [        U [        [        -  5      (       a'  [	        [        [        [           [        -  U 5      S9nGO[        U [        [        -  5      (       a  [        U 5      R                  5       (       a}  [        U 5      R                  S5      (       a  [        [        [        U 5      S9nGO-[        U 5      R                  S5      (       a  [        [        [        U 5      S9nO[        SU  35      e[        U [        [        -  5      (       a  [        U 5      R                  S5      (       ad  [!        [        [        [        -  U 5      5      nUS:X  a  [#        [        [        [        -  U 5      S9nOh[%        [        [        [        -  U 5      S9nOI[        U [&        [(        -  5      (       a  [+        [        [&        [(        -  U 5      S	9nO[        S
U  35      e[,        R/                  SU 35        U$ )a  
Infer the appropriate transport type from the given transport argument.

This function attempts to infer the correct transport type from the provided
argument, handling various input types and converting them to the appropriate
ClientTransport subclass.

The function supports these input types:
- ClientTransport: Used directly without modification
- FastMCP or FastMCP1Server: Creates an in-memory FastMCPTransport
- Path or str (file path): Creates PythonStdioTransport (.py) or NodeStdioTransport (.js)
- AnyUrl or str (URL): Creates StreamableHttpTransport (default) or SSETransport (for /sse endpoints)
- MCPConfig or dict: Creates MCPConfigTransport, potentially connecting to multiple servers

For HTTP URLs, they are assumed to be Streamable HTTP URLs unless they end in `/sse`.

For MCPConfig with multiple servers, a composite client is created where each server
is mounted with its name as prefix. This allows accessing tools and resources from multiple
servers through a single unified client interface, using naming patterns like
`servername_toolname` for tools and `protocol://servername/path` for resources.
If the MCPConfig contains only one server, a direct connection is established without prefixing.

Examples:
    ```python
    # Connect to a local Python script
    transport = infer_transport("my_script.py")

    # Connect to a remote server via HTTP
    transport = infer_transport("http://example.com/mcp")

    # Connect to multiple servers using MCPConfig
    config = {
        "mcpServers": {
            "weather": {"url": "http://weather.example.com/mcp"},
            "calendar": {"url": "http://calendar.example.com/mcp"}
        }
    }
    transport = infer_transport(config)
    ```
rn  r   r  r  zUnsupported script type: r   sser   r  z(Could not infer a valid transport from: zInferred transport: )rz   r#   r   rb  r&   r	   r   r   ri   r'  r   r)   r'   ra   r   r{   r   r*   r,   r   r   rf  r   r   )r   inferred_transportinferred_transport_types      rH   r/   r/     s   h )_-- 
Iw7	8	8-WS\N2I>

 
Itcz	*	*tI/E/E/G/Gy>""5))!5$tYBW!X^$$U++!3T9@U!V8DEE 
Iv|	,	,Y1J1J61R1R"?#y)#
 #e+!-$v|Y2O!P!8#y1"
 
Iti/	0	0/y()4
 CI;OPP
LL'(:';<=rG   )\re   r   rg   r@   r+  rA  r   rw   collections.abcr   pathlibr   typingr   r   r   r   r	   r
   r   rj   	mcp.typesrC   r   r   mcp.client.sessionr   r   r   r   r   mcp.client.sser   mcp.client.stdior   mcp.client.streamable_httpr   mcp.server.fastmcpr   rb  mcp.shared._httpx_utilsr   mcp.shared.memoryr   pydanticr   typing_extensionsr   r   rt   fastmcp.client.auth.bearerr   fastmcp.client.auth.oauthr   fastmcp.mcp_configr   r   fastmcp.server.dependenciesr   fastmcp.server.serverfastmcp.utilities.loggingr    6fastmcp.utilities.mcp_server_config.v1.environments.uvr!   r;   r   r"   __all__r1   ABCr#   rm   r*   r,   r+   ri   r   r   r   r   r   r)   r%   r'   r-   r.   r(   r&   rh   rT  rf  r/   r:   rG   rH   <module>r     s   
    	  
  )  @ @    4  & ) < 8 8 A  /  1 + G 8 ) 0 P	H	 -5FG  	1IU 	1*Ecgg *EZ$9/ $9NC3? C3LD>o D>N{
_ {
|55
s)5 
c3h$	5 
t	5
 Vmd"5 "5 5 5 NN=15p2'> 2'j'N ':2' 2'jL
~ L
^>( >(B; ;|6B 6Br n$4  ]? ]?@ 
 I/ I4D I 
 I 
 @w @+; @ 
 @ 
 G~ G2B G 
 G 
 Dy D-? D 
 D 
 ItCH~ I2D I 
 I 
11++1 
1
 
 --<?VV 
 
 Vt V(<?Q(Q V 
 V]  	
  38n 

] ]rG   