o
    hp                     @  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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.m/Z/ ddl0m1Z1 e2e3Z4ededZ5ededZ6e7e8ef Z9de:d< ee j; Z<de:d< e=e<e9f Z>de:d< e?dZ@de:d< G dd dZAed*d!d"ZBG d#d$ d$ee5e6f ZCd+d(d)ZDd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)create_call_wrapper)ReadResourceContents)InitializationOptions)ServerSession)RequestContext)McpError)ServerMessageMetadataSessionMessage)RequestResponder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)   [/var/www/html/openai_agents/venv/lib/python3.10/site-packages/mcp/server/lowlevel/server.py__init__m   s   
zNotificationOptions.__init__N)FFF)r#   r$   r%   r$   r&   r$   )__name__
__module____qualname__r+   r)   r)   r)   r*   r"   l   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)   )r/   r)   r)   r*   lifespanx   s   

r3   c                   @  s   e Zd Zddddefd\ddZ		d]d^ddZd_ddZed`ddZdd Z	d d! Z
d"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zdad2d3Zdbd6d7Zd8d9dcd<d=Zd>d? Zd@dA Z	B	BdddedJdKZ	BdfdgdRdSZdhdWdXZdidZd[ZdS )jServerNnamestrversion
str | Noneinstructionswebsite_urliconslist[types.Icon] | Noner3   [Callable[[Server[LifespanResultT, RequestT]], AbstractAsyncContextManager[LifespanResultT]]c                 C  sL   || _ || _|| _|| _|| _|| _tjti| _	i | _
i | _td| d S )NzInitializing server %r)r5   r7   r9   r:   r;   r3   typesPingRequest_ping_handlerrequest_handlersnotification_handlers_tool_cacheloggerdebug)r(   r5   r7   r9   r:   r;   r3   r)   r)   r*   r+      s   zServer.__init__notification_optionsNotificationOptions | Noneexperimental_capabilities dict[str, dict[str, Any]] | Noner1   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.packager6   r1   c                 S  s,   zddl m} || W S  ty   Y dS w )Nr   )r7   unknown)importlib.metadatar7   	Exception)rJ   r7   r)   r)   r*   pkg_version   s   
z9Server.create_initialization_options.<locals>.pkg_versionmcp)server_nameserver_versioncapabilitiesr9   r:   r;   N)rJ   r6   r1   r6   )r   r5   r7   get_capabilitiesr"   r9   r:   r;   )r(   rF   rH   rN   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S )z9Convert existing handlers to a ServerCapabilities object.N)listChangedF)	subscriberW   )prompts	resourcestoolsloggingexperimentalcompletions)r>   ListPromptsRequestrA   PromptsCapabilityr#   ListResourcesRequestResourcesCapabilityr%   ListToolsRequestToolsCapabilityr&   SetLevelRequestLoggingCapabilityCompleteRequestCompletionsCapabilityServerCapabilities)r(   rF   rH   prompts_capabilityresources_capabilitytools_capabilitylogging_capabilitycompletions_capabilityr)   r)   r*   rS      s2   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_contextc                      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)rY   )
isinstancer>   ListPromptsResultServerResultrw   resultwrapperr)   r*   handler   
   
z7Server.list_prompts.<locals>.decorator.<locals>.handler)rw   rx   )rD   rE   r   r>   r_   rA   rt   r   rq   r   r*   	decorator   
   
	z&Server.list_prompts.<locals>.decorator)rt   ru   r)   r(   r   r)   rq   r*   list_prompts      zServer.list_promptsc                   rs   )Nrt   HCallable[[str, dict[str, str] | None], Awaitable[types.GetPromptResult]]c                   (   t d d fdd}|jtj<  S )Nz(Registering handler for GetPromptRequestrw   types.GetPromptRequestc                   s$    | j j| j jI d H }t|S r'   )paramsr5   	argumentsr>   r|   )rw   
prompt_getrt   r)   r*   r     s   
z5Server.get_prompt.<locals>.decorator.<locals>.handler)rw   r   )rD   rE   rA   r>   GetPromptRequestr   rq   r   r*   r     s   
z$Server.get_prompt.<locals>.decorator)rt   r   r)   r   r)   rq   r*   
get_prompt  s   zServer.get_promptc                   rs   )Nrt   |Callable[[], Awaitable[list[types.Resource]]] | Callable[[types.ListResourcesRequest], Awaitable[types.ListResourcesResult]]c                   rv   )Nz,Registering handler for ListResourcesRequestrw   types.ListResourcesRequestc                   ry   )N)rZ   )rz   r>   ListResourcesResultr|   r}   r   r)   r*   r     r   z9Server.list_resources.<locals>.decorator.<locals>.handler)rw   r   )rD   rE   r   r>   ra   rA   r   rq   r   r*   r     r   z(Server.list_resources.<locals>.decorator)rt   r   r)   r   r)   rq   r*   list_resources  r   zServer.list_resourcesc                   rs   )Nrt   5Callable[[], Awaitable[list[types.ResourceTemplate]]]c                   r   )Nz4Registering handler for ListResourceTemplatesRequestr/   r
   c                   s      I d H }t t j|dS )N)resourceTemplates)r>   r|   ListResourceTemplatesResult)r/   	templatesr   r)   r*   r   /  s   zBServer.list_resource_templates.<locals>.decorator.<locals>.handler)r/   r
   )rD   rE   rA   r>   ListResourceTemplatesRequestr   rq   r   r*   r   ,     
z1Server.list_resource_templates.<locals>.decorator)rt   r   r)   r   r)   rq   r*   list_resource_templates+     
zServer.list_resource_templatesc                   rs   )Nrt   KCallable[[AnyUrl], Awaitable[str | bytes | Iterable[ReadResourceContents]]]c                   r   )Nz+Registering handler for ReadResourceRequestrw   types.ReadResourceRequestc                   s   j jI d H }dfdd |   td r n  td r# n  n } tjdtd	d
  |d }n&  td rQ } fdd|D }t	tj
|dS   	 tdt| t	tj
|gdS )Ndatastr | bytes	mime_typer8   c                   sp   |   t d r }  tj jj| |pddS    td r4 } dd l}tj jj|| 	 |p1ddS   d S )Nr)   z
text/plain)uritextmimeTyper   zapplication/octet-stream)r   blobr   )
r6   r>   TextResourceContentsr   r   bytesbase64BlobResourceContents	b64encodedecode)r   r   r   rw   r)   r*   create_contentA  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qS r)   )contentr   ).0content_item)r   r)   r*   
<listcomp>\  s    zLServer.read_resource.<locals>.decorator.<locals>.handler.<locals>.<listcomp>)contentsz+Unexpected return type from read_resource: )r   r   r   r8   )r   r   r6   r   warningswarnDeprecationWarningr   r>   r|   ReadResourceResult
ValueErrortype)rw   r~   r   r   r   contents_listr   )r   rw   r*   r   >  s:   .
	z8Server.read_resource.<locals>.decorator.<locals>.handler)rw   r   )rD   rE   rA   r>   ReadResourceRequestr   rq   r   r*   r   9  s   
/z'Server.read_resource.<locals>.decorator)rt   r   r)   r   r)   rq   r*   read_resource8  s   7zServer.read_resourcec                   rs   )Nrt   /Callable[[types.LoggingLevel], Awaitable[None]]c                   r   )Nz'Registering handler for SetLevelRequestrw   types.SetLevelRequestc                   "    | j jI d H  tt S r'   )r   levelr>   r|   EmptyResultr   r   r)   r*   r   v     z<Server.set_logging_level.<locals>.decorator.<locals>.handler)rw   r   )rD   rE   rA   r>   re   r   rq   r   r*   r   s  r   z+Server.set_logging_level.<locals>.decorator)rt   r   r)   r   r)   rq   r*   set_logging_levelr  r   zServer.set_logging_levelc                   rs   )Nrt   #Callable[[AnyUrl], Awaitable[None]]c                   r   )Nz(Registering handler for SubscribeRequestrw   types.SubscribeRequestc                   r   r'   r   r   r>   r|   r   r   r   r)   r*   r     r   z=Server.subscribe_resource.<locals>.decorator.<locals>.handler)rw   r   )rD   rE   rA   r>   SubscribeRequestr   rq   r   r*   r     r   z,Server.subscribe_resource.<locals>.decoratorrt   r   r)   r   r)   rq   r*   subscribe_resource  r   zServer.subscribe_resourcec                   rs   )Nrt   r   c                   r   )Nz*Registering handler for UnsubscribeRequestrw   types.UnsubscribeRequestc                   r   r'   r   r   r   r)   r*   r     r   z?Server.unsubscribe_resource.<locals>.decorator.<locals>.handler)rw   r   )rD   rE   rA   r>   UnsubscribeRequestr   rq   r   r*   r     r   z.Server.unsubscribe_resource.<locals>.decoratorr   r)   r   r)   rq   r*   unsubscribe_resource  r   zServer.unsubscribe_resourcec                   rs   )Nrt   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 ListToolsRequestrw   types.ListToolsRequestc                   sp   | I d H }t |tjr|jD ]}| j|j< qt|S  j  |D ]}| j|j< q&ttj|dS )N)r[   )rz   r>   ListToolsResultr[   rC   r5   r|   clear)rw   r~   tool)r(   r   r)   r*   r     s   


z5Server.list_tools.<locals>.decorator.<locals>.handler)rw   r   )rD   rE   r   r>   rc   rA   r   rq   r   r*   r     s
   
z$Server.list_tools.<locals>.decorator)rt   r   r)   r   r)   rq   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)r>   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)rC   r>   rc   rA   rD   rE   rp   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.
        rt   VCallable[..., Awaitable[UnstructuredContent | StructuredContent | CombinationContent]]c                   s,   t d d fdd}|jtj<  S )Nz'Registering handler for CallToolRequestrw   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r[t|dkr[tt|\}}n1t
|trst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 } 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   r5   r   r   
jsonschemavalidateinputSchemaValidationErrorr   messagerz   tuplelenr   r    dictr   r>   r   jsondumpshasattrr   r   r,   outputSchemar|   r   listrM   r6   )rw   r   r   r   eresultsunstructured_contentmaybe_structured_content)rt   r(   r   r)   r*   r     sX    



 z4Server.call_tool.<locals>.decorator.<locals>.handler)rw   r   )rD   rE   rA   r>   CallToolRequestr   r(   r   r   r*   r     s   
8z#Server.call_tool.<locals>.decoratorN)rt   r   r)   )r(   r   r   r)   r   r*   	call_tool  s   CzServer.call_toolc                   rs   )Nrt   GCallable[[str | int, float, float | None, str | None], Awaitable[None]]c                   r   )Nz,Registering handler for ProgressNotificationrw   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   +  s   z@Server.progress_notification.<locals>.decorator.<locals>.handler)rw   r   )rD   rE   rB   r>   ProgressNotificationr   rq   r   r*   r   &  s   
z/Server.progress_notification.<locals>.decorator)rt   r   r)   r   r)   rq   r*   progress_notification%  s   zServer.progress_notificationc                   s   d fdd}|S )z7Provides completions for prompts and resource templatesrt   Callable[[types.PromptReference | types.ResourceTemplateReference, types.CompletionArgument, types.CompletionContext | None], Awaitable[types.Completion | None]]c                   r   )Nz'Registering handler for CompleteRequestrw   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contextr>   r|   CompleteResult
Completion)rw   r  r   r)   r*   r   G  s   z5Server.completion.<locals>.decorator.<locals>.handler)rw   r  )rD   rE   rA   r>   rg   r   rq   r   r*   r   ;  s   


z$Server.completion.<locals>.decoratorN)rt   r  r)   r   r)   rq   r*   r  8  s   zServer.completionFread_stream5MemoryObjectReceiveStream[SessionMessage | Exception]write_stream&MemoryObjectSendStream[SessionMessage]initialization_optionsraise_exceptions	statelessc              
     s   t  4 I d H ^}|| | I d H }|t||||dI d H }t 4 I d H &}	|j2 z3 d H W }
td|
 |		| j
|
||| q.6 W d   I d H  n1 I d H sVw   Y  W d   I d H  d S 1 I d H slw   Y  d S )N)r  zReceived message: %s)r   enter_async_contextr3   r   anyiocreate_task_groupincoming_messagesrD   rE   
start_soon_handle_message)r(   r  r  r  r  r  stacklifespan_contextsessiontgr   r)   r)   r*   runV  s0   
	*.z
Server.runr   `RequestResponder[types.ClientRequest, types.ServerResult] | types.ClientNotification | Exceptionr  r   r  r   c           
   	     s   t jddh}|  td rA d tjd r@ d   }} | | |||||I d H  W d    n!1 s:w   Y  n   tjd rW d  }| |I d H  n |D ]}	t	d|	j
j|	j qZW d    d S 1 srw   Y  d S )NT)recordrequestr   )rootzWarning: %s: %s)r   catch_warningsr   r>   ClientRequest_handle_requestClientNotification_handle_notificationrD   infocategoryr,   r   )
r(   r   r  r  r  wrw   	respondernotifyr   r)   r)   r*   r  }  s   0"zServer._handle_message9RequestResponder[types.ClientRequest, types.ServerResult]rw   r
   c              
     s  t dt|j | jt| }rt dt|j d }zz(d }|jd ur2t|jt	r2|jj
}tt|j|j|||d}||I d H }	W nR ty] }
 z	|
j}	W Y d }
~
nBd }
~
w t y{   t d|j Y W |d uryt| 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!  z4Request %s cancelled - duplicate response suppressedr   )coder   r   zMethod not found)r/  r   zResponse sent)rD   r)  r   r,   rA   rp   rE   message_metadatarz   r   rr   r!   setr   
request_idrequest_metar   errorr  get_cancelled_exc_classresetrM   r>   	ErrorDatar6   respondMETHOD_NOT_FOUND)r(   r   rw   r  r  r  r   tokenrequest_dataresponseerrr)   r)   r*   r&    sh   	 

zServer._handle_requestr-  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)rB   rp   r   rD   rE   r,   rM   	exception)r(   r-  r   r)   r)   r*   r(    s   zServer._handle_notification)r5   r6   r7   r8   r9   r8   r:   r8   r;   r<   r3   r=   )NN)rF   rG   rH   rI   r1   r   )rF   r"   rH   rU   r1   rV   )r1   ro   )r   r6   r1   r   )r   r6   r1   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.  rw   r
   r  r   r  r   r  r$   )r-  r
   )r,   r-   r.   r3   r+   rT   rS   propertyrr   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r&  r(  r)   r)   r)   r*   r4      sD    
+:

	T',
;r4   r"  types.PingRequestr   c                   s   t t  S r'   )r>   r|   r   r!  r)   r)   r*   r@     s   r@   )r/   r0   r1   r2   )r"  r@  r1   r   )E__doc__
__future__r   _annotationscontextvarsr   r\   r   collections.abcr   r   r   r   
contextlibr   r   r	   typingr
   r   r   r   r  r   anyio.streams.memoryr   r   pydanticr   typing_extensionsr   	mcp.typesr>   #mcp.server.lowlevel.func_inspectionr    mcp.server.lowlevel.helper_typesr   mcp.server.modelsr   mcp.server.sessionr   mcp.shared.contextr   mcp.shared.exceptionsr   mcp.shared.messager   r   mcp.shared.sessionr   	getLoggerr,   rD   r   r   r   r6   r   __annotations__ContentBlockr   r   r    
ContextVarr!   r"   r3   r4   r@   r)   r)   r)   r*   <module>   sN    C
    T