+
    lHàj·‡  ã                   óÌ   € R t ^ RIt^ RIt^ RIt^ RIHt ^ RIHt ^ RIH	t	H
t
HtHt ^ RIHt ^ RIHt ^ RIHt ]P(                  ! R4      t] ! R	 R
4      4       t ! R R4      tR# )aC  Lifecycle of :class:`tools.mcp_tool.MCPServerTask`: the long-lived ``run`` state machine
(connect -> serve -> reconnect/park/recycle), keepalive-driven lifecycle waits, start/shutdown
and tool deregistration. Origin state and patchable helpers are read through ``_core`` so
``mock.patch("tools.mcp_tool.X")`` keeps working.N)Ú	dataclass)ÚOptional)Ú_coreÚ_get_lifecycle_secondsÚ	_jitteredÚ_resolve_tool_timeout)Úmcp_tool_errors)Úmcp_tool_registration)Úmcp_tool_samplingztools.mcp_toolc                   ó8   a € ] tR t^t o Rt^ tRtV 3R ltRtV t	R# )Ú_RetryBudgetz\Per-run() retry counters (``_reconnect_retries`` stays on the task: handlers/tests read it).ç      ð?c                ó2   <€ V ^8„  d   Qh/ S[ ;R&   S[;R&   # )é   Úinitial_retriesÚbackoff)ÚintÚfloat)ÚformatÚ__classdict__s   "€Ú>/home/ubuntu/.hermes/hermes-agent/tools/mcp_tool_server_run.pyÚ__annotate__Ú_RetryBudget.__annotate__   s   ø‡ ‚ ñ Ññ	 ñ
 Ñò ó    © N)
Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   r   Ú__annotate_func__Ú__static_attributes__Ú__classdictcell__©r   s   @r   r   r      s   ø‡ € áfà€OØ€G÷ ƒ r   r   c                   óÚ  a € ] tR t^t o Rt]V 3R lR l4       tV 3R lR ltV 3R lR ltV 3R lR	 lt	V 3R
 lR lt
R3V 3R lR lltV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltR4tV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR  ltV 3R! lR" ltV 3R# lR$ ltV 3R% lR& ltV 3R' lR( ltV 3R) lR* ltV 3R+ lR, ltV 3R- lR. ltR/ tV 3R0 lR1 ltR2tV t R# )5ÚMCPServerRunMixinzVMethods of :class:`tools.mcp_tool.MCPServerTask` (mixed in; relies on its attributes).c                ó8   <€ V ^8„  d   QhRS[ P                  RR/# )r   ÚtasksÚreturnN)ÚasyncioÚTask)r   r   s   "€r   r   ÚMCPServerRunMixin.__annotate__   s   ø€ ÷ ñ ¡g§l¡lð °tñ r   c               ‡  óÎ   "  € V  F6  pVP                  4       '       d   K  VP                  4         VG R j  x€L
  K8  	  R #  L
  \        P                  \        3 d     K\  i ; i5i©N)ÚdoneÚcancelr)   ÚCancelledErrorÚ	Exception)r'   Úts   * r   Ú_cancel_waitersÚ!MCPServerRunMixin._cancel_waiters   sP   é € ãˆAØ—6‘6—8”8Ø—‘”
ðØ—G’Gó	 ñ øÜ×.Ñ.´	Ð:ô Úðüs<   ‚A% A%±A¶A·A»A%ÁAÁA"ÁA%Á!A"Á"A%c                ó    <€ V ^8„  d   QhRS[ /# ©r   r(   )Útuple)r   r   s   "€r   r   r+   (   s   ø€ ÷ Eñ E¡ñ Er   c                óº   € \         P                  ! V P                  P                  4       4      \         P                  ! V P                  P                  4       4      3# )zPFresh ``(shutdown, reconnect)`` wait tasks; cancel them via ``_cancel_waiters``.)r)   Úensure_futureÚ_shutdown_eventÚwaitÚ_reconnect_event©Úselfs   &r   Ú_event_waitersÚ MCPServerRunMixin._event_waiters(   sH   € ä×%Ò% d×&:Ñ&:×&?Ñ&?Ó&AÓBÜ×%Ò% d×&;Ñ&;×&@Ñ&@Ó&BÓCðEð 	Er   c                ó    <€ V ^8„  d   QhRS[ /# r6   ©Úbool)r   r   s   "€r   r   r+   -   s   ø€ ÷ ñ ¡ñ r   c                óT   € V P                  4       pVf   R# V P                  V4       R# )zALatch a stdio idle/lifetime recycle when its deadline has passed.FT)Ú_stdio_recycle_reasonÚ_mark_stdio_recycled)r>   Úrecycle_reasons   & r   Ú_recycle_if_dueÚ!MCPServerRunMixin._recycle_if_due-   s*   € à×3Ñ3Ó5ˆØÒ!ÙØ×!Ñ! .Ô1Ùr   c                ó   <€ V ^8„  d   QhRR/# ©r   r(   Nr   )r   r   s   "€r   r   r+   5   s   ø€ ÷ ñ ¨$ñ r   c              ƒ  ó¬   "  € V P                   ;_uu_4       GRj  x€L
   RRR4      GRj  x€L
  R#  L L  + GRj  x€L 
 '       g   i     R# ; i5i)z>Wake the lifecycle loop when the active RPC releases its lock.N)Ú	_rpc_lockr=   s   &r   Ú_wait_for_rpc_idleÚ$MCPServerRunMixin._wait_for_rpc_idle5   s"   é € à—>—>—>“>Ø÷ "—>—>—>—>—>üs@   ‚A›3œAŸ7¡A¬5­AµA·A	½A ¾
A	Á	A	Á	Ac                ó    <€ V ^8„  d   QhRS[ /# r6   ©Ústr)r   r   s   "€r   r   r+   :   s   ø€ ÷ bñ b±ñ br   c              ƒ  óŒ
  "  € V P                  4       pV P                  P                  R4      pRpV'       g   Ve8   \        \        P
                  \        Vf   \        P                  MT4      4      pRpVf=   V P                  '       g+   \        P                  ! 4       \        P                  ,           pV P                  4       w  rVRpWV.p  V P                  4       '       d    V P                  ! V!  G Rj  x€L
  R# Tp	V	f=   V P                  '       g+   Ve'   \        RV\        P                  ! 4       ,
          4      p	V P                  4       p
V
e9   \        RV
\        P                  ! 4       ,
          4      pV	f   TM
\        W›4      p	MVV'       gO   V P                   P#                  4       '       d/   T;'       g%    \$        P&                  ! V P)                  4       4      pWVV3 Uu. uF
  qÌf   K  VNK  	  pp\$        P*                  ! W‰\$        P,                  R7      G Rj  x€L
 w  rÞW]9   g   Wm9   d   EM™W}9   d   RpEKw  V P                  4       '       d    V P                  ! V!  G Rj  x€L
  R# Vf{   V P                  '       gf   Veb   \        P                  ! 4       V8¼  dH   V P/                  4       '       d"   \0        P3                  RV P4                  4       MòV P7                  4        EK&  V P8                  '       g   EK;  V P                   P#                  4       '       gO   \:        ;QJ d&    R V P<                   4       F  '       g   K   RM	  R	M! R V P<                   4       4      '       d   EK¬   V P                   ;_uu_4       GRj  x€L
  V P?                  4       G Rj  x€L
  RRR4      GRj  x€L
  T P7                  4        EK  V P                  ! V!  G Rj  x€L
  V PP                  PS                  4       '       d   V PU                  R4       R# V PU                  R4       V PL                  PW                  4        R#  ELRu upi  EL. ELç LÅ L¯ L¡  + GRj  x€L 
 '       g   i     L¸; i  \@         dœ   p\B        PD                  ! T4      p\0        P3                  R
T P4                  \G        T4      PH                  T4       T PK                  R\G        T4      PH                   RT 24       T PL                  PO                  4         Rp?EKI  Rp?ii ; i EL>  T P                  ! T!  G Rj  x€L 
  i ; i5i)uc  Serve until a lifecycle event: ``"shutdown"`` (exits run), ``"reconnect"`` (session torn
down, transport re-entered; event cleared first) or ``"recycle"`` (stdio idle/lifetime
limit; restarts lazily on next call). Shutdown wins a tie. Remote transports run a
keepalive (``ping``, with a ``list_tools`` fallback for servers lacking the optional ping
utility â€” see :meth:`_keepalive_probe`) every ``keepalive_interval`` (which must stay
below the server's session TTL) so idle TCP/session state never goes stale (#17003);
stdio does so only when explicitly configured. A keepalive failure triggers a reconnect.
Úkeepalive_intervalNTÚrecycleg        )ÚtimeoutÚreturn_whenuz   MCP server '%s' stdio child exited before the session proved healthy; triggering reconnect (state: connected â†’ degraded)c              3   óJ   "  € T F  qP                  4       '       * x € K  	  R # 5ir-   )r.   )Ú.0r2   s   & r   Ú	<genexpr>Ú>MCPServerRunMixin._wait_for_lifecycle_event.<locals>.<genexpr>„   s   é € Ð5aÑL`Àq¿&¹&»(·l±lÓL`ùs   ‚!#Fu^   MCP server '%s' keepalive failed, triggering reconnect (state: connected â†’ degraded): %s: %szkeepalive failed: z: ÚshutdownÚ	reconnect),Ú_is_httpÚ_configÚgetÚmaxr   Ú_MIN_KEEPALIVE_INTERVALr   Ú_DEFAULT_KEEPALIVE_INTERVALÚ_session_provenÚtimeÚ	monotonicr?   rH   r3   Ú_next_stdio_recycle_deadlineÚminrM   Úlockedr)   r9   rN   r;   ÚFIRST_COMPLETEDÚ_stdio_children_deadÚloggerÚwarningÚnameÚ_mark_session_provenÚsessionÚanyÚ_inflight_tasksÚ_keepalive_prober1   Ú_errorsÚ_unwrap_exception_groupÚtyper   Úmark_suspectr<   Úsetr:   Úis_setÚ_fail_inflight_callsÚclear)r>   Úis_httpÚ
configuredrT   Úproof_atÚshutdown_taskÚreconnect_taskÚrpc_idle_taskÚwaitersrV   Úrecycle_deadlineÚrecycle_timeoutr2   r.   Ú_pendingÚexcÚroots   &                r   Ú_wait_for_lifecycle_eventÚ+MCPServerRunMixin._wait_for_lifecycle_event:   s%  é € ð —-‘-“/ˆØ—\‘\×%Ñ%Ð&:Ó;ˆ
Ø!Ðß�jÒ,Ü!$Ü×-Ñ-Ü¸:Ò;M”e×7Ò7ÐS]Ó^ó"`Ðð ˆØÒ%¨d×.B×.BÐ.BÜ—~’~Ó'¬%×*KÑ*KÕKˆHØ(,×(;Ñ(;Ó(=Ñ%ˆØˆØ Ð1ˆðA	1ØØ×'Ñ'×)Ò)Ø$ð| ×&Ò&¨Ñ0×0Ò0ð{ -�Ø’?¨4×+?×+?Ð+?ÀHÒDXÜ! # x´$·.².Ó2BÕ'BÓC�GØ#'×#DÑ#DÓ#FÐ Ø#Ò/Ü&)¨#Ð/?Ä$Ç.Â.ÓBRÕ/RÓ&S�OØ18²™oÄcÈ'ÓFc‘Gß  T§^¡^×%:Ñ%:×%<Ò%<ð
 %2×$eÐ$e´W×5JÒ5JÈ4×KbÑKbÓKdÓ5e�MØ'4ÀmÑ&TÓfÑ&T Ÿ1˜1Ñ&T�ÐfÜ'.§|¢|Ø¼'×:QÑ:Qô(S÷ "S‘�à Ô(¨NÔ,BÙØ Ô(Ø$(�MÚØ×'Ñ'×)Ò)Ø$ðN ×&Ò&¨Ñ0×0Ò0ðM &Ò-ð
 !×0×0Ð0°XÒ5IÜ $§¢Ó 0°HÔ <Ø×4Ñ4×6Ò6ô
 #ŸN™Nð ,kà+/¯9©9ô6ð "Ø×1Ñ1Ô3Úð —<—<“<Ø—~‘~×,Ñ,×.Ò.·#³#Ñ5aÈD×L`ÒL`Ó5a·#·#²#Ñ5aÈD×L`ÒL`Ó5a×2aÒ2aÚ ð	Ø#'§>§>§>£>Ø"&×"7Ñ"7Ó"9×9Ð9÷ $2§>ð ×-Ñ-×/à×&Ò&¨Ñ0×0Ð0Ø×Ñ×&Ñ&×(Ò(Ø×%Ñ% jÔ1Ùð 	×!Ñ! +Ô.Ø×Ñ×#Ñ#Ô%Ùò 1ùòa gò"Sò^ 1ñ $2Ù9÷ $2§>§>¢>ûä$ô Ü&×>Ò>¸sÓC˜ÜŸ™ð (;Ø<@¿I¹IÄtÈDÃz×GZÑGZÐ\`ôbà×)Ñ)Ð,>¼tÀD»z×?RÑ?RÐ>SÐSUÐVZÐU[Ð*\Ô]Ø×-Ñ-×1Ñ1Ô3Þûðúò 1ø�$×&Ò&¨Ñ0×0Ò0üs  ‚BUÂAUÃT& Ã%UÃ8Q
Ã9UÃ?T& ÄA=T& ÆT& Æ5T& Æ>+T& Ç)QÇ3QÇ9+T& È$QÈ%4T& ÉUÉ.QÉ/UÉ5T& Ê3T& Ê?AT& ÌT& Ì(
T& Ì3T& Í$T& Í6T& Í:Q: ÎQÎQ: ÎQÎ*QÎ+QÎ/Q: Î:QÎ;Q: Î?T& ÏUÏ%T#Ï&#UÐ
AUÑT& ÑUÑQ: ÑQÑQ: ÑQ7	Ñ$Q'Ñ%
Q7	Ñ0Q7	Ñ2Q: Ñ6T& Ñ7Q: Ñ:T ÒBTÔT& ÔT Ô T& Ô#UÔ&UÔ:T=Ô;UÕUNc                ó6   <€ V ^8„  d   QhRS[ S[,          RS[/# )r   rV   r(   )r   r   rR   )r   r   s   "€r   r   r+   ž   s    ø€ ÷ ñ ¹XÁe½_ð ÑX[ñ r   c              ƒ  óÈ  "  € V P                  4       w  r# \        P                  ! W#0\        P                  VR7      G Rj  x€L
  V P	                  W#4      G Rj  x€L
  V P
                  P                  4       '       d   R# V P                  P                  4       '       g   R# V P                  P                  4        R#  L} Lf  T P	                  Y#4      G Rj  x€L 
  i ; i5i)z¡Parked wait: ``"shutdown"``, ``"reconnect"`` (explicit request; event cleared first) or
``"self-probe"`` (``timeout`` elapsed with neither). Shutdown wins a tie.)rW   rV   Nr\   ú
self-prober]   )	r?   r)   r;   rj   r3   r:   ry   r<   r{   )r>   rV   r   r€   s   &&  r   Ú_wait_for_reconnect_or_shutdownÚ1MCPServerRunMixin._wait_for_reconnect_or_shutdownž   s´   é € ð )-×(;Ñ(;Ó(=Ñ%ˆð	FÜ—,’, Ð>ÌG×LcÑLcÐmtÔu×uÐuà×&Ñ& }ÓE×EÐEØ×Ñ×&Ñ&×(Ò(ÙØ×$Ñ$×+Ñ+×-Ò-ÙØ×Ñ×#Ñ#Ô%Ùñ váEø�$×&Ñ& }ÓE×EÒEüsX   ‚C"–+C ÁB?ÁC ÁC"ÁCÁ#C"Á?!C"Â!C"Â?C ÃC"ÃCÃCÃCÃC"c                ó$   <€ V ^8„  d   QhRS[ RR/# )r   Úmsgr(   NrQ   )r   r   s   "€r   r   r+   ­   s   ø€ ÷ 'ñ '™Sð '¨Dñ 'r   c                óÞ   € V'       d	   W,          MTpV P                   '       d+   W0P                  8X  d   \        P                  ! V.VO5!   R# W0n        \        P                  ! V.VO5!   R# )u&  Park chatter control (#115713): re-parking a server that never revived is not a state
transition â€” ``hermes mcp list`` already surfaces the parked state, so one identical
WARNING per self-probe carries no new information. The first park (and the revived line
in ``_mark_session_proven``) stays a WARNING; an identical repeat while still parked is
demoted to DEBUG so a long-lived gateway's error log is not flooded (10k+ identical
lines/month). A park for a DIFFERENT reason (auth error after connection refused) is new
information and warns again.N)Ú_was_parkedÚ_last_park_linerl   Údebugrm   )r>   r�   ÚargsÚlines   &&* r   Ú	_log_parkÚMCPServerRunMixin._log_park­   sN   € ÷ "ˆsŽz sˆØ××Ð ×(<Ñ(<Ô <Ü�LŠL˜Ð$˜tÖ$à#'Ô Ü�NŠN˜3Ð& Ö&r   c                ó&   <€ V ^8„  d   QhRS[ RS[/# )r   Úrevival_reasonr(   )rR   rC   )r   r   s   "€r   r   r+   ¼   s   ø€ ÷ 4ñ 4©#ð 4±$ñ 4r   c              ƒ  ó  "  € RV n         Wn        V P                  4        V P                  P	                  4        Rp V P                  \        P                  R7      G Rj  x€L
 pVR8X  d   R# VR8X  dT   V P                  4       '       g>   V'       d   \        P                  M\        P                  ! RV P                  4       RpKŒ  VR8X  d   ^ RIHp VP                  R4       \        P                  R	V P                  VV4       R#  L©5i)
a’  Drop this server's tools and wait for a reconnect request; True when shutdown came instead.
The run task must NOT exit (it is the only ``_reconnect_event`` listener, so returning
leaves the server unrevivable). With tools deregistered no call can reach the breaker
probe, so the wait is TIMED (one self-probe per ``_PARKED_RETRY_INTERVAL``); an explicit
``_reconnect_event.set()`` wakes it immediately.TF©rV   Nr\   rŒ   zqMCP server '%s': parked entry is disabled or gone from mcp_servers; pausing the self-probe until it is re-enabled)Ú_oauth_interactive_enabledzBMCP server '%s': attempting revival %s (%s); rebuilding transport.)r’   Ú_park_reasonÚ_deregister_toolsr<   r{   r�   r   Ú_PARKED_RETRY_INTERVALÚ_still_configured_enabledrl   r”   Úinforn   Útools.mcp_oauthr�   rx   )r>   rš   ÚpausedÚoutcomer�   s   &&   r   Ú_parkÚMCPServerRunMixin._park¼   sò   é € ð  ˆÔØ*ÔØ×ÑÔ Ø×Ñ×#Ñ#Ô%ØˆØØ ×@Ñ@Ü×4Ñ4ð Aó 6÷ 6ˆGà˜*Ô$Ùð ˜,Ô&¨t×/MÑ/M×/OÒ/Oß!'”—’¬V¯[©[Ð8ð8Ø9=¿¹ôDð �Ùð ˜,Ô&ÝFà*×.Ñ.¨uÔ5Ü�L‰LØTØ—	‘	ØØô	ñ ñC6ùs   ‚ADÁ D
Á!)DÂDÂA8Dc                ó    <€ V ^8„  d   QhRS[ /# r6   rB   )r   r   s   "€r   r   r+   ò   s   ø€ ÷ ñ ©4ñ r   c                óÂ   €  ^ RI Hp VP                  4       ;'       g    / P                  V P                  4      pVf   R# ^ RIHp V! V4      #   \         d     R# i ; i)aA  Whether ``mcp_servers`` on disk still wants this server connected: entry present
and ``enabled`` not false. Config read is cached on the file signature, so a parked
task polling this every ``_PARKED_RETRY_INTERVAL`` stays cheap. Fail-open on a
config-read error: a broken config must not wedge a healthy server's revival.©Úmcp_tool_configF)Úmcp_server_enabledT)Útoolsr«   Ú_load_mcp_configr`   rn   Útools.mcp_tool_commonr¬   r1   )r>   r_   Úentryr¬   s   &   r   r¡   Ú+MCPServerRunMixin._still_configured_enabledò   sW   € ð
	Ý8Ø×-Ñ-Ó/×5Ð5°2×:Ñ:¸4¿9¹9ÓEˆEØŠ}ÙÝ@Ù% eÓ,Ð,øÜô 	Úð	ús   ‚A Ÿ A ÁA ÁAÁAc                ó&   <€ V ^8„  d   QhRS[ RS[/# ©r   Úconfigr(   )ÚdictrC   )r   r   s   "€r   r   r+     s   ø€ ÷ +ñ +©ð +±$ñ +r   c              ƒ  óœ  a "  € VS n         \        V4      S n        VP                  R4      ;'       g    RP	                  4       P                  4       S n        \        VR4      S n        \        VR4      S n	        \        P                  ! 4        VP                  R/ 4      pVP                  RR4      '       d8   \        P                  '       d"   \        P                  ! S P                  V4      MRS n        VP                  R	/ 4      pVP                  RR4      '       d>   \        P                   '       d(   \        P"                  ! S P                  VV 3R
 lR7      MRS n        RV9   d(   RV9   d!   \&        P)                  RS P                  4       S P+                  4       '       g   R#  \,        P.                  ! S P                  VP                  R4      4       ^ RIHp VP                  R4      R8w  dø   VP                  R4      '       gá   V! S P                  4      P4                  R8w  dÀ   S P6                  P9                  4       '       g    S P                  R8w  d�   S P;                  VR,          \=        VP                  R4      ;'       g    / 4      VP                  RR4      \,        P>                  ! S P                  V4      \A        VP                  R4      4      R7      G Rj  x€L
  R#  L  \,        PB                  \,        PD                  3 d3   p\&        P)                  RT4       S PG                  T4        Rp?R# Rp?ii ; i5i)a  Bind config, build sampling/elicitation handlers, validate HTTP. False when the server
must not start (bad remote URL / non-MCP endpoint: fail fast with ``_error`` set and
``_ready`` fired instead of burning the reconnect ladder inside the SDK's httpx layer).ÚauthÚ Úidle_timeout_secondsÚmax_lifetime_secondsÚsamplingÚenabledTNÚelicitationc                  ó   <€ S P                   # r-   )Ú_pending_call_contextr=   s   €r   Ú<lambda>Ú0MCPServerRunMixin._prepare_run.<locals>.<lambda>  s   ø€ ÈD×LfÒLfr   )Úcall_contextÚurlÚcommandzMCP server '%s' has both 'url' and 'command' in config. Using HTTP transport ('url'). Remove 'command' to silence this warning.)Úliveness_forÚ	transportÚsseÚskip_preflightÚserver_jsonÚoauthÚheadersÚ
ssl_verifyÚstrict_redirect_headers)rË   rÌ   Úclient_certrÍ   z%sF)$r_   r   Útool_timeoutr`   ÚlowerÚstripÚ
_auth_typer   Ú_idle_timeout_secondsÚ_max_lifetime_secondsr   Ú_ensure_mcp_sdkÚ_MCP_SAMPLING_TYPESÚ	_samplingÚSamplingHandlerrn   Ú_MCP_ELICITATION_TYPESÚElicitationHandlerÚ_elicitationrl   rm   r^   rt   Ú_validate_remote_mcp_urlÚtools.mcp_livenessrÅ   ÚkindÚ_readyry   Ú_preflight_content_typerµ   Ú_resolve_client_certrC   ÚInvalidMcpUrlErrorÚNonMcpEndpointErrorÚ_publish_error)r>   r´   Úsampling_configÚelicitation_configrÅ   r†   s   f&    r   Ú_prepare_runÚMCPServerRunMixin._prepare_run  s�  øé € ð ˆŒÜ1°&Ó9ˆÔØ!Ÿ:™: fÓ-×3Ð3°×:Ñ:Ó<×BÑBÓDˆŒÜ%;¸FÐDZÓ%[ˆÔ"Ü%;¸FÐDZÓ%[ˆÔ"ä×ÒÔØ Ÿ*™* Z°Ó4ˆà,×0Ñ0°¸D×AÒAÄe×F_×F_ÐF_ô $×3Ò3°D·I±I¸ÔOØeið 	Œð $ŸZ™Z¨°rÓ:Ðð !3× 6Ñ 6°yÀ$× GÒ GÌE×Lh×LhÐLhô '×9Ò9¸$¿)¹)ÐEWÜDfõhànrð 	Ôð �FŒ?˜y¨FÔ2Ü�N‰Nð PØQU×QZÑQZô\à�}‰}�ŠÙð	Ü×,Ò,¨T¯Y©Y¸¿
¹
À5Ó8IÔJõ 8Ø—
‘
˜;Ó'¨5Ô0¸¿¹ÐDT×9UÒ9UÙ$ T§Y¡YÓ/×4Ñ4¸ÔEØ ŸK™K×.Ñ.×0Ò0°T·_±_ÈÔ5OØ×2Ñ2Ø˜5•M¬4°·
±
¸9Ó0E×0KÐ0KÈÓ+LØ%Ÿz™z¨,¸Ó=Ü '× <Ò <¸T¿Y¹YÈÓ OÜ,0°·±Ð<UÓ1VÓ,Wð	 3ó Y÷ Yð Yñ ñYøô
 ×*Ñ*¬G×,GÑ,GÐHô 	Ü�N‰N˜4 Ô%Ø×Ñ Ô$Ýûð	üsr   ƒC
MÃAMÄ MÄ6A1MÆ(MÆ+A"K2 ÈA K2 ÉA K2 ÊAK2 Ë)K0Ë*K2 Ë.MË0K2 Ë2%M	Ì'MÌ>MÍM	Í	Mc                ó$   <€ V ^8„  d   QhRS[ RR/# )r   r†   r(   N©ÚBaseException)r   r   s   "€r   r   r+   .  s   ø€ ÷ ñ ¡-ð °Dñ r   c                óF   € Wn         V P                  P                  4        R# )z&Hand *exc* to the waiting ``start()``.N)Ú_errorrß   rx   )r>   r†   s   &&r   rä   Ú MCPServerRunMixin._publish_error.  s   € àŒØ�‰�‰Ör   c                ó&   <€ V ^8„  d   QhRS[ RS[ /# r³   ©rµ   )r   r   s   "€r   r   r+   5  s   ø€ ÷ ñ ©Tð ±dñ r   c                óª  aa€ V P                  4       '       g   S# ^ RIHp VP                  4       ;'       g    / P	                  V P
                  4      o\        S\        4      '       d^   RS9  gW   \        ;QJ d*    VV3R lV P                   4       F  '       d   K   RM	  RM! VV3R lV P                   4       4      '       d   S# \        P                  RV P
                  SP	                  R4      SP	                  R4      4       SV n        SP	                  R4      ;'       g    RP                  4       P                  4       V n        RV n        S# )	uÔ  Before rebuilding a remote transport, re-read this server's definition from config.yaml and
adopt it when the endpoint or its auth changed (#113907). ``run()`` otherwise keeps the dict it
was started with, so a ``url`` edited while the process runs (dashboard/Desktop re-auth, a
catalog migration) left the loop probing the OLD URL â€” and that stale-URL provider evicted the
fresh one the dashboard had just authorised for the new URL, dropping its tokens/DCR client.rª   rÃ   c              3   ój   <"  € T F(  pSP                  V4      SP                  V4      8H  x € K*  	  R # 5ir-   )r`   )rY   Úkr´   Úfreshs   & €€r   rZ   Ú;MCPServerRunMixin._refresh_remote_config.<locals>.<genexpr>?  s,   øé € ð DQÙ7O°!�—	‘	˜!“ §
¡
¨1£Ö-Ó7Oùs   ƒ03FTzZMCP server '%s': definition changed in config.yaml (%s -> %s); rebuilding with the new oner·   r¸   )r^   r­   r«   r®   r`   rn   Ú
isinstancerµ   ÚallÚ_REMOTE_REBIND_KEYSrl   r¢   r_   rÐ   rÑ   rÒ   Ú_sse_fallback)r>   r´   r_   rô   s   &f @r   Ú_refresh_remote_configÚ(MCPServerRunMixin._refresh_remote_config5  s  ù€ ð �}‰}�ŠØˆMÝ4Ø×)Ñ)Ó+×1Ð1¨r×6Ñ6°t·y±yÓAˆÜ˜%¤×&Ò&¨%°uÔ*<ÇÃõ DQØ7;×7OÒ7OóDQÇÇÂõ DQØ7;×7OÒ7OóDQ÷ AQò AQàˆMÜ�‰ÐpØ—I‘I˜vŸz™z¨%Ó0°%·)±)¸EÓ2Bô	DàˆŒØ Ÿ9™9 VÓ,×2Ð2°×9Ñ9Ó;×AÑAÓCˆŒØ"ˆÔØˆr   c                ó    <€ V ^8„  d   QhRS[ /# ©r   r´   rð   )r   r   s   "€r   r   r+   I  s   ø€ ÷ //ñ //¡ñ //r   c              ƒ  óÜ  "  € V P                  V4      G Rj  x€L
 '       g   R# ^ V n        \        4       pRp  V'       dZ   ^ RIHp ^ RIHp V! 4       G Rj  x€L
 p VP                  V P                  V P                  V4      4      pVe   ^ RI
Hp V! V4       RpRV n        V P                  4       '       d   V P                  MV P                  pRV n        T P#                  V! V4      G Rj  x€L
 V4      G Rj  x€L
 '       g    RV n        \'        4       V n        R#  RT n        \'        4       T n        EK   EL" Lä  Te   ^ RI
Hp T! T4       i i ; i Lg L\  \*        P,                   d
    RT n        h \.         dN   p	RT n        T P1                  Y’4      G Rj  x€L 
 '       g    Rp	?	RT n        \'        4       T n        R#  Rp	?	L©Rp	?	ii ; i  RT n        \'        4       T n        i ; i5i)aJ  Long-lived: connecting -> connected -> (degraded -> parked -> revived)*. Unproven drops
and transport errors charge a rapid-drop budget with jittered backoff; exhausting it (or
a permanent error) parks via :meth:`_park` rather than exiting, so the server stays
revivable. Branch helpers return True to keep looping, False to exit.NFTrª   )Ú_install_owner_secret_scope)Úreset_secret_scope)rç   Ú_reconnect_retriesr   r­   r«   Útools.mcp_tool_discoveryrÿ   Ú_require_rendered_remotern   rú   Úagent.secret_scoper   Ú
_auth_parkr^   Ú	_run_httpÚ
_run_stdioÚ_resolved_identityÚ_on_clean_returnrp   rx   Ú_stdio_child_pidsr)   r0   r1   Ú_on_transport_error)
r>   r´   ÚbudgetÚrebuildr_   rÿ   Úscope_tokenr   Úrun_transportr†   s
   &&        r   ÚrunÚMCPServerRunMixin.runI  s¥  é € ð
 ×&Ñ& vÓ.×.Ö.ÙØ"#ˆÔÜ“ˆØˆØð$/ßõ AÝTÙ(CÓ(E×"E�Kð<Ø!(×!AÑ!AÀ$Ç)Á)ÈT×MhÑMhÐioÓMpÓ!q˜à&Ò2ÝMÙ.¨{Ô;Ø�Ø"&�”Ø26·-±-·/²/ §¢ÀtÇÁ�Ø*.�Ô'Ø!×2Ñ2¹ÀvÓ9N×3NÐPVÓW×WÖWØð  $�”ä),«�Ö&ð% Xð   $�”ä),«�×&òU /ñ #Føð 'Ò2ÝMÙ.¨{Õ;ð 3úñ 4OÑWøä×)Ñ)ô ð  $�”ØÜô Ø#�”Ø!×5Ñ5°cÓB×B×BÛà#�”ä),«�Ö&ô Cûðûð
  $�”ä),«�Õ&üsÁ   ‚G,—D9˜	G,¢G,¹E ÁD<ÁE Á+D> Â0E Â95E Ã.EÃ/E Ã;EÃ<	E ÄG,ÄG Ä G,Ä<E Ä>EÅE ÅE Å%GÆ GÆG	ÆFÆ
G	Æ(G Æ,G,ÇG Ç	GÇG ÇG)Ç)G,c                ó,   <€ V ^8„  d   QhRS[ RS[RS[/# )r   Úlifecycle_reasonr  r(   ©rR   r   rC   )r   r   s   "€r   r   r+   z  s#   ø€ ÷ 'ñ '±sð 'ÁLð 'ÑUYñ 'r   c              ƒ  óš  "  € V P                   P                  4       '       d   R# VR8X  dN   \        P                  RV P                  V P
                  4       RV n        V P                  4       G Rj  x€L
 R8g  # \        P                  RV P                  4       V P                  '       dC   V P                  '       g1   \        P                  RV P                  4       RRuV n	        Vn        M¶V P                  '       d   ^ RuV n        Vn        M”V ;P                  ^,          un        V P                  \        P                  8”  d]   V P                  R	V P                  \        P                  \        P                   4       V P#                  R
V4      G Rj  x€L
 '       g   R# V P$                  P'                  4        RV n        R#  ELU L25i)zoClean transport return: shutdown, stdio recycle, or a requested rebuild (not a failure
for the retry counters).FrU   zLMCP server '%s': stdio session recycled after %s; waiting for lazy reconnectNr\   z@MCP server '%s': reconnecting (OAuth recovery or manual refresh)zpMCP server '%s': reconnect after teardown race (in-flight calls were failed); not charging the rapid-drop budgetr   uµ   MCP server '%s': %d consecutive reconnects without a healthy session (rapid-drop budget exhausted), parking; will self-probe every %ds until it recovers (state: degraded â†’ parked)úfrom parked stateT)r:   ry   rl   r¢   rn   Ú_recycled_reasonrp   r�   r”   Ú_teardown_racerd   r   r  r   Ú_MAX_RECONNECT_RETRIESr—   r    Ú_park_and_rearmrß   r{   )r>   r  r  s   &&&r   r	  Ú"MCPServerRunMixin._on_clean_returnz  sj  é € ð ×Ñ×&Ñ&×(Ò(ÙØ˜yÔ(Ü�K‰KÐfØŸ	™	 4×#8Ñ#8ô:àˆDŒLà×=Ñ=Ó?×?À:ÑMÐMä�‰ÐWÐY]×YbÑYbÔcð ××Ð t×';×';Ð';Ü�K‰Kð =Ø>B¿i¹iôIà27¸Ð/ˆDÔ ¥Ø×!×!Ð!Ø67¸Ð3ˆDÔ# V¥^à×#Ò# qÕ(Õ#Ø×&Ñ&¬×)EÑ)EÔEØ—‘ðtà—I‘Iœu×;Ñ;¼U×=YÑ=Yô[ð "×1Ñ1Ð2EÀvÓN×NÖNÙ à�‰×ÑÔØˆŒÙò; @ñ0 Oùs>   ‚A/GÁ1GÁ28GÂ+GÂ=AGÃ?BGÆG	Æ	GÆ!&GÇ	Gc                ó,   <€ V ^8„  d   QhRS[ RS[RS[/# )r   rš   r  r(   r  )r   r   s   "€r   r   r+   £  s#   ø€ ÷ ñ ±Cð Áð ÑRVñ r   c              ƒ  óŽ   "  € V P                  V4      G Rj  x€L
 '       d   R# \        P                  RuV n        Vn        R#  L+5i)z€Park; on revival leave ONE probe per wake so a still-dead server re-parks instead of
burning 5 rapid retries. False on shutdown.NFr   T)r¦   r   r  r  r   )r>   rš   r  s   &&&r   r  Ú!MCPServerRunMixin._park_and_rearm£  s<   é € ð —‘˜NÓ+×+Ö+ÙÜ27×2NÑ2NÐPSÐ/ˆÔ ¤Ùñ ,ùs   ‚A—A˜	A¢"Ac                ó2   <€ V ^8„  d   QhRS[ RS[RS[RS[/# )r   r†   rš   r  r(   )r1   rR   r   rC   )r   r   s   "€r   r   r+   «  s+   ø€ ÷ 	ñ 	©yð 	É#ð 	ÑWcð 	Ñhlñ 	r   c              ƒ  óâ   "  € V P                  V4       V P                  V4      G Rj  x€L
 '       d   R# ^ ;Vn        V n        RVn        RV n        V P                  P                  4        R#  LD5i)z\Publish ``exc`` to ``start()``, park, and on revival reset every counter. False on shutdown.NFr   T)rä   r¦   r   r  r   rí   rß   r{   )r>   r†   rš   r  s   &&&&r   Ú_park_initial_failureÚ'MCPServerRunMixin._park_initial_failure«  s^   é € à×Ñ˜CÔ Ø—‘˜NÓ+×+Ö+ÙØ;<Ð<ˆÔ Ô!8ØˆŒØˆŒØ�‰×ÑÔÙñ ,ùs   ‚&A/¨A-©	A/³;A/c                ó$   <€ V ^8„  d   QhRS[ RR/# )r   r  r(   N)r   )r   r   s   "€r   r   r+   ¶  s   ø€ ÷ Mñ M©<ð M¸Dñ Mr   c              ƒ  óÔ   "  € \         P                  ! \        VP                  4      4      G R j  x€L
  \	        VP                  ^,          \
        P                  4      Vn        R #  L65ir-   )r)   Úsleepr   r   rh   r   Ú_MAX_BACKOFF_SECONDS)r>   r  s   &&r   Ú_backoff_sleepÚ MCPServerRunMixin._backoff_sleep¶  sB   é € Ü�mŠmœI f§n¡nÓ5Ó6×6Ð6Ü˜VŸ^™^¨aÕ/´×1KÑ1KÓLˆŽñ 	7ùs   ‚-A(¯A&°7A(c                ó,   <€ V ^8„  d   QhRS[ RS[RS[/# )r   r†   r  r(   )r1   r   rC   )r   r   s   "€r   r   r+   º  s#   ø€ ÷ $1ñ $1©Yð $1Áð $1ÑQUñ $1r   c           
   ƒ  óÆ  "  € \         P                  ! V4      p\         P                  ! V4      pV P                  4       '       d=   \        P                  RV P                  \        V4      P                  V4       RV n	        V P                  '       g   V P                  WWB4      G Rj  x€L
 # V P                  P                  4       '       d8   \        P                  RV P                  \        V4      P                  V4       R# VR8X  d   V P                  W24      G Rj  x€L
 # V ;P                   ^,          un        V P                   \"        P$                  8”  dj   V P'                  RV P                  \"        P$                  \"        P(                  \        V4      P                  V4       V P+                  RV4      G Rj  x€L
 # \        P                  RV P                  V P                   \"        P$                  VP,                  \        V4      P                  V4       V P/                  V4      G Rj  x€L
  V P                  P                  4       '       * #  EL¯ EL; Lœ L+5i)	z[Transport raised: classify, then run the initial-connect or reconnect ladder. False = exit.zfMCP server '%s': lazy reconnect after stdio recycle failed, marking unavailable while retrying: %s: %sNz4MCP server '%s' disconnected during shutdown: %s: %sFÚ	permanentu�   MCP server '%s' failed after %d reconnection attempts, parking; will self-probe every %ds until it recovers (state: degraded â†’ parked): %s: %sr  zNMCP server '%s' connection lost (attempt %d/%d), reconnecting in %.0fs: %s: %s)rt   ru   Ú_classify_mcp_failureÚ_is_recycled_stdiorl   rm   rn   rv   r   r  Ú_ever_connectedÚ_on_initial_connect_errorr:   ry   r”   Ú_on_permanent_errorr  r   r  r—   r    r  r   r'  )r>   r†   r  r‡   Úfailure_classs   &&&  r   r  Ú%MCPServerRunMixin._on_transport_errorº  sß  é € ô ×.Ò.¨sÓ3ˆÜ×5Ò5°dÓ;ˆØ×"Ñ"×$Ò$Ü�N‰Nð 4Ø59·Y±YÄÀTÃ
×@SÑ@SÐUYô[à$(ˆDÔ!ð ×#×#Ð#Ø×7Ñ7¸À=ÓY×YÐYØ×Ñ×&Ñ&×(Ò(Ü�L‰LÐOØŸ™¤D¨£J×$7Ñ$7¸ô?áØ˜KÔ'Ø×1Ñ1°$Ó?×?Ð?Ø×Ò 1Õ$ÕØ×"Ñ"¤U×%AÑ%AÔAØ�N‰NðIà—	‘	œ5×7Ñ7¼×9UÑ9UÔW[Ð\`ÓWa×WjÑWjÐlpôrð ×-Ñ-Ð.AÀ6ÓJ×JÐJÜ�‰ÐeØ—Y‘Y × 7Ñ 7¼×9UÑ9UÐW]×WeÑWeÜ˜$“Z×(Ñ(¨$ô	0ð ×!Ñ! &Ó)×)Ð)Ø×'Ñ'×.Ñ.Ó0Ô0Ð0ò% Zò @ñ Kñ 	*ùsW   ‚BI!ÂI!Â(IÂ)#I!ÃAI!ÄIÄ B I!Ç IÇA2I!È3IÈ4$I!ÉI!ÉI!ÉI!c          
      ó8   <€ V ^8„  d   QhRS[ RS[RS[RS[RS[/# )r   r†   r‡   r1  r  r(   )r1   rë   rR   r   rC   )r   r   s   "€r   r   r+   à  s3   ø€ ÷ 1ñ 1±9ð 1ÁMð 1Ù7:ð1ÙDPð1ÙUYñ1r   c           
   ƒ  óê  "  € VR 8X  d�   \         P                  ! V4      '       d   RV P                   R2MRpV P                  RV P                  V\	        V4      P
                  V4       V P                  V4       V P                  VRV4      G Rj  x€L
 # V;P                  ^,          un        VP                  \        P                  8”  d\   V P                  RV P                  \        P                  \	        V4      P
                  V4       V P                  VRV4      G Rj  x€L
 # \        P                  R	V P                  VP                  \        P                  VP                  \	        V4      P
                  V4       V P                  V4      G Rj  x€L
  V P                  P!                  4       '       d   V P#                  V4       V P                  P!                  4       '       * #  EL[ LÊ LY5i)
r+  zYauthentication, parking until credentials change; re-authenticate with `hermes mcp login Ú`z:connection with a permanent error, parking without retriesuH   MCP server '%s' failed initial %s (state: connecting â†’ parked): %s: %szafter permanent initial failureNuŠ   MCP server '%s' failed initial connection after %d attempts, parking until a reconnect is requested (state: connecting â†’ parked): %s: %sz!after initial connection failureszTMCP server '%s' initial connection failed (attempt %d/%d), retrying in %.0fs: %s: %s)rt   Ú_is_auth_errorrn   r—   rv   r   Ú_arm_auth_parkr!  r   r   Ú_MAX_INITIAL_CONNECT_RETRIESrl   r”   r   r'  r:   ry   rä   )r>   r†   r‡   r1  r  Údetails   &&&&& r   r/  Ú+MCPServerRunMixin._on_initial_connect_errorà  s¢  é € à˜KÔ'ô <C×;QÒ;QÐRV×;WÒ;Wð+Ø+/¯9©9¨+°Qñ8àWð ð �N‰NÐeØŸ9™9 f¬d°4«j×.AÑ.AÀ4ôIà×Ñ Ô%Ø×3Ñ3°CÐ9ZÐ\bÓc×cÐcØ×Ò !Õ#ÕØ×!Ñ!¤E×$FÑ$FÔFØ�N‰NðCà—	‘	œ5×=Ñ=¼tÀD»z×?RÑ?RÐTXôZð ×3Ñ3°CÐ9\Ð^dÓe×eÐeÜ�‰ØbØ�I‰I�v×-Ñ-¬u×/QÑ/QÐSY×SaÑSaÜ�‹J×Ñ ô	'ð ×!Ñ! &Ó)×)Ð)Ø×Ñ×&Ñ&×(Ò(Ø×Ñ Ô$Ø×'Ñ'×.Ñ.Ó0Ô0Ð0ò dñ fñ
 	*ùsC   ‚#G3¦A+G3ÂG,ÂBG3Ä$G/Ä%A2G3ÆG1Æ#G3Æ<1G3Ç/G3Ç1G3c                ó,   <€ V ^8„  d   QhRS[ RS[RS[/# )r   r‡   r  r(   )rë   r   rC   )r   r   s   "€r   r   r+   ü  s(   ø€ ÷ Yñ Y©mð YÁ\ð YÑVZñ Yr   c              ƒ  ó²  "  € \         P                  ! V4      '       dÊ   V P                  '       d¸   V P                  '       g¦   R V n        V P	                  RV 24       \
        P                  RV P                  \        V4      P                  V4       ^ RuV n
        Vn        \        P                  ! \        R4      4      G Rj  x€L
  V P                  P!                  4       '       * # V P#                  RV P                  \$        P&                  \        V4      P                  V4       V P)                  V4       V P+                  RV4      G Rj  x€L
 #  LŽ L5i)Tzauth error on proven session: u£   MCP server '%s': auth error on a previously healthy session â€” marking suspect and forcing one reconnect instead of parking (state: connected â†’ suspect): %s: %sr   Nu   MCP server '%s' hit a permanent error, parking without retries; will self-probe every %ds (state: connected â†’ parked): %s: %sz#from parked state (permanent error))rt   r6  rd   Ú_permanent_grace_usedrw   rl   rm   rn   rv   r   r  r   r)   r%  r   r:   ry   r—   r   r    r7  r  )r>   r‡   r  s   &&&r   r0  Ú%MCPServerRunMixin._on_permanent_errorü  s  é € ô ×!Ò! $×'Ò'¨D×,@×,@Ð,@È×Ic×IcÐIcØ)-ˆDÔ&Ø×ÑÐ >¸t¸fÐEÔFÜ�N‰NðZà—	‘	œ4 ›:×.Ñ.°ô6ð 78¸Ð3ˆDÔ# V¤^Ü—-’-¤	¨#£Ó/×/Ð/Ø×+Ñ+×2Ñ2Ó4Ô4Ð4à�‰ð4Ø59·Y±YÄ×@\Ñ@\Ô^bÐcgÓ^h×^qÑ^qÐswô	yð 	×Ñ˜DÔ!Ø×)Ñ)Ð*OÐQWÓX×XÐXñ 0ñ Yùs0   ‚.E±EÁBEÃEÃB	EÅEÅEÅEc                ó$   <€ V ^8„  d   QhRS[ RR/# )r   r‡   r(   Nrê   )r   r   s   "€r   r   r+     s   ø€ ÷ 	Dñ 	D¡=ð 	D°Tñ 	Dr   c                óÞ   € V P                   R8X  d\   \        P                  ! V4      '       d>   ^ RIHp ^ RIHp V! V P                  V! 4       R7      pWDP                  4       3V n	        R# R# R# )ah  Record the OAuth credentials an auth-failure park failed with. Until a re-authorization
rewrites them, a discovery pass has nothing new to try: every nudge replayed the same rejected
refresh token, so a backend building agents (each one re-runs discovery while no server is
connected) hit the authorization server once per session, enough for a rate-limit ban.rÊ   )Úget_hermes_home)ÚHermesTokenStorage)Úhermes_homeN)
rÒ   rt   r6  Úhermes_constantsrA  r£   rB  rn   Úcredential_stampr  )r>   r‡   rA  rB  Ústorages   &&   r   r7  Ú MCPServerRunMixin._arm_auth_park  sU   € ð
 �?‰?˜gÔ%¬'×*@Ò*@À×*FÒ*FÝ8Ý:Ù(¨¯©ÁÓ@QÔRˆGØ&×(@Ñ(@Ó(BÐCˆDŽOñ	 +GÑ%r   c                ó    <€ V ^8„  d   QhRS[ /# rý   rð   )r   r   s   "€r   r   r+     s   ø€ ÷ ñ ¡$ñ r   c              ƒ  ó´  "  € \         P                  ! V P                  V4      4      V n         V P                  P                  4       G Rj  x€L
  T P                  '       d   T P                  hR#  L$  \         P                   dO    T P                  '       d;   T P                  P                  4       '       g   T P                  P                  4        h i ; i5i)z<Create the background Task and wait until ready (or failed).N)
r)   r9   r  Ú_taskrß   r;   r0   r.   r/   rí   )r>   r´   s   &&r   ÚstartÚMCPServerRunMixin.start  sœ   é € ä×*Ò*¨4¯8©8°FÓ+;Ó<ˆŒ
ð	Ø—+‘+×"Ñ"Ó$×$Ð$ð �;�;ˆ;Ø—+‘+Ðñ ñ %øÜ×%Ñ%ô 	ð �z�zˆz $§*¡*§/¡/×"3Ò"3Ø—
‘
×!Ñ!Ô#Øð	üs@   ‚+C®A2 ÁA0ÁA2 ÁCÁ"CÁ0A2 Á2&CÂCÂ9CÃCc              ƒ  ób  "  € V P                   P                  4        V P                  P                  4        V P                  '       dL   V P                  P	                  4       '       g,    \
        P                  ! V P                  ^
R7      G Rj  x€L
  V P                  '       do   \        V P                  4       F  pVP                  4        K  	  \
        P                  ! V P                  RR/ G Rj  x€L
  V P                  P!                  4        V P#                  4        RV n        R#  L�  \         dq    \        P                  RT P                  4       T P                  P                  4         T P                  G Rj  x€L 
   Lø  \
        P                   d      ELi ; ii ; i L·5i)z=Signal the Task to exit and wait for clean resource teardown.rœ   Nz3MCP server '%s' shutdown timed out, cancelling taskÚreturn_exceptionsT)r:   rx   r<   rJ  r.   r)   Úwait_forÚTimeoutErrorrl   rm   rn   r/   r0   Ú_pending_refresh_tasksÚlistÚgatherr{   rŸ   rp   )r>   Útasks   & r   r\   ÚMCPServerRunMixin.shutdown*  s<  é € à×Ñ× Ñ Ô"ð 	×Ñ×!Ñ!Ô#Ø�:�:ˆ:˜dŸj™jŸo™o×/Ò/ðÜ×&Ò& t§z¡z¸2Ô>×>Ð>ð ×&×&Ð&Ü˜T×8Ñ8Ö9�Ø—‘–ñ :ä—.’. $×"=Ñ"=ÐVÐQUÑV×VÐVØ×'Ñ'×-Ñ-Ô/Ø×ÑÔ ØˆŽñ ?øÜô Ü—‘ÐTÐVZ×V_ÑV_Ô`Ø—
‘
×!Ñ!Ô#ðØŸ*™*×$Ó$øÜ×-Ñ-ô Ûðúðúñ Wùsz   ‚A&F/Á*%D/ ÂD-ÂD/ ÂF/Â&AF/Ã5F-Ã67F/Ä-D/ Ä/AF*Å5FÆFÆFÆ
F/ÆF&Æ!F*Æ"F/Æ%F&Æ&F*Æ*F/c                ó   <€ V ^8„  d   QhRR/# rK   r   )r   r   s   "€r   r   r+   B  s   ø€ ÷ )ñ ) 4ñ )r   c                óz   € \        \        V R. 4      4       F  p\        P                  ! W4       K  	  . V n        R# )z–Drop this server's tools from the registry (idempotent); on shutdown AND budget
exhaustion, so a dead server never leaves phantom tools in the prompt.Ú_registered_tool_namesN)rR  ÚgetattrÚ_registrationÚ_deregister_mcp_tool_all_scopesrX  )r>   Ú	tool_names   & r   rŸ   Ú#MCPServerRunMixin._deregister_toolsB  s4   € ô œg dÐ,DÀbÓIÖJˆIÜ×9Ò9¸$ÖJñ Kà&(ˆÖ#r   )r  rÒ   r_   rÛ   rí   rÓ   r“   rÔ   rž   r=  r  r  rX  r  r×   rù   r
  rJ  r  r’   rp   rÏ   r-   )rÃ   r·   rÊ   rË   rÆ   )!r   r   r   r   r   Ústaticmethodr3   r?   rH   rN   rˆ   r�   r—   r¦   r¡   rç   rä   rø   rú   r  r	  r  r!  r'  r  r/  r0  r7  rK  r\   rŸ   r!   r"   r#   s   @r   r%   r%      s  ø‡ € Ù`à÷ó ð÷Eð E÷
ð ÷ð ÷
bð b÷Hò ÷'ð '÷4ð 4÷lð ÷+ð +÷Zð ð
 KÐ÷ð ÷(//ð //÷b'ð '÷Rð ÷	ð 	÷Mð M÷$1ð $1÷L1ð 1÷8Yð Y÷(	Dð 	D÷ð ò÷0)ö )r   r%   )r   r)   Úloggingre   Údataclassesr   Útypingr   r¯   r   r   r   r   r­   r   rt   r	   rZ  r
   r×   Ú	getLoggerrl   r   r%   r   r   r   Ú<module>rc     s`   ðñ5ó
 Û Û Ý !Ý ß aÓ aÝ ,Ý 8Ý 0à	×	Ò	Ð+Ó	,€ð ÷ð ó ð÷l)ó l)r   