+
    lHàjòÁ  ã                  ój  a € 0 t $ R t^ RIHt ^ RI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Ht ^ RIHt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" ^ RI#H$t$H%t%H&t&H't'H(t( ]PR                  ! R4      t*^t+R R lt,R R lt-R R lt.R R lt/R R lt0R t1Rt2/ t3R]4R&   R R lt5]	R 4       t6R  R! lt7R" R# lt8R$ R% lt9R& R' lt:R( R) lt;R* R+ lt<R, R- lt=R. R/ lt>R0 R1 lt?R2 R3 lt@R4 R5 ltAR6 R7 ltBR8 R9 ltCR: R; ltDR<^ R=^ /R> R? lltER@ RA ltFRB RC ltGRD RE ltHRF tIRkRG RH lltJRI RJ ltKRK RL ltLRM RN ltMRO RP ltNRQ RR ltORS RT ltPRU RV ltQRW RX ltR]P¦                  ! 4       tTRY RZ ltUR[ R\ ltVR] R^ ltWRkR_R`/Ra Rb llltXRc Rd ltYRe Rf ltZRg Rh lt[Ri Rj lt\R# )la`  Connecting and discovery for tools.mcp_tool: per-server connect cooldown, connect /
lazy-start / recycled-stdio wake-up, ``register_mcp_servers`` / ``discover_mcp_tools`` and
the status / probe public API. Origin state (``_servers``, ``_lock``, the loop, patchable
helpers) is read through ``_core`` so ``mock.patch("tools.mcp_tool.X")`` keeps working.)ÚannotationsN)Úcontextmanager)ÚPath)ÚDictÚListÚOptionalÚSetÚTuple)Ú_coreÚ_parse_boolishÚmcp_server_enabled)Úmcp_tool_config)Úmcp_tool_errors)Úmcp_tool_lifecycle)Úmcp_tool_loop)Úmcp_tool_registration)ÚMCP_TOOL_NAME_PREFIX)Ú	_key_nameÚ
_key_scopeÚ_key_visible_in_scopeÚ_resolve_server_keyÚ_server_keyztools.mcp_toolc               ó   € V ^8„  d   QhRR/# )é   ÚreturnÚint© )Úformats   "Ú=/home/ubuntu/.hermes/hermes-agent/tools/mcp_tool_discovery.pyÚ__annotate__r       s   € ÷ ñ ¨ñ ó    c                 óR  €  ^ RI Hp  V ! 4       P                  R4      ;'       g    / P                  R\        4      p\        T\        4      '       g   \        T\        4      '       d   T^ 8  d"   \        P                  RT\        4       \        # T#   \         d
    \        u # i ; i)z¦``mcp.discovery_concurrency`` from config (0 = unlimited); a non-integer or negative value
warns and falls back to the default rather than silently running unbounded.)Úload_configÚmcpÚdiscovery_concurrencyzDmcp.discovery_concurrency=%r is not a non-negative integer; using %d)
Úhermes_cli.configr"   ÚgetÚ_DISCOVERY_CONNECT_CONCURRENCYÚ	ExceptionÚ
isinstanceÚboolr   ÚloggerÚwarning)r"   Úraws     r   Ú_discovery_connect_concurrencyr.       s‹   € ð.Ý1Ù‹}× Ñ  Ó'×-Ð-¨2×2Ñ2Ð3JÔLjÓkˆô �#”t×Ò¤J¨s´C×$8Ò$8¸CÀ!¼GÜ�‰Ð]ØÔ:ô	<ä-Ð-Ø€Jøô ô .Ü-Ò-ð.ús   ‚"B ¥B ÂB&Â%B&c               ó    € V ^8„  d   QhRRRR/# ©r   Úserver_nameÚstrr   ÚNoner   )r   s   "r   r   r   /   s   € ÷ Hñ H¨ð H°ñ Hr    c                ód  € \        V 4      p\        P                  P                  V^ 4      ^,           pV\        P                  V&   \	        \        P
                  ^V^,
          ,          ,          \        P                  4      p\        P                  ! 4       V,           \        P                  V&   R# )zRStamp a geometric, capped retry cooldown after a failed connect (under ``_lock``).N)
r   r
   Ú_server_connect_failuresr&   ÚminÚ_CONNECT_RETRY_BASE_BACKOFF_SECÚ_CONNECT_RETRY_MAX_BACKOFF_SECÚtimeÚ	monotonicÚ_server_connect_retry_after)r1   ÚkeyÚnÚbackoffs   &   r   Ú_record_connect_failurer?   /   sz   € ä
�kÓ
"€CÜ×&Ñ&×*Ñ*¨3°Ó2°QÕ6€AØ*+„E×"Ñ" 3Ñ'Ü”%×7Ñ7¸1ÀÀQÅ½<ÕHÌ%×JnÑJnÓo€GÜ-1¯^ª^Ó-=ÀÕ-G„E×%Ñ% cÓ*r    c               ó    € V ^8„  d   QhRRRR/# r0   r   )r   s   "r   r   r   8   s   € ÷ 5ñ 5¨ð 5°ñ 5r    c                óœ   € \        V 4      p\        P                  P                  VR4       \        P                  P                  VR4       R# )z?Clear the connect-cooldown state after a successful connection.N)r   r
   r5   Úpopr;   )r1   r<   s   & r   Ú_clear_connect_failurerC   8   s8   € ä
�kÓ
"€CÜ	×"Ñ"×&Ñ& s¨DÔ1Ü	×%Ñ%×)Ñ)¨#¨tÖ4r    c               ó    € V ^8„  d   QhRRRR/# ©r   r1   r2   r   r*   r   )r   s   "r   r   r   ?   s   € ÷ @ñ @¨#ð @°$ñ @r    c                óš   € \         P                  P                  \        V 4      4      pVRJ;'       d    \        P
                  ! 4       V8  # )z¢True if ``server_name`` is still within its retry cooldown (this scope's connection: one
profile's failing ``x`` must not shadow another profile's healthy ``x``).N)r
   r;   r&   r   r9   r:   )r1   Údeadlines   & r   Ú_connect_cooldown_activerH   ?   s>   € ô ×0Ñ0×4Ñ4´[ÀÓ5MÓN€HØ˜4Ð×?Ð?¤D§N¢NÓ$4°xÑ$?Ð?r    c               ó   € V ^8„  d   QhRR/# )r   r   zOptional[Path]r   )r   s   "r   r   r   F   s   € ÷ :ñ :˜>ñ :r    c                 óx   € \         P                  ! 4       p V f   R# ^ RIHp \	        V! 4       ;'       g    T 4      # )uM  The profile home whose secret scope MCP credential reads must resolve under, or None for a
single-profile process (scope key ``None``).

The owner is the profile the connection is keyed under (``_mcp_registry_scope()``), never the
ambient one, so a served profile is never handed another profile's token (#111151). A scope the
caller already bound is rebuilt rather than trusted: a bound mapping is a snapshot, and the
gateway's boot-time one is taken before the profile's external secret source may have answered
(#119092) â€” the rebuild retries that hydration (cached once it succeeds).N)Úcurrent_secret_scope_home)r
   Ú_mcp_registry_scopeÚagent.secret_scoperK   r   )Ú	scope_keyrK   s     r   Ú_owner_scope_homerO   F   s5   € ô ×)Ò)Ó+€IØÒÙÝ<ÜÑ)Ó+×8Ð8¨yÓ9Ð9r    c               ƒ  ó¢   "  € ^ RI Hp  \        4       pVf   R# T ! \        P                  ! \
        V4      G Rj  x€L
 \        V4      R7      #  L5i)añ  Bind the connection OWNER's profile secret scope when the caller has none; else None.

``MCPServerTask.start`` ensure_futures the run task, which copies THIS context, so one
binding covers transport bring-up (``_build_safe_env`` stdio child env) and every later
revival inside that task; unscoped, those ``get_secret`` reads fail closed under multiplexing
and the server parks with zero tools (#113746). ``${VAR}`` refs are interpolated earlier, at
config load, under :func:`_owner_secret_scope`.
)Úset_secret_scopeN©Úprofile_home)rM   rQ   rO   ÚasyncioÚ	to_threadÚ_owner_secret_mappingr2   )rQ   Úhomes     r   Ú_install_owner_secret_scoperX   V   sB   é € õ 4ÜÓ€DØ‚|Ùá¤'×"3Ò"3Ô4IÈ4Ó"P×PÔ_bÐcgÓ_hÔiÐiÑPùs   ‚7A¹AºAç      >@zdict[str, float]Ú_hydrate_retry_afterc               ó    € V ^8„  d   QhRRRR/# )r   rW   r   r   zdict[str, str]r   )r   s   "r   r   r   k   s   € ÷ ,ñ , ð ,¨ñ ,r    c                ó„  € ^ RI HpHp ^ RIHp \        V P                  4       4      p\        P                  ! 4       \        P                  VR4      8¼  dI   VP                  V 4       WCP                  9  d(   \        P                  ! 4       \        ,           \        V&   V! V 4      '       d   ^ RIHp V! V 4      # V! V 4      # )a*  The owner's FRESH secret mapping. The launch profile's is ``launch_secret_scope`` (its files
over the frozen launch env): a credential injected only by systemd ``Environment=`` /
``op run`` / Compose has no file to rebuild from, so a files-only rebuild dropped it, left the
header literal ``${VAR}`` and parked a server that worked. A served profile gets its own ``.env``
+ external sources only. A source that did not fully hydrate is retried at most once per
interval per home: every retry is a helper subprocess, and connect/reconnect loops are tight.)Ú_is_process_homeÚbuild_profile_secret_scope)Ú
env_loaderg        )Úlaunch_secret_scope)rM   r]   r^   Ú
hermes_clir_   r2   Úresolver9   r:   rZ   r&   Úhydrate_profile_secret_sourcesÚ_APPLIED_HOMESÚ_HYDRATE_RETRY_INTERVAL_SECÚ!tui_gateway.launch_profile_policyr`   )rW   r]   r^   r_   r<   r`   s   &     r   rV   rV   k   sŽ   € ÷ PÝ%Ü
ˆd�l‰l‹nÓ
€CÜ‡~‚~ÓÔ/×3Ñ3°C¸Ó=Ô=Ø×1Ñ1°$Ô7Ø×/Ñ/Ô/Ü(,¯ªÓ(8Ô;VÕ(VÔ  Ñ%Ù˜×ÒÝIÙ" 4Ó(Ð(Ù% dÓ+Ð+r    c               #  ó²   "  € ^ RI Hp Hp \        4       pVf   Rx € R# V! \	        V4      \        V4      R7      p Rx € V ! V4       R#   T ! T4       i ; i5i)uÙ  Sync twin of :func:`_install_owner_secret_scope` for the config load in the caller's thread.

``_load_mcp_config`` interpolates ``${VAR}`` header/URL refs through ``get_secret`` and swallows
the resulting ``UnscopedSecretError`` into ``{}``, so an unscoped discover / reconcile / status /
probe for a routed profile saw ZERO servers â€” stdio siblings included â€” before the connect-site
binding could ever run (#113746). Same owner rule; scope key ``None`` binds nothing.)Úreset_secret_scoperQ   NrR   )rM   rh   rQ   rO   rV   r2   )rh   rQ   rW   Útokens       r   Ú_owner_secret_scoperj      sM   é € ÷ HÜÓ€DØ‚|ÛÙÙÔ2°4Ó8ÄsÈ4ÃyÔQ€Eð"Ûá˜5Ö!øÑ˜5Õ!üs   ‚9A¼A
 Á 
AÁ

AÁAc               ó$   € V ^8„  d   QhRRRRRR/# )r   Únamer2   ÚconfigÚdictr   ú_core.MCPServerTaskr   )r   s   "r   r   r   “   s"   € ÷ !ñ ! ð !¨Tð !Ð6Iñ !r    c              ƒ  óX  "  € \         P                  ! V 4      p\         P                  P                  4       pVe	   V! V4       Ve    \         P                  P	                  R4      MRpRp \        4       G Rj  x€L
 p\        P                  ! V \        P                  ! V4      4      pVP                  V4      G Rj  x€L
   Te   ^ RIHp T! T4       Te    \         P                  P'                  T4       T#  L€ L>  \        P                   d    h \         dP    TfJ    TP                  4       G Rj  x€L 
  h   \         d!   p\        P!                  RY4        Rp?h Rp?ii ; ih i ; i  Te   ^ RIHp T! T4       Te!   \         P                  P'                  T4       i i ; i5i)z¬Create an MCPServerTask, start it, return once ready (tear down with ``server.shutdown()``
on the same loop). Raises on bad config, missing HTTP support or connect failure.Nz6MCP server '%s' shutdown during orphan-reap failed: %s)rh   )r
   ÚMCPServerTaskÚ_connect_server_claimr&   ÚsetrX   Ú_configÚ_require_rendered_remoteÚ_interpolate_env_varsÚstartrT   ÚCancelledErrorÚBaseExceptionÚshutdownr(   r+   ÚdebugrM   rh   Úreset)rl   rm   ÚserverÚclaimÚclaim_tokenÚscope_tokenÚshutdown_excrh   s   &&      r   Ú_connect_serverr‚   “   sx  é € ô × Ò  Ó&€FÜ×'Ñ'×+Ñ+Ó-€EØÒÙˆfŒà;@Ò;L”%×-Ñ-×1Ñ1°$Ô7ÐRV€KØ€Kð;Ü7Ó9×9ˆô ×1Ò1°$¼×8UÒ8UÐV\Ó8]Ó^ˆØ�l‰l˜6Ó"×"Ñ"ð Ò"Ý=Ù˜{Ô+ØÒ"Ü×'Ñ'×-Ñ-¨kÔ:Ø€Mñ- :ñ
 	#øÜ×!Ñ!ô ØÜô àŠ=ðkØ—o‘oÓ'×'Ñ'ð 	øô ô kÜ—‘ÐUÐW[×jÐjØûðkúàðûð Ò"Ý=Ù˜{Ô+ØÒ"Ü×'Ñ'×-Ñ-¨kÕ:ð #üs‹   ‚A(F*Á+C= Á8C9Á9AC= Â<C;Â=C= Ã7F*Ã9C= Ã;C= Ã=E,ÄE,Ä"D<Ä5D8Ä6D<Ä;E,Ä<E'ÅE"ÅE,Å"E'Å'E,Å,E/ Å/8F'Æ'F*c               ó$   € V ^8„  d   QhRRRRRR/# )r   r1   r2   r}   ro   r   r*   r   )r   s   "r   r   r   ·   s"   € ÷ ñ ¨ð Ð6Ið Èdñ r    c                ón  a€ SP                  4       '       d   \        P                  ! 4       MRpVf   R# R V3R llpVP                  V4       R V3R llp \	        \        P
                  ! V\        P                  R7      4      #   \         d"   p\        P                  RY4        Rp?R# Rp?ii ; i)	zBWake a recycled stdio server and wait briefly for a fresh session.NFc               ó   € V ^8„  d   QhRR/# ©r   r   r3   r   )r   s   "r   r   Ú-_request_lazy_reconnect.<locals>.__annotate__½   s   € ÷ &ñ &�4ñ &r    c                 óp   <€ S P                   P                  4        S P                  P                  4        R # ©N)Ú_readyÚclearÚ_reconnect_eventrs   )r}   s   €r   Ú_wakeÚ&_request_lazy_reconnect.<locals>._wake½   s%   ø€ Ø�‰×ÑÔØ×Ñ×#Ñ#Ö%r    c               ó   € V ^8„  d   QhRR/# ©r   r   r*   r   )r   s   "r   r   r‡   Ã   s   € ÷ ñ  ñ r    c               “  ó<  <"  € \         P                  ! 4       \        P                  ,           p \         P                  ! 4       V 8  dQ   SP                  e#   SP
                  P                  4       '       d   R# \        P                  ! R4      G R j  x€L
  Kj  R#  L5i)NTgš™™™™™©?F)	r9   r:   r
   Ú_RECYCLED_RECONNECT_TIMEOUTÚsessionrŠ   Úis_setrT   Úsleep)rG   r}   s    €r   Ú_await_readyÚ-_request_lazy_reconnect.<locals>._await_readyÃ   se   øé € Ü—>’>Ó#¤e×&GÑ&GÕGˆÜ�nŠnÓ Ô)Ø�~‰~Ò)¨f¯m©m×.BÑ.B×.DÒ.DÙÜ—-’- Ó%×%Ò%Ùñ &ùs   ƒA2BÁ6BÂBÂ	B©Útimeoutz>MCP server '%s': lazy reconnect after stdio recycle failed: %s)Ú_is_recycled_stdioÚ_loopÚ_running_loopÚcall_soon_threadsafer*   Ú_run_on_mcp_loopr
   r’   r(   r+   r,   )r1   r}   Úloopr�   r–   Úexcs   &f    r   Ú_request_lazy_reconnectr¡   ·   s“   ø€ à$*×$=Ñ$=×$?Ò$?Œ5×ÒÔ ÀT€DØ‚|Ù÷&ð &ð 	×Ñ˜eÔ$÷ð ðÜ”E×*Ò*¨<Ä×AbÑAbÔcÓdÐdøÜô Ü�‰ÐWÐYdÔjÝûðús   Á.B ÂB4ÂB/Â/B4c               ó$   € V ^8„  d   QhRRRRRR/# )r   rl   r2   rm   rn   r   r*   r   )r   s   "r   r   r   Ò   s&   € ÷ Dñ D˜sð D¨Dð D°Tñ Dr    c                ó<   € \        VP                  RR4      RR7      # )a  True when ``mcp_servers.<name>.lazy`` defers connect to first tool use (default off).

Gated per-server by ``mcp_servers.<name>.lazy`` in config (default OFF), following the same per-server
key pattern as ``idle_timeout_seconds``. Design from #56832 (Vansh5632).
ÚlazyF©Údefault)r   r&   )rl   rm   s   &&r   Ú_resolve_server_lazyr§   Ò   s   € ô ˜&Ÿ*™* V¨UÓ3¸UÔCÐCr    c               ó$   € V ^8„  d   QhRRRRRR/# )r   rl   r2   r    ry   r   r   )r   s   "r   r   r   Û   s!   € ÷ ñ  ð ¨-ð ¸Cñ r    c                ó,  € \         P                  ! V4      p\        P                  ;_uu_ 4        \	        V 4      p\        P
                  P                  V4       V\        P                  V&   \        V 4       RRR4       V#   + '       g   i     T# ; i)zQRecord a failed connect (under ``_lock``): error text for status, cooldown stamp.N)	Ú_errorsÚ_format_connect_errorr
   Ú_lockr   Ú_server_connectingÚdiscardÚ_server_connect_errorsr?   )rl   r    Úmessager<   s   &&  r   Ú_note_connect_failurer±   Û   sl   € ä×+Ò+¨CÓ0€GÜ	��‹Ü˜$ÓˆÜ× Ñ ×(Ñ(¨Ô-Ø,3Œ×$Ñ$ SÑ)Ü Ô%÷	 
ð
 €N÷ 
Žð
 €Nús   ¯A	BÂB	c               ó    € V ^8„  d   QhRRRR/# )r   rl   r2   r   r   )r   s   "r   r   r   æ   s   € ÷ Lñ L˜Cð L Cñ Lr    c                óˆ   € ^ RI Hp V! V 4      pV'       g   R# RP                  R VP                  4        4       4      pRV 2# )u  Operator-facing stderr tail for a connect-failure log line (#125300).

``Connection closed`` alone hides why the child died â€” the reason sits in the shared
mcp-stderr.log. The stored status message stays single-line; only the log line quotes
the child's output.)Ú_tail_server_stderrÚ Ú
c              3  ó,   "  € T F
  pR V 2x € K  	  R# 5i)z    Nr   )Ú.0Úlines   & r   Ú	<genexpr>Ú$_stderr_tail_note.<locals>.<genexpr>ð   s   é € ÐEÑ3D¨4˜4 ˜v�Ó3Dùs   ‚z1
  child stderr tail (full log: mcp-stderr.log):
)Útools.mcp_tool_configr´   ÚjoinÚ
splitlines)rl   r´   ÚtailÚindenteds   &   r   Ú_stderr_tail_noterÁ   æ   s?   € õ :Ù˜tÓ$€DßÙØ�y‰yÑE°4·?±?Ô3DÓEÓE€HØ@ÀÀ
ÐKÐKr    c               ó    € V ^8„  d   QhRRRR/# )r   rl   r2   r   r3   r   )r   s   "r   r   r   ô   s   € ÷ %ñ % ð %¨ñ %r    c                ó  € \         P                  ;_uu_ 4        \        V 4      p\         P                  P	                  V4       \         P
                  P                  VR4       \        V 4       RRR4       R#   + '       g   i     R# ; i)zSClear connecting/error/cooldown state after a successful connect (under ``_lock``).N)r
   r¬   r   r­   r®   r¯   rB   rC   )rl   r<   s   & r   Ú_note_connect_successrÄ   ô   sS   € ä	��‹Ü˜$ÓˆÜ× Ñ ×(Ñ(¨Ô-Ü×$Ñ$×(Ñ(¨¨dÔ3Ü˜tÔ$÷	 
��Šús   ™AA9Á9B
	c               ó$   € V ^8„  d   QhRRRRRR/# )r   rl   r2   r}   ro   r   r3   r   )r   s   "r   r   r   ý   s'   € ÷ Dñ D˜ð DÐ%8ð D¸Tñ Dr    c                óø   € \         P                  ;_uu_ 4        \        V 4      pV\         P                  V&   \         P                  ! 4       \         P
                  V&   RRR4       R#   + '       g   i     R# ; i)zVPublish *server* into ``_servers`` under the connecting scope's key (under ``_lock``).N)r
   r¬   r   Ú_serversrL   Ú_server_scope_keys)rl   r}   r<   s   && r   Ú_adopt_serverrÉ   ý   sH   € ä	��‹Ü˜$ÓˆØ$Œ�‰�sÑÜ(-×(AÒ(AÓ(CŒ× Ñ  Ñ%÷ 
��Šús   ™AA(Á(A9	c               ó    € V ^8„  d   QhRRRR/# rE   r   )r   s   "r   r   r     s   € ÷ *=ñ *=¨sð *=°tñ *=r    c           	     ó˜  a a€ \         P                  ;_uu_ 4        \        S 4      p\         P                  P	                  V4      pVe   VP
                  e    RRR4       R# \         P                  P	                  V4      oS'       d'   \        S 4      '       g   V\         P                  9   d    RRR4       R# \         P                  P                  V4       \         P                  P                  VR4       RRR4       \        P                  RS 4       \        P                  ! 4        SP	                  R\         P                   4      p \        P"                  ! VV 3R l\%        V4      R,           R7       \/        S 4       \         P                  ;_uu_ 4        \         P                  P                  XR4       \         P0                  P                  TR4      p\         P2                  P                  TR4      ;'       g    . p\         P                  P	                  T4      p\5        \7        TR
. 4      ;'       g    . 4      pRRR4       X Uu. uF  qˆX9  g   K  TNK  	  p	pT	'       dR   T	 F  p
\8        P:                  ! XT
4       K  	  \        P                  RS \=        T	4      XRP?                  T	4      4       XRJ;'       d    TP
                  RJ#   + '       g   i     ELë; i  \&         d7   p\        P)                  R	S \+        S T4      \-        S 4      4        Rp?R# Rp?ii ; i  + '       g   i     Lô; iu upi )a  Connect a lazily-registered server on demand (sync; blocks). Honours the cooldown and the
``_server_connecting`` dedup set; routes through ``_discover_and_register_server`` so
park/recycle/cooldown bookkeeping stays in one place. True when a live session exists.

See #50394.
NTFz(MCP server '%s': lazy start on first useÚconnect_timeoutc                 ó   <€ \        SS 4      # r‰   ©Ú_discover_and_register_server)rm   r1   s   €€r   Ú<lambda>Ú/_ensure_lazy_server_connected.<locals>.<lambda>  s   ø€ Ô'DÀ[ÐRXÔ'Yr    rY   r˜   z&Lazy MCP connect failed for '%s': %s%sÚ_registered_tool_nameszoMCP server '%s': deregistered %d phantom cached tool(s) not served live (stale schema-cache fingerprint %s): %sú, ) r
   r¬   r   rÇ   r&   r“   Ú_lazy_server_configsrH   r­   Úaddr¯   rB   r+   Úinfor›   Ú_ensure_mcp_loopÚ_DEFAULT_CONNECT_TIMEOUTrž   Úfloatry   r,   r±   rÁ   rÄ   Ú_lazy_server_fingerprintsÚ_lazy_server_tool_namesrs   ÚgetattrÚ_registrationÚ_deregister_mcp_tool_all_scopesÚlenr½   )r1   r<   r}   rÌ   r    Ústale_fingerprintÚcached_namesÚ
live_namesr=   Úphantom_namesÚ	tool_namerm   s   f          @r   Ú_ensure_lazy_server_connectedrå     sy  ù€ ô 
��‹Ü! +Ó.ˆÜ—‘×#Ñ# CÓ(ˆØÒ &§.¡.Ò"<Ø÷	 
‰ô
 ×+Ñ+×/Ñ/°Ó4ˆßÔ2°;×?Ò?Øœ%×2Ñ2Ô2Ø÷ 
‰ô 	× Ñ ×$Ñ$ SÔ)Ü×$Ñ$×(Ñ(¨¨dÔ3÷ 
ô ‡K�KÐ:¸KÔHÜ	×ÒÔØ—j‘jÐ!2´E×4RÑ4RÓS€OðÜ×ÒÕYÜ',¨_Ó'=ÀÕ'Dõ	Fô ˜+Ô&Ü	��‹Ü×"Ñ"×&Ñ& s¨DÔ1Ü!×;Ñ;×?Ñ?ÀÀTÓJÐÜ×4Ñ4×8Ñ8¸¸dÓC×IÐIÀrˆÜ—‘×#Ñ# CÓ(ˆÜœ Ð)AÀ2ÓF×LÐLÈ"ÓMˆ
÷ 
ñ !-ÓD¡˜1¸Ñ0C—Q�Q¡€MÐDßÛ&ˆIÜ×9Ò9¸#¸yÖIñ 'ä�‰ð *Ø+6¼¸MÓ8JÐL]Ð_c×_hÑ_hÐivÓ_wô	yà˜Ð×<Ð< &§.¡.¸Ð"<Ð<÷G 
�ˆûô" ô Ü�‰Ð?Ø"Ô$9¸+ÀsÓ$KÔM^Ð_jÓMkô	måûðú÷
 
�üò EsT   ›>KÁ#&KÂ
'KÂ;?KÅ-K0 ÆB"L4ÉL4ÉMÉ!MËK-	Ë0L1Ë;+L,Ì,L1Ì4M	c               ó    € V ^8„  d   QhRRRR/# )r   r1   r2   r   zOptional[_core.MCPServerTask]r   )r   s   "r   r   r   2  s   € ÷ 'ñ '°ð 'Ð8Uñ 'r    c                óH  € \         P                  ;_uu_ 4        \        V 4      p\         P                  P	                  V4      pV\         P
                  9   pRRR4       X'       d   Xe   VP                  f   \        V 4       M6Xe1   VP                  f#   VP                  4       '       d   \        W4       MV# \         P                  ;_uu_ 4        \         P                  P	                  X4      uuRRR4       #   + '       g   i     L®; i  + '       g   i     R# ; i)a7  Return a connected server; the single first-use connect point for lazy servers and
the wake-up point for recycled stdio ones.

Also the single first-use connect point for lazy (schema-cache registered) servers, so raw tool calls
AND the resource/prompt utility handlers all trigger the deferred spawn (#56832).
N)
r
   r¬   r   rÇ   r&   rÔ   r“   rå   rš   r¡   )r1   r<   r}   Úis_lazys   &   r   Ú_get_connected_server_for_callré   2  s¸   € ô 
��‹Ü! +Ó.ˆÜ—‘×#Ñ# CÓ(ˆØœ×3Ñ3Ñ3ˆ÷ 
÷ �F’N f§n¡nÒ&<Ü% kÕ2Ø	Ò	 §¡Ò 6¸6×;TÑ;T×;VÒ;VÜ Õ4àˆÜ	��‹Ü�~‰~×!Ñ! #Ó&÷ 
Š÷ 
�ú÷ 
�ˆús   ™>C=ÃDÃ=D	ÄD!	c               ó$   € V ^8„  d   QhRRRRRR/# )r   rl   r2   rm   rn   r   ú	list[str]r   )r   s   "r   r   r   G  s!   € ÷ ñ ¨cð ¸4ð ÀIñ r    c           	   ƒ  óÊ  "  € . p\         P                  P                  VP                  4      p \        P
                  ! \        W4      VP                  R\         P                  4      R7      G Rj  x€L
 p \         P                  P#                  T4       \         P$                  ;_uu_ 4        \'        T 4      p\         P(                  P+                  T4       \         P,                  P/                  TR4       RRR4       \        Y4       \0        P2                  ! YT4      p\5        T4      Tn        \8        P;                  RT RT9   d   RMR\=        T4      R	P?                  T4      4       T#  Lý  \         d­    T'       d
   T^ ,          MRpTe   TP                  MRpTe#   \        TR4      '       d   TP                  4       M^ pTe=   TP                  e/   Te+   TP                  4       '       g   T'       g   \        Y4       h Te   TP!                  4       G Rj  x€L 
  h i ; i  \         P                  P#                  T4       i ; i  + '       g   i     EL_; i5i)
zDConnect one server, register its tools; return the registered names.rÌ   r˜   NÚ
cancellingz/MCP server '%s' (%s): registered %d tool(s): %sÚurlÚHTTPÚstdiorÓ   ) r
   rr   rs   ÚappendrT   Úwait_forr‚   r&   rØ   ry   Ú_taskÚhasattrrí   Ú_errorÚdonerÉ   rz   r|   r¬   r   r­   r®   r¯   rB   rÝ   Ú_register_server_toolsÚlistrÒ   r+   rÖ   rß   r½   )	rl   rm   Úclaimedr   r}   ÚtaskÚtask_cancellingr<   Úregistered_namess	   &&       r   rÏ   rÏ   G  sÒ  é € ð *,€GÜ×-Ñ-×1Ñ1°'·.±.ÓA€Kð7Ü×'Ò'¬¸Ó(EØ06·
±
Ð;LÌe×NlÑNlÓ0môo÷ o‰ô 	×#Ñ#×)Ñ)¨+Ô6Ü	��‹Ü˜$ÓˆÜ× Ñ ×(Ñ(¨Ô-Ü×$Ñ$×(Ñ(¨¨dÔ3÷ 
ô �$ÔÜ$×;Ò;¸DÈ&ÓQÐÜ$(Ð)9Ó$:€FÔ!Ü
‡K�KÐAÀ4Ø 6œ/‘¨w¼Ð<LÓ8MÈtÏyÉyÐYiÓOjôlàÐñ1oøäô 
ß&�˜–¨DˆØ%Ò1ˆv�|Š|°tˆØ/3Ò/?ÄGÈDÐR^×D_ÒD_˜$Ÿ/™/Ô+ÐefˆØÒ 6§=¡=Ò#<ÀÒAQØŸ	™	Ÿš¯Oä˜$Ô'ð 	ð ÒØ—/‘/Ó#×#Ñ#Øð
ûô 	×#Ñ#×)Ñ)¨+Õ6úß	�ˆüst   ‚,I#¯AE1 Á1E/Á2E1 Á77I#Â.AIÃ9A6I#Å/E1 Å1H(ÆA0H(Ç5H(Ç=#H(È H#È!H(È(H+ È+!IÉI#ÉI 	É	I#c               ó    € V ^8„  d   QhRRRR/# )r   Úserversúdict[str, dict]r   r   )r   s   "r   r   r   h  s   € ÷ 'ñ ' ð '°_ñ 'r    c                óü  € \         P                  ;_uu_ 4        \         P                  ! 4       pV  Uu/ uF  q"\        W!RR7      bK  	  ppV P	                  4        UUu/ uF„  w  r$W2,          \         P
                  9  g   K"  W2,          \         P                  9  g   K?  W2,          \         P                  9  g   K\  \        V4      '       g   Ko  \        V4      '       d   K‚  W$bK†  	  pppV P	                  4        UUu. uF~  w  r$W2,          \         P
                  9   g   K"  \        V4      '       g   K5  \        \         P
                  W2,          ,          RR4      e   Ka  \         P
                  W2,          ,          NK€  	  pppV Fg  p\         P                  P                  W7,          4       V\         P                  W7,          &   \         P                  P                  W7,          R4       Ki  	  V P	                  4        Fu  w  rx\        WqRR7      p	\!        VP#                  RR4      RR7      '       d"   \         P$                  P                  V	4       KV  \         P$                  P'                  V	4       Kw  	  RRR4       X FO  p
\        V
RR4      pVe&   V^ ,          P)                  4       V^,          8w  g   K9  \*        P,                  ! V
4       KQ  	  X# u upi u uppi u uppi   + '       g   i     Lx; i)a  Pick connect candidates (enabled, not connected/connecting/lazy, not in backoff) and
refresh per-server bookkeeping. Known servers without a live session are parked or
mid-reconnect with tools deregistered, so nothing else can nudge them: signal a reconnect.F©Úcurrentr“   NÚsupports_parallel_tool_callsr¥   Ú
_auth_park)r
   r¬   rL   r   ÚitemsrÇ   r­   rÔ   r   rH   rÜ   rÕ   rÈ   r¯   rB   r   r   r&   Ú_parallel_safe_serversr®   Úcredential_stampr›   Ú_signal_reconnect)rþ   Úcurrent_scopeÚkÚkeysÚvÚnew_serversÚstale_cachedÚsrv_nameÚsrv_cfgÚown_keyÚsrvÚ	auth_parks   &           r   Ú_select_new_serversr  h  sQ  € ô 
��‹Ü×1Ò1Ó3ˆñ RYÓYÑQXÈAÔ& qÀÔGÒGÑQXˆÐYð
 %Ÿ]™]œ_ôKÙ,‘T�QØ�wœeŸn™nÑ,ô Ø15µÄ×@XÑ@XÑ1Xô à•œu×9Ñ9Ñ9ô ô # 1×%ô ô /GÀq×.Iô ˆAŠD™_ð 	ñ Kð
 =D¿M¹M¼Oô W¹O±D°AØ�7¤e§n¡nÑ4ô 0Ü9KÈA×9Nô 0ä#¤E§N¡N°4µ7Õ$;¸YÈÓMô 0œŸ™ t¥w×/Ð/¹Oˆñ Wó $ˆHÜ×$Ñ$×(Ñ(¨­Ô8Ø7DŒE×$Ñ$ T¥^Ñ4Ü×(Ñ(×,Ñ,¨T­^¸TÖBñ $ð ")§¡¦ÑˆHÜ! (À5ÔIˆGÜ˜gŸk™kÐ*HÈ%ÓPÐZ_×`Ó`Ü×,Ñ,×0Ñ0°Ö9ä×,Ñ,×4Ñ4°WÖ=ñ "1÷1 
ó< ˆÜ˜C ¨tÓ4ˆ	àÒ 	¨!¥× =Ñ =Ó ?À9ÈQÅ<Ö OÜ×#Ò# CÖ(ñ	 ð
 Ðùò= ZùóKùó
W÷ 
�úse   ™K+³KÁ	K+ÁK
ÂK
ÂK
Â<K
ÃK
Ã"K
Ã(K+Ã>K%
Ä"K%
Ä5'K%
Å!!K%
ÆC9K+ËK+Ë+K;	c               ó    € V ^8„  d   QhRRRR/# )r   r  rÿ   r   z tuple[dict[str, dict], int, int]r   )r   s   "r   r   r   ’  s   € ÷ =ñ =¨?ð =Ð?_ñ =r    c           	     óJ  € \        V 4      p^ p^ p ^ RIHpHp T P                  4        F¾  w  rg\        Yg4      '       g   K  T! Yd! T4      4      pT'       g   K0  \        P                  ;_uu_ 4        \        P                  P                  \        T4      4       RRR4        \        P                  ! YgT4      p	TP#                  TR4       T\%        T	4      ,          pT^,          pKÀ  	  YT3#   \         d	    T^ ^ 3u # i ; i  + '       g   i     Ls; i  \         d€   p
\        P                  RYj4       \        P                  ;_uu_ 4        \        P                  P!                  \        T4      4       RRR4       M  + '       g   i     M; i Rp
?
EKt  Rp
?
ii ; i)zÆRegister ``lazy: true`` servers from a valid schema-cache entry without connecting
(missing/stale entry or failed registration -> eager). Returns (eager servers, lazy tool
count, lazy server count).)Úconfig_fingerprintÚget_cached_entryNz)Failed lazy MCP registration for '%s': %s)rn   Útools.mcp_schema_cacher  r  r(   r  r§   r
   r¬   r­   r®   r   rÝ   Ú_register_from_cache_syncr+   r,   rÕ   rB   rß   )r  Úeager_serversÚlazy_registeredÚlazy_server_countr  r  rl   ÚcfgÚentryÚnamesr    s   &          r   Ú_register_lazy_from_cacher!  ’  sL  € ô &*¨+Ó%6€MØ€OØÐð#ßOð !×&Ñ&Ö(‰	ˆÜ# D×.Ò.ÙÙ  Ð'9¸#Ó'>Ó?ˆßÙÜ�[�[‹[Ü×$Ñ$×,Ñ,¬[¸Ó->Ô?÷ ð	Ü!×;Ò;¸DÀuÓMˆEð 	×Ñ˜$ Ô%Øœ3˜u›:Õ%ˆØ˜QÕÒñ# )ð$ Ð+<Ð<Ð<øô) ô #Ø˜a Ð"Ò"ð#ú÷ �[ûô ô 	Ü�N‰NÐFÈÔRÜ——“Ü×(Ñ(×,Ñ,¬[¸Ó->Ô?÷ ——�úæûð		úsM   ‘C/ Á1)DÂ#DÃ/DÄDÄDÄF"Ä#.FÅ)F	Å:	FÆFÆFÆF"c               ó    € V ^8„  d   QhRRRR/# ©r   r  rÿ   r   r3   r   )r   s   "r   r   r   ´  s   € ÷ (ñ ( _ð (¸ñ (r    c           
   ƒ  ó
  aa"  € \        4       pV^ 8”  d   \        P                  ! V4      MRoR V3R llo\        P                  ! V3R lV P	                  4        4       RR/ G Rj  x€L
 p\        W4       Fƒ  w  r4\        V\        4      '       d^   V P                  V/ 4      P                  R4      p\        W44      p\        P                  RY5'       d   R	V R
2MRV\        V4      4       Kx  \        V4       K…  	  R#  L˜5i)a  Connect every candidate concurrently; record per-server outcome.

Concurrency is bounded: every stdio server spawns child processes, so an
unbounded gather turns a config with many servers into a simultaneous
N-process spawn burst (RAM/CPU spike, EMFILE risk) on every backend boot.
Nc               ó    € V ^8„  d   QhRRRR/# )r   rl   r2   r  rn   r   )r   s   "r   r   Ú#_discover_all.<locals>.__annotate__¿  s   € ÷ Bñ B Sð B¨tñ Br    c              “  óô   <"  € Sf   \        W4      G R j  x€L
 # S;_uu_4       GR j  x€L
  \        W4      G R j  x€L
 uuR R R 4      GR j  x€L
  #  L< L+ L L  + GR j  x€L 
 '       g   i     R # ; i5ir‰   rÎ   )rl   r  Ú	semaphores   &&€r   Ú_connect_boundedÚ'_discover_all.<locals>._connect_bounded¿  sL   øé € ØÒÜ6°tÓA×AÐAß—9’9Ü6°tÓA×A÷ —9’9ñ BÙÙA÷ —9—9“9üsj   ƒA8–A—A8©AªA8­A¼A½AÁ A8ÁAÁA8ÁA8ÁAÁA8ÁA5	Á!A$Á"
A5	Á-A5	Á/	A8c              3  ó8   <"  € T F  w  rS! W4      x € K  	  R # 5ir‰   r   )r¸   rl   r  r)  s   &  €r   rº   Ú _discover_all.<locals>.<genexpr>Æ  s   øé € Ð	KÑ7J©)¨$Ñ
˜4×
%Ð
%Ó7Jùs   ƒÚreturn_exceptionsTÚcommandz,Failed to connect to MCP server '%s'%s: %s%sz
 (command=Ú)rµ   )r.   rT   Ú	SemaphoreÚgatherr  Úzipr)   ry   r&   r±   r+   r,   rÁ   rÄ   )	r  ÚcapÚresultsrl   Úresultr.  r°   r)  r(  s	   &      @@r   Ú_discover_allr6  ´  sá   ùé € ô )Ó
*€CØ*-°¬'”×!Ò! #Ô&°t€I÷Bð Bô —N’NÜ	K°{×7HÑ7HÔ7JÓ	Kð àñ ÷  €Gô ˜KÖ1‰ˆÜ�fœm×,Ò,Ø!—o‘o d¨BÓ/×3Ñ3°IÓ>ˆGÜ+¨DÓ9ˆGÜ�N‰NÐIØ¾G :¨g¨Y°aÑ!8ÈÈWÜ,¨TÓ2ö4ô " $Ö'ó 2ñ ùs   „A$DÁ(DÁ)BDc               ó    € V ^8„  d   QhRRRR/# r#  r   )r   s   "r   r   r   Ó  s   € ÷ &!ñ &! _ð &!¸ñ &!r    c                ó   a € ^ RI HpHp V! 4       pV'       d	   V! R4        \        4       ;'       g    \	        S 4      ;'       g    ^p\        ^\	        S 4      ) V,          ) 4      p\        ^xV,          \        P                  4      p\        P                  ! V 3R lVR7        T'       d   T! R4       R# R#   \        \        3 Ed-   p\        T\        4      '       d   RMRp\        P                  ;_uu_ 4        S  U	u. uF%  p	\        T	4      \        P                   9   g   K#  T	NK'  	  Mu up	i p
p	T
'       dš   \"        P%                  RT\	        T
4      RP'                  T
4      4       T
 Fc  p\        P                   P)                  \        T4      4       \        P*                  P-                  \        T4      R	T R
24       \/        T4       Ke  	  RRR4       h   + '       g   i     h ; iRp?ii ; i  T'       d
   T! R4       i i ; i)zRun ``_discover_all`` on the MCP loop with the interrupt flag parked; clean up
``_server_connecting`` when the pass dies early.)Úis_interruptedÚset_interruptFc                 ó   <€ \        S 4      # r‰   )r6  )r  s   €r   rÐ   Ú%_run_discovery_pass.<locals>.<lambda>æ  s
   ø€ ¤}°[Ô'Ar    r˜   z	timed outÚinterruptedz\MCP discovery %s while %d server(s) were still connecting; clearing stale connecting set: %srÓ   zConnection attempt z during discoveryNT)Útools.interruptr9  r:  r.   rß   Úmaxr6   r
   Ú_MCP_DISCOVERY_PASS_MAX_SECr›   rž   ÚTimeoutErrorÚInterruptedErrorr)   r¬   r   r­   r+   r,   r½   r®   r¯   Ú
setdefaultr?   )r  Ú_is_interruptedÚ_set_interruptÚ_was_interruptedr3  Úwavesr™   Ú_eÚhowr=   ÚstaleÚ_sns   f           r   Ú_run_discovery_passrL  Ó  sž  ø€ ÷ cÙ&Ó(ÐßÙ�uÔð!ô -Ó.×GÐG´#°kÓ2B×GÐGÀaˆÜ�Aœ#˜kÓ*Ð*¨cÕ1Ð2Ó3ˆÜ�c˜E•k¤5×#DÑ#DÓEˆÜ×ÒÔAÈ7ÖS÷$ Ù˜4Ö ñ øô# Ô*Ð+õ ä'¨¬L×9Ò9‰k¸}ˆÜ�[�[‹[Ù +ÓZ¡˜1¬{¸1«~Ä×AYÑAYÑ/Y—Q�Q¢ùÒZˆEÐZßÜ—‘ð  4Ø58¼#¸e»*ÀdÇiÁiÐPUÓFVôXã �CÜ×,Ñ,×4Ñ4´[ÀÓ5EÔFÜ×0Ñ0×;Ñ;Ü# CÓ(Ð,?À¸uÐDUÐ*VôXô ,¨CÖ0ñ !÷ ð 	÷ Ž[ð 	þðû÷" Ù˜4Õ ð úsU   ¢#B9 ÁAB9 Â9G7Ã2G2Ã=GÄ D.
Ä'D.
Ä-B)GÇ	G2ÇG/Ç*G2Ç2G7Ç7G: Ç:HÚ
lazy_toolsÚlazy_serversc               ó$   € V ^8„  d   QhRRRRRR/# )r   rM  r   rN  r   z&tuple[int, int, list[tuple[str, str]]]r   )r   s   "r   r   r   ü  s(   € ÷ Jñ J¨Sð JØ%(ðJØ1WñJr    c          
     óN  a€ \         P                  ;_uu_ 4        V  Uu/ uF  q3\        V4      bK  	  upoV  Uu. uFA  pSV,          \         P                  9   g   K!  SV,          \         P                  9  g   K?  VNKC  	  pp\        V3R lV 4       4      pV  Uu. uF=  q3V9  g   K  T\         P                  P                  SV,          4      ;'       g    R3NK?  	  ppRRR4       XV,           \        X4      V,           X3# u upi u upi u upi   + '       g   i     L;; i)zö(tool count, connected count, ``[(failed name, reason)]``) for candidate names, plus lazy
servers. The reason is the recorded connect error; a candidate this pass never attempted (still
inside its retry cooldown from an earlier failure) has none.c              3  óˆ   <"  € T F7  p\        \        \        P                  SV,          ,          R . 4      4      x € K9  	  R# 5i)rÒ   N)rß   rÜ   r
   rÇ   ©r¸   r=   r  s   & €r   rº   Ú%_connected_summary.<locals>.<genexpr>  s4   øé € ÐpÑfoÐabœœW¤U§^¡^°D¸µGÕ%<Ð>VÐXZÓ[×\Ð\Ófoùs   ƒ?Az!not attempted (in retry cooldown)N)r
   r¬   r   rÇ   r¯   Úsumr&   rß   )r   rM  rN  r=   Ú	connectedÚ
tool_countÚfailedr  s   &$$    @r   Ú_connected_summaryrX  ü  s  ø€ ô
 
��‹Ù+0Ó1©5 a”;˜q“>Ò!©5Ñ1ˆÙ %ó c¡˜1Ø˜Q�¤5§>¡>Ñ1ô Ø6:¸1µgÄU×EaÑEaÑ6a÷ �Q¡ˆ	ð cäÔpÑfoÓpÓpˆ
á ó8Ù �a¨YÑ$6ô h�1”e×2Ñ2×6Ñ6°t¸AµwÓ?×fÐfÐCfÓgÙ ð 	ð 8÷ 
ð ˜
Õ"¤C¨	£N°\Õ$AÀ6ÐIÐIùò 2ùòcùò8÷ 
�úsJ   šDŸD³DºD
ÁD
Á;D
ÂDÂDÂ)-DÃDÃDÄDÄD$	c               ó    € V ^8„  d   QhRRRR/# )r   Úprefixr2   r   r3   r   )r   s   "r   r   r     s   € ÷ ñ ˜ð °ñ r    c                ó�  € \        V3/ VB w  r4pV'       g    V'       g   VP                  R4      '       d�   V  RV RV R2pV'       d;   VR\        V4       R2RP                  R V 4       4      ,           R	,           ,          pVP                  R4      '       d   VRVR,           R
2,          p\        P                  V4       R# R# )a@  Log ``<prefix> N tool(s) from M server(s) (K failed: name (reason), ...)`` when anything
happened. The failures are named on the summary line itself (#114746): the count alone left
the failing server identifiable only by elimination, and a candidate skipped for its retry
cooldown never gets a per-server WARNING at all.rN  Ú z tool(s) from z
 server(s)ú (z	 failed: z; c              3  ó6   "  € T F  w  rV R V R2x € K  	  R# 5i)r]  r/  Nr   )r¸   rl   Úreasons   &  r   rº   Ú_log_summary.<locals>.<genexpr>  s#   é € ð ?AÙ9?©¨�4�&˜˜6˜( !Õ$»ùs   ‚r/  z lazy, not spawned yet)N)rX  r&   rß   r½   r+   rÖ   )rZ  r   r¤   Únew_tool_countÚconnected_countrW  Úsummarys   &&,    r   Ú_log_summaryrd    sÇ   € ô
 /AÀÑ.OÈ$Ñ.OÑ+€N VßŸ 4§8¡8¨N×#;Ò#;Ø�H˜A˜nÐ-¨^¸OÐ;LÈJÐWˆßØ˜œC ›K˜=¨	Ð2°T·Y±Yñ ?AÙ9?ó?Aó 6Aõ AØCFõGõ GˆGà�8‰8�N×#Ò#Ø˜˜D Õ0Ð1Ð1HÐIÕIˆGÜ�‰�GÖñ $<r    c               ó    € V ^8„  d   QhRRRR/# ©r   rþ   rÿ   r   rë   r   )r   s   "r   r   r     s   € ÷ 3ñ 3 /ð 3°iñ 3r    c                ó2  € ^ RI Hp V! 4       '       d   . # \        P                  ! 4       '       g   \        P                  R4       . # \        P                  ! V 4      p  \        V 4      \        P                  ! 4        #   \        P                  ! 4        i ; i)z«Connect ``{name: config}`` servers and register their tools; idempotent for connected
names, ``enabled: false`` skipped without disconnecting. Returns every MCP tool name.©Úsafe_worker_enabledz;MCP SDK not available -- skipping explicit MCP registration)Úagent.safe_worker_policyri  r
   Ú_ensure_mcp_sdkr+   r{   rt   Ú_filter_suspicious_mcp_serversÚ_register_mcp_serversÚ
_lifecycleÚ_reregister_orphaned_adopters)rþ   ri  s   & r   Úregister_mcp_serversrp    sp   € õ =Ù×Òð ˆ	Ü× Ò ×"Ò"Ü�‰ÐRÔSØˆ	Ü×4Ò4°WÓ=€Gð3Ü$ WÓ-ô 	×0Ò0Õ2øŒ
×0Ò0Õ2ús   Á
A? Á?Bc               ó    € V ^8„  d   QhRRRR/# rf  r   )r   s   "r   r   r   /  s   € ÷ 0ñ 0 ?ð 0°yñ 0r    c                óh  € \         P                  ! V 4      pV '       gD   \        P                  R 4       \        P
                  ! 4       e   \         P                  ! 4       # . # \        V 4      pV'       d   \        P                  RV4       V'       g   \         P                  ! 4       # \        V4      w  r#pV'       g4   V'       d   \        P                  RV4       \         P                  ! 4       # \        P                  ! 4        \        V4       \        RW#VR7       \         P                  ! 4       # )z No explicit MCP servers providedzFMCP: registered %d already-connected server(s) into this profile scopezHMCP: registered %d lazy tool(s) from schema cache (no processes spawned)zMCP: registered©rM  rN  )rÝ   Ú%register_connected_into_current_scoper+   r{   r
   rL   Ú_existing_tool_namesr  rÖ   r!  r›   r×   rL  rd  )rþ   Úscoped_healedr  r  r  s   &    r   rm  rm  /  sÝ   € Ü!×GÒGÈÓP€MßÜ�‰Ð7Ô8Ü7<×7PÒ7PÓ7RÒ7^Œ}×1Ò1Ó3ÐfÐdfÐfÜ% gÓ.€KßÜ�‰Ð\Ð^kÔlßÜ×1Ò1Ó3Ð3Ü6OÐP[Ó6\Ñ3€KÐ"3ßßÜ�K‰KÐbØ'ô)ä×1Ò1Ó3Ð3Ü	×ÒÔÜ˜Ô$ÜÐ" KÐZkÕlÜ×-Ò-Ó/Ð/r    c                 óÊ  € \         P                  ! 4       p V e   V # \        P                  R4       \	        \
        P                  4       FB  p\        P                  ! \
        P                  4       \         P                  ! 4       p V f   KB   M	  V f'   \        P                  R\
        P                  4       V # V \
        P                  Jd   \        P                  R4       V # )z¶Cross-process guard: a lock loser waits for the holder then discovers itself; unavailable
locking or an expired wait runs unguarded (fail-soft). None / _LOCK_UNAVAILABLE = unguarded.zAAnother process holds MCP discovery lock -- retrying with backoffzMMCP discovery lock still held after %d retries -- running discovery unguardedz.Retry succeeded -- acquired MCP discovery lock)r›   Ú_try_acquire_mcp_discovery_lockr+   r{   Úranger
   Ú_MCP_DISCOVERY_LOCK_MAX_RETRIESr9   r•   Ú!_MCP_DISCOVERY_LOCK_RETRY_DELAY_Sr,   Ú_LOCK_UNAVAILABLE)ÚcookieÚ_s     r   Ú"_acquire_discovery_lock_with_retryr  E  s°   € ô ×2Ò2Ó4€FØÒØˆÜ
‡L�LÐTÔUÜ”5×8Ñ8Ö9ˆÜ�
Š
”5×:Ñ:Ô;Ü×6Ò6Ó8ˆØÔÙñ	 :ð ‚~Ü�‰ÐfÜ×<Ñ<ô	>ð €Mð 
”u×.Ñ.Ó	.Ü�‰ÐEÔFØ€Mr    c               ó    € V ^8„  d   QhRRRR/# )r   Úallowed_mcp_nameszOptional[list[str]]r   rë   r   )r   s   "r   r   r   \  s   € ÷ 6ñ 6Ð*=ð 6Èñ 6r    c                ó�  a€ ^ RI Hp V! 4       '       d   . # \        4       ;_uu_ 4        \        P                  ! 4       pRRR4       X'       g   \
        P                  R4       . # V eÛ   V  Uu0 uF  p\        V4      kK  	  ppVP                  4        UUu/ uF  w  rVWT9   g   K  WVbK  	  ppp\        V4      \        V4      8w  d\   \
        P                  R\        V4      \        V4      RP                  \        \        V4      \        V4      ,
          4      4      4       TpV'       g   \
        P                  R4       . # \        P                  ! 4       '       g   \
        P                  R4       . # \        4       p \        P                   ;_uu_ 4        V Uu/ uF  qU\#        V4      bK  	  upoVP                  4        UUu. uFV  w  rVSV,          \        P$                  9  g   K#  SV,          \        P&                  9  g   KA  \)        V4      '       g   KT  VNKX  	  p	pp\        \        P*                  4      p
RRR4       \-        V4      pX	'       d·   \        P                   ;_uu_ 4        V	 Uu. uF#  pSV,          \        P*                  9   g   K!  VNK%  	  ppV Uu. uF  pSV,          X
9  g   K  VNK  	  pp\/        V3R lV 4       4      pRRR4       \1        R	V	 Uu. uF  q3X9  g   K  VNK  	  upX\        X4      R
7       TVR\        P2                  39  d   VP5                  4        # #   + '       g   i     EL; iu upi u uppi u upi u uppi   + '       g   i     EL.; iu upi u upi   + '       g   i     L²; iu upi   TR\        P2                  39  d   TP5                  4        i i ; i)aø  Entry point: load config, connect servers, register tools. [] without the ``mcp``
package; idempotent (only servers missing from a previous call are retried).

``allowed_mcp_names``: spawn only the MCP servers named in it (built-in toolset names in the
list simply don't match); ``None`` spawns every configured server. Used by
``hermes -z -t <toolsets>`` to skip cold-starting servers the caller doesn't need (10-60s
each); it only affects which servers start, not which names ``-t`` validation can see.rh  NzNo MCP servers configuredz]MCP discovery filter: spawning %d/%d configured server(s) per --toolsets filter (skipped: %s)Ú,z?No MCP servers in --toolsets filter; skipping MCP load entirelyz4MCP SDK not available -- skipping MCP tool discoveryc              3  ó„   <"  € T F5  p\        \        P                  P                  SV,          . 4      4      x € K7  	  R # 5ir‰   )rß   r
   rÛ   r&   rR  s   & €r   rº   Ú%discover_mcp_tools.<locals>.<genexpr>Œ  s4   øé € Ð iÑ^hÐYZ¤¤U×%BÑ%B×%FÑ%FÀtÈAÅwÐPRÓ%S×!TÐ!TÓ^hùs   ƒ=A z  MCP:rs  )rj  ri  rj   rt   Ú_load_mcp_configr+   r{   r2   r  rß   r½   Úsortedrs   r
   rk  r  r¬   r   rÇ   r­   r   rÔ   rp  rT  rd  r|  Úrelease)r�  ri  rþ   r=   Úallowed_setrl   r  Úfilteredr}  Únew_server_namesÚ
prior_lazyÚ
tool_namesÚlazy_nowÚ
newly_lazyrM  r  s   &              @r   Údiscover_mcp_toolsr�  \  sõ  ø€ õ =Ù×ÒØˆ	Ü	×	Õ	Ü×*Ò*Ó,ˆ÷ 
çÜ�‰Ð0Ô1Øˆ	ØÒ$Ù'8Ó9Ñ'8 !”s˜1–vÑ'8ˆÐ9Ø/6¯}©}¬ÔV©¡) $À$ÑBU”I�D’I©ˆÑVÜˆx‹=œC ›LÔ(Ü�L‰Lð )Ü*-¨h«-¼¸W»ÀsÇxÁxÔPVÔWZÐ[bÓWcÔfiÐjrÓfsÕWsÓPtÓGuôwàˆßÜ�L‰LÐZÔ[ØˆIô × Ò ×"Ò"Ü�‰ÐKÔLØˆ	Ü/Ó1€FðÜ�[�[‹[Ù@GÓHÁ¸Ô-¨dÓ3Ò3ÁÑHˆDØ6=·m±m´oô  =±o©¨Ø#'¨¥:´U·^±^Ñ#Cô !%ØHLÈTÍ
ÔZ_×ZrÑZrÑHrô !%ä$6°s×$;÷ !% ±oÐñ  =ô œU×7Ñ7Ó8ˆJ÷ ô *¨'Ó2ˆ
ßô
 ——“Ù'7ÓaÑ'7 !¸4À½7Äe×F`ÑF`Ñ;`ŸA˜AÑ'7�ÐaÙ)1ÓO© A°T¸!µWÀJÑ5NŸa˜a©�
ÐOÜ Ô iÑ^hÓ iÓi�
÷ ô ˜Ñ/?Ó#UÑ/?¨!ÈHÑCT§A AÑ/?Ñ#UØ$.¼SÀ»_õNàà˜$¤× 7Ñ 7Ð8Ô8Ø�N‰NÕð 9÷U 
×	Ð	üò :ùÛVùò  Iùó =÷ �[ˆ[üò bùÚO÷ —üò $Vøð ˜$¤× 7Ñ 7Ð8Ô8Ø�N‰NÕð 9úsÅ   ©L;Á.MÂ
MÂ&MÆN ÆM%ÆMÆ2M%Ç M
Ç-M
ÈM
ÈM
È$M%É 3N É3NÉ8M9ÊM9Ê!NÊ'M>Ê<M>ËNËN Ë+N
Ë8N
Ë>N Ì;M	ÍM%Í%M6	Í0	N Í9
NÎN	ÎN Î*Oc               ó   € V ^8„  d   QhRR/# )r   r   zdict[str, list[str]]r   )r   s   "r   r   r   •  s   € ÷ 4ñ 4Ð+?ñ 4r    c            	     óö  € \        4       ;_uu_ 4        \        P                  ! 4       p RRR4       X P                  4        UUu0 uF  w  r\	        V4      '       g   K  VkK  	  ppp\
        P                  ! 4       p\
        P                  ;_uu_ 4        \
        P                  P                  4        UUu. uF  w  rVWd8X  g   K  VNK  	  pppV Uu0 uF$  qU\
        P                  9   g   K  \        V4      kK&  	  ppV Uu0 uF$  qU\
        P                  9   g   K  \        V4      kK&  	  p	p\
        P                   Uu0 uF)  p\        V4      V8X  g   K  \        V4      V9  g   K'  VkK+  	  p
pRRR4       \        XV,
          4      pV'       dG   \        P!                  RRP#                  V4      4       \$        P&                  ! V\)        V4      R7       X
 F  p\+        V4       K  	  \-        W44      pV'       d   \/        4        RV\        R V
 4       4      ,           RVR\        X	V,
          4      /#   + '       g   i     EL; iu uppi u uppi u upi u upi u upi   + '       g   i     Lÿ; i)	u  Bring the live server set in step with ``mcp_servers`` as it is on disk NOW: tear down
servers that were removed from config or set ``enabled: false`` (a parked server keeps
self-probing forever otherwise â€” for hours after the user deleted its entry), then connect
anything enabled that is not live via :func:`discover_mcp_tools` â€” newly configured, or one
whose earlier connect failed and whose cooldown has lapsed. Scoped to the current registry
scope (one multiplexed profile's config prunes only its own connections). A lazily registered
(schema-cache) server loses its cached tools; one still mid-connect cannot be torn down yet and
is reported under ``"pending"`` so the caller retries. Returns
``{"removed": [...], "added": [...], "pending": [...]}``; a no-op when nothing changed.NzAMCP server(s) %s no longer in config (or disabled); disconnectingrÓ   ©Úscoper   Úremovedc              3  ó8   "  € T F  p\        V4      x € K  	  R # 5ir‰   )r   )r¸   r
  s   & r   rº   Ú4reconcile_mcp_servers_with_config.<locals>.<genexpr>²  s   é € Ð%A¹D°q¤i°§l l»Dùs   ‚ÚaddedÚpending)rj   rt   r†  r  r   r
   rL   r¬   rÈ   rÇ   r   r­   rÔ   r   r‡  r+   rÖ   r½   rn  Úshutdown_mcp_serversrs   Ú_forget_lazy_serverÚ_awaiting_connectr�  )rþ   rl   r  Úwantedr”  r<   ÚownerÚownedÚliveÚ
connectingr¤   rJ  r˜  s                r   Ú!reconcile_mcp_servers_with_configr¢  •  sÝ  € ô 
×	Õ	Ü×*Ò*Ó,ˆ÷ 
à$+§M¡M¤OÔO¡O‘y�tÔ7IÈ#×7N�dˆd¡O€FÑOÜ×%Ò%Ó'€EÜ	��‹Ü',×'?Ñ'?×'EÑ'EÔ'GÔZÑ'G™˜È5É>—�Ñ'GˆÑZÙ*/ÓI©% 3¼%¿.¹.Ñ3H””	˜#–©%ˆÐIÙ05ÓY±¨Ä×@XÑ@XÑ9X”n”i –n±ˆ
ÐYÜ$×9Ò9ó NÑ9˜Ü˜c“? eÑ+ô Ü09¸#³ÀfÑ0L÷ �Ñ9ˆð N÷	 
ô �4˜&•=Ó!€EßÜ�‰ÐWÐY]×YbÑYbÐchÓYiÔjÜ×'Ò'¨e¼3¸u»:ÕFÛˆÜ˜CÖ ñ ä˜fÓ,€EßÜÔØ�uœvÑ%A¹DÓ%AÓAÕAÀ7ÈEØ”v˜j¨6Õ1Ó2ð4ð 4÷' 
×	Ð	üãOùó [ùÚIùÚYùòN÷	 
�úsw   “H9ÁIÁIÂ"I(Â6
I
ÃI
ÃI(ÃIÃ-IÃ<I(ÄIÄIÄ,I(Å I#ÅI#Å)I#Å/I(È9I
	ÉI(É(I8	c               ó    € V ^8„  d   QhRRRR/# ©r   r�  úset[str]r   r   )r   s   "r   r   r   ¶  s   € ÷ 	ñ 	˜(ð 	¨hñ 	r    c                óR  € \         P                  ;_uu_ 4        V  Uu0 uFS  p\        W!R R7      ;p\         P                  9   g-   V\         P                  9   g   V\         P
                  9   g   KQ  VkKU  	  ppRRR4       W,
          # u upi   + '       g   i     T X,
          # ; i)Fr  N)r
   r¬   r   rÇ   r­   rÔ   )r�  r”  rl   r<   Úknowns   &&   r   Ú_unregisteredr¨  ¶  s‹   € Ü	��‹ñ
 #)ó Z¡&˜$Ü/°ÀUÔKÐK�SÔPU×P^ÑP^Ô^Øœ5×3Ñ3Ô3°s¼e×>XÑ>XÑ7X÷ �¡&ˆð Z÷ 
ð �>ÐùòZ÷ 
Žð �E�>Ðús#   ™BžAB	Á1B	Á7BÂ	BÂB&	c               ó    € V ^8„  d   QhRRRR/# )r   r�  r¥  r   rë   r   )r   s   "r   r   r   Â  s   € ÷ gñ g˜hð g°)ñ gr    c                ó8   € \        R  \        W4       4       4      # )c              3  óL   "  € T F  p\        V4      '       d   K  Vx € K  	  R # 5ir‰   )rH   )r¸   rl   s   & r   rº   Ú$_awaiting_connect.<locals>.<genexpr>Ç  s   é € ÐfÑ#?˜4ÔG_Ð`d×Ge—$’$Ó#?ùs   ‚$š
$)r‡  r¨  )r�  r”  s   &&r   rœ  rœ  Â  s   € ô
 Ñf¤=°Ô#?ÓfÓfÐfr    c               ó   € V ^8„  d   QhRR/# )r   r   r¥  r   )r   s   "r   r   r   Ê  s   € ÷ Nñ N˜xñ Nr    c                 ó  € \        4       ;_uu_ 4        \        P                  ! 4       p R R R 4       X P                  4        UUu0 uF  w  r\	        V4      '       g   K  VkK  	  upp#   + '       g   i     LG; iu uppi r‰   )rj   rt   r†  r  r   )rþ   rl   r  s      r   Ú_enabled_config_namesr¯  Ê  sP   € Ü	×	Õ	Ü×*Ò*Ó,ˆ÷ 
à")§-¡-¤/ÔM¡/‘Y�TÔ5GÈ×5L�DˆD¡/ÒMÐM÷ 
×	üãMs   “A(ÁA;ÁA;Á(A8	c               ó    € V ^8„  d   QhRRRR/# r¤  r   )r   s   "r   r   r   Ð  s   € ÷ 
:ñ 
:˜8ð 
:¨xñ 
:r    c                óÌ  € \         P                  ;_uu_ 4        V  Uu0 uFŽ  p\        W!R R7      ;p\         P                  9   d:   V\         P                  9   gS   \        \         P                  V,          RR4      f/   V\         P                  9   g   Ku  V\         P                  9   g   KŒ  VkK�  	  ppRRR4       \        W4      X,          # u upi   + '       g   i     L'; i)Fr  Ú_park_reasonN)r
   r¬   r   rÇ   r¯   rÜ   rÔ   r¨  )r�  r”  rl   r<   Úserving_nothings   &&   r   Ú_not_connectedr´  Ð  s¹   € Ü	��‹ñ -3ó k©F DÜ':¸4ÐPUÔ'VÐ V Ô[`×[iÑ[iÔiØ$'¬5×+GÑ+GÔ$GÜ'.¬u¯~©~¸cÕ/BÀNÐTXÓ'YÒ'eØ"¤e×&@Ñ&@Ñ@ô	  ð FIÌE×LhÑLhÑEh÷	  ˜4©Fˆð k÷	 
ô ˜Ó'¨/Õ9Ð9ùòk÷	 
�ús)   ™CžA2CÂCÂ,CÂ2CÃCÃC#	c               ó   € V ^8„  d   QhRR/# ©r   r   rë   r   )r   s   "r   r   r   Ý  s   € ÷ Xñ X 9ñ Xr    c                 ób   € \        \        \        4       \        P                  ! 4       4      4      # )a  Enabled ``mcp_servers`` entries the current registry scope has no live, connecting or lazy
registration for, in connect cooldown or not, or whose registration (lazy included) is parked or
failed its connect: after a reload, the servers that did not connect.)r‡  r´  r¯  r
   rL   r   r    r   Úmcp_servers_not_connectedr¸  Ý  s#   € ô ”.Ô!6Ó!8¼%×:SÒ:SÓ:UÓVÓWÐWr    c               ó   € V ^8„  d   QhRR/# r¶  r   )r   s   "r   r   r   ä  s   € ÷ >ñ >˜9ñ >r    c                 óz  € \        4       \        P                  ! 4       r\        P                  ;_uu_ 4        V  Uu0 uF>  p\	        W!RR7      ;p\        P
                  9   g   V\        P                  9   g   K<  VkK@  	  ppRRR4       \        X\        W4      ,
          4      # u upi   + '       g   i     L0; i)z‚Enabled ``mcp_servers`` entries the current registry scope serves now: live, or lazily registered
and not failed on its first use.Fr  N)	r¯  r
   rL   r¬   r   rÇ   rÔ   r‡  r´  )r�  r”  rl   r<   Ú
registereds        r   Úmcp_servers_readyr¼  ä  s�   € ô *Ó+¬U×-FÒ-FÓ-HˆEÜ	��‹Ù'-ó <¡v˜tÜ!4°TÈ%Ô!PÐP˜#ÔUZ×UcÑUcÔcØ¤× :Ñ :Ñ:÷ �d¡vˆ
ð <÷ 
ô �*œ~¨fÓ<Õ<Ó=Ð=ùò<÷ 
�ús"   ·B*¼9B%Á:B%Â B*Â%B*Â*B:	c               ó   € V ^8„  d   QhRR/# r¶  r   )r   s   "r   r   r   ï  s   € ÷ Sñ S iñ Sr    c                 óP   € \        \        4       \        P                  ! 4       4      # )u(  Enabled ``mcp_servers`` entries the current registry scope has no live, connecting or lazy
registration for, whose connect cooldown has lapsed: added to config since the last discovery
run, or one whose earlier connect failed. Read-only â€” what the next :func:`discover_mcp_tools`
would connect.)rœ  r¯  r
   rL   r   r    r   Úmcp_servers_awaiting_connectr¿  ï  s   € ô
 Ô2Ó4´e×6OÒ6OÓ6QÓRÐRr    c               ó    € V ^8„  d   QhRRRR/# )r   r   r¥  r   rë   r   )r   s   "r   r   r   û  s   € ÷ %ñ %¨xð %¸Iñ %r    c                óÀ  € \         ;_uu_ 4        \        P                  ! 4       p. . r2\        4       ;_uu_ 4        \        P
                  ! 4       p\        V 4       Fá  pVP                  V4      p\        P                  ;_uu_ 4        \        WQRR7      p\        P                  P                  V4      pRRR4       \        XRR4      p	Ve   V	e   \        V4      '       g   K‰  \        P                  ! V\        P                  ! V4      4      V	8w  g   K»  X\!        WQRR7      8X  d   TMTP#                  WW34       Kã  	  RRR4       V'       g   V'       g   . uuRRR4       # \        R W#,            4       4      p
\$        P'                  RRP)                  V
4      4       V'       d,   \*        P,                  ! Y UUu0 uF  w  r[VkK	  	  uppR7       V F  w  rÇ\        P.                  ! Wq4       K  	  V
 F  p\1        V4       K  	  \3        4        V
uuRRR4       #   + '       g   i     ELt; i  + '       g   i     Lû; iu uppi   + '       g   i     R# ; i)	a…  Reconnect each live server in *names* whose resolved launch inputs (stdio command/env/cwd,
HTTP url/headers) no longer hash to what it connected with, e.g. after a plugin settings form
saved a new ``${VAR}`` its ``env`` passes through. A server whose inputs did not change keeps
its connection. Returns the names restarted.

Serialized: a second save waits for the first reconnect, then compares against what THAT one
connected with, so a newer key is never lost to an older in-flight start. A connection this
profile only borrows (same inputs as another profile's) is left running for its owner; this
profile just detaches and connects its own.Fr  NÚ_resolved_identityc              3  ó*   "  € T F	  w  rVx € K  	  R # 5ir‰   r   )r¸   rl   Ú_keys   &  r   rº   Ú6restart_mcp_servers_with_new_inputs.<locals>.<genexpr>  s   é € ÐAÑ0@¡* $�Ó0@ùs   ‚z5MCP server(s) %s: launch inputs changed; reconnectingrÓ   r“  )Ú_RESTART_LOCKr
   rL   rj   rt   r†  r‡  r&   r¬   r   rÇ   rÜ   r   rÝ   Ú_adopter_identity_digestrv   r   rñ   r+   rÖ   r½   rn  rš  Ú_remove_server_scoperC   r�  )r   r”  rŸ  Úborrowedrþ   rl   rm   r<   r}   ÚrecordedÚchangedrÄ  Ú_names   &            r   Ú#restart_mcp_servers_with_new_inputsrÍ  û  s¸  € ÷ 
ŽÜ×)Ò)Ó+ˆØ˜bˆxÜ ×"Õ"Ü×.Ò.Ó0ˆGÜ˜už�Ø Ÿ™ TÓ*�Ü—[—[“[Ü-¨dÀ5ÔI�CÜ"Ÿ^™^×/Ñ/°Ó4�F÷ !ô # 6Ð+?ÀÓF�Ø’> XÒ%5Ô=OÐPV×=WÒ=WÙä ×9Ò9¸$Ä×@]Ò@]Ð^dÓ@eÓfÐjrÖrØ!¤[°ÀeÔ%LÔL‘UÐRZ×bÑbÐdhÐcnÖoñ &÷ #÷ ŸXØ÷# 
Šô$ ÑA°Ö0@ÓAÓAˆÜ�‰ÐKÈTÏYÉYÐW^ÓM_Ô`ßÜ×+Ò+°%ÐW\Ô?]ÑW\ÉÈÃÑW\Ò?]Õ^Û"‰JˆEÜ×.Ò.¨sÖ:ñ #ãˆDÜ" 4Ö(ñ äÔØ÷7 
Š÷ !—[�[ú÷	 #×"üó$ @^÷+ 
�ˆúsb   �+IºAH3	Â-HÂ4AH3	Ä*H3	Å IÅIÅIÅ$AIÆ>IÇA	IÈH0È*	H3	È3IÈ>IÉI	c               ó   € V ^8„  d   QhRR/# r†   r   )r   s   "r   r   r   #  s   € ÷ Fñ F ñ Fr    c                ó€  € \         P                  ;_uu_ 4        \         P                  P                  V R4       \         P                  P                  V R4       \         P
                  P                  V R4      ;'       g    . pRRR4       X F  p\        P                  ! W4       K  	  R#   + '       g   i     L1; i)z•Drop a schema-cache (lazy) registration whose config entry is gone: its cached tools would
otherwise stay callable and spawn the server on first use.N)r
   r¬   rÔ   rB   rÚ   rÛ   rÝ   rÞ   )r<   rá   rä   s   &  r   r›  r›  #  s€   € ô 
��‹Ü×"Ñ"×&Ñ& s¨DÔ1Ü×'Ñ'×+Ñ+¨C°Ô6Ü×4Ñ4×8Ñ8¸¸dÓC×IÐIÀrˆ÷ 
ó "ˆ	Ü×5Ò5°cÖEó "÷	 
�ús   ™A+B-Â-B=	c               ó    € V ^8„  d   QhRRRR/# )r   rä   r2   r   r*   r   )r   s   "r   r   r   .  s   € ÷ ^ñ ^¨ð ^°ñ ^r    c                óF  € V P                  \        4      '       g   R# \        P                  ;_uu_ 4        \        P                  P                  V 4      p\        T;'       d    \        V4      \        P                  9   4      uuRRR4       #   + '       g   i     R# ; i)z£True when the tool's server opted into ``supports_parallel_tool_calls`` (provenance
captured at registration, never the ambiguous ``mcp__{server}__{tool}`` shape).FN)	Ú
startswithr   r
   r¬   Ú_mcp_tool_server_namesr&   r*   r   r  )rä   r1   s   & r   Úis_mcp_tool_parallel_saferÔ  .  sd   € ð ×ÑÔ 4×5Ò5ÙÜ	��‹Ü×2Ñ2×6Ñ6°yÓAˆÜ�K×\Ð\¤K°Ó$<Ä×@\Ñ@\Ñ$\Ó]÷ 
��‹ús   ¶ABÂB 	Úinclude_runtimeTc               ó$   € V ^8„  d   QhRRRRRR/# )r   Ú
configuredzOptional[dict[str, dict]]rÕ  r*   r   z
list[dict]r   )r   s   "r   r   r   8  s$   € ÷ 7ñ 7Ð8ð 7ÐUYð 7Ðeoñ 7r    c               óö  aa€ V f2   \        4       ;_uu_ 4        \        P                  ! 4       p RRR4       M\        V 4      p V '       g   . # \        P
                  ! 4       o\        P                  ;_uu_ 4        R VV3R llp\        P                  P                  4        UUu/ uF!  w  r4V! V4      '       g   K  \        V4      VbK#  	  ppp\        P                   Uu0 uF  q2! V4      '       g   K  \        V4      kK  	  pp\        P                  P                  4        UUu/ uF!  w  r7V! V4      '       g   K  \        V4      VbK#  	  ppp\        P                  P                  4        UU	u/ uFO  w  r9S'       g   K  \        VS4      '       g   K#  V\        P                  9   g   K:  \        V4      \        V	4      bKQ  	  p
pp	RRR4       . pV P                  4        EFP  w  rÍ\!        V4      pXP#                  V4      pVRJ;'       d    VP$                  RJpV'       d   RM&V'       g   RMVX9   d   RMVX9   d   RM
VX
9   d   RMR	pR
TRRV9   d   VP#                  RR4      MRR^ RRRVR8H  RV/pV'       dz   RVR&   \'        VR4      '       d   \        VP(                  4      M\        VP*                  4      VR&   VP,                  '       d#   \        VP,                  P.                  4      VR&   M'VR8X  d   XV,          VR&   MVR8X  d   X
V,          VR&   VP1                  V4       EKS  	  V#   + '       g   i     EL
; iu uppi u upi u uppi u up	pi   + '       g   i     EL¥; i)aÕ  Per-server status dicts for banner/TUI: name, transport, tools, connected, disabled,
status (connected / disabled / connecting / failed / lazy / configured) and error for failed.
Reads cached runtime state only; never connects.

``lazy`` is a registered-but-not-spawned server (``lazy: true``, tools from the schema
cache): its tools are callable and the process starts on first use. Reporting it as
``configured`` (never registered) misreads a working setup (#111717).Nc               ó   € V ^8„  d   QhRR/# r�   r   )r   s   "r   r   Ú$get_mcp_status.<locals>.__annotate__I  s   € ÷ 	Zñ 	Z˜Dñ 	Zr    c                óF   <€ S;'       d    \         P                  ! V S4      # r‰   )r
   Ú_server_visible_in_scope)r<   r	  rÕ  s   &€€r   ÚvisibleÚget_mcp_status.<locals>.visibleI  s    ø€ ð #×YÐY¤u×'EÒ'EÀcÈ=Ó'YÐYr    rU  Údisabledr¡  rW  r¤   r×  rl   Ú	transportrî   Úhttprð   ÚtoolsFÚstatusTrÒ   ÚsamplingÚerror)rj   rt   r†  rn   r
   rL   r¬   rÇ   r  r   r­   r¯   rÛ   r   rÔ   rß   r   r&   r“   rô   rÒ   Ú_toolsÚ	_samplingÚmetricsrñ   )r×  rÕ  rÝ  r
  ÚsÚactive_serversr¡  ÚeÚconnect_errorsr  rM  r5  rl   r  Úenabledr}   r   rã  r  r	  s   &d                 @r   Úget_mcp_statusrî  8  só  ù€ ð ÒÜ ×"Õ"Ü ×1Ò1Ó3ˆJ÷ #Ð"ô ˜*Ó%ˆ
ßØˆ	Ü×-Ò-Ó/€MÜ	��‹÷	Zñ 	Zô 7<·n±n×6JÑ6JÔ6LÔ[Ñ6L©d¨aÑPWÐXY×PZœ/œ) A›,¨š/Ñ6LˆÑ[Ü,1×,DÒ,DÓSÑ,D qÈÐPQÏ
”l”i –lÑ,Dˆ
ÐSÜ6;×6RÑ6R×6XÑ6XÔ6ZÔiÑ6Z©d¨aÑ^eÐfg×^hœ/œ) A›,¨š/Ñ6ZˆÑiô 8=×7TÑ7T×7ZÑ7ZÔ7\ô ;Ñ7\©t¨qÜ(ô +Ü-BÀ1Àm×-Tô +àœu×9Ñ9Ñ9ô +”i “l¤C¨£FÒ*Ñ7\ˆ
ñ ;÷ 
ð" €FØ×%Ñ%×'‰	ˆÜ$ SÓ)ˆØ×#Ñ# DÓ)ˆØ˜TÐ!×@Ð@ f§n¡n¸DÐ&@ˆ÷ "&‘+¿W©:ÐZ^ÐblÔZlÉ,Ø#'¨>Ô#9‘xÈÐQ[ÔI[¹vÐamð 	à˜˜{ÈEÐUXÌL¨C¯G©G°KÀÔ,HÐ^eØ˜!˜[¨%°¸VÀzÑ=QÐS[Ð]cðeˆçØ!%ˆE�+ÑÜDKÈFÐTl×DmÒDmœc &×"?Ñ"?Ô@Ü#& v§}¡}Ó#5ð �'‰Nà××ÐÜ$(¨×)9Ñ)9×)AÑ)AÓ$B��jÑ!øØ�xÔØ+¨DÕ1ˆE�'ŠNØ�vÔØ'¨Õ-ˆE�'‰NØ�‰�e×ñ) (ð* €M÷] #×"Ð"üó \ùÚSùÛiùó;÷ 
�ˆúsq   ™L<Á:,M'Â&M
Â=M
ÃM'Ã"MÃ6MÄ#M'Ä(M
Ä?M
Å$M'Å3M!
ÆM!
ÆM!
Æ/M!
ÇM'Ì<M	ÍM'Í'M8	c               ó    € V ^8„  d   QhRRRR/# )r   rl   r2   r   r*   r   )r   s   "r   r   r   r  s   € ÷ ;ñ ; #ð ;¨$ñ ;r    c                óº  € \         P                  ;_uu_ 4        \         P                  P                  \	        V 4      4      pRRR4       Xe!   VP
                  f   VP                  '       g   R# VP                  '       d   RVP                  9   d   R# VP                  RJ ;'       g     VP                  P                  4       '       * #   + '       g   i     L�; i)a8  True when this profile's connection to *name* connected once in this process and is now
between sessions (degraded/parked) after a transient failure: the run task is alive and
self-probing, so the outage is environmental and heals on its own. A server that never
connected here (wrong URL, other profile's credentials) is not reconnecting, and neither is one
parked on a PERMANENT error (revoked credentials, endpoint gone): its self-probe fails the same
way every time, so callers must treat it as blocked rather than wait forever. Reads cached
state; never connects.NFÚ	permanent)
r
   r¬   rÇ   r&   r   r“   Ú_ever_connectedr²  ró   rö   )rl   r}   s   & r   Úmcp_server_reconnectingró  r  s“   € ô 
��‹Ü—‘×#Ñ#Ô$7¸Ó$=Ó>ˆ÷ 
à‚~˜Ÿ™Ò3¸6×;Q×;QÐ;QÙØ××Ð˜{¨f×.AÑ.AÔAÙØ�<‰<˜4Ð×:Ð: v§|¡|×'8Ñ'8Ó':Ô#:Ð:÷ 
�ús   ™)C
Ã
C	c               ó   € V ^8„  d   QhRR/# )r   r   zdict[str, list[tuple]]r   )r   s   "r   r   r   ƒ  s   € ÷  ñ  Ð 6ñ  r    c            	     ó˜  aaa€ \         P                  ! 4       '       g   / # \        4       ;_uu_ 4        \        P                  ! 4       ;'       g    / P                  4        U Uu/ uF  w  r\        V4      '       g   K  WbK  	  upp oRRR4       S'       g   / # \        P                  ! 4        / o. oVVV3R lp \        P                  ! V^xR7       \        P                  ! 4        S# u upp i   + '       g   i     Lq; i  \         d!   p\        P                  RT4        Rp?LVRp?ii ; i  \        P                  ! 4        i ; i)z�Connect each enabled server, list ``(tool_name, description)``, disconnect; nothing is
registered and failed servers are omitted.Nc               “  óš  <"  € SP                  4        U Uu. uFD  w  r\        P                  ! \        W4      VP	                  R \
        P                  4      R7      NKF  	  pp p\        P                  ! VRR/ G Rj  x€L
 p\        SV4       Fƒ  w  r\        V\        4      '       d   \        P                  RW4       K3  SP                  V4       VP                   Uu. uF%  qUP                  \!        VRR4      ;'       g    R3NK'  	  upSV &   K…  	  \        P                  ! R S 4       RR/ G Rj  x€L
  R# u upp i  LÄu upi  L5i)	rÌ   r˜   r-  TNz$Probe: failed to connect to '%s': %sÚdescriptionrµ   c              3  ó@   "  € T F  qP                  4       x € K  	  R # 5ir‰   )rz   )r¸   ré  s   & r   rº   Ú=probe_mcp_server_tools.<locals>._probe_all.<locals>.<genexpr>›  s   é € ÐD±^°Ÿz™zŸ|˜|³^ùs   ‚)r  rT   rò   r‚   r&   r
   rØ   r1  r2  r)   r(   r+   r{   rñ   ræ  rl   rÜ   )	rl   r  ÚcorosÚoutcomesÚoutcomeÚtrí  Úprobed_serversr5  s	         €€€r   Ú
_probe_allÚ*probe_mcp_server_tools.<locals>._probe_all�  s  øé € ð #*§-¡-¤/ô3á"1‘Y�Tô ×!Ò!¤/°$Ó"<Ø*-¯'©'Ð2CÄU×EcÑEcÓ*d÷fá"1ð 	ñ 3ô !Ÿš¨ÐGÀ$ÑG×GˆÜ  ¨(Ö3‰MˆDÜ˜'¤9×-Ò-Ü—‘ÐCÀTÔSÙØ×!Ñ! 'Ô*ØSZ×SaÒSaÓbÑSaÈaŸV™V¤W¨Q°¸rÓ%B×%HÐ%HÀbÓIÑSaÑbˆF�4‹Lñ 4ô �nŠnÑD±^ÓDÐ]ÐX\Ñ]×]Ò]ùó3ñ Hùò cÙ]ùsB   ƒE—A
D<Á!EÁ=EÁ>A"EÃ "EÄEÄ*EÄ5E	Ä6EÅEr˜   zMCP probe failed: %s)r
   rk  rj   rt   r†  r  r   r›   r×   rž   r(   r+   r{   rn  Ú_stop_mcp_loop_if_idle)r
  r  rÿ  r    rí  rþ  r5  s       @@@r   Úprobe_mcp_server_toolsr  ƒ  só   ú€ ô × Ò ×"Ò"Øˆ	Ü	×	Õ	Ü%,×%=Ò%=Ó%?×%EÐ%EÀ2×$LÑ$LÔ$NÔhÑ$N™D˜AÔRdÐef×Rg”4�1’4Ñ$NÒhˆ÷ 
çØˆ	Ü	×ÒÔØ%'€FØ02€N÷^ð,Ü×Ò˜z°3Õ7ô 	×)Ò)Ô+Ø€Mùó5 i÷ 
×	ûô. ô 2Ü�‰Ð+¨S×1Ñ1ûð2ûô 	×)Ò)Õ+úsM   ³1C1Á$C+
Á>C+
ÂC1Â<D Ã+C1Ã1D	ÄD/ÄD*Ä%D2 Ä*D/Ä/D2 Ä2E	c               ó   € V ^8„  d   QhRR/# r�   r   )r   s   "r   r   r   ¦  s   € ÷ 2ñ 2 $ñ 2r    c                 ó¢   € \         P                  ;_uu_ 4        \        \         P                  4      uuRRR4       #   + '       g   i     R# ; i)z‚True if any MCP server has registered TOOLS (not merely connected), so the per-turn
refresh hook stays idle for zero-tool servers.N)r
   r¬   r*   rÓ  r   r    r   Úhas_registered_mcp_toolsr  ¦  s'   € ô 
��‹Ü”E×0Ñ0Ó1÷ 
��‹ús	   ™=½A	c               ó   € V ^8„  d   QhRR/# )r   r   rs   r   )r   s   "r   r   r   ­  s   € ÷ :ñ :¨ñ :r    c                 ó¾   € \         P                  ;_uu_ 4        \        \         P                  P	                  4       4      uuRRR4       #   + '       g   i     R# ; i)uT   Server names that registered at least one tool (live, filtered â€” not config.yaml).N)r
   r¬   rs   rÓ  Úvaluesr   r    r   Úget_registered_mcp_server_namesr	  ­  s.   € ä	��‹Ü”5×/Ñ/×6Ñ6Ó8Ó9÷ 
��‹ús   ™'AÁA	r‰   )]Ú__conditional_annotations__Ú__doc__Ú
__future__r   rT   ÚloggingÚ	threadingr9   Ú
contextlibr   Úpathlibr   Útypingr   r   r   r   r	   Útools.mcp_tool_commonr
   r   r   râ  r   rt   r   rª   r   rn  r   r›   r   rÝ   Útools.mcp_tool_schemar   Útools.mcp_tool_scoper   r   r   r   r   Ú	getLoggerr+   r'   r.   r?   rC   rH   rO   rX   re   rZ   Ú__annotations__rV   rj   r‚   r¡   r§   r±   rÁ   rÄ   rÉ   rå   ré   rÏ   r  r!  r6  rL  rX  rd  rp  rm  r  r�  r¢  r¨  rœ  r¯  r´  r¸  r¼  r¿  ÚLockrÆ  rÍ  r›  rÔ  rî  ró  r  r  r	  )r
  s   @r   Ú<module>r     s£  øðô[õ
 #ã Û Û Û Ý %Ý ß 3Õ 3ß KÑ KÝ ,Ý ,Ý 2Ý (Ý 8Ý 6ß oÕ oà	×	Ò	Ð+Ó	,€ð
 "#Ð õõHõ5õ@õ:ò jð" #Ð Ø)+Ð Ð&Ó +õ,ð( ñ"ó ð"õ&!õHõ6DõõLõ%õDõ*=õZ'õ*õB'õT=õD(õ>&!ðRJ°1ð JØ+,÷Jõõ 3õ(0ò,÷.6õr4õB	õgõNõ
:õXõ>õSð —’Ó €õ%õPFõ^ñ7Ð\`÷ 7ð 7õt;õ" õF2÷:r    