
    qi*7                     ~   U d Z ddlZddlmZmZmZ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 ddl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mZ ddlmZ ddlm Z  ddl!m"Z" eez  ez  Z'ee(d<    G d de      Z)y# e#$ r7Z$ e
jJ                  de$         e
jJ                  d        e&de$       dZ$[$ww xY w)zMMCP (Model Context Protocol) client for integrating external tools with LLMs.    N)AnyCallableDictListOptional	TypeAlias)logger)FunctionSchema)ToolsSchema)LLMSwitcher)FunctionCallParams
LLMService)
BaseObject)ClientSessionStdioServerParameters)r   )SseServerParametersStreamableHttpParameters)
sse_client)stdio_client)streamablehttp_clientzException: zIIn order to use an MCP client, you need to `pip install pipecat-ai[mcp]`.zMissing module: ServerParametersc                       e Zd ZdZ	 	 ddedeee      deeee	e
ge
f   f      f fdZdeez  defd	Zdefd
Zdedeez  ddfdZdedeee
f   defdZdefdZdeddfdZdefdZdeddfdZdefdZdeddfdZd Zd Z xZS )	MCPClientaS  Client for Model Context Protocol (MCP) servers.

    Enables integration with MCP servers to provide external tools and resources
    to LLMs. Supports both stdio and SSE server connections with automatic tool
    registration and schema conversion.

    Raises:
        TypeError: If server_params is not a supported parameter type.
    Nserver_paramstools_filtertools_output_filtersc                    t        |   di | || _        t        | _        || _        |xs i | _        t        |t              r.t        | _
        | j                  | _        | j                  | _        yt        |t              r.t         | _
        | j"                  | _        | j$                  | _        yt        |t&              r.t(        | _
        | j*                  | _        | j,                  | _        yt/        |  d      )aA  Initialize the MCP client with server parameters.

        Args:
            server_params: Server connection parameters (stdio or SSE).
            tools_filter: Optional list of tool names to register. If None, all tools are registered.
            tools_output_filters: Optional dict mapping tool names to filter functions that process tool outputs.
                                  Each filter function receives the raw tool output (any type) and returns the processed output (any type).
            **kwargs: Additional arguments passed to the parent BaseObject.
        z invalid argument type: `server_params` must be either StdioServerParameters, SseServerParameters, or StreamableHttpParameters.N )super__init___server_paramsr   _session_tools_filter_tools_output_filters
isinstancer   r   _client_stdio_list_tools_list_tools_stdio_tool_wrapper_tool_wrapperr   r   _sse_list_tools_sse_tool_wrapperr   r   _streamable_http_list_tools_streamable_http_tool_wrapper	TypeError)selfr   r   r   kwargs	__class__s        N/opt/pipecat/venv/lib/python3.12/site-packages/pipecat/services/mcp_service.pyr    zMCPClient.__init__.   s      	"6"+%)%9%?R"m%:;'DL#55D!%!9!9D':;%DL#33D!%!7!7D'?@0DL#??D!%!C!CD&  X  Y     llmreturnc                 z   K   | j                          d{   }| j                  ||       d{    |S 7  7 w)a  Register all available MCP tools with an LLM service.

        Connects to the MCP server, discovers available tools, converts their
        schemas to Pipecat format, and registers them with the LLM service.

        This is the equivalent of calling get_tools_schema() followed by
        register_tools_schema().

        Args:
            llm: The Pipecat LLM service to register tools with.

        Returns:
            A ToolsSchema containing all successfully registered tools.
        N)get_tools_schemaregister_tools_schema)r0   r5   tools_schemas      r3   register_toolszMCPClient.register_toolsU   s>      "2244((s;;; 5;s   ;7;9;;c                 B   K   | j                          d{   }|S 7 w)af  Get the schema of all available MCP tools without registering them.

        Connects to the MCP server, discovers available tools, and converts their
        schemas to Pipecat format.

        Returns:
            A ToolsSchema containing all available tools. This can be used for
            subsequent registration using register_tools_schema().
        N)r(   )r0   r:   s     r3   r8   zMCPClient.get_tools_schemah   s$      "--// 0s   r:   c                 z   K   |j                   D ](  }|j                  |j                  | j                         * yw)zRegister the MCP tools (previously obtained from get_tools_schema()) with the LLM service.

        Args:
            tools_schema: The ToolsSchema to register with the LLM service.
            llm: The Pipecat LLM service to register tools with.
        N)standard_toolsregister_functionnamer*   )r0   r:   r5   function_schemas       r3   r9   zMCPClient.register_tools_schemau   s;       ,:: 	LO!!/"6"68J8JK	Ls   9;	tool_nametool_schemac                    t        j                  d| d       t        j                  dt        j                  |d              |d   j                  di       }|d   j                  dg       }t        ||d	   ||
      }t        j                  dt        j                  |j                         d              |S )zConvert an mcp tool schema to Pipecat's FunctionSchema format.

        Args:
            tool_name: The name of the tool
            tool_schema: The mcp tool schema
        Returns:
            A FunctionSchema instance
        zConverting schema for tool ''zOriginal schema:    indentinput_schema
propertiesrequireddescription)r@   rL   rJ   rK   zConverted schema: )r	   debugtracejsondumpsgetr
   to_default_dict)r0   rB   rC   rJ   rK   schemas         r3   _convert_mcp_schema_to_pipecatz(MCPClient._convert_mcp_schema_to_pipecat   s     	3I;a@A(K)J(KLM 044\2F
~.22:rB#M2!	
 	)$**V5K5K5MVW*X)YZ[r4   c                 T  K   t        j                  d| j                          t        j                  d        | j                  di | j                  j	                         4 d{   \  }}| j                  ||      4 d{   }|j                          d{    | j                  |       d{   }|cddd      d{    cddd      d{    S 7 w7 [7 E7 .7 7 # 1 d{  7  sw Y   nxY wddd      d{  7   y# 1 d{  7  sw Y   yxY ww)zList all available mcp tools with the LLM service.

        Returns:
            A ToolsSchema containing all registered tools
        zSSE server parameters: Starting reading mcp toolsNr   )r	   rM   r!   r&   
model_dumpr"   
initialize_list_tools_helper)r0   readwritesessionr:   s        r3   r+   zMCPClient._sse_list_tools   s     	.t/B/B.CDE134<<C$"5"5"@"@"BC 	$ 	$}e}}T51 $ $W((***%)%<%<W%EE#$ $ $	$ 	$ 	$$*E$	$$ $ $	$ 	$ 	$ 	$ 	$s   A&D((C )D(,DC"D
C,C$C,7C&8C,=D	C(
DD(C*D("D$C,&C,(D*D(,C>	2C53C>	:DD(DD(D%DD%!D(paramsc                   K   t        j                  d|j                   d|j                          t        j                  dt        j                  |j                  d              	  | j                  d	i | j                  j                         4 d{   \  }}| j                  ||      4 d{   }|j                          d{    | j                  ||j                  |j                  |j                         d{    ddd      d{    ddd      d{    y7 7 y7 c7 +7 # 1 d{  7  sw Y   -xY w7 $# 1 d{  7  sw Y   yxY w# t        $ rT}d|j                   dt!        |       }t        j"                  |       |j                  |       d{  7   Y d}~yd}~ww xY ww
FWrapper for mcp tool calls to match Pipecat's function call interface.Executing tool '' with call ID: Tool arguments: rF   rG   NError calling mcp tool : r   r	   rM   function_nametool_call_idrN   rO   rP   	argumentsr&   r!   rW   r"   rX   
_call_toolresult_callback	Exceptionstrerror)r0   r]   rZ   r[   r\   e	error_msgs          r3   r,   zMCPClient._sse_tool_wrapper   s    '(<(<'==MfNaNaMbcd'

63C3CA(N'OPQ
	4#t||Gd&9&9&D&D&FG  =DRW==u5  !,,...//!5!5v7G7GI_I_     .        	41&2F2F1Gr#a&RILL#((333	4s   A'G*.E$ D.E$ E6D07E:D8D29D8D4	D8ED6EE$ (E)E$ -G.E$ 0E2D84D86E8E
	>E?E
	EE$ E!EE!E$  G!E$ $	G-AF<1F42F<7G<GGc                   K   t        j                  d       | j                  | j                        4 d{   }| j	                  |d   |d         4 d{   }|j                          d{    | j                  |       d{   }|cddd      d{    cddd      d{    S 7 z7 [7 E7 .7 7 # 1 d{  7  sw Y   nxY wddd      d{  7   y# 1 d{  7  sw Y   yxY ww)zList all available mcp tools with the LLM service.

        Returns:
            A ToolsSchema containing all available tools.
        rV   Nr      )r	   rM   r&   r!   r"   rX   rY   )r0   streamsr\   r:   s       r3   r'   zMCPClient._stdio_list_tools   s      	13<< 3 34 	$ 	$}}WQZ< $ $((***%)%<%<W%EE#$ $ $	$ 	$ 	$$*E$	$$ $ $	$ 	$ 	$ 	$ 	$s   5C:B2C:C%B4C%B>0B61B>	B8
B>C%B:C% C:,B<-C:4C%6B>8B>:C%<C:>C	CC	C%C:C!C:%C7+C.,C73C:c                 t  K   t        j                  d|j                   d|j                          t        j                  dt        j                  |j                  d              	 | j                  | j                        4 d{   }| j                  |d   |d         4 d{   }|j                          d{    | j                  ||j                  |j                  |j                         d{    ddd      d{    ddd      d{    y7 7 y7 c7 +7 # 1 d{  7  sw Y   -xY w7 $# 1 d{  7  sw Y   yxY w# t        $ rT}d	|j                   d
t        |       }t        j                   |       |j                  |       d{  7   Y d}~yd}~ww xY ww)r`   ra   rb   rc   rF   rG   Nr   rr   rd   re   )r	   rM   rg   rh   rN   rO   rP   ri   r&   r!   r"   rX   rj   rk   rl   rm   rn   )r0   r]   rs   r\   ro   rp   s         r3   r)   zMCPClient._stdio_tool_wrapper   s    '(<(<'==MfNaNaMbcd'

63C3CA(N'OPQ
	4||D$7$78  G==WQZ@  G!,,...//!5!5v7G7GI_I_     .        	41&2F2F1Gr#a&RILL#((333	4s   A'F8*E 	D"
E E*D$+E.D,D&9D,<D(=D,ED*EE EE !F8"E $E&D,(D,*E,D>	2D53D>	:EE E	E
EE F8E 	F5!AF0%F(&F0+F80F55F8c                   K   t        j                  d        | j                  di | j                  j	                         4 d{   \  }}}| j                  ||      4 d{   }|j                          d{    | j                  |       d{   }|cddd      d{    cddd      d{    S 7 x7 [7 E7 .7 7 # 1 d{  7  sw Y   nxY wddd      d{  7   y# 1 d{  7  sw Y   yxY ww)zList all available mcp tools with the LLM service using streamable HTTP.

        Returns:
            A ToolsSchema containing all available tools.
        z0Starting reading mcp tools using streamable HTTPNr   )r	   rM   r&   r!   rW   r"   rX   rY   )r0   read_streamwrite_stream_r\   r:   s         r3   r-   z%MCPClient._streamable_http_list_tools   s      	GI4<<C$"5"5"@"@"BC 	$ 	$ H
}}[,? $ $7((***%)%<%<W%EE#$ $ $	$ 	$ 	$
$*E$	$
$ $ $	$ 	$ 	$ 	$ 	$s   ADB?D
C2%C&C2)C=C>CCCC2(C)C2-D9C	:DC2CCC2	DC	CC	C2 D+C.,D2D8C;9D Dc                   K   t        j                  d|j                   d|j                          t        j                  dt        j                  |j                  d              	  | j                  d	i | j                  j                         4 d{   \  }}}| j                  ||      4 d{   }|j                          d{    | j                  ||j                  |j                  |j                         d{    ddd      d{    ddd      d{    y7 7 y7 c7 +7 # 1 d{  7  sw Y   -xY w7 $# 1 d{  7  sw Y   yxY w# t        $ rT}d|j                   dt!        |       }t        j"                  |       |j                  |       d{  7   Y d}~yd}~ww xY wwr_   rf   )r0   r]   rv   rw   rx   r\   ro   rp   s           r3   r.   z'MCPClient._streamable_http_tool_wrapper   s    '(<(<'==MfNaNaMbcd'

63C3CA(N'OPQ	4#t||Gd&9&9&D&D&FG 	 	 L==lC  w!,,...//!5!5v7G7GI_I_   	 	 	
.   	 	 	 	  	41&2F2F1Gr#a&RILL#((333	4s   A'G*.E% D/E% E7D18E;D9D39D9	D5
D9ED7EE% )E*E% .G/E% 1E3D95D97E9E	?E E	EE% E"EE"E% !G"E% %	G.AF=2F53F=8G=GGc                   K   t        j                  d| d       	 |j                  ||       d {   }d}rt        |d      rw|j                  rkt        |j                        D ]R  \  }	}
t        |
d      rA|
j                  r5t        j                  d	|	 d|
j                          ||
j                  z  }ST nt        j
                  d
| d       || j                  v r.	  | j                  |   |      }t        j                  d|        |rMt        |      rBt        |t              r2t        j                  d| d       t        j                  d|        nd} ||       d {    y 7 C# t        $ r1}d| dt	        |       }t        j
                  |       Y d }~vd }~ww xY w# t        $ r t        j
                  d|        d}Y w xY w7 nw)NzCalling mcp tool 'rE   )ri   rd   re    contenttextzTool response chunk zError getting content from z	 results.zFinal response (after filter): z!Error applying output filter for zTool 'z' completed successfullyzFinal response: z"Sorry, could not call the mcp tool)r	   rM   	call_toolrl   rm   rn   hasattrr|   	enumerater}   r$   lenr%   info)r0   r\   rg   ri   rk   resultsro   rp   responseir|   s              r3   rj   zMCPClient._call_tool   s    )-:;	$#--my-QQG
 w	*w"+GOO"< JAww/GLL';A3b%OP GLL0  :=/ST D666D455mDXN>xjIJ H*Xs*CKK&/GHILL+H:67;Hh'''E R 	$1-3q6(KILL##	$.  @PQ 	(so   G!E9 E6E9 B.G!'-F6 AG!0G1G!6E9 9	F3&F.(G!.F33G!6#GG!GG!c           
      0  K   |j                          d {   }g }t        j                  dt        |j                         d       |j                  D ]  }|j
                  }| j                  r(|| j                  vrt        j                  d| d       Ct        j                  d|        t        j                  d|j                          	 | j                  ||j                  |j                  d      }|j                  |       t        j                  d| d	        t        j                  dt        |       d       t        |      }|S 7 B# t        $ r/}t        j                  d
| dt        |              Y d }~9d }~ww xY ww)NzFound z available toolszSkipping tool 'z' - not in allowed tools listzProcessing tool: zTool description: )rL   rI   zSuccessfully read tool 'rE   zFailed to read tool 'z': zCompleted reading z tools)r>   )
list_toolsr	   rM   r   toolsr@   r#   rL   rT   inputSchemaappendrl   rn   rm   r   )	r0   r\   available_toolstool_schemastoolrB   rA   ro   r:   s	            r3   rY   zMCPClient._list_tools_helper'  st     ' 2 2 44-/vc/"7"7899IJK#)) 	D		I !!it7I7I&Iyk9VWXLL,YK89LL-d.>.>-?@A"&"E"E$($4$4dFVFVW# ##O47	{!DE)	4 	)#l*;)<FCD",?E 56  4YKs3q6(KLs;   FEB;FAE&3F	F$$FFFF)NN)__name__
__module____qualname____doc__r   r   r   rm   r   r   r   r    r   r   r   r;   r8   r9   r
   rT   r+   r   r,   r'   r)   r-   r.   rj   rY   __classcell__)r2   s   @r3   r   r   #   s0    -1JN	%'% tCy)% 'tC3%*1E,E'FG	%N
[(@ [ & 
L'
L.8;.F
L	
L+/S>	8${ $4.@ 4T 4 $ $40B 4t 4 $; $$4:L 4QU 4(%(N#r4   r   )*r   rO   typingr   r   r   r   r   r   logurur	   (pipecat.adapters.schemas.function_schemar
   %pipecat.adapters.schemas.tools_schemar   pipecat.pipeline.llm_switcherr   pipecat.services.llm_servicer   r   pipecat.utils.base_objectr   mcpr   r   mcp.client.sessionmcp.client.session_groupr   r   mcp.client.sser   mcp.client.stdior   mcp.client.streamable_httpr   ModuleNotFoundErrorro   rn   rl   r   __annotations__r   r   r4   r3   <module>r      s    T  A A  C = 5 G 0
,80V)-@ 46IILdd ) dg
 g  ,FLL;qc"#FLL\]
&qc*
++,s   (B   B<2B77B<