
    hS              
       
   U d Z ddlZddlmZmZmZmZmZ ddlm	Z	m
Z
mZmZmZmZ ddlmZ ddlZddlmZmZ ddlmZ ddlmZ  e	d	d
g      ZdZeed<   	  ej:                  d
       erddl!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z( ddl)m*Z* ddl+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1 ddl2m3Z3 ddl4m5Z5 ddl6m7Z7 de8fdZ9dee,   de8defdZ:ejw                  dd
g e
e3      g       e
e3      fde1fd       Z<ejw                  d d
g e
e3      g       e
e3      fde1fd!       Z=ejw                  d"d# e
e3      gee,   $       e
e3      fde1fd%       Z>ejw                  d&d' e
e3      ge,$       e
e3      fd(e8de1fd)       Z?ej                  d"d* e
e3      ge,ej                  +      e7 e
e3       edd,-      fd.e.de1d/ee8   fd0              ZBej                  d&d1 e
e3      geej                  2      e7 e
e3       edd,-      fd(e8de1d/ee8   fd3              ZEej                  d"d1 e
e3      ge,ej                  +      e7 e
e3       edd,-      fd.e0de1d/ee8   fd4              ZGyy# e$ r"Z ej@                  de        dZY dZ[dZ[ww xY w)5aV  
1. Allow proxy admin to perform create, update, and delete operations on MCP servers in the db.
2. Allows users to view the mcp servers they have access to.

Endpoints here:
- GET `/v1/mcp/server` - Returns all of the configured mcp servers in the db filtered by requestor's access
- GET `/v1/mcp/server/{server_id}` - Returns the the specific mcp server in the db given `server_id` filtered by requestor's access
- GET `/v1/mcp/server/{server_id}/tools` - Get all the tools from the mcp server specified by the `server_id`
- POST `/v1/mcp/server` - Add a new external mcp server.
- PUT `/v1/mcp/server` -  Edits an existing mcp server.
- DELETE `/v1/mcp/server/{server_id}` - Deletes the mcp server given `server_id`.
- GET `/v1/mcp/tools - lists all the tools available for a key
- GET `/v1/mcp/access_groups` - lists all available MCP access groups

    N)DictIterableListOptionalcast)	APIRouterDependsHeaderHTTPExceptionResponsestatus)JSONResponse)verbose_loggerverbose_proxy_logger)LITELLM_PROXY_ADMIN_NAME))validate_and_normalize_mcp_server_payloadz/v1/mcpmcp)prefixtagsTMCP_AVAILABLEzMCP module not found: F)create_mcp_serverdelete_mcp_serverget_all_mcp_serversget_all_mcp_servers_for_userget_mcp_serverget_mcp_serversupdate_mcp_serverglobal_mcp_server_manager)LiteLLM_MCPServerTableLitellmUserRolesNewMCPServerRequestSpecialMCPServerNameUpdateMCPServerRequestUserAPIKeyAuthuser_api_key_auth)_user_has_admin_view)management_endpoint_wrappermessagec                 P    ddl m} |t        t        j                  d| i      |S )Nr   prisma_clienterrorstatus_codedetail)litellm.proxy.proxy_serverr-   r   r   HTTP_500_INTERNAL_SERVER_ERROR)r*   r-   s     w/var/www/Befach/backend/env/lib/python3.12/site-packages/litellm/proxy/management_endpoints/mcp_management_endpoints.pyget_prisma_client_or_throwr5   @   s1    < "AA)      mcp_server_recordsmcp_server_idreturnc                 4    | D ]  }|j                   |k(  s y y)za
        Check if the mcp server with the given id exists in the iterable of mcp servers
        TF)	server_id)r7   r8   mcp_server_records      r4   does_mcp_server_existr=   J   s%     "4 **m; "4 r6   z/tools)r   dependenciesuser_api_key_dictc                    K   ddl m} ddlm} |j	                  |        d{   }g }|D ]+  }|j                   |j                  |       d{          - t        j                  d|        d|iS 7 R7 (w)ze
        Get all MCP tools available for the current key, including those from access groups
        r   )MCPRequestHandlerr   NzAvailable tools: tools)	Alitellm.proxy._experimental.mcp_server.auth.user_api_key_auth_mcprA   9litellm.proxy._experimental.mcp_server.mcp_server_managerr    _get_allowed_mcp_servers_for_keyextendget_tools_for_serverr   debug)r?   rA   r   
server_idsrB   r;   s         r4   get_mcp_toolsrJ   X   s     	
	

 -MMN_``
#ILLM8MMiXXY $ 	""%6ug#>? a Ys!   !A:A6+A:A8
'A:8A:z/access_groupsc                 ,  K   ddl m} ddlm} t	               }|j
                  j                         D ]*  }|j                  s|j                  |j                         , |j	 |j                  j                  j                          d{   }|D ]7  }t        |d      s|j                  s|j                  |j                         9 	 t#        t%        |            }d|iS 7 Y# t        $ r"}t        j                   d|        Y d}~@d}~ww xY ww)zR
        Get all available MCP access groups from the database AND config
        r   r,   r   Nmcp_access_groupsz!Error getting MCP access groups: access_groups)r2   r-   rD   r   setconfig_mcp_serversvaluesrM   updatedblitellm_mcpservertable	find_manyhasattrrL   	Exceptionr   rH   sortedlist)r?   r-   r   rM   servermcp_serverseaccess_groups_lists           r4   get_mcp_access_groupsr]   u   s      	=g 0BBIIKF##$$V%9%9: L
 $T$1$4$4$K$K$U$U$WW)Fv':;@X@X%,,V-E-EF * $D$78!344 X  T$**-Nqc+RSSTsT   A DD#'C& 
C$C& !C& .C& D$C& &	D/DDDDz/serverz1Returns the mcp server list with associated teams)descriptionr>   response_modelc                 x  K   ddl m } t        d      }g }|j                  j                  j	                  ddi       d{   }t        |       r|}nT|D ]O  }|j                  s|j                  D ]1  }d|v s|d   |d   | j                  k(  s!|j                  |       3 Q i }|D ]  }|j                  s|j                  j                  s'|j                  j                  D ]A  }||vrg ||<   ||   j                  |j                  |j                  |j                  d	       C  g }	|D ]K  }|j                  s|j                  j                  s'|	j                  |j                  j                         M t        ||	       d{   }
t        |       r:t!        |       d{   }|D ]"  }|j"                  |	vs|
j                  |       $ t%        j&                  | 
       d{   }t$        j(                  }|j+                         D ]  \  }}||v s|
j                  t-        ||j.                  |j0                  |j2                  |j4                  |j6                  |j8                  |j;                         |j;                         |j<                  t?        |dd      t?        |dd      xs g t?        |dd      xs i               |
D cg c]D  }t-        di d|j"                  d|j@                  d|j0                  d|jB                  d|j2                  d|j4                  d|j6                  d|j8                  d|jD                  d|jF                  d|jH                  d|jJ                  d|jL                  |jL                  ng d|j<                  dtO        tP        tR        tT        tT        dz  f      |jW                  |j"                  g             dt?        |dd      dt?        |dd      xs g dt?        |dd      xs i G }
}|
S 7 7 7 7 ?c c}w w)z
        Get all of the configured mcp servers for the user in the db with their associated teams
        ```
        curl --location 'http://localhost:4000/v1/mcp/server'         --header 'Authorization: Bearer your_api_key_here'
        ```
        r   )datetime8Database not connected. Connect a database to your proxyobject_permissionT)includeNuser_id)team_id
team_aliasorganization_idr&   commandargsenv)r;   server_namealiasurl	transportspec_version	auth_type
created_at
updated_atmcp_infori   rj   rk   r;   rl   rm   r^   rn   ro   rp   rq   rr   
created_byrs   
updated_byrL   rt   teams ),ra   r5   rR   litellm_teamtablerT   r(   members_with_rolesre   appendrc   rZ   rf   rg   rh   rF   r   r   r;   r   get_allowed_mcp_serversrO   itemsr    namerm   rn   ro   rp   rq   nowrt   getattrrl   r^   rr   ru   rs   rv   rL   r   r   r   strget)r?   ra   r-   
user_teamsrw   teammemberserver_to_teams_mapr;   mcp_server_idsLIST_MCP_SERVERSall_mcp_serversrY   ALLOWED_MCP_SERVER_IDSALL_CONFIG_MCP_SERVERS
_server_id_server_configs                    r4   fetch_all_mcp_serversr      sf      	&2F

 
#&&88BB' C  
   12J**"&"9"9%/ &y 1 = &y 15F5N5N N&--d3 #:  @BD%%$*@*@*L*L!%!7!7!C!CI (;;9;+I6'	299#'<<&*oo+/+?+?;  "D  D%%$*@*@*L*L%%d&<&<&H&HI  "1!OO 12$7$FFO)##>9$++F3 * ,CC"3  	
 ";!M!M*@*F*F*H&J33 ''*",$2$7$7,22*.."0":":%3%@%@"0":":#+<<>#+<<>!/!8!8 '	4 H$^VTBHb#NE4@FB +IX +-
, + #  **".. ll #..	
 JJ !** $00 !** ",, ",, ",, ",, ?E>V>V>b&":":hj   4S#*_ 568K8O8OPVP`P`bd8ef"  	48#$ VVT28b%& FE406B'
 
2  OP P G6
s   ?P:P)#P:&P::P: P:(P:<P:A/P:P:6P:P,P:.P//P:,P:3P24.P:#B8P:E
P5%P:,P:/P:2P:5P:z/server/{server_id}zReturns the mcp server infor;   c                 d  K   t        d      }t        ||        d{   }|!t        t        j                  dd|  di      t        |      r|S t        ||       d{   }t        ||       }|rt        j                  |       |S t        t        j                  dd|  di      7 7 Lw)	aY  
        Get the info on the mcp server specified by the `server_id`
        Parameters:
        - server_id: str - Required. The unique identifier of the mcp server to get info on.
        ```
        curl --location 'http://localhost:4000/v1/mcp/server/server_id'         --header 'Authorization: Bearer your_api_key_here'
        ```
        rb   Nr.   MCP Server with id z
 not foundr/   z9User does not have permission to view mcp server with id z8. You can only view mcp servers that you have access to.)r5   r   r   r   HTTP_404_NOT_FOUNDr(   r   r=   r   add_update_serverHTTP_403_FORBIDDEN)r;   r?   r-   
mcp_serverr7   existss         r4   fetch_mcp_serverr     s     & 3F

 *-CC
"55#6yk!LM    12 $@,$
 
 ''99E%77
C"55XYbXc  d\  ] + D
s#   B0B,AB0!B."AB0.B0zAllows creation of mcp servers)r^   r>   r_   r0   zThe litellm-changed-by header enables tracking of actions performed by authorized users on behalf of other users, providing an audit trail for accountability)r^   payloadlitellm_changed_byc           	      `  K   t        d      }t        |        t        j                  |j                  k7  rt        t        j                  ddi      | j                  Kt        || j                         d{   }|t        t        j                  dd| j                   di      t        j                  | j                  k(  st        j                  | j                  k(  r+t        t        j                  dd| j                   di      	 t        || |j                  xs t         	       d{   }t#        j$                  |       |S 7 7 # t&        $ rO}t)        j*                  d
t-        |              t        t        j.                  dd
t-        |       i      d}~ww xY ww)z?
        Allow users to add a new external mcp server.
        rb   r.   znUser does not have permission to create mcp servers. You can only create mcp servers if you are a PROXY_ADMIN.r/   Nr   z' already exists. Cannot create another.z is special and cannot be used.
touched_byzError creating mcp server: )r5   r   r!   PROXY_ADMIN	user_roler   r   r   r;   r   HTTP_400_BAD_REQUESTr#   all_team_serversall_proxy_serversr   re   r   r   r   rV   r   	exceptionr   r3   )r   r?   r   r-   r   new_mcp_serverr[   s          r4   add_mcp_serverr   N  s    & 3F

 	2': ''+<+F+FF"55  N  *-mW=N=NOOJ%# & ; ;#6w7H7H6IIp!q  !11W5F5FF#559J9JJ"77273D3D2EEde 	#4,44P8P$ N
 &77G G P.  	 **-HQ+QR"AA#>s1vh!GH 	sJ   A6F.8E9BF.#E 3E4E F.E 	F+A
F&&F++F.z$Allows deleting mcp serves in the db)r^   r>   response_classr0   c                   K   t        d      }t        j                  |j                  k7  r,t	        t
        j                  ddj                  d      i      t        ||        d{   }| t	        t
        j                  dd|  i      t        j                  |       t        j                  r	 t        t
        j                        S 7 fw)	ak  
        Delete MCP Server from db and associated MCP related server entities.

        Parameters:
        - server_id: str - Required. The unique identifier of the mcp server to delete.
        ```
        curl -X "DELETE" --location 'http://localhost:4000/v1/mcp/server/server_id'         --header 'Authorization: Bearer your_api_key_here'
        ```
        Database not connected. Connect a database to your proxy - https://docs.litellm.ai/docs/simple_proxy#managing-auth---virtual-keysr.   zJCall not allowed to delete MCP server. User is not a proxy admin. route={}zDELETE /v1/mcp/serverr/   N'MCP Server not found, passed server_id=)r0   )r5   r!   r   r   r   r   r   formatr   r   r   remove_serverlitellmstore_audit_logsr   HTTP_202_ACCEPTED)r;   r?   r   r-   mcp_server_record_deleteds        r4   remove_mcp_serverr     s     4 3 P

 ''+<+F+FF"55ipp/  +<M9*U$U!$,"55#J9+!VW  	"//0IJ ## F$<$<==' %Vs   A$C&C'A'Cc                   K   t        d      }t        |        t        j                  |j                  k7  r,t        t        j                  ddj                  d      i      t        || |j                  xs t               d{   }|*t        t        j                  dd| j                   i      t        j                  |       t         j"                  r	 |S 7 Xw)	a5  
        Updates the MCP Server in the db.

        Parameters:
        - payload: UpdateMCPServerRequest - Required. The updated mcp server data.
        ```
        curl -X "PUT" --location 'http://localhost:4000/v1/mcp/server'         --header 'Authorization: Bearer your_api_key_here'
        ```
        r   r.   zJCall not allowed to update MCP server. User is not a proxy admin. route={}zPUT /v1/mcp/serverr/   r   Nr   )r5   r   r!   r   r   r   r   r   r   r   re   r   r   r;   r   r   r   r   )r   r?   r   r-   mcp_server_record_updateds        r4   edit_mcp_serverr     s     4 3 P

 	2': ''+<+F+FF"55ipp,  +<(00L4L+
 %
! %,"55FwGXGXFYZ  	"334MN ##(('%
s   BC CAC )H__doc__	importlibtypingr   r   r   r   r   fastapir   r	   r
   r   r   r   fastapi.responsesr   r   litellm._loggingr   r   litellm.constantsr   ,litellm.proxy._experimental.mcp_server.utilsr   routerr   bool__annotations__import_moduleImportErrorr[   rH   )litellm.proxy._experimental.mcp_server.dbr   r   r   r   r   r   r   rD   r   litellm.proxy._typesr    r!   r"   r#   r$   r%   $litellm.proxy.auth.user_api_key_authr'   /litellm.proxy.management_endpoints.common_utilsr(   &litellm.proxy.management_helpers.utilsr)   r   r5   r=   r   rJ   r]   r   r   postHTTP_201_CREATEDr   deleter   r   putr   rx   r6   r4   <module>r      s     7 7 O O *  A 6 b	)5'	2t IE"
     GTRC 	$%;<	MP			 ZZW/01   188I0J - 
 0 ZZW/01   188I0J5-5
5> ZZG/0123	   -44E,Fy )y y v ZZ1/01-	   -44E,F,,),,\ [[4/01-++   ! -44E,F,2 x-
?$?)? %SM? !?B ]]:/01#,,   ! -44E,F,2 x-
5>5>)5> %SM5> !5>n ZZ:/01-,,   ! -44E,F,2 x-
8)'8))8) %SM8) !8)o 	  N1!56Ms   I J I==J