
    hi                        U d Z ddlZddl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mZ ddlmZ ddlmZ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mZ ddl m!Z! ddl"m#Z#m$Z$ ddl%m&Z& ddl'm(Z( dZ)e*e+d<   	 ddl,m-Z- da1e)rddl,m-Z- ddl2m3Z3m4Z4 ddl5m6Z6 ddl7m8Z8m9Z9m:Z: ddl7m;Z< ddl=m>Z> ddl?m@Z@ ddlAmBZB ddlCmDZD ddlmEZE  G d de<      ZF e-ee       ZGe-e+d!<    eBd"      ZHeBe+d#<    e6eGddd$      ZI e6eGddd$      ZJdaKdaLd% ZMd& ZNej                  d'ed   fd(       ZPeGj                         d'ee<   fd)       ZQeGj                         d*eSd+eeSef   dz  d'eee:e9e8f      fd,       ZT	 dHd-e	e!   d.e	eS   d/e	eeS      d0e	eeSeSf      d'ee<   f
d1ZU	 	 	 	 dId-e	e!   d.e	eS   d/e	eeS      d0e	eeSeSf      d'ee<   f
d2ZVe(	 	 	 	 dId*eSd+e	eeSef      d-e	e!   d.e	eS   d0e	eeSeSf      d3ed'eee:e9e8f      fd4       ZWd*eSd+eeSef   d5e	eS   d'e&fd6ZX	 	 	 dJd*eSd+eeSef   d-e	e!   d.e	eS   d0e	eeSeSf      d'eee:e9e8f      fd7ZYd*eSd+eeSef   d'eee:e9e8f      fd8ZZd9 Z[d:ed;ed<ed'dfd=Z\d:ed;ed<ed'dfd>Z] eeeeeP?      Z^e^j                  d@dAB      d'eeSe*f   fdC       Z`e^j                  dDe\       e^j                  dEe]       e^j                  e3       	 	 	 dJd-e!d.e	eS   d/e	eeS      d0e	eeSeSf      d'df
dFZcd'e
e	e!   e	eS   e	eeS      e	eeSeSf      f   fdGZdy e       Z^y# e.$ r"Z/ ej`                  de/        dZ)Y dZ/[/dZ/[/ww xY w)Kz
LiteLLM MCP Server Routes
    N)datetime)AnyAsyncIteratorDictListOptionalTupleUnion)FastAPIHTTPException)
ConfigDict)ReceiveScopeSend)verbose_logger)Logging)MCPRequestHandler)LITELLM_MCP_SERVER_DESCRIPTIONLITELLM_MCP_SERVER_NAMELITELLM_MCP_SERVER_VERSION)UserAPIKeyAuth)MCPInfo	MCPServer)StandardLoggingMCPToolCall)clientTMCP_AVAILABLE)ServerzMCP module not found: F)AuthContextMiddlewareauth_context_var)StreamableHTTPSessionManager)EmbeddedResourceImageContentTextContent)Tool)MCPAuthenticatedUser)global_mcp_server_manager)SseServerTransport)global_mcp_tool_registry)get_server_name_prefix_tool_mcpc                   8    e Zd ZU dZdZee   ed<    ed      Z	y)!ListMCPToolsRestAPIResponseObjectzD
        Object returned by the /tools/list REST API route.
        Nmcp_infoT)arbitrary_types_allowed)
__name__
__module____qualname____doc__r,   r   r   __annotations__r   model_config     i/var/www/Befach/backend/env/lib/python3.12/site-packages/litellm/proxy/_experimental/mcp_server/server.pyr+   r+   K   s"    	 '+(7#*!$?r5   r+   )nameversionserverz/mcp/sse/messagessse)appevent_storejson_response	statelessc                  :  K   t         ryt        j                  d       t        j	                         at        j	                         at
        j                          d{    t        j                          d{    da t        j                  d       y7 87 w)zFInitialize the session managers. Can be called from main app lifespan.Nz$Initializing MCP session managers...Tz@MCP Server started with StreamableHTTP and SSE session managers!)	_SESSION_MANAGERS_INITIALIZEDr   infosession_managerrun_session_manager_cmsse_session_manager_sse_session_manager_cm
__aenter__r4   r5   r6   initialize_session_managersrH   p   s      )BC .113"5"9"9"; ",,...%00222(,%N	
	 	/2s$   ABBB:B;BBc                  J  K   t         rgt        j                  d       	 t        rt        j	                  ddd       d{    t
        rt
        j	                  ddd       d{    dadada yy7 17 # t        $ r"} t        j                  d|         Y d} ~ 2d} ~ ww xY ww)zShutdown the session managers.z%Shutting down MCP session managers...Nz'Error during session manager shutdown: F)r@   r   rA   rD   	__aexit__rF   	Exception	exception)es    r6   shutdown_session_managersrN      s      ) GHX&-77dDIII*1;;D$MMM #'&*#,1) )
 JM X((+RSTRU)VWWXsQ   B# A5 A1 $A5 $A3%A5 )B#1A5 3A5 5	B >BB#B  B#returnc                   K   t                d{    	 d t                d{    y7 7 # t                d{  7   w xY ww)z%Application lifespan context manager.N)rH   rN   )r;   s    r6   lifespanrQ      s@      *+++	.+---	 	, .+---s<   A
.A
2 A
0A
A
A AAA
c                     K   t               \  } }}}t        j                  d|         t        j                  d|        t        j                  d|rt        |j	                               nd        t        | |||       d{   S 7 w)z*
        List all available tools
        z1MCP list_tools - User API Key Auth from context: z+MCP list_tools - MCP servers from context: z*MCP list_tools - MCP server auth headers: Nuser_api_key_authmcp_auth_headermcp_serversmcp_server_auth_headers)get_auth_contextr   debuglistkeys_list_mcp_toolsrS   s       r6   
list_toolsr]      s      TdSeP?K9P?@Q?RS	
 	9+G	
 	8ax>U>Z>Z>\9]  C  9D  E	
 %/+#$;	
 
 	
 
s   BBBBr7   	argumentsc                 h  K   ddl m} ddlm} ddlm} t               \  }}}}t        j                  d|        	 | |d}	 |ddd	d
gd      }
| ||	|
||       d{   }n|	}t        d|||d| d{   }|S 7  7 # t        $ r}t        j                  d|        |d}~ww xY ww)a  
        Call a specific tool with the provided arguments

        Args:
            name (str): Name of the tool to call
            arguments (Dict[str, Any] | None): Arguments to pass to the tool

        Returns:
            List[Union[MCPTextContent, MCPImageContent, MCPEmbeddedResource]]: Tool execution results

        Raises:
            HTTPException: If tool not found or arguments missing
        r   )Request)add_litellm_data_to_request)proxy_configz;MCP mcp_server_tool_call - User API Key Auth from context: )r7   r^   httpPOSTz/mcp/tools/call)s   content-types   application/json)typemethodpathheaders)scopeN)datarequestuser_api_key_dictrb   )rT   rU   rW   z"MCP mcp_server_tool_call - error: r4   )fastapir`   $litellm.proxy.litellm_pre_call_utilsra   litellm.proxy.proxy_serverrb   rX   r   rY   call_mcp_toolrK   rL   )r7   r^   r`   ra   rb   rT   rU   _rW   	body_datark   rj   responserM   s                 r6   mcp_server_tool_callrt      s     " 	$T; JZI[F?A/FIJ[I\]	
	!%I>I"$- FG	G !,8"#&7!-	  !* "3 /(? 	 H '  	$$'I!%MNG	sL   :B2%B "B#B <B=B B2B B 	B/B**B//B2rT   rU   rV   rW   c           
        K   t         sg S t        j                  |        d{   }|W|D cg c]  }|j                          c}|D cg c]-  t	        fdt        j
                        fD              r/ }}g }|D ]  t        j
                        }|d}	|r(|j                  |j                  |j                        }	n)|r'|j                  |j                  |j                        }	|	|}		 t        j                  ||	       d{   }
|j                  |
       t        j                  dt        |
       d|j                           t        j$                  dt        |       d       |S 7 [c c}w c c}w 7 v# t        $ r9}t        j                   d|j                   dt#        |              Y d}~Ed}~ww xY ww)	a  
        Helper method to fetch tools from MCP servers based on server filtering criteria.

        Args:
            user_api_key_auth: User authentication info for access control
            mcp_auth_header: Optional auth header for MCP server (deprecated)
            mcp_servers: Optional list of server names/aliases to filter by
            mcp_server_auth_headers: Optional dict of server-specific auth headers {server_alias: auth_value}

        Returns:
            List[MCPTool]: Combined list of tools from filtered servers
        Nc              3      K   | ]8  }|4|j                   |j                  fD ]  }||j                         v   : y wN)aliasserver_namelower).0r9   server_aliasmcp_servers_lower	server_ids      r6   	<genexpr>z._get_tools_from_mcp_servers.<locals>.<genexpr>%  s`      
)**!)	
 %
 $/ !&&(,==
=
s   >A)r9   rU   zSuccessfully fetched z tools from server z Error getting tools from server z: z! tools total from all MCP servers)r   r&   get_allowed_mcp_serversrz   anyget_mcp_server_by_idrx   getry   _get_tools_from_serverextendr   rY   lenr7   rK   rL   strrA   )rT   rU   rV   rW   allowed_mcp_serverssr~   	all_toolsr9   server_auth_headertoolsrM   r}   s         `     @r6   _get_tools_from_mcp_serversr     s    $ I %>$U$U%
 

 "4? @q @ "5# 
#<#Q#QR[#\"]
 
 # #" 	,I.CCINF~ "&&6<<+C%<%@%@%N"(V-?-?-K%<%@%@ASAS%T" ")%4"
7NN!$6    '$$'<SZLH[\b\g\g[h%ij- -: 	3C	N3CCdefq
 !A#F  ((6v{{m2c!fXN sj   !GF 
GFG2FA:G<FFAF'G
GF	G.GGGGc                   K   t         sg S t        | |||       d{   }t        j                         }g }|D ]?  }t	        |j
                  |j                  |j                        }|j                  |       A ||z   }	|	S 7 ew)a  
        List all available MCP tools.

        Args:
            user_api_key_auth: User authentication info for access control
            mcp_auth_header: Optional auth header for MCP server (deprecated)
            mcp_servers: Optional list of server names/aliases to filter by
            mcp_server_auth_headers: Optional dict of server-specific auth headers {server_alias: auth_value}

        Returns:
            List[MCPTool]: Combined list of tools from all accessible servers
        rS   N)r7   descriptioninputSchema)	r   r   r(   r]   MCPToolr7   r   input_schemaappend)
rT   rU   rV   rW   managed_toolslocal_tools_rawlocal_toolstoolmcp_toolr   s
             r6   r\   r\   T  s     $ I :/+#$;	
 
 3==? #DYY ,, --H
 x( $ "K/	1
s   BBA&Bkwargsc                 8  K   t        j                         }|t        dd      t        |       \  }}t	        |||      }	|j                  dd      }
|
r|	|
j                  d<   d|  |
_        t        j                  |       }|r;|j                  xs i j                  d	      |	d	<   t        | ||||
       d{   }nt        ||       d{   }|
r;t        j                         }|
j                  |
j                  |||       d{    |S 7 X7 E7 
w)z`
        Call a specific tool with the provided arguments (handles prefixed tool names)
        Ni  zRequest arguments are requiredstatus_codedetail)r7   r^   ry   litellm_logging_objmcp_tool_call_metadatazMCP: mcp_server_cost_infor7   r^   rT   rU   rW   )r   response_obj
start_timeend_time)r   nowr   r)   #_get_standard_logging_mcp_tool_callr   model_call_detailsmodelr&   _get_mcp_server_from_tool_namer,   _handle_managed_mcp_tool_handle_local_mcp_toolasync_post_mcp_tool_call_hook)r7   r^   rT   rU   rW   r   r   original_tool_nameserver_name_from_prefixstandard_logging_mcp_tool_callr   
mcp_serverrs   r   s                 r6   rp   rp     se     \\^
(H 
 7V7
33
 0'#3 	' <B::!4<
 .  223KL +0v%
 &DDTJ 	 ##)rc() ++AB 7#"3 /(? H 44F	RRH ||~H%CC*==%%!	 D    7 Ss6   B9D;D<DD<DDDDDry   c           	          t        j                  |       }|rL|j                  xs i }t        | ||j	                  d      |j	                  d      |r| d|        S |       S t        | ||r| d|        S |       S )Nry   logo_url/)r7   r^   mcp_server_namemcp_server_logo_urlnamespaced_tool_name)r7   r^   r   )r&   r   r,   r   r   )r7   r^   ry   r   r,   s        r6   r   r     s    
 /MMdS
!**0bH-# (] ;$,LL$<@K}AdV%< 
 RV  .#@K}AdV%<  RV r5   c                    K   t        j                  | ||||       d{   }t        j                  d|       |j                  S 7 &w)z.Handle tool execution for managed server toolsr   NzCALL TOOL RESULT: %s)r&   	call_toolr   rY   content)r7   r^   rT   rU   rW   call_tool_results         r6   r   r     sR      ";!D!D/+$;"
 
 	35EF'''
s   A	A'A	c                   K   t        j                  |       }|st        dd|  d      	  |j                  d	i |}t	        t        |      d      gS # t        $ r$}t	        dt        |       d      gcY d}~S d}~ww xY ww)
z
        Handle tool execution for local registry tools
        Note: Local tools don't use prefixes, so we use the original name
        i  zTool 'z' not foundr   text)r   re   zError: Nr4   )r(   get_toolr   handlerr#   r   rK   )r7   r^   r   resultrM   s        r6   r   r     s      (006C&k8RSS	G!T\\.I.FS[v>?? 	Gws1vh%7fEFF	Gs4   )B(A B	BA=7B8B=BBc                   K   ddl }d}|j                  d|      }|rP|j                  d      }|r=|j                  d      D cg c]#  }|j	                         s|j	                         % }}|%t        j                  |        d{   \  }}}	}
|}n"t        j                  |        d{   \  }}}}
||||
fS c c}w 7 97 w)z
        Extracts mcp_servers from the path and processes the MCP request for auth context.
        Returns: (user_api_key_auth, mcp_auth_header, mcp_servers, mcp_server_auth_headers)
        r   Nz^/mcp/([^/]+)(/.*)?$   ,)rematchgroupsplitstripr   process_mcp_request)ri   rg   r   mcp_servers_from_pathmcp_path_matchmcp_servers_strr   rT   rU   rq   rW   rV   s               r6   extract_mcp_auth_contextr   
  s     
 	 $"94@,2215O<K<Q<QRU<V(dqZ[ZaZaZc(d%(d ,';;EBB K3J 0K (;;EBB U=T !/;@WWW )e C
 Cs6   ACB<B<+CC$C,C-CCri   receivesendc                 &  K   	 | j                  dd      }t        | |       d{   \  }}}}t        j                  d|        t        j                  d|rt	        |j                               nd        t        ||||       t        s/t                d{    t        j                  d       d{    t        j                  | ||       d{    y7 7 C7 (7 # t        $ r}t        j                  d|        |d}~ww xY ww)	z+Handle MCP requests through StreamableHTTP.rg    N'MCP request mcp_servers (header/path): MCP server auth headers: rS   皙?Error handling MCP request: )r   r   r   rY   rZ   r[   set_auth_contextr@   rH   asynciosleeprB   handle_requestrK   rL   	ri   r   r   rg   rT   rU   rV   rW   rM   s	            r6   handle_streamable_http_mcpr   "  s     	99VR(D]uv{  ~B  ^C  XCT=T  #J;-!XY  #<e|TBYB^B^B`=a  CG  =H  "I  J"3 /'(?	 11333mmC(((!00FFF# XC 4(F 	$$'CA3%GHG	o   D!C& CA6C& C C& 9C":C& C$C& DC&  C& "C& $C& &	D/D		DDc                 &  K   	 | j                  dd      }t        | |       d{   \  }}}}t        j                  d|        t        j                  d|rt	        |j                               nd        t        ||||       t        s/t                d{    t        j                  d       d{    t        j                  | ||       d{    y7 7 C7 (7 # t        $ r}t        j                  d|        |d}~ww xY ww)	z Handle MCP requests through SSE.rg   r   Nr   r   rS   r   r   )r   r   r   rY   rZ   r[   r   r@   rH   r   r   rE   r   rK   rL   r   s	            r6   handle_sse_mcpr   >  s     	99VR(D]uv{  ~B  ^C  XCT=T  #J;-!XY  #<e|TBYB^B^B`=a  CG  =H  "I  J"3 /'(?	 11333mmC(((%44UGTJJJ XC 4(J 	$$'CA3%GHG	r   )titler   r8   rQ   z/enabledz$Returns if the MCP server is enabled)r   c                      dt         iS )z6
        Returns if the MCP server is enabled
        enabled)r   r4   r5   r6   get_mcp_server_enabledr   ]  s     =))r5   r   z/ssec                 L    t        | |||      }t        j                  |       y)a  
        Set the UserAPIKeyAuth in the auth context variable.

        Args:
            user_api_key_auth: UserAPIKeyAuth object
            mcp_auth_header: MCP auth header to be passed to the MCP server (deprecated)
            mcp_servers: Optional list of server names and access groups to filter by
            mcp_server_auth_headers: Optional dict of server-specific auth headers {server_alias: auth_value}
        rS   N)r%   r   set)rT   rU   rV   rW   	auth_users        r6   r   r   p  s*     )/+#$;	
	 	Y'r5   c                      t        j                         } | r>t        | t              r.| j                  | j
                  | j                  | j                  fS y)aQ  
        Get the UserAPIKeyAuth from the auth context variable.

        Returns:
            Tuple[Optional[UserAPIKeyAuth], Optional[str], Optional[List[str]], Optional[Dict[str, str]]]: 
            UserAPIKeyAuth object, MCP auth header (deprecated), MCP servers (can include access groups), and server-specific auth headers
        NNNN)r   r   
isinstancer%   rT   rU   rV   rW   )r   s    r6   rX   rX     sR     %((*	I/CD++))%%11	  &r5   rw   r   )NNN)er1   r   
contextlibr   typingr   r   r   r   r   r	   r
   rm   r   r   pydanticr   starlette.typesr   r   r   litellm._loggingr   *litellm.litellm_core_utils.litellm_loggingr   LiteLLMLoggingObjAlitellm.proxy._experimental.mcp_server.auth.user_api_key_auth_mcpr   ,litellm.proxy._experimental.mcp_server.utilsr   r   r   litellm.proxy._typesr   +litellm.types.mcp_server.mcp_server_managerr   r   litellm.types.utilsr   litellm.utilsr   r   boolr2   
mcp.serverr   ImportErrorrM   rY   r@   'mcp.server.auth.middleware.auth_contextr   r   "mcp.server.streamable_http_managerr    	mcp.typesr!   r"   r#   r$   r   @litellm.proxy._experimental.mcp_server.auth.litellm_auth_handlerr%   9litellm.proxy._experimental.mcp_server.mcp_server_managerr&   4litellm.proxy._experimental.mcp_server.sse_transportr'   4litellm.proxy._experimental.mcp_server.tool_registryr(   r)   r+   r9   r:   rB   rE   rD   rF   rH   rN   asynccontextmanagerrQ   r]   r   r   rt   r   r\   rp   r   r   r   r   r   r   r;   r   r   mountadd_middlewarer   rX   r4   r5   r6   <module>r     s      I I I *  0 0 + S 
 0 J :   t ! !& ! PEE) X@G @ $*FF  11DEC	E 3	O 7	 "
,2& ##.}T2 . $. 
d7m 
 
. ;;"38nt3;	eK/??@	A; ;R =A	N#N3N!#N d3i(N "*$sCx.!9	N
 
gNb 7;)-+/<@	.#N3.!#. d3i(. "*$sCx.!9	.
 
g.`  37:>-1@DJJS#X/J  (7J &c]	J
 &.d38n%=J J 
eK/??@	AJ JXS> c] 
$	2 7;)-<@((S>( $N3( "#	(
 "*$sCx.!9( 
eK/??@	A($GG"38nG	eK/??@	AG"X0&.2	8E G 4 D . %2*	C 	WW:  *DdO *	* IIc-.IIfn%,- *.+/<@	()(!#( d3i(( "*$sCx.!9	(
 
(.&h~&xS	7JHUYZ]_bZbUcLdde&2 )Cy  N1!56Ms   :L$ $M)MM