o
    c۷iۂ                     @  s  U d Z ddlmZ ddlZddlZddlZddlZddlZddl	m
Z
mZmZmZ ddlmZmZmZ ddlmZmZmZmZ ddlZddl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' ddl(m)Z) ddl*m+Z+ ddl,m-Z- ddl.m/Z/ ddl0m1Z1m2Z2 ddl3m4Z4m5Z5 ddl6m7Z7 ddl8m9Z9 e:e;Z<ededZ=ededZ>e?e@ef ZAdeBd< ee!jC ZDdeBd< eEeDeAf ZFdeBd< eGdZHdeBd< G dd dZIed-d$d%ZJG d&d' d'ee=e>f ZKd.d+d,ZLdS )/ay  
MCP Server Module

This module provides a framework for creating an MCP (Model Context Protocol) server.
It allows you to easily define and handle various types of requests and notifications
in an asynchronous manner.

Usage:
1. Create a Server instance:
   server = Server("your_server_name")

2. Define request handlers using decorators:
   @server.list_prompts()
   async def handle_list_prompts(request: types.ListPromptsRequest) -> types.ListPromptsResult:
       # Implementation

   @server.get_prompt()
   async def handle_get_prompt(
       name: str, arguments: dict[str, str] | None
   ) -> types.GetPromptResult:
       # Implementation

   @server.list_tools()
   async def handle_list_tools(request: types.ListToolsRequest) -> types.ListToolsResult:
       # Implementation

   @server.call_tool()
   async def handle_call_tool(
       name: str, arguments: dict | None
   ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
       # Implementation

   @server.list_resource_templates()
   async def handle_list_resource_templates() -> list[types.ResourceTemplate]:
       # Implementation

3. Define notification handlers if needed:
   @server.progress_notification()
   async def handle_progress(
       progress_token: str | int, progress: float, total: float | None,
       message: str | None
   ) -> None:
       # Implementation

4. Run the server:
   async def main():
       async with mcp.server.stdio.stdio_server() as (read_stream, write_stream):
           await server.run(
               read_stream,
               write_stream,
               InitializationOptions(
                   server_name="your_server_name",
                   server_version="your_version",
                   capabilities=server.get_capabilities(
                       notification_options=NotificationOptions(),
                       experimental_capabilities={},
                   ),
               ),
           )

   asyncio.run(main())

The Server class provides methods to register handlers for various MCP requests and
notifications. It automatically manages the request context and handles incoming
messages from the client.
    )annotationsN)AsyncIterator	AwaitableCallableIterable)AbstractAsyncContextManagerAsyncExitStackasynccontextmanager)AnyGeneric	TypeAliascast)MemoryObjectReceiveStreamMemoryObjectSendStream)AnyUrl)TypeVar)Experimental)ExperimentalHandlers)create_call_wrapper)ReadResourceContents)InitializationOptions)ServerSession)RequestContext)McpErrorUrlElicitationRequiredError)ServerMessageMetadataSessionMessage)RequestResponder)validate_and_warn_tool_nameLifespanResultT)defaultRequestTr   StructuredContentUnstructuredContentCombinationContentrequest_ctxz?contextvars.ContextVar[RequestContext[ServerSession, Any, Any]]c                   @  s   e Zd Z			d	d
ddZdS )NotificationOptionsFprompts_changedboolresources_changedtools_changedc                 C  s   || _ || _|| _d S N)r'   r)   r*   )selfr'   r)   r*    r-   P/home/ubuntu/vllm_env/lib/python3.10/site-packages/mcp/server/lowlevel/server.py__init__q   s   
zNotificationOptions.__init__N)FFF)r'   r(   r)   r(   r*   r(   )__name__
__module____qualname__r/   r-   r-   r-   r.   r&   p   s
    r&   _!Server[LifespanResultT, RequestT]returnAsyncIterator[dict[str, Any]]c                 C s   i V  dS )zDefault lifespan context manager that does nothing.

    Args:
        server: The server instance this lifespan is managing

    Returns:
        An empty context object
    Nr-   )r3   r-   r-   r.   lifespan|   s   

r7   c                   @  s  e Zd Zddddefd`ddZ		dadbddZdcddZeddddZededd Z	d!d" Z
d#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zdfd5d6Zdgd9d:Zd;d<dhd?d@ZdAdB ZdCdD Z	E	EdidjdMdNZ	EdkdldUdVZdmdZd[Zdnd^d_ZdS )oServerNnamestrversion
str | Noneinstructionswebsite_urliconslist[types.Icon] | Noner7   [Callable[[Server[LifespanResultT, RequestT]], AbstractAsyncContextManager[LifespanResultT]]c                 C  sR   || _ || _|| _|| _|| _|| _tjti| _	i | _
i | _d | _td| d S )NzInitializing server %r)r9   r;   r=   r>   r?   r7   typesPingRequest_ping_handlerrequest_handlersnotification_handlers_tool_cache_experimental_handlersloggerdebug)r,   r9   r;   r=   r>   r?   r7   r-   r-   r.   r/      s   zServer.__init__notification_optionsNotificationOptions | Noneexperimental_capabilities dict[str, dict[str, Any]] | Noner5   r   c                 C  sH   d	dd}t | j| jr| jn|d| |pt |pi | j| j| jdS )
z8Create initialization options from this server instance.packager:   r5   c                 S  s,   zddl m} || W S  ty   Y dS w )Nr   )r;   unknown)importlib.metadatar;   	Exception)rO   r;   r-   r-   r.   pkg_version   s   
z9Server.create_initialization_options.<locals>.pkg_versionmcp)server_nameserver_versioncapabilitiesr=   r>   r?   N)rO   r:   r5   r:   )r   r9   r;   get_capabilitiesr&   r=   r>   r?   )r,   rK   rM   rS   r-   r-   r.   create_initialization_options   s   

z$Server.create_initialization_optionsr&   dict[str, dict[str, Any]]types.ServerCapabilitiesc           	      C  s   d}d}d}d}d}t j| jv rt j|jd}t j| jv r%t jd|jd}t j| jv r2t j	|j
d}t j| jv r<t  }t j| jv rFt  }t j||||||d}| jrZ| j| |S )z9Convert existing handlers to a ServerCapabilities object.N)listChangedF)	subscriber\   )prompts	resourcestoolsloggingexperimentalcompletions)rB   ListPromptsRequestrE   PromptsCapabilityr'   ListResourcesRequestResourcesCapabilityr)   ListToolsRequestToolsCapabilityr*   SetLevelRequestLoggingCapabilityCompleteRequestCompletionsCapabilityServerCapabilitiesrH   update_capabilities)	r,   rK   rM   prompts_capabilityresources_capabilitytools_capabilitylogging_capabilitycompletions_capabilityrW   r-   r-   r.   rX      s8   zServer.get_capabilities8RequestContext[ServerSession, LifespanResultT, RequestT]c                 C  s   t  S )zFIf called outside of a request context, this will raise a LookupError.)r%   getr,   r-   r-   r.   request_context   s   zServer.request_contextr   c                 C  s"   | j du rt| | j| j| _ | j S )zExperimental APIs for tasks and other features.

        WARNING: These APIs are experimental and may change without notice.
        N)rH   r   rE   rF   rw   r-   r-   r.   rb      s   
zServer.experimentalc                      d fdd}|S )NfuncvCallable[[], Awaitable[list[types.Prompt]]] | Callable[[types.ListPromptsRequest], Awaitable[types.ListPromptsResult]]c                   4   t d t| tj d fdd}|jtj< | S )Nz)Registering handler for PromptListRequestreqtypes.ListPromptsRequestc                   8    | I d H }t |tjrt|S ttj|dS )N)r^   )
isinstancerB   ListPromptsResultServerResultr}   resultwrapperr-   r.   handler  
   
z7Server.list_prompts.<locals>.decorator.<locals>.handler)r}   r~   )rI   rJ   r   rB   rd   rE   rz   r   rw   r   r.   	decorator  
   
	z&Server.list_prompts.<locals>.decorator)rz   r{   r-   r,   r   r-   rw   r.   list_prompts     zServer.list_promptsc                   ry   )Nrz   HCallable[[str, dict[str, str] | None], Awaitable[types.GetPromptResult]]c                   (   t d d fdd}|jtj<  S )Nz(Registering handler for GetPromptRequestr}   types.GetPromptRequestc                   s$    | j j| j jI d H }t|S r+   )paramsr9   	argumentsrB   r   )r}   
prompt_getrz   r-   r.   r     s   
z5Server.get_prompt.<locals>.decorator.<locals>.handler)r}   r   )rI   rJ   rE   rB   GetPromptRequestr   rw   r   r.   r     s   
z$Server.get_prompt.<locals>.decorator)rz   r   r-   r   r-   rw   r.   
get_prompt  s   zServer.get_promptc                   ry   )Nrz   |Callable[[], Awaitable[list[types.Resource]]] | Callable[[types.ListResourcesRequest], Awaitable[types.ListResourcesResult]]c                   r|   )Nz,Registering handler for ListResourcesRequestr}   types.ListResourcesRequestc                   r   )N)r_   )r   rB   ListResourcesResultr   r   r   r-   r.   r   1  r   z9Server.list_resources.<locals>.decorator.<locals>.handler)r}   r   )rI   rJ   r   rB   rf   rE   r   rw   r   r.   r   )  r   z(Server.list_resources.<locals>.decorator)rz   r   r-   r   r-   rw   r.   list_resources(  r   zServer.list_resourcesc                   ry   )Nrz   5Callable[[], Awaitable[list[types.ResourceTemplate]]]c                   r   )Nz4Registering handler for ListResourceTemplatesRequestr3   r
   c                   s      I d H }t t j|dS )N)resourceTemplates)rB   r   ListResourceTemplatesResult)r3   	templatesr   r-   r.   r   C  s   zBServer.list_resource_templates.<locals>.decorator.<locals>.handler)r3   r
   )rI   rJ   rE   rB   ListResourceTemplatesRequestr   rw   r   r.   r   @     
z1Server.list_resource_templates.<locals>.decorator)rz   r   r-   r   r-   rw   r.   list_resource_templates?     
zServer.list_resource_templatesc                   ry   )Nrz   KCallable[[AnyUrl], Awaitable[str | bytes | Iterable[ReadResourceContents]]]c                   r   )Nz+Registering handler for ReadResourceRequestr}   types.ReadResourceRequestc                   s   j jI d H }ddfdd |   td	 r n  td	 r$ n  n } tjd
tdd  |d }n&  td	 rR } fdd|D }t	tj
|dS   	 tdt| t	tj
|gdS )Ndatastr | bytes	mime_typer<   metadict[str, Any] | Nonec                   s   |d urd|ini }|   t d r$ }  tjd jj| |pdd|S    td rB } tjd jjt| 	 |p<dd|S   d S )N_metar-   z
text/plain)uritextmimeTypezapplication/octet-stream)r   blobr   )
r:   rB   TextResourceContentsr   r   bytesBlobResourceContentsbase64	b64encodedecode)r   r   r   meta_kwargsr}   r-   r.   create_contentU  s(   zPServer.read_resource.<locals>.decorator.<locals>.handler.<locals>.create_contentr-   zdReturning str or bytes from read_resource is deprecated. Use Iterable[ReadResourceContents] instead.   )
stacklevelc              	     s$   g | ]} |j |jt|d dqS )r   N)contentr   getattr).0content_item)r   r-   r.   
<listcomp>r  s    zLServer.read_resource.<locals>.decorator.<locals>.handler.<locals>.<listcomp>)contentsz+Unexpected return type from read_resource: r+   )r   r   r   r<   r   r   )r   r   r:   r   warningswarnDeprecationWarningr   rB   r   ReadResourceResult
ValueErrortype)r}   r   r   r   r   contents_listr   )r   r}   r.   r   R  s:   .
z8Server.read_resource.<locals>.decorator.<locals>.handler)r}   r   )rI   rJ   rE   rB   ReadResourceRequestr   rw   r   r.   r   M  s   
4z'Server.read_resource.<locals>.decorator)rz   r   r-   r   r-   rw   r.   read_resourceL  s   <zServer.read_resourcec                   ry   )Nrz   /Callable[[types.LoggingLevel], Awaitable[None]]c                   r   )Nz'Registering handler for SetLevelRequestr}   types.SetLevelRequestc                   "    | j jI d H  tt S r+   )r   levelrB   r   EmptyResultr   r   r-   r.   r        z<Server.set_logging_level.<locals>.decorator.<locals>.handler)r}   r   )rI   rJ   rE   rB   rj   r   rw   r   r.   r     r   z+Server.set_logging_level.<locals>.decorator)rz   r   r-   r   r-   rw   r.   set_logging_level  r   zServer.set_logging_levelc                   ry   )Nrz   #Callable[[AnyUrl], Awaitable[None]]c                   r   )Nz(Registering handler for SubscribeRequestr}   types.SubscribeRequestc                   r   r+   r   r   rB   r   r   r   r   r-   r.   r     r   z=Server.subscribe_resource.<locals>.decorator.<locals>.handler)r}   r   )rI   rJ   rE   rB   SubscribeRequestr   rw   r   r.   r     r   z,Server.subscribe_resource.<locals>.decoratorrz   r   r-   r   r-   rw   r.   subscribe_resource  r   zServer.subscribe_resourcec                   ry   )Nrz   r   c                   r   )Nz*Registering handler for UnsubscribeRequestr}   types.UnsubscribeRequestc                   r   r+   r   r   r   r-   r.   r     r   z?Server.unsubscribe_resource.<locals>.decorator.<locals>.handler)r}   r   )rI   rJ   rE   rB   UnsubscribeRequestr   rw   r   r.   r     r   z.Server.unsubscribe_resource.<locals>.decoratorr   r-   r   r-   rw   r.   unsubscribe_resource  r   zServer.unsubscribe_resourcec                   ry   )Nrz   pCallable[[], Awaitable[list[types.Tool]]] | Callable[[types.ListToolsRequest], Awaitable[types.ListToolsResult]]c                   s6   t d t| tj d fdd}|jtj< | S )Nz(Registering handler for ListToolsRequestr}   types.ListToolsRequestc                   s   | I d H }t |tjr$|jD ]}t|j | j|j< qt|S  j  |D ]}t|j | j|j< q+ttj|dS )N)r`   )	r   rB   ListToolsResultr`   r   r9   rG   r   clear)r}   r   tool)r,   r   r-   r.   r     s   




z5Server.list_tools.<locals>.decorator.<locals>.handler)r}   r   )rI   rJ   r   rB   rh   rE   r   rw   r   r.   r     s
   
z$Server.list_tools.<locals>.decorator)rz   r   r-   r   r-   rw   r.   
list_tools  s   zServer.list_toolserror_messagetypes.ServerResultc                 C  s    t t jt jd|dgddS )z3Create a ServerResult with an error CallToolResult.r   r   r   T)r   isError)rB   r   CallToolResultTextContent)r,   r   r-   r-   r.   _make_error_result  s   zServer._make_error_result	tool_nametypes.Tool | Nonec                   s^   || j vrtj| jv rtd| | jtj dI dH  | j |}|du r-td| |S )z|Get tool definition from cache, refreshing if necessary.

        Returns the Tool object if found, None otherwise.
        z(Tool cache miss for %s, refreshing cacheNz5Tool '%s' not listed, no validation will be performed)rG   rB   rh   rE   rI   rJ   rv   warning)r,   r   r   r-   r-   r.   _get_cached_tool_definition  s   
z"Server._get_cached_tool_definitionT)validate_inputr   r(   c                  s   d fdd}|S )a  Register a tool call handler.

        Args:
            validate_input: If True, validates input against inputSchema. Default is True.

        The handler validates input against inputSchema (if validate_input=True), calls the tool function,
        and builds a CallToolResult with the results:
        - Unstructured content (iterable of ContentBlock): returned in content
        - Structured content (dict): returned in structuredContent, serialized JSON text returned in content
        - Both: returned in content and structuredContent

        If outputSchema is defined, validates structuredContent or errors if missing.
        rz   Callable[..., Awaitable[UnstructuredContent | StructuredContent | CombinationContent | types.CallToolResult | types.CreateTaskResult]]c                   s,   t d d fdd}|jtj<  S )Nz'Registering handler for CallToolRequestr}   types.CallToolRequestc              
     s  z| j j}| j jpi }|I d H }r@|r@z
tj||jd W n tjy? } zd|j	 W  Y d }~W S d }~ww  ||I d H }t
|tjrTt|W S t
|tjr`t|W S t
|trst|dkrstt|\}}n1t
|trtt|}tjdtj|dddg}nt|drtt|}d }ndt|j W S |r|jd ur|d u rd	W S z
tj||jd W n tjy } zd
|j	 W  Y d }~W S d }~ww ttjt||ddW S  ty     ty } zt |W  Y d }~S d }~ww )N)instanceschemazInput validation error: r   r   )indentr   __iter__z"Unexpected return type from tool: zOOutput validation error: outputSchema defined but no structured output returnedzOutput validation error: F)r   structuredContentr   )!r   r9   r   r   
jsonschemavalidateinputSchemaValidationErrorr   messager   rB   r   r   CreateTaskResulttuplelenr   r$   dictr"   r   jsondumpshasattrr#   r   r0   outputSchemalistr   rR   r:   )r}   r   r   r   eresultsunstructured_contentmaybe_structured_content)rz   r,   r   r-   r.   r   	  sd    



 z4Server.call_tool.<locals>.decorator.<locals>.handler)r}   r   )rI   rJ   rE   rB   CallToolRequestr   r,   r   r   r.   r     s   
Az#Server.call_tool.<locals>.decoratorN)rz   r   r-   )r,   r   r   r-   r  r.   	call_tool  s   RzServer.call_toolc                   ry   )Nrz   GCallable[[str | int, float, float | None, str | None], Awaitable[None]]c                   r   )Nz,Registering handler for ProgressNotificationr}   types.ProgressNotificationc                   s*    | j j| j j| j j| j jI d H  d S r+   )r   progressTokenprogresstotalr   r   r   r-   r.   r   U  s   z@Server.progress_notification.<locals>.decorator.<locals>.handler)r}   r	  )rI   rJ   rF   rB   ProgressNotificationr   rw   r   r.   r   P  s   
z/Server.progress_notification.<locals>.decorator)rz   r  r-   r   r-   rw   r.   progress_notificationO  s   zServer.progress_notificationc                   s   d fdd}|S )z7Provides completions for prompts and resource templatesrz   Callable[[types.PromptReference | types.ResourceTemplateReference, types.CompletionArgument, types.CompletionContext | None], Awaitable[types.Completion | None]]c                   r   )Nz'Registering handler for CompleteRequestr}   types.CompleteRequestc                   sP    | j j| j j| j jI d H }ttj|d ur|dS tjg d d ddS )N)valuesr  hasMore)
completion)r   refargumentcontextrB   r   CompleteResult
Completion)r}   r  r   r-   r.   r   q  s   z5Server.completion.<locals>.decorator.<locals>.handler)r}   r  )rI   rJ   rE   rB   rl   r   rw   r   r.   r   e  s   


z$Server.completion.<locals>.decoratorN)rz   r  r-   r   r-   rw   r.   r  b  s   zServer.completionFread_stream5MemoryObjectReceiveStream[SessionMessage | Exception]write_stream&MemoryObjectSendStream[SessionMessage]initialization_optionsraise_exceptions	statelessc              
     s  t  4 I d H z}|| | I d H }|t||||dI d H }| jr)| jjnd }	|	d ur>|	| ||	 I d H  t	 4 I d H &}
|j
2 z3 d H W }td| |
| j|||| qJ6 W d   I d H  n1 I d H srw   Y  W d   I d H  d S 1 I d H sw   Y  d S )N)r  zReceived message: %s)r   enter_async_contextr7   r   rH   task_supportconfigure_sessionrunanyiocreate_task_groupincoming_messagesrI   rJ   
start_soon_handle_message)r,   r  r  r  r  r  stacklifespan_contextsessionr!  tgr   r-   r-   r.   r#    s8   


*.z
Server.runr   `RequestResponder[types.ClientRequest, types.ServerResult] | types.ClientNotification | Exceptionr+  r   r*  r   c           
   	     s2  t jdd}|  td rA d tjd r@ d   }} | | |||||I d H  W d    nA1 s:w   Y  n8    tjd rY d  } | |I d H  n td rw t	
d|  |jdd	d
dI d H  |rv|n |D ]}	t	d|	jj|	j qzW d    d S 1 sw   Y  d S )NT)recordrequestr   )rootr-   z Received exception from stream: errorzInternal Server Errorzmcp.server.exception_handler)r   r   rI   zWarning: %s: %s)r   catch_warningsr   rB   ClientRequest_handle_requestClientNotification_handle_notificationrR   rI   r2  send_log_messageinfocategoryr0   r   )
r,   r   r+  r*  r  wr}   	respondernotifyr   r-   r-   r.   r(    s2   0

"zServer._handle_message9RequestResponder[types.ClientRequest, types.ServerResult]r}   types.ClientRequestTypec                   s  t dt|j | jt| }rt dt|j d }zzbd }d }	d }
|jd ur>t|jt	r>|jj
}|jj}	|jj}
|jrE|jjnd }| jrN| jjnd }d }t|drc|jd urct|jdd }tt|j|j||t||||d||	|
d}||I d H }W nR ty } z	|j}W Y d }~nBd }~w t y   t d|j Y W |d urt| d S d S  ty } z|r|t j!dt"|d d	}W Y d }~nd }~ww W |d urt| n|d urt| w w |#|I d H  n|#t j!t j$d
dI d H  t d d S )NzProcessing request of type %szDispatching request of type %sr   task)task_metadata_client_capabilities_session_task_support)r0  close_sse_streamclose_standalone_sse_streamz4Request %s cancelled - duplicate response suppressedr   )coder   r   zMethod not found)rG  r   zResponse sent)%rI   r9  r   r0   rE   rv   rJ   message_metadatar   r   rx   rE  rF  client_paramsrW   rH   r!  r   r   r   r%   setr   
request_idrequest_metar   r   r2  r$  get_cancelled_exc_classresetrR   rB   	ErrorDatar:   respondMETHOD_NOT_FOUND)r,   r   r}   r+  r*  r  r   tokenrequest_dataclose_sse_stream_cbclose_standalone_sse_stream_cbclient_capabilitiesr!  rA  responseerrr-   r-   r.   r5    s    

zServer._handle_requestr=  r
   c                   s`   | j t| }r.tdt|j z
||I d H  W d S  ty-   td Y d S w d S )Nz#Dispatching notification of type %sz*Uncaught exception in notification handler)rF   rv   r   rI   rJ   r0   rR   	exception)r,   r=  r   r-   r-   r.   r7    s   zServer._handle_notification)r9   r:   r;   r<   r=   r<   r>   r<   r?   r@   r7   rA   )NN)rK   rL   rM   rN   r5   r   )rK   r&   rM   rZ   r5   r[   )r5   ru   )r5   r   )r   r:   r5   r   )r   r:   r5   r   )r   r(   )FF)
r  r  r  r  r  r   r  r(   r  r(   )F)r   r-  r+  r   r*  r   r  r(   )
r   r>  r}   r?  r+  r   r*  r   r  r(   )r=  r
   )r0   r1   r2   r7   r/   rY   rX   propertyrx   rb   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r#  r(  r5  r7  r-   r-   r-   r.   r8      sH    
.?
!
	c'2
Pr8   r0  types.PingRequestr   c                   s   t t  S r+   )rB   r   r   r/  r-   r-   r.   rD   "  s   rD   )r3   r4   r5   r6   )r0  r[  r5   r   )M__doc__
__future__r   _annotationsr   contextvarsr   ra   r   collections.abcr   r   r   r   
contextlibr   r   r	   typingr
   r   r   r   r$  r   anyio.streams.memoryr   r   pydanticr   typing_extensionsr   	mcp.typesrB   'mcp.server.experimental.request_contextr    mcp.server.lowlevel.experimentalr   #mcp.server.lowlevel.func_inspectionr    mcp.server.lowlevel.helper_typesr   mcp.server.modelsr   mcp.server.sessionr   mcp.shared.contextr   mcp.shared.exceptionsr   r   mcp.shared.messager   r   mcp.shared.sessionr   mcp.shared.tool_name_validationr   	getLoggerr0   rI   r   r!   r   r:   r"   __annotations__ContentBlockr#   r   r$   
ContextVarr%   r&   r7   r8   rD   r-   r-   r-   r.   <module>   sX    C
     