+
    Q(i/                    ~   R t ^ RIHt ^ RIt^ RIt^ RIHtHtHt ^ RI	H
t
HtHt ^ RIHt ^ RIt^ RIHt ^ RIHt ^ RIHt ^ R	IHtHt ^ R
IHt ^ RIHtHtHtHt ^ RIH t  ^ RI!H"t"H#t# ^ RI$H%t% ^ RI&H't' ^ RI(H)t) ^ RI*H+t+ ^ RI,H-t- ^ RI.H/t/H0t0 ^ RI1H2t2 ^ RI3H4t4H5t5H6t6 ^ RI7H8t8 ^ RI9H:t:H;t; ^ RI<H=t=H>t> ^ RI?H@t@ ^ RIAHBtB ^ RICHDtD ^ RIEHFtF ^ RIGHHtH ^ RIIHJtJHKtK ^ RILHMtMHNtN ^ R IOHPtP ]
'       d   ^ R!IQHRtR ^ R"I,HStS ]P! ]T4      tU]. ]"3,          ]. ]]",          3,          ,          tV ! R# R$]J4      tW ! R% R&]:4      tX ! R' R(];4      tY ! R) R*]54      tZ ! R+ R,]D4      t[R- R. lt\ ! R/ R0]F4      t]R1 R2 lt^R3 R4 lt_R5 R6 lt`R7 R8 ltaR9 R: ltbR; R< ltcR= R> ltd ! R? R@]"]-,          4      te ! RA RB]e]-,          4      tfR# )CzProxyProvider for proxying to remote MCP servers.

This module provides the `ProxyProvider` class that proxies components from
a remote MCP server via a client factory. It also provides proxy component
classes that forward execution to remote servers.
)annotationsN)	AwaitableCallableSequence)TYPE_CHECKINGAnycast)quote)ServerSession)ClientSession)request_ctx)LifespanContextTRequestContext)McpError)METHOD_NOT_FOUNDBlobResourceContentsElicitRequestFormParamsTextResourceContents)AnyUrl)ClientFastMCP1Server)ElicitResult)
LogMessage)	RootsList)client_span)ClientTransportT)ResourceError	ToolError)	MCPConfig)MessagePromptPromptResult)PromptArgument)ResourceResourceTemplate)ResourceContentResourceResult)Context)get_context)Provider)FastMCP)
TaskConfig)Tool
ToolResult)FastMCPComponentget_fastmcp_metadata)
get_logger)Path)ClientTransportc                     a  ] tR t^Ct$ Rt]! RR7      tR]R&   RtR]R&   R	 V 3R
 llt	R R lt
R V 3R llt]R R l4       tRR R lltR V 3R lltRtV ;t# )	ProxyToolz>A Tool that represents and executes a tool on a remote server.	forbiddenmoder+   task_configN
str | None_backend_namec                    V ^8  d   QhRRRR/#    client_factoryClientFactoryTkwargsr    )formats   "d/Users/agent/.openclaw/workspace/venv/lib/python3.14/site-packages/fastmcp/server/providers/proxy.py__annotate__ProxyTool.__annotate__I        . .~ . .    c                	4   < \         SV `  ! R/ VB  Wn        R # NrA   super__init___client_factoryselfr>   r@   	__class__s   &&,rC   rL   ProxyTool.__init__I       "6"-rG   c                   V ^8  d   QhRR/# r=   returnr   rA   )rB   s   "rC   rD   rE   M         6 rG   c                   "   V P                  4       p\        P                  ! V4      '       d   \        \        VG Rj  xL
 4      pV#  L
5iz<Gets a client instance by calling the sync or async factory.NrM   inspectisawaitabler   r   rO   clients   & rC   _get_clientProxyTool._get_clientM   <     %%'v&&&,/F #/   <AA	
Ac                    V ^8  d   QhRRRR/# )r=   r@   r   rU   r4   rA   )rB   s   "rC   rD   rE   T   s     , ,3 ,9 ,rG   c                   < VP                  R/ 4      pRV9   d%   V P                  f   / VCRV P                  /CpW!R&   \        SV `  ! R/ VB # z5Override to preserve _backend_name when name changes.updatenamer:   rA   getr:   rf   rK   
model_copyrO   r@   re   rP   s   &, rC   ri   ProxyTool.model_copyT   V    Hb)V 2 2 :;;;F%8w!+F++rG   c               $    V ^8  d   QhRRRRRR/# )r=   r>   r?   mcp_toolzmcp.types.ToolrU   r4   rA   )rB   s   "rC   rD   rE   ^   s$     
 
+
7E
	
rG   c                   V ! VVP                   VP                  VP                  VP                  VP                  VP
                  VP                  VP                  \        VP                  4      P                  R. 4      R7
      # )z@Factory method to create a ProxyTool from a raw MCP tool schema.tags)
r>   rf   titledescription
parametersr   output_schemaiconsmetarp   )
rf   rq   rr   inputSchemar   outputSchemaru   rv   r/   rh   )clsr>   rn   s   &&&rC   from_mcp_toolProxyTool.from_mcp_tool]   sm    
 ).. ,,++ ,,"//..%hmm488D
 	
rG   c               $    V ^8  d   QhRRRRRR/# )r=   	argumentsdict[str, Any]contextContext | NonerU   r-   rA   )rB   s   "rC   rD   rE   o   s(     5 5!5  5 
	5rG   c           
     t  "   V P                   ;'       g    V P                  p\        RV 2RV4      ;_uu_ 4       pVP                  RR4       V P	                  4       G Rj  xL
 pT;_uu_4       GRj  xL
  T;'       g    \        4       p\        V\        4      '       d?   VP                  VP                  3\        \        \        ,          VP                  4      ^ &   Rp\        VR4      '       d   VP                  p\        VR4      '       d(   VP                  '       d   \!        VP                  4      p\        VR4      '       dx   \        VP"                  R	4      '       d\   VP"                  P$                  '       d@   VP"                  P&                  p	V	'       d"   T;'       g    / pV	P)                  R
R7      VR&   VP+                  W1VR7      G Rj  xL
 p
RRR4      GRj  xL
  X
P,                  '       dI   \/        \        \0        P2                  P4                  V
P6                  ^ ,          4      P8                  4      h\;        V
P6                  V
P<                  V
P                  R7      uuRRR4       #  EL EL L L  + GRj  xL 
 '       g   i     L; i  + '       g   i     R# ; i5i)z6Executes the tool by making a call through the client.ztools/call z
tools/callfastmcp.provider.typeProxyProviderNrequest_contextrv   experimentalis_taskT)exclude_nonezmodelcontextprotocol.io/task)rf   r}   rv   )contentstructured_contentrv   )r:   rf   r   set_attributer^   r(   
isinstanceStatefulProxyClientr   _fastmcpr   listr   _proxy_rc_refhasattrrv   dictr   r   task_metadata
model_dumpcall_tool_mcpisErrorr   mcptypesTextContentr   textr-   structuredContent)rO   r}   r   backend_namespanr]   ctxrv   req_ctxr   results   &&&        rC   runProxyTool.runo   s     ))66TYY,(,
 
6H++--Fvv..
 f&9::++@DcF$8$89!<
 /33 122!11Gw//GLLL#GLL1  88#G$8$8)DD#00888(/(<(<(J(J(#'::2D - 8 8d 8 K !!?@  &33%  4   ? vD ~~~SYY%:%:FNN1<M N S STT#)#;#;[[U
 
 .>? vvv
 
 
s   9J8&J$!I>"J$4J5J$8B,J	%AJ	J	"J	+.J	JJ	J$)J*J$ A3J$3J8>J$J$J	J$J!J
J!J!J$$J5	/	J8c                   V ^8  d   QhRR/# r=   rU   r~   rA   )rB   s   "rC   rD   rE           
 
^ 
rG   c                	J   < \         SV `  4       R RRV P                  /,          # r   r   zfastmcp.proxy.backend_namerK   get_span_attributesr:   rO   rP   s   &rC   r   ProxyTool.get_span_attributes   -    w*,#_($*<*<0
 
 	
rG   rM   N)__name__
__module____qualname____firstlineno____doc__r+   r8   __annotations__r:   rL   r^   ri   classmethodrz   r   r   __static_attributes____classcell__rP   s   @rC   r4   r4   C   s\    H(k:K: $M:$. ., , 
 
"5n
 
rG   r4   c                     a  ] tR t^t$ Rt]! RR7      tR]R&   RtR]R&   Rt	R	]R
&   RR/R V 3R lllt
R R ltR V 3R llt]R R l4       tR R ltR V 3R lltRtV ;t# )ProxyResourcezEA Resource that represents and reads a resource from a remote server.r5   r6   r+   r8   NResourceResult | None_cached_contentr9   _backend_uric                    V ^8  d   QhRRRR/# )r=   r>   r?   r   r   rA   )rB   s   "rC   rD   ProxyResource.__annotate__   s     	/ 	/&	/ /		/rG   c               	@   < \         SV `  ! R/ VB  Wn        W n        R # rI   )rK   rL   rM   r   )rO   r>   r   r@   rP   s   &&$,rC   rL   ProxyResource.__init__   s!     	"6"-.rG   c                   V ^8  d   QhRR/# rT   rA   )rB   s   "rC   rD   r      rV   rG   c                   "   V P                  4       p\        P                  ! V4      '       d   \        \        VG Rj  xL
 4      pV#  L
5irX   rY   r\   s   & rC   r^   ProxyResource._get_client   r`   ra   c                    V ^8  d   QhRRRR/# )r=   r@   r   rU   r   rA   )rB   s   "rC   rD   r           , ,3 ,= ,rG   c                   < VP                  R/ 4      pRV9   d.   V P                  f    / VCR\        V P                  4      /CpW!R&   \        SV `  ! R/ VB # )z3Override to preserve _backend_uri when uri changes.re   urir   rA   )rh   r   strr   rK   ri   rj   s   &, rC   ri   ProxyResource.model_copy   sY    Hb)F?t008>>DHH>F%8w!+F++rG   c               $    V ^8  d   QhRRRRRR/# )r=   r>   r?   mcp_resourcezmcp.types.ResourcerU   r   rA   )rB   s   "rC   rD   r      s(     
 
&
 )
 
	
rG   c                    T ! TVP                   VP                  VP                  VP                  VP                  ;'       g    RVP
                  VP                  \        VP                  4      P                  R. 4      \        RR7      R7
      # )zHFactory method to create a ProxyResource from a raw MCP resource schema.
text/plainrp   r5   r6   )
r>   r   rf   rq   rr   	mime_typeru   rv   rp   r8   )
r   rf   rq   rr   mimeTyperu   rv   r/   rh   r+   )ry   r>   r   s   &&&rC   from_mcp_resourceProxyResource.from_mcp_resource   s~     )  ""$$$00"++;;|$$""%l&7&78<<VRH"4
 	
rG   c                   V ^8  d   QhRR/# )r=   rU   r&   rA   )rB   s   "rC   rD   r      s     +5 +5N +5rG   c                  "   V P                   e   V P                   # V P                  ;'       g    \        V P                  4      p\	        RV 2RVVR7      ;_uu_ 4       pVP                  RR4       V P                  4       G Rj  xL
 pT;_uu_4       GRj  xL
  VP                  V4      G Rj  xL
 pRRR4      GRj  xL
  X'       g   \        RV 24      h. pV F  p\        V\        4      '       d>   VP                  \        VP                  VP                  VP                  R7      4       KV  \        V\         4      '       dR   VP                  \        \"        P$                  ! VP&                  4      VP                  VP                  R7      4       K  \        R	\)        V4       24      h	  \+        VR
7      uuRRR4       #  ELG EL7 EL! EL  + GRj  xL 
 '       g   i     EL,; i  + '       g   i     R# ; i5i)z1Read the resource content from the remote server.Nzresources/read zresources/read)resource_urir   r   )Remote server returned empty content for r   r   rv   Unsupported content type: contents)r   r   r   r   r   r   r^   read_resourcer   r   r   appendr%   r   r   rv   r   base64	b64decodeblobtyper&   )rO   backend_urir   r]   r   r   items   &      rC   readProxyResource.read   s    +'''''883txx=k]+$	
 

 6H++--Fvv%33K@@ v#?}M 
 /1Hd$899OO'$(II&*mm!%  &:;;OO'$*$4$4TYY$?&*mm!% (*DT$ZL(QRR% ( "84K
 
 .@ vvv
 
 
s   -H
0H
 &G6GG6GG6G	2G3G	7G6GG6C3G6H
G6G6G	G6G3G" 
G3+G3-	G66H		H
c                   V ^8  d   QhRR/# r   rA   )rB   s   "rC   rD   r     r   rG   c                	J   < \         SV `  4       R RRV P                  /,          # )r   r   zfastmcp.proxy.backend_uri)rK   r   r   r   s   &rC   r   !ProxyResource.get_span_attributes  s-    w*,#_'):):0
 
 	
rG   )r   rM   )r   r   r   r   r   r+   r8   r   r   r   rL   r^   ri   r   r   r   r   r   r   r   s   @rC   r   r      sq    O(k:K:-1O*1#L*#	/ 26		/ 	/, , 
 
(+5Z
 
rG   r   c                     a  ] tR tRt$ Rt]! RR7      tR]R&   RtR]R	&   R
 V 3R llt	R R lt
R V 3R llt]R R l4       tRR R lltR V 3R lltRtV ;t# )ProxyTemplatei  zWA ResourceTemplate that represents and creates resources from a remote server template.r5   r6   r+   r8   Nr9   _backend_uri_templatec                    V ^8  d   QhRRRR/# r<   rA   )rB   s   "rC   rD   ProxyTemplate.__annotate__  rF   rG   c                	4   < \         SV `  ! R/ VB  Wn        R # rI   rJ   rN   s   &&,rC   rL   ProxyTemplate.__init__  rR   rG   c                   V ^8  d   QhRR/# rT   rA   )rB   s   "rC   rD   r   "  rV   rG   c                   "   V P                  4       p\        P                  ! V4      '       d   \        \        VG Rj  xL
 4      pV#  L
5irX   rY   r\   s   & rC   r^   ProxyTemplate._get_client"  r`   ra   c                    V ^8  d   QhRRRR/# )r=   r@   r   rU   r   rA   )rB   s   "rC   rD   r   )  r   rG   c                   < VP                  R/ 4      pRV9   d%   V P                  f   / VCRV P                  /CpW!R&   \        SV `  ! R/ VB # )zEOverride to preserve _backend_uri_template when uri_template changes.re   uri_templater   rA   )rh   r   r   rK   ri   rj   s   &, rC   ri   ProxyTemplate.model_copy)  sY    Hb)V#(B(B(JKK 79J9JKF%8w!+F++rG   c               $    V ^8  d   QhRRRRRR/# )r=   r>   r?   mcp_templatezmcp.types.ResourceTemplaterU   r   rA   )rB   s   "rC   rD   r   3  s$     
 
+
;U
	
rG   c                "   T ! TVP                   VP                  VP                  VP                  VP                  ;'       g    RVP
                  / VP                  \        VP                  4      P                  R. 4      \        RR7      R7      # )zHFactory method to create a ProxyTemplate from a raw MCP template schema.r   rp   r5   r6   )r>   r   rf   rq   rr   r   ru   rs   rv   rp   r8   )
uriTemplaterf   rq   rr   r   ru   rv   r/   rh   r+   )ry   r>   r   s   &&&rC   from_mcp_templateProxyTemplate.from_mcp_template2  s     )%11""$$$00"++;;|$$""%l&7&78<<VRH"4
 	
rG   c               (    V ^8  d   QhRRRRRRRR/# )	r=   r   r   paramsr~   r   r   rU   r   rA   )rB   s   "rC   rD   r   F  s2     <
 <
<
 <
  	<

 
<
rG   c                  "   V P                   ;'       g    V P                  pVP                  ! R
/ VP                  4        UUu/ uF  w  rVV\	        VRR7      bK  	  uppB pV P                  4       G Rj  xL
 pT;_uu_4       GRj  xL
  VP                  V4      G Rj  xL
 p	RRR4      GRj  xL
  X	'       g   \        RV 24      h. p
V	 F  p\        V\        4      '       d>   V
P                  \        VP                  VP                  VP                  R7      4       KV  \        V\        4      '       dR   V
P                  \        \         P"                  ! VP$                  4      VP                  VP                  R7      4       K  \        R\'        V4       24      h	  \)        V
R7      p\+        V P,                  VV P.                  V P0                  V P2                  V	^ ,          P                  V P4                  V P                  \7        V P                  4      P9                  R. 4      VR	7
      # u uppi  EL EL EL EL  + GRj  xL 
 '       g   i     EL; i5i)zACreate a resource from the template by calling the remote server. )safeNr   r   r   r   rp   )
r>   r   rf   rq   rr   r   ru   rv   rp   r   rA   )r   r   rB   itemsr	   r^   r   r   r   r   r   r%   r   r   rv   r   r   r   r   r   r&   r   rM   rf   rq   rr   ru   r/   rh   )rO   r   r   r   backend_templatekvparameterized_urir]   r   r   r   cached_contents   &&&&         rC   create_resourceProxyTemplate.create_resourceF  s      55JJ9J9J,33 
06?q%##?
 ''))66!//0ABBF 6 ;<M;NO 
 +-D$ 455# $		"&--!YY D"677# & 0 0 ;"&--!YY $&@d$MNN% ( (://!**((h**%dii044VR@*
 	
G @)B 666s   AI'H8I'6H>7I'	I
I'I
"I#I
'I'2I3I'?F I'I'I
I'
I$	I
I$	I$		I'c                   V ^8  d   QhRR/# r   rA   )rB   s   "rC   rD   r     r   rG   c                	J   < \         SV `  4       R RRV P                  /,          # )r   r   z"fastmcp.proxy.backend_uri_template)rK   r   r   r   s   &rC   r   !ProxyTemplate.get_span_attributes  s-    w*,#_0$2L2L0
 
 	
rG   r   r   )r   r   r   r   r   r+   r8   r   r   rL   r^   ri   r   r   r  r   r   r   r   s   @rC   r   r     s]    a(k:K:(,:,. ., , 
 
&<
|
 
rG   r   c                     a  ] tR tRt$ Rt]! RR7      tR]R&   RtR]R	&   R
 V 3R llt	R R lt
R V 3R llt]R R l4       tR R ltR V 3R lltRtV ;t# )ProxyPrompti  zCA Prompt that represents and renders a prompt from a remote server.r5   r6   r+   r8   Nr9   r:   c                   V ^8  d   QhRR/# r=   r>   r?   rA   )rB   s   "rC   rD   ProxyPrompt.__annotate__  s     . .~ .rG   c                	4   < \         SV `  ! R/ VB  Wn        R # rI   rJ   rN   s   &&,rC   rL   ProxyPrompt.__init__  rR   rG   c                   V ^8  d   QhRR/# rT   rA   )rB   s   "rC   rD   r    rV   rG   c                   "   V P                  4       p\        P                  ! V4      '       d   \        \        VG Rj  xL
 4      pV#  L
5irX   rY   r\   s   & rC   r^   ProxyPrompt._get_client  r`   ra   c                    V ^8  d   QhRRRR/# )r=   r@   r   rU   r  rA   )rB   s   "rC   rD   r    s     , ,3 ,; ,rG   c                   < VP                  R/ 4      pRV9   d%   V P                  f   / VCRV P                  /CpW!R&   \        SV `  ! R/ VB # rd   rg   rj   s   &, rC   ri   ProxyPrompt.model_copy  rl   rG   c               $    V ^8  d   QhRRRRRR/# )r=   r>   r?   
mcp_promptzmcp.types.PromptrU   r  rA   )rB   s   "rC   rD   r    s$     
 
+
9I
	
rG   c                   VP                   ;'       g    .  Uu. uF9  p\        VP                  VP                  VP                  ;'       g    RR7      NK;  	  ppV ! VVP                  VP
                  VP                  VVP                  VP                  \        VP                  4      P                  R. 4      \        RR7      R7	      # u upi )zDFactory method to create a ProxyPrompt from a raw MCP prompt schema.F)rf   rr   requiredrp   r5   r6   )	r>   rf   rq   rr   r}   ru   rv   rp   r8   )r}   r"   rf   rr   r  rq   ru   rv   r/   rh   r+   )ry   r>   r  argr}   s   &&&  rC   from_mcp_promptProxyPrompt.from_mcp_prompt  s     "++11r1
 2 XXOO..
 2 	 
 )"""..""%joo6::62F"4

 
	

s   2C
C
c                    V ^8  d   QhRRRR/# )r=   r}   r~   rU   r!   rA   )rB   s   "rC   rD   r    s      n  rG   c           
       "   V P                   ;'       g    V P                  p\        RV 2RV4      ;_uu_ 4       pVP                  RR4       V P	                  4       G Rj  xL
 pT;_uu_4       GRj  xL
  VP                  W!4      G Rj  xL
 pRRR4      GRj  xL
  XP                   Uu. uF$  p\        VP                  VP                  R7      NK&  	  pp\        VVP                  VP                  R7      uuRRR4       #  L L L~ Lp  + GRj  xL 
 '       g   i     L; iu upi   + '       g   i     R# ; i5i)z6Render the prompt by making a call through the client.zprompts/get zprompts/getr   r   N)r   role)messagesrr   rv   )r:   rf   r   r   r^   
get_promptr"  r   r   r!  r!   rr   rv   )rO   r}   r   r   r]   r   mr"  s   &&      rC   renderProxyPrompt.render  s    ))66TYY<.)=,
 
6H++--Fvv%00II v BHAPA		7    !"..[[
 
 .I vvv

 
 
s   9E&D1!D"D14D
5D18D	DD	D1DD10*D,#D1=ED1
D1D	D1D)D
D)"D)$D11E	<	Ec                   V ^8  d   QhRR/# r   rA   )rB   s   "rC   rD   r    r   rG   c                	J   < \         SV `  4       R RRV P                  /,          # r   r   r   s   &rC   r   ProxyPrompt.get_span_attributes  r   rG   r   )r   r   r   r   r   r+   r8   r   r:   rL   r^   ri   r   r  r%  r   r   r   r   s   @rC   r  r    s[    M(k:K: $M:$. ., , 
 
0,
 
rG   r  c                  z   a  ] tR tRtRtR V 3R lltR R ltR R ltR	 R
 ltR R lt	R R lt
R R ltRtV ;t# )r   i  a  Provider that proxies to a remote MCP server via a client factory.

This provider fetches components from a remote server and returns Proxy*
component instances that forward execution to the remote server.

All components returned by this provider have task_config.mode="forbidden"
because tasks cannot be executed through a proxy.

Example:
    ```python
    from fastmcp import FastMCP
    from fastmcp.server.providers.proxy import ProxyProvider, ProxyClient

    # Create a proxy provider for a remote server
    proxy = ProxyProvider(lambda: ProxyClient("http://localhost:8000/mcp"))

    mcp = FastMCP("Proxy Server")
    mcp.add_provider(proxy)

    # Can also add with namespace
    mcp.add_provider(proxy.with_namespace("remote"))
    ```
c                   V ^8  d   QhRR/# r  rA   )rB   s   "rC   rD   ProxyProvider.__annotate__  s     - -&-rG   c                0   < \         SV `  4        Wn        R# )a  Initialize a ProxyProvider.

Args:
    client_factory: A callable that returns a Client instance when called.
                   This gives you full control over session creation and reuse.
                   Can be either a synchronous or asynchronous function.
N)rK   rL   r>   )rO   r>   rP   s   &&rC   rL   ProxyProvider.__init__  s     	,rG   c                   V ^8  d   QhRR/# rT   rA   )rB   s   "rC   rD   r,    rV   rG   c                   "   V P                  4       p\        P                  ! V4      '       d   \        \        VG Rj  xL
 4      pV#  L
5irX   )r>   rZ   r[   r   r   r\   s   & rC   r^   ProxyProvider._get_client  s<     $$&v&&&,/F #/ra   c                   V ^8  d   QhRR/# )r=   rU   zSequence[Tool]rA   )rB   s   "rC   rD   r,    s      > rG   c           	       "    V P                  4       G Rj  xL
 pT;_uu_4       GRj  xL
  VP                  4       G Rj  xL
 pV Uu. uF#  p\        P                  V P                  V4      NK%  	  upuuRRR4      GRj  xL
  #  Lq L` LJu upi  L  + GRj  xL 
 '       g   i     R# ; i  \
         d-   pTP                  P                  \        8X  d   . u Rp?# h Rp?ii ; i5i)z&List all tools from the remote server.N)	r^   
list_toolsr4   rz   r>   r   errorcoder   )rO   r]   	mcp_toolstes   &    rC   _list_toolsProxyProvider._list_tools  s     
	++--Fvv"("3"3"55	MVMVI++D,?,?CY vv .5 vvv
  	ww||//		   C-B3 B	B3 BB3 BBB)B4B6B3 BB3 C-	B3 B3 BBB3 B0	B
B0	(B0	*B3 .C-0B3 3C*> C%C*C-$C%%C**C-c                   V ^8  d   QhRR/# )r=   rU   zSequence[Resource]rA   )rB   s   "rC   rD   r,  $  s      '9 rG   c           	       "    V P                  4       G Rj  xL
 pT;_uu_4       GRj  xL
  VP                  4       G Rj  xL
 pV Uu. uF#  p\        P                  V P                  V4      NK%  	  upuuRRR4      GRj  xL
  #  Lq L` LJu upi  L  + GRj  xL 
 '       g   i     R# ; i  \
         d-   pTP                  P                  \        8X  d   . u Rp?# h Rp?ii ; i5i)z*List all resources from the remote server.N)	r^   list_resourcesr   r   r>   r   r5  r6  r   )rO   r]   mcp_resourcesrr9  s   &    rC   _list_resourcesProxyProvider._list_resources$  s     	++--Fvv&,&;&;&= = +* "33D4G4GK* vv . = vvv  	ww||//		r<  c                   V ^8  d   QhRR/# )r=   rU   zSequence[ResourceTemplate]rA   )rB   s   "rC   rD   r,  7  s      0J rG   c           	       "    V P                  4       G Rj  xL
 pT;_uu_4       GRj  xL
  VP                  4       G Rj  xL
 pV Uu. uF#  p\        P                  V P                  V4      NK%  	  upuuRRR4      GRj  xL
  #  Lq L` LJu upi  L  + GRj  xL 
 '       g   i     R# ; i  \
         d-   pTP                  P                  \        8X  d   . u Rp?# h Rp?ii ; i5i)z3List all resource templates from the remote server.N)	r^   list_resource_templatesr   r   r>   r   r5  r6  r   )rO   r]   mcp_templatesr8  r9  s   &    rC   _list_resource_templates&ProxyProvider._list_resource_templates7  s     	++--Fvv&,&D&D&F F +* "33D4G4GK* vv . F vvv  	ww||//		r<  c                   V ^8  d   QhRR/# )r=   rU   zSequence[Prompt]rA   )rB   s   "rC   rD   r,  J  s      %5 rG   c           	       "    V P                  4       G Rj  xL
 pT;_uu_4       GRj  xL
  VP                  4       G Rj  xL
 pV Uu. uF#  p\        P                  V P                  V4      NK%  	  upuuRRR4      GRj  xL
  #  Lq L` LJu upi  L  + GRj  xL 
 '       g   i     R# ; i  \
         d-   pTP                  P                  \        8X  d   . u Rp?# h Rp?ii ; i5i)z(List all prompts from the remote server.N)	r^   list_promptsr  r  r>   r   r5  r6  r   )rO   r]   mcp_promptspr9  s   &    rC   _list_promptsProxyProvider._list_promptsJ  s     	++--Fvv$*$7$7$99 )(  //0C0CQG( vv .9 vvv  	ww||//		r<  c                   V ^8  d   QhRR/# )r=   rU   zSequence[FastMCPComponent]rA   )rB   s   "rC   rD   r,  ]  s      !; rG   c                   "   . # 5i)a  Return empty list since proxy components don't support tasks.

Override the base implementation to avoid calling list_tools() during
server lifespan initialization, which would open the client before any
context is set. All Proxy* components have task_config.mode="forbidden".
rA   )rO   s   &rC   	get_tasksProxyProvider.get_tasks]  s      	   r>   )r   r   r   r   r   rL   r^   r:  rB  rH  rO  rS  r   r   r   s   @rC   r   r     s5    0- -$&&& rG   r   c                    V ^8  d   QhRRRR/# )r=   targetz}Client[ClientTransportT] | ClientTransport | FastMCP[Any] | FastMCP1Server | AnyUrl | Path | MCPConfig | dict[str, Any] | strrU   r?   rA   )rB   s   "rC   rD   rD   o  s      -$ -$	-$ -$rG   c                   aa \        V \        4      '       dD   V oSP                  4       '       d!   \        P	                  R4       R V3R llpV# R V3R llpV# \        \        \        V 4      4      oR V3R llpV# )aJ  Create a client factory from the given target.

Internal helper that handles the session strategy based on the target type:
- Connected Client: reuses existing session (with warning about context mixing)
- Disconnected Client: creates fresh sessions per request
- Other targets: creates ProxyClient and fresh sessions per request
zProxy detected connected client - reusing existing session for all requests. This may cause context mixing in concurrent scenarios.c                   V ^8  d   QhRR/# rT   rA   )rB   s   "rC   rD   ,_create_client_factory.<locals>.__annotate__  s      & rG   c                    < S # r   rA   r]   s   rC   reuse_client_factory4_create_client_factory.<locals>.reuse_client_factory  s    rG   c                   V ^8  d   QhRR/# rT   rA   )rB   s   "rC   rD   r[    s     $ $& $rG   c                 $   < S P                  4       # r   newr]  s   rC   fresh_client_factory4_create_client_factory.<locals>.fresh_client_factory  s    zz|#rG   c                   V ^8  d   QhRR/# rT   rA   )rB   s   "rC   rD   r[    s     	% 	%f 	%rG   c                 $   < S P                  4       # r   rb  )base_clients   rC   proxy_client_factory4_create_client_factory.<locals>.proxy_client_factory  s    ??$$rG   )r   r   is_connectedloggerinfoProxyClientr   r   )rX  r^  rd  ri  rh  r]   s   &   @@rC   _create_client_factoryro  o  s    ( &&!!  KKI
  ('$ $ (' "$sF"34	% 	% $#rG   c                  2   a  ] tR tRtRtR V 3R lltRtV ;t# )FastMCPProxyi  a  A FastMCP server that acts as a proxy to a remote MCP-compliant server.

This is a convenience wrapper that creates a FastMCP server with a
ProxyProvider. For more control, use FastMCP with add_provider(ProxyProvider(...)).

Example:
    ```python
    from fastmcp.server import create_proxy
    from fastmcp.server.providers.proxy import FastMCPProxy, ProxyClient

    # Create a proxy server using create_proxy (recommended)
    proxy = create_proxy("http://localhost:8000/mcp")

    # Or use FastMCPProxy directly with explicit client factory
    proxy = FastMCPProxy(client_factory=lambda: ProxyClient("http://localhost:8000/mcp"))
    ```
c                   V ^8  d   QhRR/# r  rA   )rB   s   "rC   rD   FastMCPProxy.__annotate__  s     $ $ '$rG   c               l   < \         SV `  ! R/ VB  Wn        \        V4      pV P	                  V4       R# )a  Initialize the proxy server.

FastMCPProxy requires explicit session management via client_factory.
Use create_proxy() for convenience with automatic session strategy.

Args:
    client_factory: A callable that returns a Client instance when called.
                   This gives you full control over session creation and reuse.
                   Can be either a synchronous or asynchronous function.
    **kwargs: Additional settings for the FastMCP server.
NrA   )rK   rL   r>   r   add_provider)rO   r>   r@   providerrP   s   &$, rC   rL   FastMCPProxy.__init__  s3    " 	"6",*>:(#rG   rV  r   r   r   r   r   rL   r   r   r   s   @rC   rq  rq    s    $$ $rG   rq  c                    V ^8  d   QhRRRR/# )r=   r   /RequestContext[ClientSession, LifespanContextT]rU   r   rA   )rB   s   "rC   rD   rD     s     " "<""rG   c                R   "   \        4       pVP                  4       G Rj  xL
 #  L5i)zKForward list roots request from remote server to proxy's connected clients.N)r(   
list_roots)r   r   s   & rC   default_proxy_roots_handlerr}    s!      -C!!!!s   '%'c               (    V ^8  d   QhRRRRRRRR/# )	r=   r"  zlist[mcp.types.SamplingMessage]r   z$mcp.types.CreateMessageRequestParamsr   rz  rU   zmcp.types.CreateMessageResultrA   )rB   s   "rC   rD   rD     s0      -0 = #	rG   c                n  "   \        4       pVP                  \        V 4      VP                  VP                  VP
                  VP                  R7      G Rj  xL
 p\        P                  P                  RVP                  ;'       g    RR7      p\        P                  P                  RRVR7      #  L[5i)	zIForward sampling request from remote server to proxy's connected clients.)system_prompttemperature
max_tokensmodel_preferencesNr   r   )r   r   	assistantzfastmcp-client)r!  modelr   )r(   sampler   systemPromptr  	maxTokensmodelPreferencesr   r   r   r   CreateMessageResult)r"  r   r   r   r   r   s   &&&   rC   default_proxy_sampling_handlerr    s      -C::X))&&## 11   F ii##fkk6G6GR#HG99((	 )  s   AB5B30B5	+B5c          
     ,    V ^8  d   QhRRRRRRRRR	R
/# )r=   messager   response_typer   r   zmcp.types.ElicitRequestParamsr   rz  rU   r   rA   )rB   s   "rC   rD   rD     sA     F FFF *F =	F
 FrG   c                  "   \        4       p\        V\        4      '       d   VP                  MRRR/ /pVP                  P                  V VVP                  R7      G Rj  xL
 p\        VP                  VP                  R7      #  L%5i)zLForward elicitation request from remote server to proxy's connected clients.r   object
properties)r  requestedSchemarelated_request_idN)actionr   )
r(   r   r   r  sessionelicit
request_idr   r  r   )r  r  r   r   r   requested_schemar   s   &&&&   rC   !default_proxy_elicitation_handlerr    s      -C f566 	hb1 
 ;;%%(>> &  F
 v}}fnnEEs   AB B!&Bc                    V ^8  d   QhRRRR/# )r=   r  r   rU   NonerA   )rB   s   "rC   rD   rD     s     U UZ UD UrG   c                   "   \        4       pV P                  P                  R4      pV P                  P                  R4      pVP                  W P                  V P
                  VR7      G Rj  xL
  R#  L5i)zIForward log notification from remote server to proxy's connected clients.msgextra)levellogger_namer  N)r(   datarh   logr  rl  )r  r   r  r  s   &   rC   default_proxy_log_handlerr    sT     
-C
,,

5
!CLLW%E
''#]]e'
TTTs   A,A7.A5/A7c               (    V ^8  d   QhRRRRRRRR/# )	r=   progressfloattotalzfloat | Noner  r9   rU   r  rA   )rB   s   "rC   rD   rD     s0     8 888 8 
	8rG   c                Z   "   \        4       pVP                  WV4      G Rj  xL
  R#  L5i)zNForward progress notification from remote server to proxy's connected clients.N)r(   report_progress)r  r  r  r   s   &&& rC   default_proxy_progress_handlerr    s$      -C


hw
777s    +)+c                    V ^8  d   QhRRRR/# )r=   rc_ref	list[Any]rU   r  rA   )rB   s   "rC   rD   rD     s     $3 $3$3	$3rG   c                   ^ RI HpHp V ^ ,          pVf   R# Vw  rE \        P                  ! 4       pTP                  TP                  J dZ   TP                  TP                  8w  d=   \        P                  ! T4       T! 4       pTe   TP                  T! T4      4       R# R# R# R#   \
         d=    \        P                  ! T4       T! 4       pTe   TP                  T! T4      4        R# i ; i)u  Set the ``request_ctx`` and ``_current_context`` ContextVars from stashed values.

Called at the start of proxy handler invocations in
``StatefulProxyClient`` to fix stale ContextVars in the receive-loop
task.  Only overrides when the ContextVar is genuinely stale (same
session, different request_id) to avoid corrupting the concurrent
case where multiple sessions share the same ref via ``copy.copy``.

We stash a ``(RequestContext, weakref[FastMCP])`` tuple — never a
``Context`` instance — because ``Context`` properties are themselves
ContextVar-dependent and would resolve stale values in the receive
loop.  Instead we construct a fresh ``Context`` here after restoring
``request_ctx``, so its property accesses read the correct values.
)r'   _current_contextN)	fastmcp.server.contextr'   r  r   rh   LookupErrorsetr  r  )r  r'   r  stashedrcfastmcp_ref
current_rcfastmcps   &       rC   _restore_request_contextr    s    " AQiGOB __&
 RZZ'J,A,AR]],R-  !12  -S'  -  !12s   B' 'AC.-C.c               $    V ^8  d   QhRRRRRR/# )r=   handlerr   r  r  rU   rA   )rB   s   "rC   rD   rD   A  s!      X y X rG   c                   a a R V V3R llpV# )zWrap a proxy handler to restore request_ctx before delegating.

The wrapper is a plain ``async def`` so it passes
``inspect.isfunction()`` checks in handler registration paths
(e.g., ``create_roots_callback``).
c               $    V ^8  d   QhRRRRRR/# )r=   argsr   r@   rU   rA   )rB   s   "rC   rD   -_make_restoring_handler.<locals>.__annotate__I  s!     . .S .C .C .rG   c                 F   <"   \        S4       S! V / VB G R j  xL
 #  L5ir   )r  )r  r@   r  r  s   *,rC   wrapper(_make_restoring_handler.<locals>.wrapperI  s$      (d-f----s   !!rA   )r  r  r  s   ff rC   _make_restoring_handlerr  A  s    . . NrG   c                  2   a  ] tR tRtRtR V 3R lltRtV ;t# )rn  iP  zA proxy client that forwards advanced interactions between a remote MCP server and the proxy's connected clients.

Supports forwarding roots, sampling, elicitation, logging, and progress.
c                   V ^8  d   QhRR/# )r=   	transportzcClientTransportT | FastMCP[Any] | FastMCP1Server | AnyUrl | Path | MCPConfig | dict[str, Any] | strrA   )rB   s   "rC   rD   ProxyClient.__annotate__V  s     > >>rG   c                	  < R V9  d   V P                  4       VR &   RV9  d
   \        VR&   RV9  d
   \        VR&   RV9  d
   \        VR&   RV9  d
   \        VR&   RV9  d
   \
        VR&   \        SV `  ! R/ VRV/,          B  R# )	rf   rootssampling_handlerelicitation_handlerlog_handlerprogress_handlerr  NrA   )generate_namer}  r  r  r  r  rK   rL   )rO   r  r@   rP   s   &&,rC   rL   ProxyClient.__init__V  s     !//1F6N& 9F7OV+)GF%& .,MF()&$=F=!V+)GF%&=6[)$<<=rG   rA   rx  r   s   @rC   rn  rn  P  s    
> >rG   rn  c                  \   a  ] tR tRt$ RtR]R&   R V 3R lltR R ltR	 tR
 R lt	Rt
V ;t# )r   iq  a  A proxy client that provides a stateful client factory for the proxy server.

The stateful proxy client bound its copy to the server session.
And it will be disconnected when the session is exited.

This is useful to proxy a stateful mcp server such as the Playwright MCP server.
Note that it is essential to ensure that the proxy server itself is also stateful.

Because session reuse means the receive-loop task inherits a stale
``request_ctx`` ContextVar snapshot, the default proxy handlers are
replaced with versions that restore the ContextVar before forwarding.
``ProxyTool.run`` stashes the current ``RequestContext`` in
``_proxy_rc_ref`` before each backend call, and the handlers consult
it to detect (and correct) staleness.
r  r   c                    V ^8  d   QhRRRR/# )r=   r  r   r@   rA   )rB   s   "rC   rD    StatefulProxyClient.__annotate__  s     I Ic IS IrG   c                	   < R .V n         R\        3R\        3R\        3R\        3R\
        33 F$  w  r4W29  g   K  \        W@P                   4      W#&   K&  	  \        SV `   ! V/ VB  / V n	        R # )Nr  r  r  r  r  )
r   r}  r  r  r  r  r  rK   rL   _caches)rO   r  r@   key
default_fnrP   s   &*,  rC   rL   StatefulProxyClient.__init__  s     #V12!?@"$EF56!?@ 
OC  5jBTBTU 
 	$)&)FHrG   c                   V ^8  d   QhRR/# )r=   rU   r  rA   )rB   s   "rC   rD   r    s       rG   c                   "   R# 5i)zjThe stateful proxy client will be forced disconnected when the session is exited.

So we do nothing here.
NrA   )rO   exc_type	exc_value	tracebacks   &&&&rC   	__aexit__StatefulProxyClient.__aexit__  s     rU  c                   "   V P                   '       d9   V P                   P                  4       w  rVP                  RR7      G Rj  xL
  KJ  R#  L5i)z3Clear all cached clients and force disconnect them.TforceN)r  popitem_disconnect)rO   _caches   &  rC   clearStatefulProxyClient.clear  sA     lll||++-HA##$#/// /s   A1AA	Ac                   V ^8  d   QhRR/# )r=   rU   zClient[ClientTransportT]rA   )rB   s   "rC   rD   r    s      6 rG   c                ,  a aa \        4       P                  oS P                  P                  SR4      oSf]   S P	                  4       o\
        P                  S RS 24       SS P                  S&   VV V3R lpSP                  P                  V4       S# )zCreate a new stateful proxy client instance with the same configuration.

Use this method as the client factory for stateful proxy server.
Nz created for c                    <"   SP                   P                  S4       \        P                  S  R 24       S P	                  RR7      G Rj  xL
  R#  L5i)z will be disconnectTr  N)r  poprl  debugr  )proxy_clientrO   r  s   rC   _on_session_exit:StatefulProxyClient.new_stateful.<locals>._on_session_exit  sC       )~-@AB"..T.:::s   A	AAA)	r(   r  r  rh   rc  rl  r  _exit_stackpush_async_callback)rO   r  r  r  s   f @@rC   new_stateful StatefulProxyClient.new_stateful  s    
 -''||''688:LLLL>wi@A$0DLL!;
 334DErG   )r  r   )r   r   r   r   r   r   rL   r  r  r  r   r   r   s   @rC   r   r   q  s0    2 I I"0 rG   r   )gr   
__future__r   r   rZ   collections.abcr   r   r   typingr   r   r   urllib.parser	   	mcp.typesr   r
   mcp.client.sessionr   mcp.server.lowlevel.serverr   mcp.shared.contextr   r   mcp.shared.exceptionsr   r   r   r   r   pydantic.networksr   fastmcp.client.clientr   r   fastmcp.client.elicitationr   fastmcp.client.loggingr   fastmcp.client.rootsr   fastmcp.client.telemetryr   fastmcp.client.transportsr   fastmcp.exceptionsr   r   fastmcp.mcp_configr   fastmcp.promptsr   r    r!   fastmcp.prompts.promptr"   fastmcp.resourcesr#   r$   fastmcp.resources.resourcer%   r&   r  r'   fastmcp.server.dependenciesr(   fastmcp.server.providers.baser)   fastmcp.server.serverr*   fastmcp.server.tasks.configr+   fastmcp.tools.toolr,   r-   fastmcp.utilities.componentsr.   r/   fastmcp.utilities.loggingr0   pathlibr1   r2   r   rl  r?   r4   r   r   r  r   ro  rq  r}  r  r  r  r  r  r  rn  r   rA   rG   rC   <module>r     sg   #   9 9 + +    , 2 ? *  % 8 3 - * 0 6 7 ( 9 9 1 8 F * 3 2 ) 2 / O 09	H	 "f*%Yv5F1F(GGg
 g
Th
H h
Vp
$ p
fM
& M
jDH D^-$j'$7 '$^".F,U8$3N>&)* >BM+&67 MrG   