
    #j1                       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 dd
lmZ erddlmZmZm Z m!Z! ddl"m#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/dS )*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)ToolTransformConfig)FastMCPBaseModel)ClientTransportSSETransportStdioTransportStreamableHttpTransport)FastMCPurlstr | AnyUrlreturnLiteral['http', 'sse']c                    t          |           } |                     d          st          d|            t          |           }|j        }t          j        d|          rdS dS )zB
    Infer the appropriate transport type from the given URL.
    httpzInvalid URL: z/sse(/|\?|&|$)sse)str
startswith
ValueErrorr
   pathresearch)r   
parsed_urlr#   s      Z/home/rurouni/.hermes/hermes-agent/venv/lib/python3.11/site-packages/fastmcp/mcp_config.pyinfer_transport_type_from_urlr(   8   sm     c((C>>&!! 0...///#J?D 
y"D)) uv    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_factoryzdict[str, ToolTransformConfig]toolsNz!The tags to include in the proxy.)defaultdescriptionzset[str] | Noneinclude_tagsz!The tags to exclude in the proxy.exclude_tagsbeforemodevaluesdict[str, Any]r   c                    t          |t                    ret          |                    d                    }|                    d          du}|                    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.   r1   Nr2   zFAt least one of 'tools', 'include_tags', or 'exclude_tags' is required)
isinstancedictboolgetr"   )clsr6   	has_toolshas_includehas_excludes        r'   %_require_at_least_one_transform_fieldzA_TransformingMCPServerMixin._require_at_least_one_transform_field\   s     fd## 	VZZ0011I **^44D@K **^44D@K    \   r)   server_name
str | Noneclient_name$tuple[FastMCP[Any], ClientTransport]c                   ddl m} ddlm} ddlm} t                                                      }t          ||          } |||          } |||          }| j	        |
                    | j	        d	           | j        |                    | j        
           | j        r)ddlm}	 |                     |	| j                             ||fS )z_Turn the Transforming MCPServer into a FastMCP Server and also return the underlying transport.r   )Client)r   )create_proxy)	transportname)rJ   NT)tagsonly)rK   )ToolTransform)fastmcp.clientrG   fastmcp.client.transportsr   fastmcp.serverrH   superto_transportr	   r1   enabler2   disabler.   fastmcp.server.transformsrM   add_transform)selfrB   rD   rG   r   rH   rI   clientwrapped_mcp_serverrM   	__class__s             r'   #_to_server_and_underlying_transportz?_TransformingMCPServerMixin._to_server_and_underlying_transportq   s2    	*)))))	
 	
 	
 	
 	
 	
 	0/////%*WW%9%9%;%;	)44	*0&9;*W*W*W)\
 
 

 (%%4+<4%HHH(&&D,=&>>> : 	H??????,,]]4:-F-FGGG!9,,r)   r   c                V    ddl m}  ||                                 d                   S )z2Get the transport for the transforming MCP server.r   )FastMCPTransport)mcp)rO   r]   r[   )rW   r]   s     r'   rR   z(_TransformingMCPServerMixin.to_transport   s9    >>>>>>D$L$L$N$Nq$QRRRRr)   r6   r7   r   r7   )NN)rB   rC   rD   rC   r   rE   )r   r   )__name__
__module____qualname____doc__r   r:   r.   __annotations__r1   r2   r   classmethodrA   r[   rR   __classcell__)rZ   s   @r'   r+   r+   L   s*        KK,1E$,G,G,GEGGGG9$)E7% % %L    
 %*E7% % %L    
 _(###   [ $#* #'"&!- !- !- !- !- !- !-FS S S S S S S Sr)   r+   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dS )StdioMCPServerzMCP server configuration for stdio transport.

    This is the canonical configuration format for MCP servers using stdio transport.
    r    commandr,   z	list[str]argsr7   envstdiozLiteral['stdio']rI   NzLiteral['stdio'] | NonetyperC   cwd
int | Nonetimeoutzbool | None
keep_aliver0   icondict[str, Any] | Noneauthenticationallowextrar   r   c                `    ddl m}  || j        | j        | j        | j        | j                  S )Nr   )r   )ri   rj   rk   rn   rq   )rO   r   ri   rj   rk   rn   rq   )rW   r   s     r'   rR   zStdioMCPServer.to_transport   sF    <<<<<<~L
 
 
 	
r)   )r   r   )r`   ra   rb   rc   rd   r   listrj   r:   rk   rI   rm   rn   rp   rq   r0   rr   rt   r   model_configrR    r)   r'   rh   rh      s*          LLL eD111D1111%555C5555 #*I))))$(D(((( CG     
 #K""""D -1N0000:G,,,L	
 	
 	
 	
 	
 	
r)   rh   c                      e Zd ZdZdS )TransformingStdioMCPServerz$A Stdio server with tool transforms.Nr`   ra   rb   rc   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dS )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'] | NonerI   r,   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_timeoutro   rp   rC   r0   rr   rs   rt   ru   T)rw   arbitrary_types_allowedr   &StreamableHttpTransport | SSETransportc                    ddl m}m} | j        t	          | j                  }n| j        }|dk    r# || j        | j        | j        | j                  S  || j        | j        | j        | j                  S )Nr   )r   r   r   )r   r   r   )	rO   r   r   rI   r(   r   r   r   r   )rW   r   r   rI   s       r'   rR   zRemoteMCPServer.to_transport   s    SSSSSSSS>!5dh??III<Y!%!6	    +*Y!%!6	   r)   )r   r   )r`   ra   rb   rc   rd   rI   r   r:   r   r   r   rp   r0   rr   rt   r   rz   rR   r{   r)   r'   r   r      s	          HHH CGIFFFF#eD999G9999 	 	     AEDDDDG #K""""D -1N0000:t  L     r)   r   c                      e Zd ZdZdS )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dS )"	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.
    r,   zdict[str, MCPServerTypes]
mcpServersru   rv   r3   r4   r6   r7   r   c                p    d|vr1t          d |                                D                       }|rd|iS |S )zMIf there's no mcpServers key but there are server configs at root, wrap them.r   c              3  P   K   | ]!}t          |t                    od |v pd|v V  "dS )ri   r   N)r9   r:   ).0vs     r'   	<genexpr>z1MCPConfig.wrap_servers_at_root.<locals>.<genexpr>&  sR         1d##Fa)E5A:     r)   )anyr6   )r=   r6   has_serverss      r'   wrap_servers_at_rootzMCPConfig.wrap_servers_at_root   s\     v%%      K  .$f--r)   rJ   r    serverMCPServerTypesNonec                    || j         |<   dS z,Add or update a server in the configuration.Nr   rW   rJ   r   s      r'   
add_serverzMCPConfig.add_server/  s     &r)   configr   c                ,    |                      |          S )z/Parse MCP configuration from dictionary format.)model_validate)r=   r   s     r'   	from_dictzMCPConfig.from_dict3  s     !!&)))r)   c                .    |                      d          S )z>Convert MCPConfig to dictionary format, preserving all fields.Texclude_none)
model_dump)rW   s    r'   to_dictzMCPConfig.to_dict8  s    D111r)   	file_pathr   c                    |j                             dd           |                    |                     d                     dS )z!Write configuration to JSON file.T)parentsexist_ok   )indentN)parentmkdir
write_textmodel_dump_json)rW   r   s     r'   write_to_filezMCPConfig.write_to_file<  sI    td;;;T111;;<<<<<r)   c                    |                                 r=|                                                                x}r|                     |          S t	          d|           )z"Load configuration from JSON file.z&No MCP servers defined in the config: )exists	read_textstripmodel_validate_jsonr"   )r=   r   contents      r'   	from_filezMCPConfig.from_fileA  sg      	4i.A.A.C.C.I.I.K.K#K7 	4**7333M)MMNNNr)   Nr_   )rJ   r    r   r   r   r   )r   r7   r   r   )r   r7   )r   r   r   r   )r   r   r   r   )r`   ra   rb   rc   r   r:   r   rd   r   rz   r   re   r   r   r   r   r   r   r{   r)   r'   r   r     s
          -2E$,G,G,GJGGGG:G,,,L_(###   [ $#' ' ' ' * * * [*2 2 2 2= = = =
 O O O [O O Or)   r   c                  N    e Zd ZU dZ ee          Zded<   edd            Z	dS )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.
    r,   z"dict[str, CanonicalMCPServerTypes]r   rJ   r    r   CanonicalMCPServerTypesr   r   c                    || j         |<   dS r   r   r   s      r'   r   zCanonicalMCPConfig.add_serverS  s     !'r)   N)rJ   r    r   r   r   r   )
r`   ra   rb   rc   r   r:   r   rd   r   r   r{   r)   r'   r   r   J  s^           6;U45P5P5PJPPPP' ' ' X' ' 'r)   r   r   r   rB   r    server_configr   r   c                |   t                               |           }|j                            |          x}rZ|                                }|                    d          }|                    i ||          }|                    ||           n|                    ||           |                    |            dS )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   rB   r   r   existing_serverexisting_dictnew_dictmerged_configs           r'   update_config_filer   Y  s       ++F !+//<<< 6'2244 +++>> &445R5R5RSS+}5555+}555
#####r)   )r   r   r   r   )r   r   rB   r    r   r   r   r   )0rc   
__future__r   datetimer$   pathlibr   typingr   r   r   r   r	   urllib.parser
   httpxpydanticr   r   r   r   r   typing_extensionsr   r   fastmcp.tools.tool_transformr   fastmcp.utilities.typesr   rO   r   r   r   r   fastmcp.server.serverr   r(   r+   rh   r}   r   r   TransformingMCPServerTypesr   r   r   r   r   r{   r)   r'   <module>r      s   0 # " " " " "  				       ? ? ? ? ? ? ? ? ? ? ? ? ? ? ! ! ! ! ! !               - , , , , , , , < < < < < < 4 4 4 4 4 4 .            .-----   (LS LS LS LS LS"2 LS LS LS^*
 *
 *
 *
 *
Y *
 *
 *
Z/ / / / /!<n / / /: : : : :i : : :z0 0 0 0 0"= 0 0 0 8:UU (?: +.EE3O 3O 3O 3O 3O	 3O 3O 3Ol' ' ' ' ' ' ' '$ $ $ $ $ $r)   