
    Ki,                       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/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)ToolTransformConfig)FastMCPBaseModel)ClientTransportSSETransportStdioTransportStreamableHttpTransportFastMCPc                    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      ^/home/jay/workspace/scripts/.codegraph-venv/lib/python3.12/site-packages/fastmcp/mcp_config.pyinfer_transport_type_from_urlr&   8   sT     c(C>>&!=.//#J??D 
yy"D)    c                       e Zd ZU dZ ed      Zded<   	  edd      Zded	<    edd
      Zded<   	 	 d	 	 	 	 	 d fdZ	ddZ
 xZS )_TransformingMCPServerMixinzAA mixin that enables wrapping an MCP Server with tool transforms..z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_tagsc                    ddl m} ddlm} ddlm} t        	|          }t        ||      } |||      } |j                  ||| j                  | j                  | j                        }||fS )z_Turn the Transforming MCPServer into a FastMCP Server and also return the underlying transport.r   r   )Client)r   )	transportname)r2   backendtool_transformationsr-   r.   )fastmcpr   fastmcp.clientr0   fastmcp.client.transportsr   superto_transportr	   as_proxyr*   r-   r.   )
selfserver_nameclient_namer   r0   r   r1   clientwrapped_mcp_server	__class__s
            r%   #_to_server_and_underlying_transportz?_TransformingMCPServerMixin._to_server_and_underlying_transport\   sv     	$)	
 &+W%9%;	)4	*09;*W-W--!%****
 "9,,r'   c                B    ddl m}  || j                         d         S )z2Get the transport for the transforming MCP server.r   )FastMCPTransport)mcp)r7   rC   rA   )r;   rC   s     r%   r9   z(_TransformingMCPServerMixin.to_transportw   s    >D$L$L$Nq$QRRr'   )NN)r<   
str | Noner=   rE   returnz$tuple[FastMCP[Any], ClientTransport])rF   r   )__name__
__module____qualname____doc__r   r*   __annotations__r-   r.   rA   r9   __classcell__)r@   s   @r%   r)   r)   L   sw    K,1#JE)69$)7%L/ 
 %*7%L/  #'"&--  - 
.	-6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<    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   commanddefault_factoryz	list[str]argsdict[str, Any]envstdiozLiteral['stdio']r1   NzLiteral['stdio'] | NonetyperE   cwd
int | Nonetimeoutr,   icondict[str, Any] | Noneauthenticationallowextrac                v    ddl m}  || j                  | j                  | j                  | j
                        S )Nr   )r   )rO   rR   rT   rW   )r7   r   rO   rR   rT   rW   )r;   r   s     r%   r9   zStdioMCPServer.to_transport   s.    <LL	
 	
r'   )rF   r   )rG   rH   rI   rJ   rK   r   listrR   dictrT   r1   rV   rW   rY   r,   rZ   r\   r   model_configr9    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rG   rH   rI   rJ   rd   r'   r%   rf   rf      s    .r'   rf   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'] | Noner1   rP   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_timeoutrX   rY   rE   r,   rZ   r[   r\   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   )rj   rk   rl   )	r7   r   r   r1   r&   r#   rj   rk   rl   )r;   r   r   r1   s       r%   r9   zRemoteMCPServer.to_transport   s    S>>!5dhh?IIYY!%!6!6	  +YY!%!6!6	 r'   )rF   z&StreamableHttpTransport | SSETransport)rG   rH   rI   rJ   rK   r1   r   rb   rj   rk   rl   rY   r,   rZ   r\   r   rc   r9   rd   r'   r%   ri   ri      s     
H CGI?F#D9G^9 	 	   AE=DGZ #K"D* -1N)0tLr'   ri   c                      e Zd ZdZy)TransformingRemoteMCPServerz%A Remote server with tool transforms.Nrg   rd   r'   r%   rp   rp      s    /r'   rp   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.
    rP   zdict[str, MCPServerTypes]
mcpServersr]   r^   before)modec                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.rs   c              3  T   K   | ]   }t        |t              xr
 d |v xs d|v  " yw)rO   r#   N)
isinstancerb   ).0vs     r%   	<genexpr>z1MCPConfig.wrap_servers_at_root.<locals>.<genexpr>  s4       1d#Fa)E5A:Fs   &()anyvalues)clsr}   has_serverss      r%   wrap_servers_at_rootzMCPConfig.wrap_servers_at_root   s>     v%  K $f--r'   c                "    || j                   |<   yz,Add or update a server in the configuration.Nrs   r;   r2   servers      r%   
add_serverzMCPConfig.add_server  s     &r'   c                $    | j                  |      S )z/Parse MCP configuration from dictionary format.)model_validate)r~   configs     r%   	from_dictzMCPConfig.from_dict  s     !!&))r'   c                &    | j                  d      S )z>Convert MCPConfig to dictionary format, preserving all fields.Texclude_none)
model_dump)r;   s    r%   to_dictzMCPConfig.to_dict  s    D11r'   c                    |j                   j                  dd       |j                  | j                  d             y)z!Write configuration to JSON file.T)parentsexist_ok   )indentN)parentmkdir
write_textmodel_dump_json)r;   	file_paths     r%   write_to_filezMCPConfig.write_to_file  s7    td;T111;<r'   c                    |j                         r1|j                         j                         x}r| j                  |      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_file   sP     i.A.A.C.I.I.K#K7#K**733A)MNNr'   N)r}   rS   rF   rS   )r2   r   r   MCPServerTypesrF   None)r   rS   rF   r   )rF   rS   )r   r   rF   r   )r   r   rF   r   )rG   rH   rI   rJ   r   rb   rs   rK   r   rc   r   classmethodr   r   r   r   r   r   rd   r'   r%   rr   rr      s{     -2$,GJ)GG,L(#  $' * *2=
 O Or'   rr   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.
    rP   z"dict[str, CanonicalMCPServerTypes]rs   c                "    || j                   |<   yr   r   r   s      r%   r   zCanonicalMCPConfig.add_server2  s     !'r'   N)r2   r   r   CanonicalMCPServerTypesrF   r   )
rG   rH   rI   rJ   r   rb   rs   rK   r   r   rd   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)rr   r   rs   getr   r   r   r   )r   r<   server_configr   existing_serverexisting_dictnew_dictmerged_configs           r%   update_config_filer   8  s       +F !++//<<<'224 +++> &445R5R5RS+}5+}5
#r'   )r#   zstr | AnyUrlrF   zLiteral['http', 'sse'])r   r   r<   r   r   r   rF   r   )0rJ   
__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   r7   r   r   r   r   fastmcp.server.serverr   r&   r)   rN   rf   ri   rp   TransformingMCPServerTypesr   r   rr   r   r   rd   r'   r%   <module>r      s  0 #  	  ? ? !   - < 4  .	(/S"2 /Sd&
Y &
R/!<n /:i :z0"= 0 8:UU (?: +.EE3O	 3Ol' '$$$ +$ 
	$r'   