
    kKj3                       d Z ddlm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 ddlm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 dd	lmZ erdd
lmZmZmZmZ 	 	 	 	 ddZ ddZ! G d de      Z" G d de      Z# G d de"e#      Z$ G d de      Z% G d de"e%      Z&e$e&z  Z'e#e%z  Z(e'e(z  Z) G d de      Z* G d de*      Z+	 	 	 	 	 	 	 	 ddZ,y)a  Canonical MCP Configuration Format.

This module defines the standard configuration format for Model Context Protocol (MCP) servers.
It provides a client-agnostic, extensible format that can be used across all MCP implementations.

The configuration format supports both stdio and remote (HTTP/SSE) transports, with comprehensive
field definitions for server metadata, authentication, and execution parameters.

Example configuration:
```json
{
    "mcpServers": {
        "my-server": {
            "command": "npx",
            "args": ["-y", "@my/mcp-server"],
            "env": {"API_KEY": "secret"},
            "timeout": 30000,
            "description": "My MCP server"
        }
    }
}
```
    )annotationsN)Path)TYPE_CHECKING	AnnotatedAnyLiteralcast)urlparse)AnyUrl	BaseModel
ConfigDictFieldmodel_validator)Selfoverride)_install_hints)ClientTransportSSETransportStdioTransportStreamableHttpTransportc                    t        |       } | j                  d      st        d|        t        |       }|j                  }t        j                  d|      ryy)zB
    Infer the appropriate transport type from the given URL.
    httpzInvalid URL: z/sse(/|\?|&|$)sse)str
startswith
ValueErrorr
   pathresearch)url
parsed_urlr   s      c/Users/ahmed/devFolder/Ultron/claude-voice/.venv/lib/python3.12/site-packages/fastmcp/mcp_config.pyinfer_transport_type_from_urlr#   6   sT     c(C>>&!=.//#J??D 
yy"D)    c           	         ddl m} | j                         D ci c]%  \  }}|t        ||      r|n|j	                  |      ' c}}S c c}}w )Nr   )ToolTransformConfig)fastmcp.tools.tool_transformr&   items
isinstancemodel_validate)toolsr&   nameconfigs       r"   _coerce_tool_transform_configsr.   J   s]    @ "KKM	 *LD& 	f12  //7	8 *	  s   *Ac                       e Zd ZU dZ ee      Zded<   	  edd      Zded	<    edd
      Z	ded<    e
d      e	 	 	 	 dd              Z	 	 d	 	 	 	 	 d fdZddZ xZS )_TransformingMCPServerMixinzAA mixin that enables wrapping an MCP Server with tool transforms.default_factorydict[str, Any]r+   Nz!The tags to include in the proxy.)defaultdescriptionzset[str] | Noneinclude_tagsz!The tags to exclude in the proxy.exclude_tagsbeforemodec                    t        |t              rQt        |j                  d            }|j                  d      du}|j                  d      du}|s|s|st	        d      |S )a  Reject if none of the transforming fields are set.

        This ensures that plain server configs (without tools, include_tags,
        or exclude_tags) fall through to the base server types during union
        validation, avoiding unnecessary proxy wrapping.
        r+   r6   Nr7   zFAt least one of 'tools', 'include_tags', or 'exclude_tags' is required)r)   dictboolgetr   )clsvalues	has_toolshas_includehas_excludes        r"   %_require_at_least_one_transform_fieldzA_TransformingMCPServerMixin._require_at_least_one_transform_fielde   se     fd#VZZ01I **^4D@K **^4D@K \  r$   c                   	 ddl m} ddlm} ddlm} t        dt        
| -               } |||      } |||	      }	| j                  |	j                  | j                  d
       | j                  |	j                  | j                         | j                   r*|	j#                   |t%        | j                                      |	|fS # t        $ r$}t        t        j                  d            |d}~ww xY w)zKTurn the transforming server into a FastMCP proxy and return its transport.r   )Client)create_proxy)ToolTransformDMCP configs that use FastMCP-specific tool transforms or tag filtersNr   )	transportr,   )r,   T)tagsonly)rK   )fastmcprF   fastmcp.serverrG   fastmcp.server.transformsrH   ImportErrorr   full_packager	   superto_transportr6   enabler7   disabler+   add_transformr.   )selfserver_nameclient_namerF   rG   rH   excrJ   clientwrapped_mcp_server	__class__s             r"   #_to_server_and_underlying_transportz?_TransformingMCPServerMixin._to_server_and_underlying_transportz   s    		&3? *EG,@,BC	)+>)&{C(%%4+<+<4%H(&&D,=,=&>::,,<TZZHI "9,,)  	++Z 		s   C 	C9C44C9c                    	 ddl m}  || j                         d         S # t        $ r$}t        t        j                  d            |d}~ww xY w)z2Get the transport for the transforming MCP server.r   )FastMCPTransportrI   N)mcp)fastmcp.client.transportsr`   rP   r   rQ   r^   )rW   r`   rZ   s      r"   rS   z(_TransformingMCPServerMixin.to_transport   sZ    	B  D$L$L$Nq$QRR  	++Z 		s   " 	AA

Ar@   r3   returnr3   )NN)rX   
str | NonerY   re   rd   ztuple[Any, ClientTransport])rd   r   )__name__
__module____qualname____doc__r   r<   r+   __annotations__r6   r7   r   classmethodrD   r^   rS   __classcell__)r]   s   @r"   r0   r0   U   s    K!$7E>79$)7%L/ 
 %*7%L/ 
 (##	  $* #'"&--  - 
%	-@Sr$   r0   c                      e Zd ZU dZded<    ee      Zded<    ee      Z	ded<   d	Z
d
ed<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<    ed      ZddZy)StdioMCPServerzMCP server configuration for stdio transport.

    This is the canonical configuration format for MCP servers using stdio transport.
    r   commandr1   z	list[str]argsr3   envstdiozLiteral['stdio']rJ   NzLiteral['stdio'] | Nonetypere   cwd
int | Nonetimeoutzbool | None
keep_aliver5   icondict[str, Any] | Noneauthenticationallowextrac                    ddl m}  || j                  | j                  | j                  | j
                  | j                        S )Nr   )r   )ro   rp   rq   rt   rw   )rb   r   ro   rp   rq   rt   rw   )rW   r   s     r"   rS   zStdioMCPServer.to_transport   s5    <LL
 	
r$   )rd   r   )rf   rg   rh   ri   rj   r   listrp   r<   rq   rJ   rs   rt   rv   rw   r5   rx   rz   r   model_configrS    r$   r"   rn   rn      s     L D1D)15C5 #*I)$(D
!( CGZ  
 #K"D* -1N)0G,L	
r$   rn   c                      e Zd ZdZy)TransformingStdioMCPServerz$A Stdio server with tool transforms.Nrf   rg   rh   ri   r   r$   r"   r   r      s    .r$   r   c                      e Zd ZU dZded<   dZded<    ee      Zded	<   dZ	d
ed<   dZ
ded<   dZded<   dZded<   dZded<   dZded<    edd      ZddZy)RemoteMCPServerzMCP server configuration for HTTP/SSE transport.

    This is the canonical configuration format for MCP servers using remote transports.
    r   r    Nz0Literal['http', 'streamable-http', 'sse'] | NonerJ   r1   zdict[str, str]headerszAnnotated[str | Literal['oauth'] | httpx.Auth | None, Field(description='Either a string representing a Bearer token, the literal "oauth" to use OAuth authentication, or an httpx.Auth instance for custom authentication.')]authz'datetime.timedelta | int | float | Nonesse_read_timeoutru   rv   re   r5   rx   ry   rz   r{   T)r}   arbitrary_types_allowedc                H   ddl m}m} | j                  t	        | j
                        }n| j                  }|dk(  r4 || j
                  | j                  | j                  | j                        S  || j
                  | j                  | j                  | j                        S )Nr   )r   r   r   )r   r   r   )	rb   r   r   rJ   r#   r    r   r   r   )rW   r   r   rJ   s       r"   rS   zRemoteMCPServer.to_transport   s    	

 >>!5dhh?IIYY!%!6!6	  +YY!%!6!6	 r$   )rd   z&StreamableHttpTransport | SSETransport)rf   rg   rh   ri   rj   rJ   r   r<   r   r   r   rv   r5   rx   rz   r   r   rS   r   r$   r"   r   r      s     
H CGI?F#D9G^9 	 	   AE=DGZ #K"D* -1N)0tLr$   r   c                      e Zd ZdZy)TransformingRemoteMCPServerz%A Remote server with tool transforms.Nr   r   r$   r"   r   r     s    /r$   r   c                      e Zd ZU dZ ee      Zded<    ed      Z	 e
d      edd	              Zdd
Zedd       ZddZddZedd       Zy)	MCPConfiga8  A configuration object for MCP Servers that conforms to the canonical MCP configuration format
    while adding additional fields for enabling FastMCP-specific features like tool transformations
    and filtering by tags.

    For an MCPConfig that is strictly canonical, see the `CanonicalMCPConfig` class.
    r1   zdict[str, MCPServerTypes]
mcpServersr{   r|   r8   r9   c                Z    d|vr&t        d |j                         D              }|rd|iS |S )zMIf there's no mcpServers key but there are server configs at root, wrap them.r   c              3  T   K   | ]   }t        |t              xr
 d |v xs d|v  " yw)ro   r    N)r)   r<   ).0vs     r"   	<genexpr>z1MCPConfig.wrap_servers_at_root.<locals>.<genexpr>6  s4      (A 1d#Fa)E5A:F(s   &()anyr@   )r?   r@   has_serverss      r"   wrap_servers_at_rootzMCPConfig.wrap_servers_at_root0  s>     v%  K $f--r$   c                "    || j                   |<   yz,Add or update a server in the configuration.Nr   rW   r,   servers      r"   
add_serverzMCPConfig.add_server?  s     &r$   c                $    | j                  |      S )z/Parse MCP configuration from dictionary format.)r*   )r?   r-   s     r"   	from_dictzMCPConfig.from_dictC  s     !!&))r$   c                &    | j                  d      S )z>Convert MCPConfig to dictionary format, preserving all fields.Texclude_none)
model_dump)rW   s    r"   to_dictzMCPConfig.to_dictH  s    D11r$   c                    |j                   j                  dd       |j                  | j                  d      d       y)z!Write configuration to JSON file.T)parentsexist_ok   )indentutf-8encodingN)parentmkdir
write_textmodel_dump_json)rW   	file_paths     r"   write_to_filezMCPConfig.write_to_fileL  s<    td;T111;gNr$   c                    |j                         r3|j                  d      j                         x}r| j                  |      S t	        d|       )z"Load configuration from JSON file.r   r   z&No MCP servers defined in the config: )exists	read_textstripmodel_validate_jsonr   )r?   r   contents      r"   	from_filezMCPConfig.from_fileQ  sV      **G*<BBDDGD**733A)MNNr$   Nrc   )r,   r   r   MCPServerTypesrd   None)r-   r3   rd   r   )rd   r3   )r   r   rd   r   )r   r   rd   r   )rf   rg   rh   ri   r   r<   r   rj   r   r   r   rk   r   r   r   r   r   r   r   r$   r"   r   r   $  s|     -2$,GJ)GG,L(#  $' * *2O
 O Or$   r   c                  @    e Zd ZU dZ ee      Zded<   edd       Z	y)CanonicalMCPConfigzCanonical MCP configuration format.

    This defines the standard configuration format for Model Context Protocol servers.
    The format is designed to be client-agnostic and extensible for future use cases.
    r1   z"dict[str, CanonicalMCPServerTypes]r   c                "    || j                   |<   yr   r   r   s      r"   r   zCanonicalMCPConfig.add_servere  s     !'r$   N)r,   r   r   CanonicalMCPServerTypesrd   r   )
rf   rg   rh   ri   r   r<   r   rj   r   r   r   r$   r"   r   r   \  s+     6;45PJ2P' 'r$   r   c                B   t         j                  |       }|j                  j                  |      x}rJ|j	                         }|j	                  d      }|j                  i ||      }|j                  ||       n|j                  ||       |j                  |        y)zUpdate an MCP configuration file from a server object, preserving existing fields.

    This is used for updating the mcpServer configurations of third-party tools so we do not
    worry about transforming server objects here.Tr   N)r   r   r   r>   r   r*   r   r   )r   rX   server_configr-   existing_serverexisting_dictnew_dictmerged_configs           r"   update_config_filer   k  s       +F !++//<<<'224 +++> &445R5R5RS+}5+}5
#r$   )r    zstr | AnyUrlrd   zLiteral['http', 'sse'])r+   r3   rd   r3   )r   r   rX   r   r   r   rd   r   )-ri   
__future__r   datetimer   pathlibr   typingr   r   r   r   r	   urllib.parser
   httpxpydanticr   r   r   r   r   typing_extensionsr   r   rM   r   rb   r   r   r   r   r#   r.   r0   rn   r   r   r   TransformingMCPServerTypesr   r   r   r   r   r   r$   r"   <module>r      s  0 #  	  ? ? !   - " 	(PS) PSf*
Y *
Z/!<n /=i =@0"= 0 8:UU (?: +.EE5O	 5Op' '$$$ +$ 
	$r$   