
    {hh              	         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< ddl=m>Z> ddl?m@Z@mAZA ddlBmCZCmDZDmEZE ddlFmGZGmHZH ddlImJZJmKZK ddlLmMZM ddlNmOZO ddlNmPZQ ddlNmRZS ddlTmUZUmVZV dd lWmXZX dd!lYmZZZ dd"l[m\Z\ dd#l]m^Z^ dd$l_m`Z` dd%lambZbmcZcmdZd dd&lemfZfmgZgmhZhmiZi dd'lem@Zj dd(lemkZl dd)lemDZm dd*lemnZo dd+lemGZp  eKeq      Zr G d, d-eeeO         Zs	 	 	 	 	 	 d5d.Zt G d/ d0eeO         Zu G d1 d2      Zv G d3 d4eeeVebedf         Zwy)6z5FastMCP - 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elicit_with_validation)ResourceError)PromptPromptManager)FunctionResourceResourceResourceManager)ToolToolManager)configure_logging
get_logger)ReadResourceContents)LifespanResultT)Server)lifespan)ServerSessionServerSessionT)SseServerTransport)stdio_server)
EventStore)StreamableHTTPSessionManager)TransportSecuritySettings)LifespanContextTRequestContextRequestT)AnyFunctionContentBlockGetPromptResultToolAnnotations)r*   )PromptArgument)r-   )ResourceTemplate)r/   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 <   y!)"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]] | Noner6   AuthSettings | Noneauth TransportSecuritySettings | Nonetransport_securityN)__name__
__module____qualname____doc__r   model_config__annotations__     Z/var/www/html/hubwallet-dev/venv/lib/python3.12/site-packages/mcp/server/fastmcp/server.pyrH   rH   7   s     &!,0L KGG I
IOM I "&% "!  $# FggQ
 98rp   rH   c                *     t         d fd       }|S )Nc                  K          4 d {   }| d d d       d {    y 7 7 # 1 d {  7  sw Y   y xY wwNro   )_contextappr6   s     rq   wrapzlifespan_wrapper.<locals>.wrapq   sD     C= 	 	GM	 	 	 	 	 	 	s8   A+A/A-AAA8AA)ru   z#MCPServer[LifespanResultT, Request]returnzAsyncIterator[LifespanResultT])r   )rw   r6   rx   s   `` rq   lifespan_wrapperrz   m   s       Krp   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	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d+dZed,d       Zed-d       Zed.d       Z	 	 d/	 	 	 	 	 d0dZd1dZ	d2dZ
d3dZd4dZd5dZd6dZd7dZ	 	 	 	 	 d*	 	 	 	 	 	 	 	 	 	 	 	 	 d8dZ	 	 	 	 	 d*	 	 	 	 	 	 	 	 	 	 	 d9dZd Zd:dZddddd	 	 	 	 	 	 	 	 	 	 	 d;dZd<dZ	 d=	 	 	 	 	 	 	 d>d Z	 	 d?	 	 	 	 	 	 	 d@d!Zd1d"ZdAdBd#Zd1d$ZdCd%ZdAdDd&ZdEd'ZdFd(ZdAdGd)Zy)HFastMCPNFINFOz	127.0.0.1i@  /z/ssez
/messages/z/mcpTro   )toolsrR   rT   rV   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rc   r6   rf   rh   c                  t        di d|d|d|	d|
d|d|d|d|d	|d
|d|d|d|dt        |      d|d|d|| _        t        |xs 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      |s|rt%        d      || _        || _        |r|st+        |      | _        || _        g | _        | j                  j0                  | _        d | _        | j5                          t7        | j                  j8                         y )NrR   rT   rV   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rc   r6   rf   rh   r|   )nameinstructionsr6   )r   r`   )r_   )ra   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 settingsro   )rH   listsettings	MCPServerr6   rz   default_lifespan_mcp_serverr0   r`   _tool_managerr.   r_   _resource_managerr+   ra   _prompt_managerrf   
ValueError_auth_server_provider_token_verifierr#   _event_store_custom_starlette_routesrc   _session_manager_setup_handlersr1   rT   )selfr   r   auth_server_providertoken_verifierevent_storer   rR   rT   rV   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rc   r6   rf   rh   s                           rq   __init__zFastMCP.__init__z   s   6 ! 


 
 	

 "
 
 &
 "6
 (
 *
 )D
 %<
 '@
 l+
 
  !
"  2#
( %"% IMH^H^&tT]]-C-CDdt
 )udmmNsNst!0T]]MvMv!w,t}}GnGno==)# !^__' !rss#~ !noo%9"-  #89M#ND '57% MM66EI 	 	$--112rp   c                .    | j                   j                  S rt   )r   r   r   s    rq   r   zFastMCP.name   s    $$$rp   c                .    | j                   j                  S rt   )r   r   r   s    rq   r   zFastMCP.instructions   s    ,,,rp   c                H    | 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.
        zSession manager can only be accessed aftercalling streamable_http_app().The session manager is created lazilyto avoid unnecessary initialization.)r   RuntimeErrorr   s    rq   session_managerzFastMCP.session_manager   s0       (7  $$$rp   c                (    t         d   }||j                  vrt        d|       |xdk(  r! t        j                   j
                         yxdk(  r t        j                   fd       ydk(  r t        j                   j                         yy)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
        )stdiossestreamable-httpzUnknown transport: r   r   c                 &    j                         S rt   )run_sse_async)rY   r   s   rq   <lambda>zFastMCP.run.<locals>.<lambda>   s    $"4"4Z"@ rp   r   N)r   __args__r   anyiorunrun_stdio_asyncrun_streamable_http_async)r   	transportrY   
TRANSPORTSs   ` ` rq   r   zFastMCP.run   ss     >?
J///29+>??		$../		@A"		$889 #rp   c                T    | j                   j                         | j                          | j                   j                  d      | j                          | j                   j                         | j                          | j                   j	                         | j                          | j                   j                         | j
                          | j                   j                         | j                          | j                   j                         | j                         y)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    rq   r   zFastMCP._setup_handlers   s    %##%doo6 	9""%"8H)'')$*=*=>(&&(););<'%%'(9(9:%##%doo6200243O3OPrp   c                   K   | j                   j                         }|D cg c]O  }t        |j                  |j                  |j
                  |j                  |j                  |j                        Q c}S c c}w w)zList all available tools.)r   titledescriptioninputSchemaoutputSchemar   )	r   r   MCPToolr   r   r   
parametersoutput_schemar   )r   r   infos      rq   r   zFastMCP.list_tools  ss     ""--/ 

  YYjj ,, OO!// ,,

 
	
 

s   A=AA85A=c                l    	 | j                   j                  }t        ||       S # t        $ r d}Y w xY w)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     rq   get_contextzFastMCP.get_context  s=    
	#"..>>O EE  	#"O	#s   % 33c                |   K   | j                         }| j                  j                  |||d       d{   S 7 w)z#Call a tool by name with arguments.T)rv   convert_resultN)r   r   r   )r   r   	argumentsrv   s       rq   r   zFastMCP.call_tool'  s;     ""$''11$	7cg1hhhhs   3<:<c           
        K   | j                   j                         }|D cg c]H  }t        |j                  |j                  xs d|j
                  |j                  |j                        J c}S c c}w w)zList all available resources. )urir   r   r   mimeType)r   r   MCPResourcer   r   r   r   	mime_type)r   	resourcesresources      rq   r   zFastMCP.list_resources,  sq      **99;	 &	
  LL]](bnn$00!++	
 		
 	
s   A6AA1.A6c           	        K   | j                   j                         }|D cg c]9  }t        |j                  |j                  |j
                  |j                        ; c}S c c}w w)N)uriTemplater   r   r   )r   list_templatesMCPResourceTemplateuri_templater   r   r   )r   	templatestemplates      rq   r   zFastMCP.list_resource_templates;  sc     **99;	 &
   $11]]nn$00	
 	
 
s   A'>A"A'c                T  K   | j                   j                  |       d{   }|st        d|       	 |j                          d{   }t	        ||j
                        gS 7 E7 # t        $ r1}t        j                  d|        t        t        |            d}~ww xY ww)zRead a resource by URI.NzUnknown resource: )contentr   zError reading resource )
r   get_resourcer)   readr3   r   	Exceptionlogger	exceptionrU   )r   r   r   r   es        rq   r   zFastMCP.read_resourceG  s      //<<SAA"4SE :;;	($MMO+G(HDVDVWXX B
 , 	(6se<=A''	(sD   B(A'B(A+ 
A)A+ &B()A+ +	B%4,B  B%%B(c                F    | j                   j                  ||||||       y)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, unconditionally creates a structured tool (return type annotation permitting)
                - If False, unconditionally creates an unstructured tool
        r   r   r   r   structured_outputN)r   add_tool)r   fnr   r   r   r   r   s          rq   r   zFastMCP.add_toolU  s/    2 	####/ 	$ 	
rp   c                T     t              rt        d      d fd}|S )at  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, unconditionally 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 @toolc                6    j                  |        | S )Nr   )r   )r   r   r   r   r   r   r   s    rq   	decoratorzFastMCP.tool.<locals>.decorator  s-    MM''"3   Irp   r   rA   ry   rA   callable	TypeError)r   r   r   r   r   r   r   s   `````` rq   toolzFastMCP.toolw  s/    P D>s 		 		 rp   c                6    | j                   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    rq   r   zFastMCP.completion  s      **,,rp   c                :    | j                   j                  |       y)zfAdd a resource to the server.

        Args:
            resource: A Resource instance to add
        N)r   add_resource)r   r   s     rq   r   zFastMCP.add_resource  s     	++H5rp   )r   r   r   r   c               T     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

        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 @resourcec                   dv xr dv }t        t        j                  |       j                        }|s|rt	        t        j                  d            }t	        t        j                  |       j                  j                               }||k7  rt        d| d|       	j                  j                  | 
       | S t        j                  | 
      }	j                  |       | S )N{}z{(\w+)}z Mismatch between URI parameters z and function parameters )r   r   r   r   r   r   )r   r   r   r   r   r   )rQ   inspect	signaturer   setrefindallkeysr   r   add_templater,   from_functionr   )r   has_uri_paramshas_func_params
uri_paramsfunc_paramsr   r   r   r   r   r   r   s         rq   r   z#FastMCP.resource.<locals>.decorator   s    CZ6C3JN"7#4#4R#8#C#CDO J!<=
!'"3"3B"7"B"B"G"G"IJ,$::,F_`k_lm 
 &&33!$ +' 4 & I ,99 +' !!(+Irp   r   r   )r   r   r   r   r   r   r   s   `````` rq   r   zFastMCP.resource  s3    ^ C=W 
#	 #	J rp   c                :    | j                   j                  |       y)z`Add a prompt to the server.

        Args:
            prompt: A Prompt instance to add
        N)r   
add_prompt)r   prompts     rq   r   zFastMCP.add_prompt'  s     	''/rp   c                L     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 @promptc                \    t        j                  |       }j                  |       | S )N)r   r   r   )r*   r   r   )funcr  r   r   r   r   s     rq   r   z!FastMCP.prompt.<locals>.decorator[  s+    ))$TT_`FOOF#Krp   )r  rA   ry   rA   r   )r   r   r   r   r   s   ```` rq   r  zFastMCP.prompt/  s2    L D>N 
	 	
 rp   c                ,     	 	 	 	 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.

        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"})
        c           	     Z    j                   j                  t        |              | S )N)endpointmethodsr   include_in_schema)r   appendr   )r  r	  r  r   pathr   s    rq   r   z'FastMCP.custom_route.<locals>.decorator~  s7     ))00!#&7 Krp   )r  (Callable[[Request], Awaitable[Response]]ry   r  ro   )r   r  r  r   r	  r   s   ````` rq   custom_routezFastMCP.custom_routeb  s%    8	:	5	 	 rp   c                  K   t               4 d{   \  }}| j                  j                  ||| j                  j                                d{    ddd      d{    y7 U7 7 	# 1 d{  7  sw Y   yxY ww)z%Run the server using stdio transport.N)r:   r   r   create_initialization_options)r   read_streamwrite_streams      rq   r   zFastMCP.run_stdio_async  s}     > 	 	%@k<""&&  >>@  	 	 		 	 	 	sV   BA'B<A-A)A-B!A+"B)A-+B-A?3A64A?;Bc                J  K   ddl }| j                  |      }|j                  || j                  j                  | j                  j
                  | j                  j                  j                               }|j                  |      }|j                          d{    y7 w)z#Run the server using SSE transport.r   NrV   rX   rT   )
uvicornsse_appConfigr   rV   rX   rT   lowerr5   serve)r   rY   r  starlette_appconfigservers         rq   r   zFastMCP.run_sse_async  s|     Z0####mm--335	   
 'llns   BB#B!B#c                H  K   ddl }| j                         }|j                  || j                  j                  | j                  j
                  | j                  j                  j                               }|j                  |      }|j                          d{    y7 w)z.Run the server using StreamableHTTP transport.r   Nr  )
r  streamable_http_appr  r   rV   rX   rT   r  r5   r  )r   r  r  r  r  s        rq   r   z!FastMCP.run_streamable_http_async  s|     002####mm--335	   
 'llns   BB"B B"c                r    |dk(  r|S |j                  d      r|dd }|j                  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   rY   r  s      rq   _normalize_pathzFastMCP._normalize_path  sR     O s##CRJ ""3'X~H H$$rp   c           
     &    ddl m} ddlm}m} || j
                  _         j                   j
                  j                   j
                  j                        }t        | j
                  j                        d fdg }g }g } j
                  j                  r j
                  j                  j                  xs g } j                  r- |t        t         j                               |t               g} j"                  rddlm}	 |j)                   |	 j"                   j
                  j                  j*                   j
                  j                  j,                   j
                  j                  j.                   j
                  j                  j0                  	              j                  rd}
 j
                  j                  rg j
                  j                  j2                  rGdd
lm}  |t9         j
                  j                  j2                        j;                  d      dz         }
|j=                   | j
                  j>                  tA        ||
      dg             |j=                   | j
                  j                  tA        jB                  ||
                   nldfd}|j=                   | j
                  j>                  |dg             |j=                   | j
                  j                  jB                                j
                  j                  r j
                  j                  j2                  r{ddlm"} |j)                   | j
                  j                  j2                   j
                  j                  j*                  g j
                  j                  j                               |j)                   jF                         tI         j
                  jJ                  ||      S )z)Return an instance of the SSE server app.r   r   r   N)security_settingsc                F  K   j                  | ||      4 d {   }j                  j                  |d   |d   j                  j                                d {    d d d       d {    t	               S 7 a7  7 # 1 d {  7  sw Y   t	               S xY ww)Nr      )connect_sser   r   r  r   )scopereceivesendstreamsr   r   s       rq   
handle_ssez#FastMCP.sse_app.<locals>.handle_sse  s       	 	 &&**AJAJ$$BBD  	 	 :	
	 	 	 	 :sV   B!A=B!?BA?B#B!.B/B!?BB!B	B
BB!backendcreate_auth_routesprovider
issuer_urlservice_documentation_urlclient_registration_optionsrevocation_options
AnyHttpUrlr~   %/.well-known/oauth-protected-resourceGETr  r  )rw   c                p   K    | j                   | j                  | j                         d {   S 7 wrt   )r(  r)  _send)requestr,  s    rq   sse_endpointz%FastMCP.sse_app.<locals>.sse_endpoint1  s(     'wVVVVs   ,646) create_protected_resource_routes)resource_urlauthorization_serversscopes_supported)rR   routes
middleware)r(  r   r)  r   r*  r   )r>  r   ry   r   )&starlette.middlewarer   starlette.routingr   r   r   rY   r"  r[   r9   rh   rf   required_scopesr   r   r    r   r   mcp.server.auth.routesr0  extendr3  r4  r5  r6  resource_server_urlpydanticr8  rU   rstripr
  rZ   r!   handle_post_messager@  r   r   rR   )r   rY   r   r   r   normalized_message_endpointrD  rE  rH  r0  resource_metadata_urlr8  r?  r@  r,  r   s   `             @@rq   r  zFastMCP.sse_app  s%   32 !'1DMM$ '+&:&:4==;S;SUYUbUbUoUo&p# !'"mm>>

	  ')')
 =="mm00@@FBO ## 0 1$2F2F G 45	
 ))E&!%!;!;#'==#5#5#@#@26--2D2D2^2^48MM4F4F4b4b+/==+=+=+P+P $(!}}!!dmm&8&8&L&L/(2**>>?FFsKNuu)%
 MMMM**2:Pef"G MMMM..-c.E.EXmnW MMMM**)"G MMMM..// ==$--"4"4"H"HOMM0!%!3!3!G!G+/==+=+=+H+H*I%)]]%7%7%G%G 	d334 t}}226jYYrp   c           
         ddl m}  j                  et         j                   j
                   j                  j                   j                  j                   j                  j                         _        t         j                        }g }g }g } j                  j                  r j                  j                  j                  xs g } j                  r- |t        t         j                               |t               g} j"                  rddlm} |j)                   | j"                   j                  j                  j*                   j                  j                  j,                   j                  j                  j.                   j                  j                  j0                                j                  rd} j                  j                  rg j                  j                  j2                  rGddlm}  |t9         j                  j                  j2                        j;                  d	      d
z         }|j=                  t?         j                  j@                  tC        |||                   n0|j=                  t?         j                  j@                  |              j                  j                  rЉ j                  j                  j2                  rddl"m#}	 ddlm$}
 ddl%m&}  | j                  j                  j2                   j                  j                  j*                  g j                  j                  j                        }|j=                  t?        d
 |
 |	|      jN                  ddg      ddg             |j)                   jP                         tS         j                  jT                  || fd      S )z4Return an instance of the StreamableHTTP server app.r   r   N)rw   r   r]   	statelessr$  r-  r/  r1  r7  r~   r9  )r  ) ProtectedResourceMetadataHandler)cors_middleware)ProtectedResourceMetadata)r   rB  rC  r:  OPTIONSr;  c                8    j                   j                         S rt   )r   r   )rw   r   s    rq   r   z-FastMCP.streamable_http_app.<locals>.<lambda>  s    !5!5!9!9!; rp   )rR   rD  rE  r6   )+rF  r   r   r<   r   r   r   r]   r^   rh   StreamableHTTPASGIApprf   rH  r   r   r    r   r   rI  r0  rJ  r3  r4  r5  r6  rK  rL  r8  rU   rM  r
  r   r\   r!   !mcp.server.auth.handlers.metadatarS  rT  mcp.shared.authrU  handler   r   rR   )r   r   r  rD  rE  rH  r0  rP  r8  rS  rT  rU  protected_resource_metadatas   `            rq   r  zFastMCP.streamable_http_appT  s   3   ($@$$ --"mm99--66"&--"B"B%D! 4D4I4IJ ')')
 =="mm00@@FBO ##0 1$2F2F G 45
 ))E&!%!;!;#'==#5#5#@#@26--2D2D2^2^48MM4F4F4b4b+/==+=+=+P+P $(!}}!!dmm&8&8&L&L/(2**>>?FFsKNuu)% MMMM6623FYno MMMM660 ==$--"4"4"H"HZ>A*C++??'+}}'9'9'D'D&E!%!3!3!C!C+'
 MM;,89TU\\	* #I.	 	d334--%%!;	
 	
rp   c                Z  K   | j                   j                         }|D cg c]u  }t        |j                  |j                  |j
                  |j                  xs g D cg c].  }t        |j                  |j
                  |j                        0 c}      w c}}S c c}w c c}}w w)zList all available prompts.)r   r   required)r   r   r   r   )	r   r   	MCPPromptr   r   r   r   MCPPromptArgumentr^  )r   promptsr  args       rq   r   zFastMCP.list_prompts  s     &&335 "
  [[ll".. !' 0 0 6B  & XX$'OO!$	
 	


s(    B+=B%3B 
B%B+ B%%B+c                f  K   	 | j                   j                  |      }|st        d|       |j                  |       d{   }t	        |j
                  t        j                  |            S 7 .# t        $ r1}t        j                  d|        t        t        |            d}~ww xY ww)z$Get a prompt by name with arguments.zUnknown prompt: N)r   messageszError getting prompt )r   r   r   renderrC   r   pydantic_coreto_jsonable_pythonr   r   r   rU   )r   r   r   r  rd  r   s         rq   r   zFastMCP.get_prompt  s     	%))44T:F #3D6!:;;#]]955H""..&99(C  6  	%4TF;<SV$$	%s:   B1?A4 A2-A4 1B12A4 4	B.=,B))B..B1)NNNNN).r   
str | Noner   rh  r   z6OAuthAuthorizationServerProvider[Any, Any, Any] | Noner   zTokenVerifier | Noner   zEventStore | Noner   zlist[Tool] | NonerR   rQ   rT   rS   rV   rU   rX   rW   rY   rU   rZ   rU   r[   rU   r\   rU   r]   rQ   r^   rQ   r_   rQ   r`   rQ   ra   rQ   rc   zCollection[str]r6   rd   rf   re   rh   rg   ry   rU   ry   rh  )ry   r<   )r   N)r   z*Literal['stdio', 'sse', 'streamable-http']rY   rh  ry   None)ry   rk  )ry   zlist[MCPTool])ry   z0Context[ServerSession, LifespanResultT, Request])r   rU   r   zdict[str, Any]ry   z'Sequence[ContentBlock] | dict[str, Any])ry   zlist[MCPResource])ry   zlist[MCPResourceTemplate])r   zAnyUrl | strry   Iterable[ReadResourceContents])r   rA   r   rh  r   rh  r   rh  r   ToolAnnotations | Noner   bool | Nonery   rk  )r   rh  r   rh  r   rh  r   rm  r   rn  ry   $Callable[[AnyFunction], AnyFunction])r   r-   ry   rk  )r   rU   r   rh  r   rh  r   rh  r   rh  ry   ro  )r  r*   ry   rk  )NNN)r   rh  r   rh  r   rh  ry   ro  )NT)r  rU   r  rb   r   rh  r	  rQ   rt   )rY   rh  ry   rk  )rY   rU   r  rU   ry   rU   )rY   rh  ry   r   )ry   r   )ry   zlist[MCPPrompt])r   rU   r   zdict[str, Any] | Nonery   rC   ) ri   rj   rk   r   propertyr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r   r   r   r"  r  r  r   r   ro   rp   rq   r|   r|   y   s     #'W[/3)-R3 $(NT($*#$,0(,*.(*nr$(?C3R3R3 !R3 U	R3
 -R3 'R3 !R3 R3 LR3 R3 R3 R3 R3 R3  "!R3" #R3$ %R3& &*'R3( "&)R3* $(+R3, &-R3. l/R30 "1R32 =3R3h % % - - % %( AH!%:=: : 
	:.Q
	Fi



("   "&.2)- 
 
  
 	 

   
 , 
 ' 
 
 
H   "&.2)-88 8  	8
 ,8 '8 
.8t-$6   "& $ZZ 	Z
 Z  Z Z 
.Zx0 \`11.81NX1	-1n  "&** * 	*
  *X%4CZJi
V
(%rp   r|   c                       e Zd ZdZddZddZy)rX  z@
    ASGI application for Streamable HTTP server transport.
    c                    || _         y rt   )r   )r   r   s     rq   r   zStreamableHTTPASGIApp.__init__  s
    .rp   c                Z   K   | j                   j                  |||       d {    y 7 wrt   )r   handle_request)r   r(  r)  r*  s       rq   __call__zStreamableHTTPASGIApp.__call__  s$     ""11%$GGGs   !+)+N)r   r<   )r(  r   r)  r   r*  r   ry   rk  )ri   rj   rk   rl   r   ru  ro   rp   rq   rX  rX    s    /Hrp   rX  c                  
    e Zd ZU dZded<   ded<   ddd	 	 	 	 	 d fdZedd	       Ze	 	 dd
       Zd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d!dZd!dZd!dZd!dZ xZS )"r   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   c               @    t        |   di | || _        || _        y )Nro   )superr   rx  rz  )r   r   r   kwargs	__class__s       rq   r   zContext.__init__  s$     	"6" /rp   c                H    | j                   t        d      | j                   S )zAccess to the FastMCP server.-Context is not available outside of a request)rz  r   r   s    rq   r   zContext.fastmcp!  s$     == LMM}}rp   c                H    | j                   t        d      | j                   S )z)Access to the underlying request context.r  )rx  r   r   s    rq   r   zContext.request_context(  s(    
   (LMM$$$rp   c                   K   | j                   j                  r | j                   j                  j                  nd}|y| j                   j                  j	                  ||||       d{    y7 w)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_tokenprogresstotalmessage)r   metaprogressTokensessionsend_progress_notification)r   r  r  r  r  s        rq   report_progresszContext.report_progress1  sq      EIDXDXD]D]--22@@cg!""**EE)	 F 
 	
 	
s   A(A2*A0+A2c                z   K   | j                   J d       | j                   j                  |       d{   S 7 w)zRead a resource by URI.

        Args:
            uri: Resource URI to read

        Returns:
            The resource content as either text or bytes
        Nr  )rz  r   )r   r   s     rq   r   zContext.read_resourceE  s9      }}(Y*YY(]]005555s   2;9;c                x   K   t        | j                  j                  ||| j                         d{   S 7 w)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  schemarelated_request_idN)r(   r   r  
request_id)r   r  r  s      rq   elicitzContext.elicitQ  s;     6 ,((00'&eietet
 
 	
 
s   1:8:)logger_namec                  K   | j                   j                  j                  |||| j                         d{    y7 w)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
        )leveldatar   r  N)r   r  send_log_messager  )r   r  r  r  s       rq   logzContext.logp  sA      ""**;;#	 < 
 	
 	
s   7A?Ac                t    | j                   j                  r!t        | j                   j                  dd      S dS )zGet the client ID if available.	client_idN)r   r  getattrr   s    rq   r  zContext.client_id  s5     IMH\H\HaHawt++00+tDkgkkrp   c                @    t        | j                  j                        S )z#Get the unique ID for this request.)rU   r   r  r   s    rq   r  zContext.request_id  s     4''2233rp   c                .    | j                   j                  S )z4Access to the underlying session for advanced usage.)r   r  r   s    rq   r  zContext.session  s     ##+++rp   c                H   K    | j                   d|fi | d{    y7 w)zSend a debug log message.rR   Nr  r   r  rP   s      rq   rR   zContext.debug  !     dhhw15111   " "c                H   K    | j                   d|fi | d{    y7 w)zSend an info log message.r   Nr  r  s      rq   r   zContext.info  s!     dhhvw0%000r  c                H   K    | j                   d|fi | d{    y7 w)zSend a warning log message.warningNr  r  s      rq   r  zContext.warning  s!     dhhy'3U333r  c                H   K    | j                   d|fi | d{    y7 w)zSend an error log message.errorNr  r  s      rq   r  zContext.error  r  r  )r   rw  r   ry  r}  r   )ry   r|   )ry   z:RequestContext[ServerSessionT, LifespanContextT, RequestT])NN)r  floatr  zfloat | Noner  rh  ry   rk  )r   zstr | AnyUrlry   rl  )r  rU   r  ztype[ElicitSchemaModelT]ry   z%ElicitationResult[ElicitSchemaModelT])r  z,Literal['debug', 'info', 'warning', 'error']r  rU   r  rh  ry   rk  rj  ri  )r  rU   rP   r   ry   rk  )ri   rj   rk   rl   rn   r   rp  r   r   r  r   r  r  r  r  r  rR   r   r  r  __classcell__)r~  s   @rq   r   r     s$   B XW
 `d"&		  \	   		 
 	    %	C% %
(
6

 )
 
/	
H #'
;
 

  
 

, l l 4 4 , ,
2142rp   r   )rw   zFastMCP[LifespanResultT]r6   zRCallable[[FastMCP[LifespanResultT]], AbstractAsyncContextManager[LifespanResultT]]ry   z]Callable[[MCPServer[LifespanResultT, Request]], AbstractAsyncContextManager[LifespanResultT]])xrl   
__future__r   _annotationsr   r   collections.abcr   r   r   r   r   r	   
contextlibr
   r   typingr   r   r   r   rf  rL  r   pydantic.networksr   pydantic_settingsr   r   starlette.applicationsr   rF  r   #starlette.middleware.authenticationr   starlette.requestsr   starlette.responsesr   rG  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(   mcp.server.fastmcp.exceptionsr)   mcp.server.fastmcp.promptsr*   r+   mcp.server.fastmcp.resourcesr,   r-   r.   mcp.server.fastmcp.toolsr/   r0   $mcp.server.fastmcp.utilities.loggingr1   r2    mcp.server.lowlevel.helper_typesr3   mcp.server.lowlevel.serverr4   r5   r   r6   r   mcp.server.sessionr7   r8   mcp.server.sser9   mcp.server.stdior:   mcp.server.streamable_httpr;   "mcp.server.streamable_http_managerr<   mcp.server.transport_securityr=   mcp.shared.contextr>   r?   r@   	mcp.typesrA   rB   rC   rD   r_  rE   r`  r   rF   r   r   ri   r   rH   rz   r|   rX  r   ro   rp   rq   <module>r     s"   ; 2  	 ^ ^ G ( (    $ > , + H & ( * 0 0 I [ k k 1 ` ` 7 < T T 6 N A 6 : C < - ) 1 K C I I Q Q ) 9 - = %	H	39|W_5 39l		!	`	 c	i%go& i%X	H 	Hs2i1A8!KL s2rp   