
    .h/                       d dl mZ d dlZd dlZd dlmZmZ d dlmZ d dl	m
Z
 d dlmZmZ d dlmZmZ d dlmZmZmZmZ d d	lmZ d d
lmZmZ d dlmZmZ ddlm Z  ddl!m!Z!  G d dej"                  Z# G d de#ej"                  Z$ G d de          Z% G d de$          Z& G d de          Z' G d de$          Z(dS )    )annotationsN)AbstractAsyncContextManagerAsyncExitStack)	timedelta)Path)AnyLiteral)MemoryObjectReceiveStreamMemoryObjectSendStream)ClientSessionStdioServerParametersToolstdio_client)
sse_client)CallToolResultJSONRPCMessage)NotRequired	TypedDict   )	UserError)loggerc                      e Zd ZdZej        d             Zeej        dd                        Zej        d             Z	ej        dd            Z
ej        dd            ZdS )	MCPServerz.Base class for Model Context Protocol servers.c                
   K   dS )zConnect to the server. For example, this might mean spawning a subprocess or
        opening a network connection. The server is expected to remain connected until
        `cleanup()` is called.
        N selfs    N/var/www/FlaskApp/flask-venv/lib/python3.11/site-packages/agents/mcp/server.pyconnectzMCPServer.connect   s       	    returnstrc                    dS )A readable name for the server.Nr   r   s    r   namezMCPServer.name   s	     	r    c                
   K   dS )zwCleanup the server. For example, this might mean closing a subprocess or
        closing a network connection.
        Nr   r   s    r   cleanupzMCPServer.cleanup%   s      
 	r    list[MCPTool]c                
   K   dS )'List the tools available on the server.Nr   r   s    r   
list_toolszMCPServer.list_tools,          	r    	tool_name	argumentsdict[str, Any] | Noner   c                
   K   dS )Invoke a tool on the server.Nr   r   r-   r.   s      r   	call_toolzMCPServer.call_tool1   r,   r    Nr!   r"   r!   r(   r-   r"   r.   r/   r!   r   )__name__
__module____qualname____doc__abcabstractmethodr   propertyr%   r'   r+   r3   r   r    r   r   r      s        88       X 	   	    	     r    r   c                  j    e Zd ZdZddZej        dd	            Zd
 Zd Z	d Z
d ZddZddZd ZdS )_MCPServerWithClientSessionzUBase class for MCP servers that use a `ClientSession` to communicate with the server.cache_tools_listboolclient_session_timeout_secondsfloat | Nonec                    d| _         t                      | _        t          j                    | _        || _        || _        d| _        d| _	        dS )a  
        Args:
            cache_tools_list: Whether to cache the tools list. If `True`, the tools list will be
            cached and only fetched from the server once. If `False`, the tools list will be
            fetched from the server on each call to `list_tools()`. The cache can be invalidated
            by calling `invalidate_tools_cache()`. You should set this to `True` if you know the
            server will not change its tools list, because it can drastically improve latency
            (by avoiding a round-trip to the server every time).

            client_session_timeout_seconds: the read timeout passed to the MCP ClientSession.
        NT)
sessionr   
exit_stackasyncioLock_cleanup_lockr@   rB   _cache_dirty_tools_list)r   r@   rB   s      r   __init__z$_MCPServerWithClientSession.__init__:   sN     .2*8*:*:+2<>> 0.L+ !15r    r!   AbstractAsyncContextManager[tuple[MemoryObjectReceiveStream[JSONRPCMessage | Exception], MemoryObjectSendStream[JSONRPCMessage]]]c                    dS )"Create the streams for the server.Nr   r   s    r   create_streamsz*_MCPServerWithClientSession.create_streamsQ   s	     	r    c                >   K   |                                   d {V  | S N)r   r   s    r   
__aenter__z&_MCPServerWithClientSession.__aenter__]   s+      llnnr    c                >   K   |                                   d {V  d S rR   )r'   )r   exc_type	exc_value	tracebacks       r   	__aexit__z%_MCPServerWithClientSession.__aexit__a   s,      llnnr    c                    d| _         dS )zInvalidate the tools cache.TN)rJ   r   s    r   invalidate_tools_cachez2_MCPServerWithClientSession.invalidate_tools_cached   s     r    c           	       K   	 | j                             |                                            d{V }|\  }}| j                             t          ||| j        rt          | j                  nd                     d{V }|                                 d{V  || _        dS # t          $ r7}t          j
        d|            |                                  d{V   d}~ww xY w)zConnect to the server.N)secondszError initializing MCP server: )rF   enter_async_contextrP   r   rB   r   
initializerE   	Exceptionr   errorr'   )r   	transportreadwriterE   es         r   r   z#_MCPServerWithClientSession.connecth   s<     	"oAA$BUBUBWBWXXXXXXXXI#KD% O??:Id&IJJJJ        G $$&&&&&&&&&"DLLL 	 	 	L>1>>???,,..       	s   B#B) )
C*32C%%C*r(   c                   K   | j         st          d          | j        r| j        s| j        r| j        S d| _        | j                                          d{V j        | _        | j        S )r*   =Server not initialized. Make sure you call `connect()` first.FN)rE   r   r@   rJ   rK   r+   toolsr   s    r   r+   z&_MCPServerWithClientSession.list_tools}   s      | 	][\\\   	$): 	$t?O 	$## " #',"9"9";";;;;;;;Br    r-   r"   r.   r/   r   c                t   K   | j         st          d          | j                             ||           d{V S )r1   rf   N)rE   r   r3   r2   s      r   r3   z%_MCPServerWithClientSession.call_tool   sJ      | 	][\\\\++IyAAAAAAAAAr    c                6  K   | j         4 d{V  	 | j                                         d{V  n.# t          $ r!}t	          j        d|            Y d}~nd}~ww xY wd| _        n# d| _        w xY w	 ddd          d{V  dS # 1 d{V swxY w Y   dS )zCleanup the server.NzError cleaning up server: )rI   rF   acloser_   r   r`   rE   )r   rd   s     r   r'   z#_MCPServerWithClientSession.cleanup   sc     % 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$$o,,.......... ? ? ?=!==>>>>>>>>?  $t#####	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$sH   B2A(
AAA(AA( B(	A11B
BBN)r@   rA   rB   rC   r!   rM   r5   r6   )r7   r8   r9   r:   rL   r;   r<   rP   rS   rX   rZ   r   r+   r3   r'   r   r    r   r?   r?   7   s        __6 6 6 6. 		 	 	 	    ! ! !  *        B B B B$ $ $ $ $r    r?   c                  Z    e Zd ZU dZded<   	 ded<   	 ded<   	 ded	<   	 d
ed<   	 ded<   dS )MCPServerStdioParamszkMirrors `mcp.client.stdio.StdioServerParameters`, but lets you pass params without another
    import.
    r"   commandzNotRequired[list[str]]argsNotRequired[dict[str, str]]envzNotRequired[str | Path]cwdzNotRequired[str]encodingz3NotRequired[Literal['strict', 'ignore', 'replace']]encoding_error_handlerNr7   r8   r9   r:   __annotations__r   r    r   rm   rm      sz           LLLU    * %$$$<    AdOOOO r    rm   c                  L     e Zd ZdZ	 	 	 dd fdZddZedd            Z xZS )MCPServerStdiozMCP server implementation that uses the stdio transport. See the [spec]
    (https://spec.modelcontextprotocol.io/specification/2024-11-05/basic/transports/#stdio) for
    details.
    FN   paramsrm   r@   rA   r%   
str | NonerB   rC   c                |   t                                          ||           t          |d         |                    dg           |                    d          |                    d          |                    dd          |                    dd          	          | _        |pd
| j        j         | _        dS )a  Create a new MCP server based on the stdio transport.

        Args:
            params: The params that configure the server. This includes the command to run to
                start the server, the args to pass to the command, the environment variables to
                set for the server, the working directory to use when spawning the process, and
                the text encoding used when sending/receiving messages to the server.
            cache_tools_list: Whether to cache the tools list. If `True`, the tools list will be
                cached and only fetched from the server once. If `False`, the tools list will be
                fetched from the server on each call to `list_tools()`. The cache can be
                invalidated by calling `invalidate_tools_cache()`. You should set this to `True`
                if you know the server will not change its tools list, because it can drastically
                improve latency (by avoiding a round-trip to the server every time).
            name: A readable name for the server. If not provided, we'll create one from the
                command.
            client_session_timeout_seconds: the read timeout passed to the MCP ClientSession.
        rn   ro   rq   rr   rs   zutf-8rt   strict)rn   ro   rq   rr   rs   rt   zstdio: N)superrL   r   getrz   rn   _namer   rz   r@   r%   rB   	__class__s        r   rL   zMCPServerStdio.__init__   s    0 	)+IJJJ+9%FB''

5!!

5!!ZZ
G44#)::.F#Q#Q
 
 
 <<t{':<<


r    r!   rM   c                *    t          | j                  S )rO   )r   rz   r   s    r   rP   zMCPServerStdio.create_streams   s     DK(((r    r"   c                    | j         S r$   r   r   s    r   r%   zMCPServerStdio.name        zr    FNry   )rz   rm   r@   rA   r%   r{   rB   rC   rk   r4   	r7   r8   r9   r:   rL   rP   r=   r%   __classcell__r   s   @r   rx   rx      s          "'78#= #= #= #= #= #= #=J	) 	) 	) 	)    X    r    rx   c                  B    e Zd ZU dZded<   	 ded<   	 ded<   	 ded<   d	S )
MCPServerSseParamsz1Mirrors the params in`mcp.client.sse.sse_client`.r"   urlrp   headerszNotRequired[float]timeoutsse_read_timeoutNru   r   r    r   r   r      sN         ;;HHH ((((,B((((PPr    r   c                  L     e Zd ZdZ	 	 	 dd fdZddZedd            Z xZS )MCPServerSsezMCP server implementation that uses the HTTP with SSE transport. See the [spec]
    (https://spec.modelcontextprotocol.io/specification/2024-11-05/basic/transports/#http-with-sse)
    for details.
    FNry   rz   r   r@   rA   r%   r{   rB   rC   c                    t                                          ||           || _        |pd| j        d          | _        dS )aG  Create a new MCP server based on the HTTP with SSE transport.

        Args:
            params: The params that configure the server. This includes the URL of the server,
                the headers to send to the server, the timeout for the HTTP request, and the
                timeout for the SSE connection.

            cache_tools_list: Whether to cache the tools list. If `True`, the tools list will be
                cached and only fetched from the server once. If `False`, the tools list will be
                fetched from the server on each call to `list_tools()`. The cache can be
                invalidated by calling `invalidate_tools_cache()`. You should set this to `True`
                if you know the server will not change its tools list, because it can drastically
                improve latency (by avoiding a round-trip to the server every time).

            name: A readable name for the server. If not provided, we'll create one from the
                URL.

            client_session_timeout_seconds: the read timeout passed to the MCP ClientSession.
        zsse: r   N)r~   rL   rz   r   r   s        r   rL   zMCPServerSse.__init__  sH    4 	)+IJJJ99T[%799


r    r!   rM   c           	         t          | j        d         | j                            dd          | j                            dd          | j                            dd                    S )	rO   r   r   Nr   ry   r   i,  )r   r   r   r   )r   rz   r   r   s    r   rP   zMCPServerSse.create_streams-  s_     E"KOOIt44KOOIq11![__-?HH	
 
 
 	
r    r"   c                    | j         S r   r   r   s    r   r%   zMCPServerSse.name=  r   r    r   )rz   r   r@   rA   r%   r{   rB   rC   rk   r4   r   r   s   @r   r   r     s          "'78: : : : : : :>
 
 
 
     X    r    r   ))
__future__r   r;   rG   
contextlibr   r   datetimer   pathlibr   typingr   r	   anyio.streams.memoryr
   r   mcpr   r   r   MCPToolr   mcp.client.sser   	mcp.typesr   r   typing_extensionsr   r   
exceptionsr   r   ABCr   r?   rm   rx   r   r   r   r    r   <module>r      s@   " " " " " " 



  B B B B B B B B                     R R R R R R R R S S S S S S S S S S S S % % % % % % 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 " " " " " "                     Fe$ e$ e$ e$ e$)SW e$ e$ e$P    9   :9 9 9 9 90 9 9 9xQ Q Q Q Q Q Q Q 8 8 8 8 8. 8 8 8 8 8r    