
    6pj-                         S r SSKJrJrJr  SSKrSSKJr  SSKJ	r	J
r
  SSKJr  \" 5       rSr " S S	\5      r " S
 S\5      r " S S\5      r " S S\5      rg)z
MCP (Model Context Protocol) API interface for ModelScope Hub.

This module provides a simple interface to interact with
ModelScope MCP plaza (https://www.modelscope.cn/mcp).
    )AnyDictOptionalN)HubApi)RequestErrorraise_for_http_status)
get_loggerz/openapi/v1/mcp/serversc                       \ rS rSrSrSrg)MCPApiError   z"Base exception for MCP API errors. N__name__
__module____qualname____firstlineno____doc____static_attributes__r       R/var/www/html/pdf-tiff/venv/lib/python3.13/site-packages/modelscope/hub/mcp_api.pyr   r      s    ,r   r   c                       \ rS rSrSrSrg)MCPApiRequestError   z,Exception raised when MCP API request fails.r   Nr   r   r   r   r   r      s    6r   r   c                       \ rS rSrSrSrg)MCPApiResponseError!   z2Exception raised when MCP API response is invalid.r   Nr   r   r   r   r   r   !   s    <r   r   c                     ^  \ rS rSrSr  SS\\   S\\   SS4U 4S jjjr\S\S\4S	 j5       r	    SS\\   S
\\
\\4      S\\   S\\   S\
\\4   4
S jjr SS\S\
\\4   4S jjr SS\S\\   S\
\\4   4S jjrSrU =r$ )MCPApi&   a=  
MCP (Model Context Protocol) API interface class.

This class provides interfaces to interact with ModelScope MCP servers,
such as to list, deploy and manage MCP servers.

Note: MCPApi inherits login() from HubApi for authentication.
Different methods have different token requirements - see individual method docs.
Nendpointtokenreturnc                 P   > [         TU ]  XS9  U R                  [        -   U l        g)z
Initialize MCP API.

Args:
    endpoint: The modelscope server address. Defaults to None (uses default endpoint).
    token: Optional access token for Bearer authentication.
)r    r!   N)super__init__r    MCP_API_PATHmcp_base_url)selfr    r!   	__class__s      r   r%   MCPApi.__init__1   s&     	(8 MML8r   	server_idc                 <    SU ;   a  U R                  SS5      S   $ U $ )z#Extract server name from server ID./   )split)r+   s    r   _get_server_name_from_idMCPApi._get_server_name_from_id?   s(     )??3*1--r   filtertotal_countsearchc           	         Ub  US:  d  US:  a  [        S5      eU=(       d    0 SUUS.n U R                  USS9nU R                  R                  U R                  XeS9n[        U5         U R                  U5      n	U	R                  S/ 5      n
U
 Vs/ s H9  nUR                  SS5      UR                  SS5      UR                  SS5      S.PM;     nnU	R                  SS5      US.$ ! [        R                  R                   a*  n[        R                  S	U5        [        S
U 35      UeSnAff = f! [         a  n[        SU 35      UeSnAff = fs  snf )a  
List available MCP servers, if (optional) token is presented, this would return private MCP servers as well.

Args:
    token: Optional access token for authentication
    filter: Optional filters to apply to the search
        - 'category': str, server category, e.g. 'communication'
        - 'tag': str, server tag, e.g. 'social-media'
        - 'is_hosted': bool, server is hosted
        When all three are passed in, the intersection is taken.
    total_count: Number of servers to return, max 100, default 20
    search: Optional search query string,e.g. Chinese service name, English service name, author/owner username
    You can combine `filter` and `search` to retrieve desired MCP servers.

Returns:
    Dict containing:
        - total_count: Total number of servers
        - servers: List of server dictionaries with name, id, description

Raises:
    MCPApiRequestError: If API request fails (network, server errors)
    MCPApiResponseError: If response format is invalid or JSON parsing fails

Authentication:
    Optional, only required if you wish to retrieve private MCP servers.
    You may leverage the token parameter for one-time authentication, or use api.login()

Returns:
    {
        'total_count': 20,
        'servers': [
            {'name': 'ServerA', 'id': '@demo/ServerA', 'description': 'This is a demo server for xxx.'},
            {'name': 'ServerB', 'id': '@demo/ServerB', 'description': 'This is another demo server.'},
            ...
        ]
    }
Nr.   d   z%total_count must be between 1 and 100)r2   page_number	page_sizer4   Fr!   token_required)urlheadersjsonzFailed to get MCP servers: %szFailed to get MCP servers: z(Invalid response from MCP servers list: mcp_server_listname iddescription)r?   rA   rB   r3   r   r3   servers)
ValueError_build_bearer_headerssessionputr'   r   requests
exceptionsRequestExceptionloggererrorr   _parse_openapi_responser   r   get)r(   r!   r2   r3   r4   bodyr<   redatar>   itemmcp_config_lists                r   list_mcp_serversMCPApi.list_mcp_serversF   s   V +/[35FDEE l$	
	O00E 1 3G  %%w ! CA!!$
	G//2D
 ((#4b9
 &	' &d HHVR(((4$88M26
 &	 	 '  88M15&
 	
# ""33 	OLL8!<$'B1#%FGQN	O  	G%:1#>@EFG	G
's6   ?C* ,D5 A E*D2%D--D25
E?EEc           	         U R                    S3n U R                  USS9nU R                  R                  X#S9n[	        U5        [        R                  SUR                   35         U R                  U5      nUR                  S	/ 5      n/ nU H  n	0 n
U	R                  S
S5      U
S
'   U	R                  SS5      U
S'   U	R                  SS5      U
S'   / U
S'   U	R                  S/ 5       HT  nU
S   R!                  UR                  S5      =(       d    SR#                  S5      S   UR                  SS5      S.5        MV     UR!                  U
5        M     UR                  SS5      US.$ ! [
        R                  R                   a,  n[        R                  SU 35        [        SU 35      UeSnAff = f! [         a  n[        SU 35      UeSnAff = f)aQ  
Get list of operational MCP servers that have been triggered hosting service by the user.

Returns:
    Dict containing:
        - total_counts: Total number of operational servers
        - servers: List of server info with name, id, description

Raises:
    MCPApiRequestError: If authentication fails or API request fails
    MCPApiResponseError: If response format is invalid or JSON parsing fails

Returns:
    {
        'total_count': 10,
        'servers': [
            {
                'name': 'ServerA',
                "id": "@Group1/ServerA",
                'description': 'This is a demo server for xxx.'
                'mcp_servers': [
                    {
                        'type': 'sse',
                        'url': 'https://mcp.api-inference.modelscope.net/{uuid}/sse'
                    },
                    {
                        'type': 'streamable_http',
                        'url': 'https://mcp.api-inference.modelscope.net/{uuid}/streamable_http'
                    },
                    ...
                ]
            },
            ...
        ]
    }
z/operationalTr9   )r<   z'Failed to get operational MCP servers: NzResponse status code: z/Invalid response from operational MCP servers: r>   r?   r@   rA   rB   mcp_serversoperational_urlsr;   r-   typer;   r3   r   rC   )r'   rF   rG   rO   r   rI   rJ   rK   rL   rM   r   debugstatus_coderN   r   r   appendr/   )r(   r!   r;   r<   rQ   rR   rS   r>   rU   rT   
mcp_configoperational_urls               r   list_operational_mcp_servers#MCPApi.list_operational_mcp_servers   s   L ""#<0	F00D 1 2G   6A!!$ 	-amm_=>	N//2D
 ((#4b9#DJ!%&"!5Jv#xxb1Jt(,(CJ}%(*J}%#'88,>#C=)00,007=2DDSI"M#''r22  $D "":. $  88M15&
 	
; ""33 	FLLB1#FG$9!=?DEF	F  	N%A!EGLMN	Ns/   4E, (F9 ,F6
'F11F69
GGGc                    U(       d  [        S5      eU R                   SU 3n U R                  USS9nU R                  R	                  X4SS0S9n[        U5         U R                  U5      nUR	                  SS5      UR	                  SS5      UR	                  SS5      S.nUR	                  SS5      n[        R!                  U5      n	UR	                  S/ 5      n
/ nU	(       a`  U
(       aY  U
 HS  nUR	                  S5      =(       d    SR#                  S5      S   UR	                  SS5      S.nUR%                  U5        MU     XS'   U$ ! [        R                  R                   a2  n[        R                  SU S	U 35        [        SU S	U 35      UeS
nAff = f! [         a  n[        SU S	U 35      UeS
nAff = f)aM  
Get detailed information for a specific MCP Server,
a valid token shall be provided if the MCP server is private.

Args:
    server_id: MCP server ID (e.g., "@amap/amap-maps")
    token: Optional access token for authentication

Returns:
    Dict containing:
        - name: Server name
        - description: Server description
        - id: Server ID
        - service_config: Connection configuration with type and url

Raises:
    ValueError: If server_id is empty or None
    MCPApiRequestError: If API request fails or server not found
    MCPApiResponseError: If response format is invalid or JSON parsing fails

Returns:
    {
        'name': 'ServerA',
        'description': 'This is a demo server for xxx.',
        'id': '@demo/serverA',
        'servers': [
            {
                'type': 'sse',
                'url': 'https://mcp.api-inference.modelscope.net/{uuid}/sse'
            },
            {
                'type': 'streamable_http',
                'url': 'https://mcp.api-inference.modelscope.net/{uuid}/streamable_http'
            }
            ...
        ]
    }
zserver_id cannot be emptyr-   Fr9   get_operational_urlT)r<   paramszFailed to get MCP server z: Nz!Invalid response from MCP server r?   r@   rB   rA   )r?   rB   rA   rZ   r;   r[   r\   rD   )rE   r'   rF   rG   rO   r   rI   rJ   rK   rL   rM   r   rN   r   r   r   r0   r/   r`   )r(   r+   r!   r;   r<   rQ   rR   rS   resultserver_namerZ   rU   rb   ra   s                 r   get_mcp_serverMCPApi.get_mcp_server   s   R 899""#1YK0		E00E 1 3G  .CT-J ! LA!!$	M//2D HHVR(88M26((4$
 HHT2&	55i@88$6;+#3,007=2DDSI"M*..ub9
  &&z2 $4 ,y? ""33 	ELL4YKr!EF$+I;b<>CDE	E  	M%3I;bDFKLM	Ms/   7E F F*-FF
G )F;;G )r'   )NN)NN   r@   )N)r   r   r   r   r   r   strr%   staticmethodr0   r   r   intrV   rc   rj   r   __classcell__)r)   s   @r   r   r   &   s#    ,0(,9#C=9 9159 9 C C   15<@6813	O
 (O
!)$sCx.!9O
 '/smO
 "*#	O
 9=S#X	O
d 37M
,/M
;?S>M
b /3S"%S&smS7;CH~S Sr   r   )r   typingr   r   r   rI   modelscope.hub.apir   modelscope.hub.errorsr   r   modelscope.utils.loggerr	   rL   r&   	Exceptionr   r   r   r   r   r   r   <module>rv      s`    ' &  % E . 
 )	) 	
	 	
	+ 	
SV Sr   