
    )`i              	      d   d Z ddlmZ ddl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mZ ddlmZmZmZ ddlZddl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  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+m,Z,m-Z- ddl.m/Z/ ddl0m1Z1m2Z2 ddl3m4Z4m5Z5m6Z6 ddl7m8Z8 ddl9m:Z:m;Z;m<Z<m=Z= ddl9m>Z? ddl@mAZA ddlBmCZCmDZD ddlEmFZFmGZGmHZH ddlImJZJmKZK ddlLmMZM ddlNmOZOmPZP ddlQmRZR ddlSmTZT ddlSmUZV dd lSmWZX dd!lYmZZZm[Z[ dd"l\m]Z] dd#l^m_Z_ dd$l`maZa dd%lbmcZc dd&ldmeZe dd'lfmgZgmhZhmiZi dd(ljmkZkmlZlmmZmmnZnmoZompZp dd)ljmCZq dd*ljmrZs dd+ljmGZt dd,ljmuZv dd-ljmJZw  ePex          Zy G d. d/eeeT                   Zzd=d6Z{ G d7 d8eeT                   Z| G d9 d:          Z} G d; d<eee[egeif                   Z~dS )>z5FastMCP - A more ergonomic interface for MCP servers.    )annotationsN)AsyncIterator	AwaitableCallable
CollectionIterableSequence)AbstractAsyncContextManagerasynccontextmanager)AnyGenericLiteral)	BaseModel)AnyUrl)BaseSettingsSettingsConfigDict)	Starlette
Middleware)AuthenticationMiddleware)Request)ResponseMountRoute)ReceiveScopeSend)AuthContextMiddleware)BearerAuthBackendRequireAuthMiddleware) OAuthAuthorizationServerProviderProviderTokenVerifierTokenVerifier)AuthSettings)ElicitationResultElicitSchemaModelTUrlElicitationResultelicit_with_validation)
elicit_url)ResourceError)PromptPromptManager)FunctionResourceResourceResourceManager)ToolToolManager)find_context_parameter)configure_logging
get_logger)ReadResourceContents)LifespanResultT)Server)lifespan)ServerSessionServerSessionT)SseServerTransport)stdio_server)
EventStore)StreamableHTTPSessionManager)TransportSecuritySettings)LifespanContextTRequestContextRequestT)AnnotationsAnyFunctionContentBlockGetPromptResultIconToolAnnotations)r,   )PromptArgument)r/   )ResourceTemplate)r1   c                      e Zd ZU dZ eddddd          Zded	<   d
ed<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   	 ded<   ded<   ded<   ded<   	 ded<   	 ded<   ded <   d!S )"SettingszFastMCP server settings.

    All settings can be configured via environment variables with the prefix FASTMCP_.
    For example, FASTMCP_DEBUG=true will set debug=True.
    FASTMCP_z.env__Tignore)
env_prefixenv_fileenv_nested_delimiter#nested_model_default_partial_updateextrabooldebug8Literal['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']	log_levelstrhostintport
mount_pathsse_pathmessage_pathstreamable_http_pathjson_responsestateless_httpwarn_on_duplicate_resourceswarn_on_duplicate_toolswarn_on_duplicate_prompts	list[str]dependenciesYCallable[[FastMCP[LifespanResultT]], AbstractAsyncContextManager[LifespanResultT]] | Noner9   AuthSettings | Noneauth TransportSecuritySettings | Nonetransport_securityN)__name__
__module____qualname____doc__r   model_config__annotations__     m/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/mcp/server/fastmcp/server.pyrM   rM   N   s          &%!,0  L KKKGGGG IIIIIIOOOMMM I &%%% "!!! $### FggggQ 988888ru   rM   appFastMCP[LifespanResultT]r9   RCallable[[FastMCP[LifespanResultT]], AbstractAsyncContextManager[LifespanResultT]]return]Callable[[MCPServer[LifespanResultT, Request]], AbstractAsyncContextManager[LifespanResultT]]c                2     t           d fd            }|S )N_#MCPServer[LifespanResultT, Request]rz   AsyncIterator[LifespanResultT]c                  K              4 d {V }|W V  d d d           d {V  d S # 1 d {V swxY w Y   d S Nrt   )r}   contextrw   r9   s     rv   wrapzlifespan_wrapper.<locals>.wrap   s       8C== 	 	 	 	 	 	 	GMMMM	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   .
88)r}   r~   rz   r   )r   )rw   r9   r   s   `` rv   lifespan_wrapperr      s;            Kru   c                     e Zd Z	 	 	 	 	 	 	 	 dddddddddd	ddd
d
d
ddddddd6Zedd8            Zedd9            Zedd:            Zedd;            Zedd=            Z		 	 dddBZ
ddCZddEZddGZddKZddMZddOZddSZ	 	 	 	 	 	 	 ddd^Zdd_Z	 	 	 	 	 	 	 dddaZdb ZddeZddddddddfddiZddlZ	 	 	 	 dddmZ	 	 dddrZddsZdddtZdduZddwZdddyZddzZ dd|Z!ddd~Z"dS )FastMCPNFINFO	127.0.0.1i@  /z/ssez
/messages/z/mcpTrt   )toolsrW   rY   r[   r]   r^   r_   r`   ra   rb   rc   rd   re   rf   rh   r9   rk   rm   name
str | Noneinstructionswebsite_urliconslist[Icon] | Noneauth_server_provider6OAuthAuthorizationServerProvider[Any, Any, Any] | Nonetoken_verifierTokenVerifier | Noneevent_storeEventStore | Noneretry_interval
int | Noner   list[Tool] | NonerW   rV   rY   rX   r[   rZ   r]   r\   r^   r_   r`   ra   rb   rc   rd   re   rf   rh   Collection[str]r9   ri   rk   rj   rm   rl   c	          
        ||dv rt          dg dg d          }t          di d|
d|d|d	|d
|d|d|d|d|d|d|d|d|dt          |          d|d|d|| _        t	          |pd|||| j        j        rt          | | j        j                  nt                    | _        t          |	| j        j
                  | _        t          | j        j                  | _        t          | j        j                  | _        | j        j        '|r|rt'          d          |s|st'          d          n|s|rt'          d          || _        || _        |r|st-          |          | _        || _        || _        g | _        | j        j        | _        d | _        |                                  t;          | j        j                   d S ) N)r   	localhostz::1T)z127.0.0.1:*zlocalhost:*z[::1]:*)zhttp://127.0.0.1:*zhttp://localhost:*zhttp://[::1]:*)enable_dns_rebinding_protectionallowed_hostsallowed_originsrW   rY   r[   r]   r^   r_   r`   ra   rb   rc   rd   re   rf   rh   r9   rk   rm   r   )r   r   r   r   r9   )r   re   )rd   )rf   z;Cannot specify both auth_server_provider and token_verifierzOMust specify either auth_server_provider or token_verifier when auth is enabledzKCannot specify auth_server_provider or token_verifier without auth settingsrt   )r@   rM   listsettings	MCPServerr9   r   default_lifespan_mcp_serverr2   re   _tool_managerr0   rd   _resource_managerr-   rf   _prompt_managerrk   
ValueError_auth_server_provider_token_verifierr#   _event_store_retry_interval_custom_starlette_routesrh   _session_manager_setup_handlersr4   rY   )selfr   r   r   r   r   r   r   r   r   rW   rY   r[   r]   r^   r_   r`   ra   rb   rc   rd   re   rf   rh   r9   rk   rm   s                              rv   __init__zFastMCP.__init__   s   > %$2S*S*S!:04GGG ^ ^ ^" " " ! 
 
 
%
i
 
 	

 "z
 X
 &
 "6!5
 (-
 *>
 )D(C
 %<$;
 '@&?
 l+++
 X
  !
"  21#
( %"%# IMH^t&tT]-CDDDdt
 
 
 )udmNsttt!0T]Mv!w!w!w,t}Gnooo=)# ` ` !^___' t t !rsss! 	l^ 	ljkkk%9"-   	O 	O#89M#N#ND '-57% M6EI 	 	$-122222ru   rz   c                    | j         j        S r   )r   r   r   s    rv   r   zFastMCP.name   s    $$ru   c                    | j         j        S r   )r   r   r   s    rv   r   zFastMCP.instructions   s    ,,ru   c                    | j         j        S r   )r   r   r   s    rv   r   zFastMCP.website_url   s    ++ru   c                    | j         j        S r   )r   r   r   s    rv   r   zFastMCP.icons   s    %%ru   r?   c                <    | j         t          d          | j         S )a  Get the StreamableHTTP session manager.

        This is exposed to enable advanced use cases like mounting multiple
        FastMCP servers in a single FastAPI application.

        Raises:
            RuntimeError: If called before streamable_http_app() has been called.
        NzSession manager can only be accessed aftercalling streamable_http_app().The session manager is created lazilyto avoid unnecessary initialization.)r   RuntimeErrorr   s    rv   session_managerzFastMCP.session_manager  s/      (7   $$ru   stdio	transport*Literal['stdio', 'sse', 'streamable-http']Nonec                "    t           d         }||j        vrt          d|           |xdk    r t          j         j                   dS xdk    r t          j         fd           dS dk    rt          j         j                   dS dS )zRun the FastMCP server. Note this is a synchronous function.

        Args:
            transport: Transport protocol to use ("stdio", "sse", or "streamable-http")
            mount_path: Optional mount path for SSE transport
        )r   ssestreamable-httpzUnknown transport: r   r   c                 .                                    S r   )run_sse_async)r^   r   s   rv   <lambda>zFastMCP.run.<locals>.<lambda>*  s    $"4"4Z"@"@ ru   r   N)r   __args__r   anyiorunrun_stdio_asyncrun_streamable_http_async)r   r   r^   
TRANSPORTSs   ` ` rv   r   zFastMCP.run  s     >?
J///>9>>???	$./////	@@@@@AAAAA"""	$899999 #"ru   c                ,    | j                                         | j                    | j                             d          | j                    | j                                         | j                    | j                                         | j                    | j                                         | j                    | j                                         | j                    | j                                         | j                   dS )z"Set up core MCP protocol handlers.F)validate_inputN)r   
list_tools	call_toollist_resourcesread_resourcelist_prompts
get_promptlist_resource_templatesr   s    rv   r   zFastMCP._setup_handlers.  s    %##%%do666 	9""%"88HHH)''))$*=>>>(&&(();<<<'%%''(9:::%##%%do6662002243OPPPPPru   list[MCPTool]c                P   K   | j                                         }d |D             S )zList all available tools.c                    g | ]A}t          |j        |j        |j        |j        |j        |j        |j        |j                   BS ))r   titledescriptioninputSchemaoutputSchemar   r   _meta)	MCPToolr   r   r   
parametersoutput_schemar   r   meta).0infos     rv   
<listcomp>z&FastMCP.list_tools.<locals>.<listcomp>>  sd     
 
 
  Yj , O!/ ,ji	 	 	
 
 
ru   )r   r   )r   r   s     rv   r   zFastMCP.list_tools;  s=      "--//
 
 
 
 
 	
ru   0Context[ServerSession, LifespanResultT, Request]c                d    	 | j         j        }n# t          $ r d}Y nw xY wt          ||           S )z
        Returns a Context object. Note that the context will only be valid
        during a request; outside a request, most methods will error.
        Nrequest_contextfastmcp)r   r   LookupErrorContext)r   r   s     rv   get_contextzFastMCP.get_contextL  sK    
	#".>OO 	# 	# 	#"OOO	#EEEEs    	argumentsdict[str, Any]'Sequence[ContentBlock] | dict[str, Any]c                v   K   |                                  }| j                            |||d           d{V S )z#Call a tool by name with arguments.T)r   convert_resultN)r   r   r   )r   r   r   r   s       rv   r   zFastMCP.call_toolW  sJ      ""$$'11$	7cg1hhhhhhhhhru   list[MCPResource]c                P   K   | j                                         }d |D             S )zList all available resources.c                    g | ]C}t          |j        |j        pd |j        |j        |j        |j        |j        |j                  DS ) )urir   r   r   mimeTyper   r   r   )	MCPResourcer   r   r   r   	mime_typer   r   r   )r   resources     rv   r   z*FastMCP.list_resources.<locals>.<listcomp>`  si     
 
 
  L](bn$0!+n$0m	 	 	
 
 
ru   )r   r   )r   	resourcess     rv   r   zFastMCP.list_resources\  s?       *99;;	
 
 &
 
 
 	
ru   list[MCPResourceTemplate]c                P   K   | j                                         }d |D             S )Nc                    g | ]A}t          |j        |j        |j        |j        |j        |j        |j        |j                   BS ))uriTemplater   r   r   r   r   r   r   )	MCPResourceTemplateuri_templater   r   r   r   r   r   r   )r   templates     rv   r   z3FastMCP.list_resource_templates.<locals>.<listcomp>p  se     
 
 
   $1]n$0!+n$0m	 	 	
 
 
ru   )r   list_templates)r   	templatess     rv   r   zFastMCP.list_resource_templatesn  s=      *99;;	
 
 &
 
 
 	
ru   r   AnyUrl | strIterable[ReadResourceContents]c                  K   |                                  }| j                            ||           d{V }|st          d|           	 |                                 d{V }t          ||j        |j                  gS # t          $ r>}t          
                    d|            t          t          |                    d}~ww xY w)zRead a resource by URI.r   NzUnknown resource: )contentr   r   zError reading resource )r   r   get_resourcer+   readr6   r   r   	Exceptionlogger	exceptionrZ   )r   r   r   r   r  es         rv   r   zFastMCP.read_resource~  s       ""$$/<<S'<RRRRRRRR 	< :S : :;;;	($MMOO++++++G(HDV]e]jkkkll 	( 	( 	(<s<<===A'''	(s   6B 
C9CCfnrE   r   r   r   ToolAnnotations | Noner   dict[str, Any] | Nonestructured_outputbool | Nonec	           
     J    | j                             ||||||||           dS )a  Add a tool to the server.

        The tool function can optionally request a Context object by adding a parameter
        with the Context type annotation. See the @tool decorator for examples.

        Args:
            fn: The function to register as a tool
            name: Optional name for the tool (defaults to function name)
            title: Optional human-readable title for the tool
            description: Optional description of what the tool does
            annotations: Optional ToolAnnotations providing additional tool information
            structured_output: Controls whether the tool's output is structured or unstructured
                - If None, auto-detects based on the function's return type annotation
                - If True, creates a structured tool (return type annotation permitting)
                - If False, unconditionally creates an unstructured tool
        r   r   r   r   r   r   r  N)r   add_tool)	r   r  r   r   r   r   r   r   r  s	            rv   r  zFastMCP.add_tool  sF    6 	####/ 	$ 		
 		
 		
 		
 		
ru   c                :    | j                             |           dS )zRemove a tool from the server by name.

        Args:
            name: The name of the tool to remove

        Raises:
            ToolError: If the tool does not exist
        N)r   remove_tool)r   r   s     rv   r  zFastMCP.remove_tool  s!     	&&t,,,,,ru   $Callable[[AnyFunction], AnyFunction]c           	     l     t                    rt          d          d fd}|S )ad  Decorator to register a tool.

        Tools can optionally request a Context object by adding a parameter with the
        Context type annotation. The context provides access to MCP capabilities like
        logging, progress reporting, and resource access.

        Args:
            name: Optional name for the tool (defaults to function name)
            title: Optional human-readable title for the tool
            description: Optional description of what the tool does
            annotations: Optional ToolAnnotations providing additional tool information
            structured_output: Controls whether the tool's output is structured or unstructured
                - If None, auto-detects based on the function's return type annotation
                - If True, creates a structured tool (return type annotation permitting)
                - If False, unconditionally creates an unstructured tool

        Example:
            @server.tool()
            def my_tool(x: int) -> str:
                return str(x)

            @server.tool()
            def tool_with_context(x: int, ctx: Context) -> str:
                ctx.info(f"Processing {x}")
                return str(x)

            @server.tool()
            async def async_tool(x: int, context: Context) -> str:
                await context.report_progress(50, 100)
                return str(x)
        zaThe @tool decorator was used incorrectly. Did you forget to call it? Use @tool() instead of @toolr  rE   rz   c           
     B                         |            | S )Nr  )r  )	r  r   r   r   r   r   r   r  r   s	    rv   	decoratorzFastMCP.tool.<locals>.decorator  s=    MM''"3  	 	 	 Iru   r  rE   rz   rE   callable	TypeError)	r   r   r   r   r   r   r   r  r  s	   ```````` rv   toolzFastMCP.tool  sy    T D>> 	s  	 	 	 	 	 	 	 	 	 	 	 	 	 ru   c                4    | j                                         S )a  Decorator to register a completion handler.

        The completion handler receives:
        - ref: PromptReference or ResourceTemplateReference
        - argument: CompletionArgument with name and partial value
        - context: Optional CompletionContext with previously resolved arguments

        Example:
            @mcp.completion()
            async def handle_completion(ref, argument, context):
                if isinstance(ref, ResourceTemplateReference):
                    # Return completions based on ref, argument, and context
                    return Completion(values=["option1", "option2"])
                return None
        )r   
completionr   s    rv   r!  zFastMCP.completion  s      **,,,ru   r   r/   c                :    | j                             |           dS )zfAdd a resource to the server.

        Args:
            resource: A Resource instance to add
        N)r   add_resource)r   r   s     rv   r#  zFastMCP.add_resource  s!     	++H55555ru   )r   r   r   r   r   r   r   r   Annotations | Nonec          
     p     t                    rt          d          d f	d}	|	S )a  Decorator to register a function as a resource.

        The function will be called when the resource is read to generate its content.
        The function can return:
        - str for text content
        - bytes for binary content
        - other types will be converted to JSON

        If the URI contains parameters (e.g. "resource://{param}") or the function
        has parameters, it will be registered as a template resource.

        Args:
            uri: URI for the resource (e.g. "resource://my-resource" or "resource://{param}")
            name: Optional name for the resource
            title: Optional human-readable title for the resource
            description: Optional description of the resource
            mime_type: Optional MIME type for the resource
            meta: Optional metadata dictionary for the resource

        Example:
            @server.resource("resource://my-resource")
            def get_data() -> str:
                return "Hello, world!"

            @server.resource("resource://my-resource")
            async get_data() -> str:
                data = await fetch_data()
                return f"Hello, world! {data}"

            @server.resource("resource://{city}/weather")
            def get_weather(city: str) -> str:
                return f"Weather for {city}"

            @server.resource("resource://{city}/weather")
            async def get_weather(city: str) -> str:
                data = await fetch_weather(city)
                return f"Weather for {city}: {data}"
        zrThe @resource decorator was used incorrectly. Did you forget to call it? Use @resource('uri') instead of @resourcer  rE   rz   c                   	 t          j        |           }dv odv }t          |j                  }|s|rt	          |           t          t          j        d                    }fd|j                                        D             }||k    rt          d| d|           j
                            | 	
	  	         n2t          j        | 	
	  	        }                    |           | S )	N{}z{(\w+)}c                     h | ]
}|k    |S rt   rt   )r   pcontext_params     rv   	<setcomp>z6FastMCP.resource.<locals>.decorator.<locals>.<setcomp>]  s#    VVVQ1CUCUqCUCUCUru   z Mismatch between URI parameters z and function parameters )	r  r   r   r   r   r   r   r   r   )	r  r   r   r   r   r   r   r   r   )inspect	signaturerV   r   r3   setrefindallkeysr   r   add_templater.   from_functionr#  )r  sighas_uri_paramshas_func_params
uri_paramsfunc_paramsr   r+  r   r   r   r   r   r   r   r   r   s          @rv   r  z#FastMCP.resource.<locals>.decoratorO  sX   #B''C CZ6C3JN"3>22O (, (, 6r : : !J!<!<==
 WVVV#.*=*=*?*?VVV,,$m:mm`kmm  
 &33!$ +' + 4 
 
 
 
 ,9 +' +
 
 
 !!(+++Iru   r  r  )
r   r   r   r   r   r   r   r   r   r  s
   ````````` rv   r   zFastMCP.resource  s    f C== 	W  
/	 /	 /	 /	 /	 /	 /	 /	 /	 /	 /	 /	 /	 /	b ru   promptr,   c                :    | j                             |           dS )z`Add a prompt to the server.

        Args:
            prompt: A Prompt instance to add
        N)r   
add_prompt)r   r:  s     rv   r<  zFastMCP.add_prompt  s!     	''/////ru   c                `     t                    rt          d          d fd}|S )a  Decorator to register a prompt.

        Args:
            name: Optional name for the prompt (defaults to function name)
            title: Optional human-readable title for the prompt
            description: Optional description of what the prompt does

        Example:
            @server.prompt()
            def analyze_table(table_name: str) -> list[Message]:
                schema = read_table_schema(table_name)
                return [
                    {
                        "role": "user",
                        "content": f"Analyze this schema:
{schema}"
                    }
                ]

            @server.prompt()
            async def analyze_file(path: str) -> list[Message]:
                content = await read_file(path)
                return [
                    {
                        "role": "user",
                        "content": {
                            "type": "resource",
                            "resource": {
                                "uri": f"file://{path}",
                                "text": content
                            }
                        }
                    }
                ]
        zgThe @prompt decorator was used incorrectly. Did you forget to call it? Use @prompt() instead of @promptfuncrE   rz   c                d    t          j        |           }                    |           | S )N)r   r   r   r   )r,   r4  r<  )r>  r:  r   r   r   r   r   s     rv   r  z!FastMCP.prompt.<locals>.decorator  s7    )$TT_glmmmFOOF###Kru   )r>  rE   rz   rE   r  )r   r   r   r   r   r  s   ````` rv   r:  zFastMCP.prompt  sj    T D>> 	N  
	 	 	 	 	 	 	 	 	 	
 ru   pathmethodsrg   include_in_schemac                $     d fd}|S )a  
        Decorator to register a custom HTTP route on the FastMCP server.

        Allows adding arbitrary HTTP endpoints outside the standard MCP protocol,
        which can be useful for OAuth callbacks, health checks, or admin APIs.
        The handler function must be an async function that accepts a Starlette
        Request and returns a Response.

        Routes using this decorator will not require authorization. It is intended
        for uses that are either a part of authorization flows or intended to be
        public such as health check endpoints.

        Args:
            path: URL path for the route (e.g., "/oauth/callback")
            methods: List of HTTP methods to support (e.g., ["GET", "POST"])
            name: Optional name for the route (to reference this route with
                  Starlette's reverse URL lookup feature)
            include_in_schema: Whether to include in OpenAPI schema, defaults to True

        Example:
            @server.custom_route("/health", methods=["GET"])
            async def health_check(request: Request) -> Response:
                return JSONResponse({"status": "ok"})
        r>  (Callable[[Request], Awaitable[Response]]rz   c           	     `    j                             t          |                      | S )N)endpointrA  r   rB  )r   appendr   )r>  rB  rA  r   r@  r   s    rv   r  z'FastMCP.custom_route.<locals>.decorator  sH     )00!#&7     Kru   )r>  rD  rz   rD  rt   )r   r@  rA  r   rB  r  s   ````` rv   custom_routezFastMCP.custom_route  sB    @	 	 	 	 	 	 	 	 	 	 ru   c                   K   t                      4 d{V \  }}| j                            ||| j                                                   d{V  ddd          d{V  dS # 1 d{V swxY w Y   dS )z%Run the server using stdio transport.N)r=   r   r   create_initialization_options)r   read_streamwrite_streams      rv   r   zFastMCP.run_stdio_async  s!     >> 	 	 	 	 	 	 	%@k<"&& >>@@        	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   =A''
A14A1c                ,  K   ddl }|                     |          }|                    || j        j        | j        j        | j        j                                                  }|                    |          }|	                                 d{V  dS )z#Run the server using SSE transport.r   Nr[   r]   rY   )
uvicornsse_appConfigr   r[   r]   rY   lowerr8   serve)r   r^   rO  starlette_appconfigservers         rv   r   zFastMCP.run_sse_async  s      Z00##m-3355	   
 
 ''llnnru   c                *  K   ddl }|                                 }|                    || j        j        | j        j        | j        j                                                  }|                    |          }|	                                 d{V  dS )z.Run the server using StreamableHTTP transport.r   NrN  )
rO  streamable_http_apprQ  r   r[   r]   rY   rR  r8   rS  )r   rO  rT  rU  rV  s        rv   r   z!FastMCP.run_streamable_http_async	  s      0022##m-3355	   
 
 ''llnnru   rF  c                    |dk    r|S |                     d          r
|dd         }|                    d          sd|z   }||z   S )a!  
        Combine mount path and endpoint to return a normalized path.

        Args:
            mount_path: The mount path (e.g. "/github" or "/")
            endpoint: The endpoint path (e.g. "/messages/")

        Returns:
            Normalized path (e.g. "/github/messages/")
        r   N)endswith
startswith)r   r^   rF  s      rv   _normalize_pathzFastMCP._normalize_path  sg     O s## 	)#CRCJ ""3'' 	&X~H H$$ru   r   c           
         ddl m} ddlm}m} || j        _                              j        j         j        j                  }t          | j        j
                  d fdg }g }g } j        j        r j        j        j        pg } j        r4 |t          t           j                             |t                     g} j        rjddlm}	 |                     |	 j         j        j        j         j        j        j         j        j        j         j        j        j                              j        rd}
 j        j        r1 j        j        j        r ddlm}  | j        j        j                  }
|                     | j        j        t;          ||
          dg                     |                     | j        j        t;          j        ||
                               nadfd}|                     | j        j        |dg                     |                     | j        j        j                              j        j        rf j        j        j        rUddlm} |                     | j        j        j         j        j        j        g j        j        j                             |                     j                    tC           j        j"        ||          S )z)Return an instance of the SSE server app.r   r   r   N)security_settingsscoper   receiver   sendr   c                2  K                        | ||          4 d {V 	 }j                            |d         |d         j                                                   d {V  d d d           d {V  n# 1 d {V swxY w Y   t	                      S )Nr      )connect_sser   r   rJ  r   )r`  ra  rb  streamsr   r   s       rv   
handle_ssez#FastMCP.sse_app.<locals>.handle_sseE  s?        	 	 	 	 	 	 	 	 &**AJAJ$BBDD        	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ::s   AA::
BBbackendcreate_auth_routesprovider
issuer_urlservice_documentation_urlclient_registration_optionsrevocation_optionsbuild_resource_metadata_urlGET)rF  rA  )rw   requestr   rz   r   c                L   K    | j         | j        | j                   d {V S r   )r`  ra  _send)ru  rg  s    rv   sse_endpointz%FastMCP.sse_app.<locals>.sse_endpoint  s3      'ZwVVVVVVVVVru    create_protected_resource_routesresource_urlauthorization_serversscopes_supported)rW   routes
middleware)r`  r   ra  r   rb  r   )ru  r   rz   r   )#starlette.middlewarer   starlette.routingr   r   r   r^   r]  r`   r<   rm   rk   required_scopesr   r   r    r   r   mcp.server.auth.routesrk  extendrn  ro  rp  rq  resource_server_urlrs  rG  r_   r!   handle_post_messagerz  r   r   rW   )r   r^   r   r   r   normalized_message_endpointr  r  r  rk  resource_metadata_urlrs  rx  rz  rg  r   s   `             @@rv   rP  zFastMCP.sse_app2  s   33333322222222 !'1DM$ '+&:&:4=;SUYUbUo&p&p# !'"m>
 
 

	 	 	 	 	 	 	  ')')
 = 	"m0@FBO # 
 J0 1$2F G G   J455	
 ) EEEEEE&&!%!;#'=#5#@26-2D2^48M4F4b+/=+=+P      *	$(!}! ldm&8&L lNNNNNN )D(CDMDVDj(k(k% MMM*2:Peff"G     MMM.-c.EXmnn     W W W W W W MMM*)"G     MMM./     = 		$-"4"H 		OOOOOOMM00!%!3!G+/=+=+H*I%)]%7%G     	d3444 t}26jYYYYru   c           
     2    ddl m}  j        Gt           j         j         j         j        j         j        j	         j        j
                   _        t           j                  }g }g }g } j        j        r j        j        j        pg } j        r4 |t          t!           j                             |t"                    g} j        rjddlm} |                     | j         j        j        j         j        j        j         j        j        j         j        j        j                              j        r}d} j        j        r1 j        j        j        r ddlm}  | j        j        j                  }|                    t;           j        j        t?          |||          	                     n.|                    t;           j        j        |	                      j        j        rf j        j        j        rUdd
lm }	 |                     |	 j        j        j         j        j        j        g j        j        j                             |                     j!                   tE           j        j#        || fd          S )z4Return an instance of the StreamableHTTP server app.r   r   N)rw   r   r   rb   	statelessr_  rh  rj  rl  rr  )rF  ry  r{  c                6    j                                         S r   )r   r   )rw   r   s    rv   r   z-FastMCP.streamable_http_app.<locals>.<lambda>  s    !5!9!9!;!; ru   )rW   r  r  r9   )$r  r   r   r?   r   r   r   r   rb   rc   rm   StreamableHTTPASGIApprk   r  r   r   r    r   r   r  rk  r  rn  ro  rp  rq  r  rs  rG  r   ra   r!   rz  r   r   rW   )
r   r   rX  r  r  r  rk  r  rs  rz  s
   `         rv   rX  zFastMCP.streamable_http_app  s   333333  ($@$ -#3"m9-6"&-"B% % %D! 4D4IJJ ')')
 = 	"m0@FBO # J0 1$2F G G   J455
 ) EEEEEE&&!%!;#'=#5#@26-2D2^48M4F4b+/=+=+P      	$(!}! ldm&8&L lNNNNNN )D(CDMDVDj(k(k%MMM623FYnoo      MMM60     = 		$-"4"H 		OOOOOOMM00!%!3!G+/=+=+H*I%)]%7%G     	d3444-%!;;;;	
 
 
 	
ru   list[MCPPrompt]c                P   K   | j                                         }d |D             S )zList all available prompts.c           	         g | ];}t          |j        |j        |j        d  |j        pg D             |j                  <S )c                P    g | ]#}t          |j        |j        |j                   $S ))r   r   required)MCPPromptArgumentr   r   r  )r   args     rv   r   z3FastMCP.list_prompts.<locals>.<listcomp>.<listcomp>  sH         & X$'O!$    ru   )r   r   r   r   r   )	MCPPromptr   r   r   r   r   )r   r:  s     rv   r   z(FastMCP.list_prompts.<locals>.<listcomp>  sv     
 
 
  [l".  !' 0 6B   l  
 
 
ru   )r   r   )r   promptss     rv   r   zFastMCP.list_prompts  s=      &3355
 
 "
 
 
 	
ru   rG   c                  K   	 | j                             |          }|st          d|           |                    ||                                            d{V }t          |j        t          j        |                    S # t          $ r>}t                              d|            t          t          |                    d}~ww xY w)z$Get a prompt by name with arguments.zUnknown prompt: r  N)r   messageszError getting prompt )r   r   r   renderr   rG   r   pydantic_coreto_jsonable_pythonr	  r
  r  rZ   )r   r   r   r:  r  r  s         rv   r   zFastMCP.get_prompt,  s      	%)44T::F < !:D!:!:;;;#]]9d>N>N>P>P]QQQQQQQQH"".&9(CC     	% 	% 	%;T;;<<<SVV$$$	%s   BB	 	
C9CC)NNNNNNNN)4r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rW   rV   rY   rX   r[   rZ   r]   r\   r^   rZ   r_   rZ   r`   rZ   ra   rZ   rb   rV   rc   rV   rd   rV   re   rV   rf   rV   rh   r   r9   ri   rk   rj   rm   rl   rz   rZ   rz   r   )rz   r   )rz   r?   )r   N)r   r   r^   r   rz   r   rz   r   )rz   r   )rz   r   )r   rZ   r   r   rz   r   )rz   r   )rz   r   )r   r  rz   r  )NNNNNNN)r  rE   r   r   r   r   r   r   r   r  r   r   r   r  r  r  rz   r   )r   rZ   rz   r   )r   r   r   r   r   r   r   r  r   r   r   r  r  r  rz   r  )r   r/   rz   r   )r   rZ   r   r   r   r   r   r   r   r   r   r   r   r$  r   r  rz   r  )r:  r,   rz   r   )NNNN)
r   r   r   r   r   r   r   r   rz   r  )NT)r@  rZ   rA  rg   r   r   rB  rV   r   )r^   r   rz   r   )r^   rZ   rF  rZ   rz   rZ   )r^   r   rz   r   )rz   r   )rz   r  )r   rZ   r   r  rz   rG   )#rn   ro   rp   r   propertyr   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r!  r#  r   r<  r:  rH  r   r   r   r]  rP  rX  r   r   rt   ru   rv   r   r      s         #'"&#'Y]/3)-%)_3 $(NT($*#$,0(,*.(*pt$(?C9_3 _3 _3 _3 _3 _3B % % % X% - - - X- , , , X, & & & X& % % % X%( AH!%: : : : :.Q Q Q Q
 
 
 
"	F 	F 	F 	Fi i i i

 
 
 
$
 
 
 
 ( ( ( ($   "&.2#'&*)-$
 $
 $
 $
 $
L	- 	- 	- 	-   "&.2#'&*)-< < < < <|- - -$6 6 6 6   "& $#'*.&*j j j j j jX0 0 0 0   "&#'5 5 5 5 5v  "&. . . . .`          % % % %4BZ BZ BZ BZ BZH_
 _
 _
 _
B
 
 
 
*% % % % % % %ru   r   c                  "    e Zd ZdZddZddZdS )r  z@
    ASGI application for Streamable HTTP server transport.
    r   r?   c                    || _         d S r   )r   )r   r   s     rv   r   zStreamableHTTPASGIApp.__init__C  s    .ru   r`  r   ra  r   rb  r   rz   r   c                N   K   | j                             |||           d {V  d S r   )r   handle_request)r   r`  ra  rb  s       rv   __call__zStreamableHTTPASGIApp.__call__F  s9      "11%$GGGGGGGGGGGru   N)r   r?   )r`  r   ra  r   rb  r   rz   r   )rn   ro   rp   rq   r   r  rt   ru   rv   r  r  >  sL         / / / /H H H H H Hru   r  c                      e Zd ZU dZded<   ded<   dddd6 fdZed7d            Zed8d            Zd9d:dZ	d;dZ
d<d"Zd=d&Zdd'd>d+Zed?d,            Zed@d-            Zed.             ZdAd/ZdAd0ZdBd2ZdBd3ZdBd4ZdBd5Z xZS )Cr   a  Context object providing access to MCP capabilities.

    This provides a cleaner interface to MCP's RequestContext functionality.
    It gets injected into tool and resource functions that request it via type hints.

    To use context in a tool function, add a parameter with the Context type annotation:

    ```python
    @server.tool()
    def my_tool(x: int, ctx: Context) -> str:
        # Log messages to the client
        ctx.info(f"Processing {x}")
        ctx.debug("Debug info")
        ctx.warning("Warning message")
        ctx.error("Error message")

        # Report progress
        ctx.report_progress(50, 100)

        # Access resources
        data = ctx.read_resource("resource://data")

        # Get request info
        request_id = ctx.request_id
        client_id = ctx.client_id

        return str(x)
    ```

    The context parameter name can be anything as long as it's annotated with Context.
    The context is optional - tools that don't need it can omit the parameter.
    ARequestContext[ServerSessionT, LifespanContextT, RequestT] | None_request_contextFastMCP | None_fastmcpNr   r   r   kwargsr   c               V     t                      j        di | || _        || _        d S )Nrt   )superr   r  r  )r   r   r   r  	__class__s       rv   r   zContext.__init__o  s5     	""6""" /ru   rz   r   c                <    | j         t          d          | j         S )zAccess to the FastMCP server.N-Context is not available outside of a request)r  r   r   s    rv   r   zContext.fastmcpz  s#     = LMMM}ru   :RequestContext[ServerSessionT, LifespanContextT, RequestT]c                <    | j         t          d          | j         S )z)Access to the underlying request context.Nr  )r  r   r   s    rv   r   zContext.request_context  s%    
  (LMMM$$ru   progressfloattotalfloat | Nonemessager   r   c                   K   | j         j        r| j         j        j        nd}|dS | j         j                            ||||           d{V  dS )zReport progress for the current operation.

        Args:
            progress: Current progress value e.g. 24
            total: Optional total value e.g. 100
            message: Optional message e.g. Starting render...
        N)progress_tokenr  r  r  )r   r   progressTokensessionsend_progress_notification)r   r  r  r  r  s        rv   report_progresszContext.report_progress  s       EIDXD]g-2@@cg!F"*EE)	 F 
 
 	
 	
 	
 	
 	
 	
 	
 	
 	
ru   r   str | AnyUrlr  c                h   K   | j         
J d            | j                             |           d{V S )zRead a resource by URI.

        Args:
            uri: Resource URI to read

        Returns:
            The resource content as either text or bytes
        Nr  )r  r   )r   r   s     rv   r   zContext.read_resource  sG       }((*Y(((]00555555555ru   rZ   schematype[ElicitSchemaModelT]%ElicitationResult[ElicitSchemaModelT]c                V   K   t          | j        j        ||| j                   d{V S )aN  Elicit information from the client/user.

        This method can be used to interactively ask for additional information from the
        client within a tool's execution. The client might display the message to the
        user and collect a response according to the provided schema. Or in case a
        client is an agent, it might decide how to handle the elicitation -- either by asking
        the user or automatically generating a response.

        Args:
            schema: A Pydantic model class defining the expected response structure, according to the specification,
                    only primive types are allowed.
            message: Optional message to present to the user. If not provided, will use
                    a default message based on the schema

        Returns:
            An ElicitationResult containing the action taken and the data if accepted

        Note:
            Check the result.action to determine if the user accepted, declined, or cancelled.
            The result.data will only be populated if action is "accept" and validation succeeded.
        )r  r  r  related_request_idN)r)   r   r  
request_id)r   r  r  s      rv   elicitzContext.elicit  sQ      6 ,(0#	
 
 
 
 
 
 
 
 
 	
ru   urlelicitation_idr(   c                X   K   t          | j        j        |||| j                   d{V S )a  Request URL mode elicitation from the client.

        This directs the user to an external URL for out-of-band interactions
        that must not pass through the MCP client. Use this for:
        - Collecting sensitive credentials (API keys, passwords)
        - OAuth authorization flows with third-party services
        - Payment and subscription flows
        - Any interaction where data should not pass through the LLM context

        The response indicates whether the user consented to navigate to the URL.
        The actual interaction happens out-of-band. When the elicitation completes,
        call `self.session.send_elicit_complete(elicitation_id)` to notify the client.

        Args:
            message: Human-readable explanation of why the interaction is needed
            url: The URL the user should navigate to
            elicitation_id: Unique identifier for tracking this elicitation

        Returns:
            UrlElicitationResult indicating accept, decline, or cancel
        )r  r  r  r  r  N)_elicit_urlr   r  r  )r   r  r  r  s       rv   r*   zContext.elicit_url  sT      6 !(0)#
 
 
 
 
 
 
 
 
 	
ru   )logger_namelevel,Literal['debug', 'info', 'warning', 'error']r  c               f   K   | j         j                            |||| j                   d{V  dS )zSend a log message to the client.

        Args:
            level: Log level (debug, info, warning, error)
            message: Log message
            logger_name: Optional logger name
            **extra: Additional structured data to include
        )r  datar
  r  N)r   r  send_log_messager  )r   r  r  r  s       rv   logzContext.log  sa       "*;;#	 < 
 
 	
 	
 	
 	
 	
 	
 	
 	
 	
ru   c                T    | j         j        rt          | j         j        dd          ndS )zGet the client ID if available.	client_idN)r   r   getattrr   s    rv   r  zContext.client_id  s1     FJEYE^hGD(-{DAAAdh	
ru   c                4    t          | j        j                  S )z#Get the unique ID for this request.)rZ   r   r  r   s    rv   r  zContext.request_id  s     4'2333ru   c                    | j         j        S )z4Access to the underlying session for advanced usage.)r   r  r   s    rv   r  zContext.session  s     #++ru   c                v   K   | j         r-| j         j        r#| j                                          d{V  dS dS dS )a  Close the SSE stream to trigger client reconnection.

        This method closes the HTTP connection for the current request, triggering
        client reconnection. Events continue to be stored in the event store and will
        be replayed when the client reconnects with Last-Event-ID.

        Use this to implement polling behavior during long-running operations -
        client will reconnect after the retry interval specified in the priming event.

        Note:
            This is a no-op if not using StreamableHTTP transport with event_store.
            The callback is only available when event_store is configured.
        N)r  close_sse_streamr   s    rv   r  zContext.close_sse_stream  sa         	;T%:%K 	;'88:::::::::::	; 	; 	; 	;ru   c                v   K   | j         r-| j         j        r#| j                                          d{V  dS dS dS )a  Close the standalone GET SSE stream to trigger client reconnection.

        This method closes the HTTP connection for the standalone GET stream used
        for unsolicited server-to-client notifications. The client SHOULD reconnect
        with Last-Event-ID to resume receiving notifications.

        Note:
            This is a no-op if not using StreamableHTTP transport with event_store.
            Currently, client reconnection for standalone GET streams is NOT
            implemented - this is a known gap.
        N)r  close_standalone_sse_streamr   s    rv   r  z#Context.close_standalone_sse_stream'  sg         	FT%:%V 	F'CCEEEEEEEEEEE	F 	F 	F 	Fru   rU   c                4   K    | j         d|fi | d{V  dS )zSend a debug log message.rW   Nr  r   r  rU   s      rv   rW   zContext.debug7  :      dhw11511111111111ru   c                4   K    | j         d|fi | d{V  dS )zSend an info log message.r   Nr  r  s      rv   r   zContext.info;  s:      dhvw00%00000000000ru   c                4   K    | j         d|fi | d{V  dS )zSend a warning log message.warningNr  r  s      rv   r  zContext.warning?  s:      dhy'33U33333333333ru   c                4   K    | j         d|fi | d{V  dS )zSend an error log message.errorNr  r  s      rv   r  zContext.errorC  r  ru   )r   r  r   r  r  r   )rz   r   )rz   r  )NN)r  r  r  r  r  r   rz   r   )r   r  rz   r  )r  rZ   r  r  rz   r  )r  rZ   r  rZ   r  rZ   rz   r(   )r  r  r  rZ   r  r   rz   r   r  r  r  )r  rZ   rU   r   rz   r   )rn   ro   rp   rq   rs   r   r  r   r   r  r   r  r*   r  r  r  r  r  r  rW   r   r  r  __classcell__)r  s   @rv   r   r   J  s
         B XWWW
 `d"&		  	  	  	  	  	  	  	     X % % % X%
 
 
 
 
(
6 
6 
6 
6 
  
  
  
D!
 !
 !
 !
P #'
 
 
 
 
 
, 
 
 
 X
 4 4 4 X4 , , X,; ; ; ;"F F F F 2 2 2 21 1 1 14 4 4 42 2 2 2 2 2 2 2ru   r   )rw   rx   r9   ry   rz   r{   )rq   
__future__r   _annotationsr-  r0  collections.abcr   r   r   r   r   r	   
contextlibr
   r   typingr   r   r   r   r  pydanticr   pydantic.networksr   pydantic_settingsr   r   starlette.applicationsr   r  r   #starlette.middleware.authenticationr   starlette.requestsr   starlette.responsesr   r  r   r   starlette.typesr   r   r   'mcp.server.auth.middleware.auth_contextr   &mcp.server.auth.middleware.bearer_authr    r!   mcp.server.auth.providerr"   r#   r$   mcp.server.auth.settingsr%   mcp.server.elicitationr&   r'   r(   r)   r*   r  mcp.server.fastmcp.exceptionsr+   mcp.server.fastmcp.promptsr,   r-   mcp.server.fastmcp.resourcesr.   r/   r0   mcp.server.fastmcp.toolsr1   r2   .mcp.server.fastmcp.utilities.context_injectionr3   $mcp.server.fastmcp.utilities.loggingr4   r5    mcp.server.lowlevel.helper_typesr6   mcp.server.lowlevel.serverr7   r8   r   r9   r   mcp.server.sessionr:   r;   mcp.server.sser<   mcp.server.stdior=   mcp.server.streamable_httpr>   "mcp.server.streamable_http_managerr?   mcp.server.transport_securityr@   mcp.shared.contextrA   rB   rC   	mcp.typesrD   rE   rF   rG   rH   rI   r  rJ   r  r   rK   r   r   rn   r
  rM   r   r   r  r   rt   ru   rv   <module>r     sk   ; ; 2 2 2 2 2 2  				                H G G G G G G G ( ( ( ( ( ( ( ( ( (            $ $ $ $ $ $ > > > > > > > > , , , , , , + + + + + + H H H H H H & & & & & & ( ( ( ( ( ( * * * * * * * * 0 0 0 0 0 0 0 0 0 0 I I I I I I                
 2 1 1 1 1 1                 8 7 7 7 7 7 < < < < < < < < T T T T T T T T T T 6 6 6 6 6 6 6 6 Q Q Q Q Q Q N N N N N N N N A A A A A A 6 6 6 6 6 6 : : : : : : C C C C C C < < < < < < < < - - - - - - ) ) ) ) ) ) 1 1 1 1 1 1 K K K K K K C C C C C C I I I I I I I I I I d d d d d d d d d d d d d d d d ) ) ) ) ) ) 9 9 9 9 9 9 - - - - - - = = = = = = % % % % % %	H		39 39 39 39 39|W_5 39 39 39l   i% i% i% i% i%go& i% i% i%X	H 	H 	H 	H 	H 	H 	H 	H{2 {2 {2 {2 {2i1A8!KL {2 {2 {2 {2 {2ru   