
    ÁjA                    v   d Z 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mZ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 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+ g dZ,dddddZ-d+dZ. e/h d      Z0 G d de1      Z2 G d de3      Z4d,dZ5d-dZ6 G d d e7      Z8dd!	 	 	 	 	 d.d"Z9dd!	 	 	 	 	 d/d#Z:dd!	 	 	 	 	 d0d$Z;dd!	 	 	 	 	 d1d%Z<	 	 	 	 d2d&Z=d3d'Z>ddddddd(	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d4d)Z?ddddddd(	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d5d*Z@y# e$ rZ ed	      edZ[ww xY w)6aG  Helpers for integrating MCP (Model Context Protocol) SDK types with the Anthropic SDK.

These helpers reduce boilerplate when converting between MCP types and Anthropic API types.

Usage::

    from anthropic.lib.tools.mcp import mcp_tool, async_mcp_tool, mcp_message

This module requires the ``mcp`` package to be installed.
    )annotationsN)AnyIterable)urlparse)Literal)
ToolTextContentContentBlockImageContentPromptMessageCallToolResultEmbeddedResourceReadResourceResultBlobResourceContentsTextResourceContents)ClientSessionz~The `mcp` package is required to use MCP helpers. Install it with: pip install anthropic[mcp]. Requires Python 3.10 or higher.   )BetaBase64PDFSourceParamBetaPlainTextSourceParamBetaBase64ImageSourceParamBetaCacheControlEphemeralParam   )	ToolErrorBetaFunctionToolBetaAsyncFunctionToolBetaFunctionToolResultType	beta_toolbeta_async_tool   )
tag_helper)Content)mcp_toolasync_mcp_toolmcp_contentmcp_messagemcp_resource_to_contentmcp_resource_to_fileUnsupportedMCPValueErrorinputSchemamimeTypeisErrorstructuredContent)input_schema	mime_typeis_errorstructured_contentc                `    	 t        | |      S # t        $ r t        | t        |         cY S w xY wN)getattrAttributeError_MCP_V1_NAMES)objnames     >/tmp/pip-target-k_scjv0h/lib/python/anthropic/lib/tools/mcp.py_mcp_field_v1_or_v2r9   R   s5    1sD!! 1sM$/001s    -->   	image/gif	image/png
image/jpeg
image/webpc                      e Zd ZdZy)_TaggedDictzA dict subclass that can carry a ``_stainless_helper`` attribute.

    Behaves identically to a regular dict for serialization and isinstance checks,
    but allows attaching tracking metadata that won't appear in JSON output.
    N__name__
__module____qualname____doc__     r8   r?   r?   `   s    rF   r?   c                      e Zd ZdZy)_TaggedTuplezBA tuple subclass that can carry a ``_stainless_helper`` attribute.Nr@   rE   rF   r8   rH   rH   h   s    LrF   rH   c                    | t         v S r2   )_SUPPORTED_IMAGE_TYPESr.   s    r8   _is_supported_image_typerL   l   s    ...rF   c                X    | d u xs% | j                  d      xs | dk(  xs t        |       S )Ntext/application/pdf)
startswithrL   rK   s    r8    _is_supported_resource_mime_typerQ   p   s?    T 	/(	/))	/ $I.	rF   c                      e Zd ZdZy)r(   zURaised when an MCP value cannot be converted to a format supported by the Claude API.Nr@   rE   rF   r8   r(   r(   ~   s    _rF   r(   cache_controlc                  t        | t              r-t        d| j                  d      }|||d<   t	        |d       |S t        | t
              r^t        | d      }t        |      st        d|       t        dt        d| j                  |	      d
      }|||d<   t	        |d       |S t        | t              rt        | j                  |      S t        | dt        |       j                         }t        d|       )zConvert a single MCP content block to an Anthropic content block.

    Handles text, image, and embedded resource content types.
    Raises :class:`UnsupportedMCPValueError` for audio and resource_link types.
    text)typerV   rT   r$   r.   zUnsupported image MIME type: imagebase64rW   data
media_typerW   sourcerS   rW   zUnsupported MCP content type: )
isinstancer	   r?   rV   r    r   r9   rL   r(   r   r[   r   _resource_contents_to_blockresourcer3   rW   rA   )contentrT   blockr.   image_blockcontent_types         r8   r$   r$      s    ';'VW\\BC$%2E/"5-('<('=	'	2*-J9++VWW!4! (	
 $+8K(;.'+,*7+;+;=YY 7FDM,B,BCL
"%CL>#R
SSrF   c                  t        | d      }|lt        |      rat        | t              st	        d| j
                         t        dt        d| j                  |      d      }|||d<   t        |d       |S |d	k(  rat        | t              st	        d
| j
                         t        dt        d| j                  d	      d      }|||d<   t        |d       |S ||j                  d      rzt        | t              r| j                  }n.t        j                  | j                        j!                  d      }t        dt#        d|d      d      }|||d<   t        |d       |S t	        d| d| j
                         )z<Convert MCP resource contents to an Anthropic content block.r.   z3Image resource must have blob data, not text. URI: rX   rY   rZ   r]   rT   r&   rO   z1PDF resource must have blob data, not text. URI: documentrN   utf-8rV   z
text/plainzUnsupported MIME type "z" for resource: )r9   rL   r_   r   r(   urir?   r   blobr    r   rP   r   rV   rY   	b64decodedecoder   )ra   rT   r.   rd   	pdf_blockr[   
text_blocks          r8   r`   r`      s    $Hk:I !9)!D($89*-`aiamam`n+opp!4!!(	
 $+8K(; 9: %%($89*-^_g_k_k^l+mnn"2!!0	
	 $)6Io&978 I009h 45==D##HMM299'BD "2+	

 $*7J':89
"%<YKGWX`XdXdWe#f
ggrF   c               z    t        | j                  t        | j                  |      gd      }t	        |d       |S )zCConvert an MCP prompt message to an Anthropic ``BetaMessageParam``.rS   )rolerb   r%   )r?   rp   r$   rb   r    )messagerT   results      r8   r%   r%      s<     LL#GOO=QR	
F v}%MrF   c               T   | j                   st        d      | j                   D cg c]  }t        |d       }}t        d t	        | j                   |      D        d      }|/|D cg c]  }||	 }}t        ddj                  |             t        ||      S c c}w c c}w )zConvert MCP resource contents to an Anthropic content block.

    Finds the first resource with a supported MIME type from the result's
    ``contents`` list.
    6Resource contents array must contain at least one itemr.   c              3  >   K   | ]  \  }}t        |      s|  y wr2   )rQ   ).0cr.   s      r8   	<genexpr>z*mcp_resource_to_content.<locals>.<genexpr>"  s     o|q)CcdmCnos   Nz>No supported MIME type found in resource contents. Available: z, rS   )contentsr(   r9   nextzipjoinr`   )rr   rT   rw   
mime_types	supportedms         r8   r&   r&     s     ??&'_``?EO!%a5OJOos6??J?oI !+=Aq}a=
=&LTYYWaMbLcd
 	
 'yNN P >s   B (B%0B%c                   | j                   st        d      | j                   d   }t        |j                        }t	        |      j
                  }|r|j                  dd      d   nd}t        |t              r t        j                  |j                        }n|j                  j                  d      }t        ||t        |d      f      }t!        |d	       |S )
zConvert MCP resource contents to a file tuple for ``files.upload()``.

    Returns a ``(filename, content_bytes, mime_type)`` tuple compatible with
    the SDK's ``FileTypes``.
    rt   r   /r   Nrh   r.   r'   )ry   r(   strri   r   pathrsplitr_   r   rY   rk   rj   rV   encoderH   r9   r    )rr   ra   uri_strr   r7   content_bytes
file_tuples          r8   r'   r'   .  s     ??&'_``q!H(,,G G!!D&*4;;sAr"D (01((7 ,,W5t]4GR]4^_`Jz12rF   c                *   t        | d      r,t        | j                  D cg c]  }t        |       c}      t        | d      }| j                  s|t	        j
                  |      S | j                  D cg c]  }t        |       c}S c c}w c c}w )zQConvert MCP ``CallToolResult`` to a value suitable for returning from ``call()``.r/   r0   )r9   r   rb   r$   jsondumps)rr   itemr0   s      r8   _convert_tool_resultr   P  s}    6:.v~~FtT*FGG -V5IJ>>0<zz,--*0..9$K99 G :s   B6B)rT   defer_loadingallowed_callerseager_input_streaminginput_examplesstrictc                  
 ddl 
| j                  d
fd}t        || j                  t	        | d      ||||||
      }	t        |	d       |	S )a  Convert an MCP tool to a sync runnable tool for ``tool_runner()``.

    Example::

        from anthropic.lib.tools.mcp import mcp_tool

        tools_result = await mcp_client.list_tools()
        runner = client.beta.messages.tool_runner(
            model="claude-sonnet-4-20250514",
            max_tokens=1024,
            tools=[mcp_tool(t, mcp_client) for t in tools_result.tools],
            messages=[{"role": "user", "content": "Use the available tools"}],
        )

    Args:
        tool: An MCP tool definition from ``client.list_tools()``.
        client: The MCP ``ClientSession`` used to call the tool.
        cache_control: Cache control configuration.
        defer_loading: If true, tool will not be included in initial system prompt.
        allowed_callers: Which callers may use this tool.
        eager_input_streaming: Enable eager input streaming for this tool.
        input_examples: Example inputs for the tool.
        strict: When true, guarantees schema validation on tool names and inputs.
    r   Nc                 h    j                   j                  j                  |       }t        |      S r2   )from_threadrun	call_toolr   )kwargsrr   anyioclient	tool_names     r8   call_mcpzmcp_tool.<locals>.call_mcp  s.    ""&&v'7'7FK#F++rF   r-   	r7   descriptionr-   rT   r   r   r   r   r   r"   r   r   returnr   )anyio.from_threadr7   r   r   r9   r    )toolr   rT   r   r   r   r   r   r   rr   r   r   s    `        @@r8   r"   r"   b  s_    L 		I, $$(~>##'3%F vz"MrF   c                  
 | j                   
d
fd}t        |
| j                  t        | d      ||||||
      }	t	        |	d       |	S )a  Convert an MCP tool to an async runnable tool for ``tool_runner()``.

    Example::

        from anthropic.lib.tools.mcp import async_mcp_tool

        tools_result = await mcp_client.list_tools()
        runner = await client.beta.messages.tool_runner(
            model="claude-sonnet-4-20250514",
            max_tokens=1024,
            tools=[async_mcp_tool(t, mcp_client) for t in tools_result.tools],
            messages=[{"role": "user", "content": "Use the available tools"}],
        )

    Args:
        tool: An MCP tool definition from ``client.list_tools()``.
        client: The MCP ``ClientSession`` used to call the tool.
        cache_control: Cache control configuration.
        defer_loading: If true, tool will not be included in initial system prompt.
        allowed_callers: Which callers may use this tool.
        eager_input_streaming: Enable eager input streaming for this tool.
        input_examples: Example inputs for the tool.
        strict: When true, guarantees schema validation on tool names and inputs.
    c                 \   K   j                  |        d {   }t        |      S 7 w)N)r7   	arguments)r   r   )r   rr   r   r   s     r8   r   z async_mcp_tool.<locals>.call_mcp  s0     ''Y&'II#F++ Js   ,*,r-   r   r"   r   )r7   r   r   r9   r    )r   r   rT   r   r   r   r   r   r   rr   r   s    `        @r8   r#   r#     s\    L 		I, $$(~>##'3%F vz"MrF   )r6   r   r7   r   r   r   )r.   r   r   bool)r.   z
str | Noner   r   )rb   r
   rT   %BetaCacheControlEphemeralParam | Noner   BetaContent)ra   z+TextResourceContents | BlobResourceContentsrT   r   r   r   )rq   r   rT   r   r   zdict[str, Any])rr   r   rT   r   r   r   )rr   r   r   z$tuple[str | None, bytes, str | None])rr   r   r   r   )r   r   r   r   rT   r   r   bool | Noner   olist[Literal['direct', 'code_execution_20250825', 'code_execution_20260120', 'code_execution_20260521']] | Noner   r   r   "Iterable[dict[str, object]] | Noner   r   r   zBetaFunctionTool[Any])r   r   r   r   rT   r   r   r   r   r   r   r   r   r   r   r   r   zBetaAsyncFunctionTool[Any])ArD   
__future__r   r   rY   typingr   r   urllib.parser   typing_extensionsr   	mcp.typesr   r	   r
   r   r   r   r   r   r   r   mcp.client.sessionr   ImportError_err
types.betar   r   r   r   _beta_functionsr   r   r   r   r   r   _stainless_helpersr    'types.beta.beta_tool_result_block_paramr!   r   __all__r5   r9   	frozensetrJ   dictr?   tuplerH   rL   rQ   	Exceptionr(   r$   r`   r%   r&   r'   r   r"   r#   rE   rF   r8   <module>r      s  	 #     ! %   1   , M$ "-	1 ##YZ $ M5 M/`y ` <@)T)T 9)T 	)T^ <@Ch9Ch 9Ch 	Ch\ <@ 9 	0 <@OO 9O 	O6)D
:, <@!% )-9=;
;; 9	;
 ;; '; 7; ; ;D <@!% )-9=9
99 9	9
 99 '9 79 9  9{  
 	Is   D% %D8*	D33D8