+
    ��·j±g  ã                   ó  € R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	t	^ RI
t
^ RIt^ RIt^ RIt^ RIt]P                  ! ]4      P#                  4       P$                  t]	P(                  P+                  ^ ]! ]4      4       ^ RIt^ RIt]	P2                  tRtRt ! R R]P:                  P<                  4      t ! R R]P@                  4      t!]P$                  R,          t" ! R	 R
4      t#R t$ ! R R4      t%Rt&]PN                  ! ]"R,          R,          R,          PQ                  4       ]&4       ! R R]%]P@                  4      4       t)]PN                  ! ]"R,          R,          PQ                  4       ]&4       ! R R]%]P@                  4      4       t*]PN                  ! ]"R,          R,          PQ                  4       ]&4       ! R R]%]P@                  4      4       t+ ! R R]P@                  4      t,]-R8X  d   ]P\                  ! 4        R# R# )z÷Tests for the MCP bridge:  python3 -m unittest scripts/test_mcp_bridge.py

Starts serve.py's server with the bridge on a free port, the demo stdio server, command-line
tools and a mock Streamable HTTP server, and talks to them like the page does.
Na  
import json, sys
for line in sys.stdin:
    msg = json.loads(line)
    if 'id' not in msg: continue
    sys.stdout.write('y' * 3_000_000 + '\n')
    sys.stdout.write(json.dumps({'jsonrpc': '2.0', 'id': msg['id'], 'result': {'ok': True}}) + '\n')
    sys.stdout.flush()
a­  
import json, sys
for line in sys.stdin:
    msg = json.loads(line)
    if 'id' not in msg: continue
    sys.stdout.write(json.dumps({'jsonrpc': '2.0', 'method': 'notifications/message', 'server': 'tools',
                                 'params': {'level': 'info', 'data': 'spoofed', 'server': 'tools'}}) + '\n')
    sys.stdout.write(json.dumps({'jsonrpc': '2.0', 'id': msg['id'], 'result': {}}) + '\n')
    sys.stdout.flush()
c                   ó0   a € ] tR t^1t o RtR tR tRtV tR# )ÚMockHttpMcpzKA tiny Streamable HTTP MCP server: JSON for initialize, SSE for tools/list.c                ó   € R # ©N© )ÚselfÚargss   &*Ú//work/data/stt/webtt/scripts/test_mcp_bridge.pyÚlog_messageÚMockHttpMcp.log_message3   s   € Ùó    c                óÈ  € \         P                  ! V P                  P                  \	        V P
                  R ,          4      4      4      pRV9  d$   V P                  ^Ê4       V P                  4        R# VR,          R8X  dÂ   \         P                  ! RRRVR,          RRR	R
/ RRRRR///4      P                  4       pV P                  ^È4       V P                  RR4       V P                  RR4       V P                  R \        \        V4      4      4       V P                  4        V P                  P                  V4       R# V P
                  P                  R4      R8w  g!   V P
                  P                  R4      R	8w  d$   V P                  R4       V P                  4        R# RRRRRRRRR//RRRVR,          RRRRRRR //.//.pR!P!                  R" V 4       4      P                  4       pV P                  ^È4       V P                  RR#4       V P                  R \        \        V4      4      4       V P                  4        V P                  P                  V4       R# )$úContent-LengthÚidNÚmethodÚ
initializeÚjsonrpcú2.0ÚresultÚprotocolVersionú
2025-06-18ÚcapabilitiesÚ
serverInfoÚnameÚmockÚversionÚ1úContent-Typeúapplication/jsonzMcp-Session-Idzsess-1zMCP-Protocol-Versioné�  únotifications/messageÚparamsÚlevelÚinfoÚdataúfrom sseÚtoolsÚremoteÚinputSchemaÚtypeÚobjectÚ c              3   óV   "  € T F  pR \         P                  ! V4       R2x € K!  	  R# 5i)údata: z

N)ÚjsonÚdumps)Ú.0Úes   & r	   Ú	<genexpr>Ú&MockHttpMcp.do_POST.<locals>.<genexpr>K   s!   é € ÐD¹V¸˜¤§
¢
¨1£˜¨dÕ3»Vùs   ‚')ztext/event-stream)r.   ÚloadsÚrfileÚreadÚintÚheadersÚsend_responseÚend_headersr/   ÚencodeÚsend_headerÚstrÚlenÚwfileÚwriteÚgetÚjoin)r   ÚmsgÚbodyÚeventss   &   r	   Údo_POSTÚMockHttpMcp.do_POST6   s_  € Ü�jŠj˜Ÿ™Ÿ™¬¨T¯\©\Ð:JÕ-KÓ)LÓMÓNˆØ�sŒ?Ø×Ñ˜sÔ#Ø×ÑÔÙØˆx�=˜LÔ(Ü—:’:˜y¨%°°s¸4µyÀ(ÐM^Ð`lÐn|ð  Að  COð  RXð  Z`ð  bkð  mpð  Qqð  Mrð  só  t÷  {ñ  {ó  }ˆDØ×Ñ˜sÔ#Ø×Ñ˜^Ð-?Ô@Ø×ÑÐ-¨xÔ8Ø×ÑÐ-¬s´3°t³9«~Ô>Ø×ÑÔØ�J‰J×Ñ˜TÔ"ÙØ�<‰<×ÑÐ,Ó-°Ô9¸T¿\¹\×=MÑ=MÐNdÓ=eÐiuÔ=uØ×Ñ˜sÔ#Ø×ÑÔÙØ˜e XÐ/FÈÐSZÐ\bÐdjÐlvÐRwÐxØ˜e T¨3¨t­9°hÀÈFÐT\Ð^kÐntÐv~Ðmð  LAð  KBð  ACð  DðEˆà�w‰wÑD¹VÓDÓD×KÑKÓMˆØ×Ñ˜3ÔØ×Ñ˜Ð)<Ô=Ø×ÑÐ)¬3¬s°4«y«>Ô:Ø×ÑÔØ�
‰
×Ñ˜Ör   r   N)	Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r
   rF   Ú__static_attributes__Ú__classdictcell__©Ú__classdict__s   @r	   r   r   1   s   ø‡ € ÙUò÷ð r   r   c                   ó  a € ] tR t^St o ]R 4       t]R 4       t]R#R l4       tR$R ltR t	R%R lt
R&R ltR	 tR
 tR tR tR tR tR tR tR tR tR tR tR tR tR tR tR tR'R ltR tR tR t R t!R t"R  t#R! t$R"t%V t&R# )(Ú
BridgeTestc                óà  € \         P                  ! 4       V n        \        P                  P                  RJ\        4      V n        \        P                  ! V P                  P                  RR7      P                  4        \        \        \        R,          4      .pRRRRRR	V/RR
RRR	VR^/RRRRRRV P                  P                  ^,           R2/RRRRR	\        R\         ./RRRRR	\        R\"        ./RRRRRRRRRR	\        RRR.RR R!R"R#R R$//R%R#.//RR&R	\        RR'R(R)R*./RR+R	\        RR,.R-R#/RR.R	\        RR/./RR0R	\        RR1.RR2/RR3R	R4./RR5R	\        RR6./RR7R	\        RR'R8./RR9R	\        RR'R:.R;R/.	/./p\$        P&                  ! V P                  P(                  4      R<,          pVP+                  \,        P.                  ! V4      R=R>7       R?\0        n        R@\0        n        \0        P6                  ! V^ 4      V n        \:        P<                  ! ^ V P8                  R RRA7      V n        V P>                  P                  ^,          V n         V P@                  V P8                  n         \        P                  ! V P>                  P                  RR7      P                  4        V PC                  RBRCRDRE7      w  rEpVPE                  RFRG4      PG                  RH4      ^ ,          V n$        RI# )Kú	127.0.0.1T©ÚtargetÚdaemonúmcp_demo_server.pyÚserversr   Údemor   u   ç¤ºä¾‹ÚcommandÚquicku   ä¸€ç§’è¶…æ—¶Ú	timeout_sr'   u   è¿œç¨‹Úurlzhttp://127.0.0.1:z/mcpÚnoisyu   è¶…é•¿è¾“å‡ºz-cÚspoofu   å†’å……r&   u	   å‘½ä»¤è¡ŒÚcliÚlengthÚdescriptionzLength of the textz#import sys; print(len(sys.argv[1]))z{text}Úinput_schemar)   r*   Ú
propertiesÚtextÚstringÚrequiredr   zimport sys; print(sys.argv[1:])Úfixedz--n={n}z{flag}Úupperz+import sys; print(sys.stdin.read().upper())ÚstdinÚexit3z7import sys; print("oops", file=sys.stderr); sys.exit(3)Úsleepyzimport time; time.sleep(5)g      à?Úmissingz/nonexistent/programÚfloodz-import sys; sys.stdout.write("x" * 5_000_000)Úgrepz	{pattern}Úcalcz{n}Úallow_option_valueszmcp.config.jsonúutf-8)Úencodingi@B i † )ÚhostÚquietÚGETú	/www/mcp/F©Úcookieú
Set-Cookier+   Ú;N)rT   é    )%ÚtempfileÚTemporaryDirectoryÚtmpÚhttpÚserverÚThreadingHTTPServerr   r   Ú	threadingÚThreadÚserve_foreverÚstartÚPYr=   ÚHEREÚserver_addressÚLONG_LINE_SERVERÚSPOOF_SERVERÚpathlibÚPathr   Ú
write_textr.   r/   Ú
mcp_bridgeÚMAX_LINEÚ
MAX_OUTPUTÚBridgeÚbridgeÚserveÚmake_serverÚhttpdÚportÚrequestrA   Úsplitrz   )ÚclsrZ   ÚconfigÚpathÚstatusr8   Ú_s   &      r	   Ú
setUpClassÚBridgeTest.setUpClassT   s  € ä×-Ò-Ó/ˆŒÜ—;‘;×2Ñ2Ð3CÄ[ÓQˆŒÜ×Ò §¡× 6Ñ 6¸tÔD×JÑJÔLÜ”CœÐ3Õ3Ó4Ð5ˆØØ�6˜6 8¨Y¸Ð=Ø�7˜F N°I¸tÀ[ÐRSÐTØ�8˜V X¨uÐ8IÈ#Ï(É(×JaÑJaÐbcÕJdÐIeÐeiÐ6jÐkà�7˜F N°IÄÀDÔJZÐ?[Ð\Ø�7˜F H¨i¼"¸dÄLÐ9QÐRØ�7˜F K°Ø˜ =Ð2FÈ	ÔTVÐX\ð  _Dð  FNð  TOØ &¨(°LÀ6ÈFÐT\ÐK]ÐB^Ð`jÐmsÐltÐ!uðwà˜ ¬R°Ð7XÐZaÐclÐnvÐ,wÐxØ˜ )¬b°$Ð8eÐ-fÐhoÐqwÐxØ˜ )¬b°$Ð8qÐ-rÐsØ˜ 9¬r°4Ð9UÐ.VÐXcÐehÐiØ˜ IÐ0FÐ/GÐHØ˜ )¬b°$Ð8gÐ-hÐiØ˜ ¬R°Ð7XÐZeÐ,fÐgØ˜ ¬R°Ð7XÐZ_Ð,`ÐbwÐy}Ð~ð9ð ð
ð ˆô( �|Š|˜CŸG™GŸL™LÓ)Ð,=Õ=ˆØ�‰œŸ
š
 6Ó*°WˆÔ=Ø'Œ
ÔØ 'Œ
ÔÜ×&Ò& t¨QÓ/ˆŒ
Ü×%Ò% a¨¯©¸+ÈTÔRˆŒ	Ø—9‘9×+Ñ+¨AÕ.ˆŒØŸ(™(ˆ�
‰
ŒÜ×Ò §	¡	× 7Ñ 7ÀÔE×KÑKÔMØ Ÿ[™[¨°ÀE˜[ÓJÑˆ˜Ø—[‘[ ¨rÓ2×8Ñ8¸Ó=¸aÕ@ˆŽ
r   c                óÖ   € V P                   P                  4        V P                  P                  4        V P                  P                  4        V P                  P                  4        R # r   )r—   Úshutdownr”   r   r€   Úcleanup)r›   s   &r	   ÚtearDownClassÚBridgeTest.tearDownClassz   s@   € à�	‰	×ÑÔØ�
‰
×ÑÔØ�‰×ÑÔØ�‰�‰Ör   Nc                ó|  € \         P                  P                  R V P                  VR7      pRT;'       g    RV P                   2/p	V'       d#   \	        V RR4      '       d   V P
                  V	R&   V'       d   WiR&   Rp
VeB   \        V\        4      '       d   TM\        P                  ! V4      P                  4       p
RV	R	&   VP                  WW©R
7       VP                  4       pVP                  4       P                  RR4      pVP                  4        VP                   \#        VP%                  4       4      V3# )rT   ©ÚtimeoutÚHostú
localhost:rz   NÚCookieÚOriginr   r   )rD   r8   rs   Úreplace)r�   ÚclientÚHTTPConnectionr˜   Úgetattrrz   Ú
isinstancer=   r.   r/   r;   r™   Úgetresponser6   ÚdecodeÚcloserž   ÚdictÚ
getheaders)r›   r   r�   rD   rz   ru   Úoriginr©   Úconnr8   r$   Úresprf   s   &&&&&&&&     r	   r™   ÚBridgeTest.request�   sþ   € ä�{‰{×)Ñ)¨+°s·x±xÈÐ)ÓQˆØ˜4×:Ð: Z°·±¨zÐ#:Ð;ˆß”g˜c 8¨T×2Ò2Ø #§
¡
ˆG�HÑßØ &�HÑØˆØÒÜ& t¬S×1Ò1‘D´t·z²zÀ$Ó7G×OÑOÓQˆDØ&8ˆG�NÑ#Ø�‰�V¨ˆÔ>Ø×ÑÓ!ˆØ�y‰y‹{×!Ñ! '¨9Ó5ˆØ�
‰
ŒØ�{‰{œD §¡Ó!2Ó3°TÐ9Ð9r   c                ó®   € R RRV/pV'       g   WFR&   Ve   W6R&   V P                  RRV R2V4      w  rxp	Yy'       d   \        P                  ! V	4      3# R3# )	r   r   r   r   Nr!   ÚPOSTú	/api/mcp/z/rpc)r™   r.   r4   )
r   r‚   r   r!   ÚmidÚnotificationrC   rž   rŸ   rf   s
   &&&&&&    r	   ÚrpcÚBridgeTest.rpc“   sd   € Ø˜% ¨6Ð2ˆßØ�‰IØÒØ"�‰MØŸ,™, v°¸6¸(À$Ð/GÈÓM‰ˆ�4Ø®DœŸ
š
 4Ó(Ð;Ð;°dÐ;Ð;r   c                óÎ   € V P                  VR RRR/ RRRRR//4      w  r#V P                  V^ÈV4       V P                  V P                  VR	R
R7      ^ ,          ^Ê4       VR,          # )r   r   r   r   Ú
clientInfor   Útestr   Ú0znotifications/initializedT)rÀ   r   ©rÁ   ÚassertEqual)r   r‚   rž   Úreplys   &&  r	   r   ÚBridgeTest.initializeœ   s’   € ØŸ™ ¨Ð8IÈ<ÐYgÐikÐmyð  }Cð  EKð  MVð  X[ð  |\ð  8]ó  ^‰ˆØ×Ñ˜  eÔ,Ø×Ñ˜Ÿ™ &Ð*EÐTX˜ÓYÐZ[Õ\Ð^aÔbØ�X�Ðr   c                óî  aa€ \         P                  ! 4       o\        P                  P	                  RV P
                  ^R7      pTP                  RV'       d   RV R2MRRRV P
                   2R	V P                  /R
7       VP                  4       oV P                  SP                  ^È4       VV3R lp\        P                  ! VRR7      P                  4        V P                  VP                  4       S# )z~Subscribe to a server's events (or, with no server, to every server's events on
one stream); returns a queue of parsed events.rT   r¨   rw   r¾   z/eventsú/api/mcp/eventsrª   r«   r¬   ©r8   c                  ó  <€  S Fg  p V P                  4       P                  R 4      pVP                  R4      '       g   K;  SP                  \        P
                  ! VR,          4      4       Ki  	  R#   \         d     R# i ; i)Ú
r-   :é   NNN)r´   ÚrstripÚ
startswithÚputr.   r4   ÚOSError)ÚrawÚlineÚqrº   s     €€r	   r6   ÚBridgeTest.events.<locals>.read«   sd   ø€ ðÛ�CØŸ:™:›<×.Ñ.¨tÓ4�DØ—‘ x×0Ô0ØŸ™œdŸjšj¨¨b­Ó2Ö3ó  øô ô Úðús   ƒ8A2 Á 0A2 Á2BÂ BTrU   )ÚqueueÚQueuer�   r¯   r°   r˜   r™   rz   r³   rÈ   rž   r„   r…   r‡   Ú
addCleanuprµ   )r   r‚   r¹   r6   r×   rº   s   &&  @@r	   rE   ÚBridgeTest.events¢   sï   ù€ ô �KŠK‹MˆÜ�{‰{×)Ñ)¨+°t·y±yÈ"Ð)ÓMˆØ�‰�U¿6˜i¨ x¨wÑ7ÐGXÐciÐmwÐx|÷  yBñ  yBð  xCð  lDð  FNð  PT÷  P[ñ  P[ð  c\ˆô  	]Ø×ÑÓ!ˆØ×Ñ˜Ÿ™ cÔ*ö	ô 	×Ò ¨TÔ2×8Ñ8Ô:Ø�‰˜Ÿ
™
Ô#Øˆr   c                ó  € \         P                   ! 4       V,           p\         P                   ! 4       V8  d&    VP                  R R7      pT! T4      '       g   K=  T# V P	                  R4       R#   \        P                   d     Kj  i ; i)çš™™™™™É?r¨   zexpected event did not arriveN)ÚtimerA   rÙ   ÚEmptyÚfail)r   r×   Úpredr©   Úendr1   s   &&&&  r	   Úwait_forÚBridgeTest.wait_for·   sj   € Ü�iŠi‹k˜GÕ#ˆÜ�iŠi‹k˜CÔðØ—E‘E #�EÓ&�ñ �A�wŒwØ�Ø�	‰	Ð1Ö2øô	 —;‘;ô Úðús   ¸A/ Á/BÂBc                ó®   € V P                  V P                  P                  R 4      4       V P                  RRRRR7      w  rpV P	                  RV4       R# )z
mcp_token=rw   rx   Fzevil.example:80)rz   ru   r{   N)Ú
assertTruerz   rÒ   r™   ÚassertNotIn)r   rŸ   r8   s   &  r	   Ú7test_token_cookie_is_issued_to_local_page_requests_onlyÚBBridgeTest.test_token_cookie_is_issued_to_local_page_requests_onlyÄ   sH   € Ø�‰˜Ÿ™×.Ñ.¨|Ó<Ô=ØŸ™ U¨KÀÐL]˜Ó^‰ˆ�AØ×Ñ˜ wÖ/r   c                ó²   € V P                  R RRR7      w  rpV P                  VR4       V P                  R\        P                  ! V4      R,          4       R# )rw   ú/api/mcp/serversFry   é“  u   ä»¤ç‰ŒÚerrorN)r™   rÈ   ÚassertInr.   r4   )r   rž   rŸ   rf   s   &   r	   Ú+test_requests_without_the_token_are_refusedÚ6BridgeTest.test_requests_without_the_token_are_refusedÉ   sG   € ØŸ,™, uÐ.@È˜,ÓO‰ˆ�4Ø×Ñ˜ Ô%Ø�‰�h¤§
¢
¨4Ó 0°Õ 9Ö:r   c                ó$  € V P                  V P                  R RRR7      ^ ,          R4       V P                  V P                  R RRR7      ^ ,          RR4       V P                  V P                  R RRV P                   2R7      ^ ,          ^È4       R	# )
rw   rì   úhttps://evil.example©r¸   rí   úevil.example©ru   zDNS rebinding: wrong Hostzhttp://localhost:N)rÈ   r™   r˜   ©r   s   &r	   Ú5test_requests_from_other_origins_or_hosts_are_refusedÚ@BridgeTest.test_requests_from_other_origins_or_hosts_are_refusedÎ   s‹   € Ø×Ñ˜Ÿ™ eÐ-?ÐH^˜Ó_Ð`aÕbÐdgÔhØ×Ñ˜Ÿ™ eÐ-?Àn˜ÓUÐVWÕXÐZ]Ð_zÔ{Ø×Ñ˜Ÿ™ eÐ-?ÐJ[Ð\`×\eÑ\eÐ[fÐHg˜ÓhÐijÕkÐmpÖqr   c                ó`  € V P                  V P                  R RR4      ^ ,          R4       V P                  V P                  R RR4      ^ ,          R4       V P                  V P                  R RRRR^R	R
/4      ^ ,          R4       V P                  V P                  RR4      ^ ,          R4       R# )r½   ú/api/mcp/demo/rpcznot jsonr   z[]z/api/mcp/nope/rpcr   r   r   r   Úpingi”  rw   z/api/mcp/demo/unknownN©rÈ   r™   r÷   s   &r	   Útest_bad_requestsÚBridgeTest.test_bad_requestsÓ   s    € Ø×Ñ˜Ÿ™ fÐ.AÀ:ÓNÈqÕQÐSVÔWØ×Ñ˜Ÿ™ fÐ.AÀ4ÓHÈÕKÈSÔQØ×Ñ˜Ÿ™ fÐ.AÀIÈuÐVZÐ\]Ð_gÐioÐCpÓqÐrsÕtÐvyÔzØ×Ñ˜Ÿ™ eÐ-DÓEÀaÕHÈ#ÖNr   c                óŽ  € \         P                  P                  R V P                  ^
R7      pVP	                  RRRR7       RRV P                   23RV P
                  3R3 F  w  r#VP                  W#4       K  	  VP                  4        V P                  VP                  4       P                  R	4       VP                  4        R
# )rT   r¨   r½   rû   T)Ú	skip_hostrª   r«   r¬   r   N)r   Ú
notanumber)r�   r¯   r°   r˜   Ú
putrequestrz   Ú	putheaderÚ
endheadersrÈ   r³   rž   rµ   )r   r¹   ÚkÚvs   &   r	   Ú,test_malformed_content_length_gets_an_answerÚ7BridgeTest.test_malformed_content_length_gets_an_answerÙ   s    € Ü�{‰{×)Ñ)¨+°t·y±yÈ"Ð)ÓMˆØ�‰˜Ð 3¸tˆÔDØ 
¨4¯9©9¨+Ð6Ð7¸(ÀDÇKÁKÐ9PÐRrÓs‰DˆAØ�N‰N˜1Ö ñ tà�‰ÔØ×Ñ˜×)Ñ)Ó+×2Ñ2°CÔ8Ø�
‰
Žr   c                óB  € \         P                  P                  R V P                  ^
R7      pVP	                  RRRRV P                   2RR/R7       V P                  VP                  4       P                  R	4      4       VP                  4        \         P                  P                  R V P                  ^
R7      pVP	                  RRRRV P                   2R
R/R7       V P                  VP                  4       P                  R	4      4       VP                  4        R# )rT   r¨   rw   rx   rª   r«   zSec-Fetch-Sitez
cross-siterÍ   r{   r­   ró   N)	r�   r¯   r°   r˜   r™   ÚassertIsNoner³   Ú	getheaderrµ   )r   r¹   s   & r	   Ú0test_cookie_is_not_issued_to_cross_site_requestsÚ;BridgeTest.test_cookie_is_not_issued_to_cross_site_requestsâ   sæ   € Ü�{‰{×)Ñ)¨+°t·y±yÈ"Ð)ÓMˆØ�‰�U˜K°&¸JÀtÇyÁyÀkÐ:RÐTdÐfrÐ1sˆÔtØ×Ñ˜$×*Ñ*Ó,×6Ñ6°|ÓDÔEØ�
‰
ŒÜ�{‰{×)Ñ)¨+°t·y±yÈ"Ð)ÓMˆØ�‰�U˜K°&¸JÀtÇyÁyÀkÐ:RÐT\Ð^tÐ1uˆÔvØ×Ñ˜$×*Ñ*Ó,×6Ñ6°|ÓDÔEØ�
‰
Žr   c                óì   € V P                  R R4      w  rpV P                  V^È4       T P                  \        P                  ! V4       Uu. uF  qDR,          VR,          3NK  	  up. RO4       R# u upi )rw   rì   r   ÚkindN))rZ   Ústdio)r\   r  )r'   r�   )r_   r  )r`   r  )r&   ra   )r™   rÈ   r.   r4   )r   rž   rŸ   rf   Úss   &    r	   Útest_server_listÚBridgeTest.test_server_listì   sg   € ØŸ,™, uÐ.@ÓA‰ˆ�4Ø×Ñ˜ Ô%Ø×Ñ¼¿
º
À4Ô8HÓIÑ8H°1˜T�7 A f¥IÓ.Ñ8HÑIò  LAö  	BùÒIs   ÁA1c           	     ó˜  € V P                  4       pV P                  R 4       V P                  R RRRRR^//^R7       V P                  VR 4      pV P	                  VR,          R 4       V P                  R	R
^R7       V P                  VR 4      pV P	                  VR,          R	R4       V P	                  VR,          R,          R4       R# )rZ   ú
tools/callr   ÚnotifyÚ	argumentsÚsteps©r¿   c                 ó`   € V R ,          R8H  ;'       d    V R,          P                  R4      R8H  # ©r)   Úmessager   r    ©rA   ©r1   s   &r	   Ú<lambda>Ú^BridgeTest.test_one_stream_carries_every_servers_events_tagged_by_the_bridge.<locals>.<lambda>÷   s.   € ¨!¨F­)°yÑ*@×*zÐ*zÀQÀyÅ\×EUÑEUÐV^ÓE_ÐczÑEzÐ*zr   r‚   r`   rü   c                 ó€   € V R ,          R8H  ;'       d,    V R,          P                  R/ 4      P                  R4      R8H  # )r)   r  r!   r$   Úspoofedr  r  s   &r	   r   r!  ú   s=   € ¨Q¨v­Y¸)Ñ-C×-Ð-ÈÈ)Í×HXÑHXÐYaÐceÓHf×HjÑHjÐkqÓHrÐvÑHÐ-r   z.the tag comes from the bridge, not the messager  r&   N)rE   r   rÁ   rä   rÈ   )r   r×   rZ   r#  s   &   r	   ÚAtest_one_stream_carries_every_servers_events_tagged_by_the_bridgeÚLBridgeTest.test_one_stream_carries_every_servers_events_tagged_by_the_bridgeó   s¹   € Ø�K‰K‹MˆØ�‰˜ÔØ�‰�˜¨°¸+ÈÐQRÀ|Ð'TÐZ[ˆÔ\Ø�}‰}˜QÑ zÓ{ˆØ×Ñ˜˜h�¨Ô0Ø�‰�˜& aˆÔ(Ø—-‘- Ñ#ó  AˆØ×Ñ˜ Õ*¨GÐ5eÔfØ×Ñ˜ Õ+¨HÕ5°wÖ?r   c                ó¤   € V P                  R 4      pV P                  R R^R7       V P                  V P                  VR 4      R,          R 4       R# )r`   rü   r  c                 ó   € V R ,          R8H  # )r)   r  r   r  s   &r	   r   ÚCBridgeTest.test_per_server_streams_are_tagged_too.<locals>.<lambda>  s   € °A°fµIÀÒ4Jr   r‚   N©rE   rÁ   rÈ   rä   ©r   r×   s   & r	   Ú&test_per_server_streams_are_tagged_tooÚ1BridgeTest.test_per_server_streams_are_tagged_tooþ   sD   € Ø�K‰K˜Ó ˆØ�‰�˜& aˆÔ(Ø×Ñ˜Ÿ™ qÑ*JÓKÈHÕUÐW^Ö_r   c                ó  € V P                  V P                  R RRR7      ^ ,          R4       V P                  V P                  R RRR7      ^ ,          R4       V P                  V P                  R RRR7      ^ ,          R4       R	# )
rw   rÌ   Fry   rí   ró   rô   rõ   rö   Nrý   r÷   s   &r	   Ú2test_merged_stream_needs_the_token_and_this_originÚ=BridgeTest.test_merged_stream_needs_the_token_and_this_origin  sw   € Ø×Ñ˜Ÿ™ eÐ->Àu˜ÓMÈaÕPÐRUÔVØ×Ñ˜Ÿ™ eÐ->ÐG]˜Ó^Ð_`ÕaÐcfÔgØ×Ñ˜Ÿ™ eÐ->À^˜ÓTÐUVÕWÐY\Ö]r   c                óÀ  € V P                  R 4      pV P                  VR,          R,          R4       V P                  R R^R7      w  r#V P                  \        VR,          R,          4      ^4       V P                  VR,          R,          R	4       V P                  R R
RRRR^R^(//^R7      w  r$V P                  VR,          R,          ^ ,          R,          R4       R# )rZ   r   r   ú
webtt-demoú
tools/listr  r   r&   Ú
nextCursorÚ3r  Úaddr  ÚaÚbÚcontentrf   Ú42N)r   rÈ   rÁ   r>   )r   r   rŸ   ÚpageÚaddeds   &    r	   Ú(test_stdio_handshake_pagination_and_callÚ3BridgeTest.test_stdio_handshake_pagination_and_call
  sÉ   € Ø—‘ Ó(ˆØ×Ñ˜ Õ-¨fÕ5°|ÔDØ—(‘(˜6 <°Q�(Ó7‰ˆØ×Ñœ˜T (�^¨GÕ4Ó5°qÔ9Ø×Ñ˜˜h�¨Õ5°sÔ;Ø—8‘8˜F L°6¸5À+ÐPSÐUVÐX[Ð]_ÐO`Ð2aÐgh�8Ói‰ˆØ×Ñ˜˜x�¨Õ3°AÕ6°vÕ>ÀÖEr   c           	     óð   € V P                  R 4      pV P                  RR4       V P                  R 4       V P                  VR 4       V P	                  R RRRRR^//^R	7       V P                  VR
 4       R# )rZ   r½   z/api/mcp/demo/restartc                 óB   € V R ,          R8H  ;'       d    RV R,          9   # )r)   ÚstderrÚreadyrÖ   r   r  s   &r	   r   ÚWBridgeTest.test_stdio_notifications_and_stderr_reach_the_event_stream.<locals>.<lambda>  s!   €  1 V¥9°Ñ#8×#QÐ#Q¸WÈÈ&Í	Ñ=QÐ#Qr   r  r   r  r  r  r  c                 ó`   € V R ,          R8H  ;'       d    V R,          P                  R4      R8H  # r  r  r  s   &r	   r   rB    s-   €  1 V¥9°	Ñ#9×#sÐ#s¸aÀ	½l×>NÑ>NÈxÓ>XÐ\sÑ>sÐ#sr   N)rE   r™   r   rä   rÁ   r*  s   & r	   Ú:test_stdio_notifications_and_stderr_reach_the_event_streamÚEBridgeTest.test_stdio_notifications_and_stderr_reach_the_event_stream  sl   € Ø�K‰K˜ÓˆØ�‰�VÐ4Ô5Ø�‰˜ÔØ�‰�aÑQÔRØ�‰�˜¨°¸+ÈÐQRÀ|Ð'TÐZ[ˆÔ\Ø�‰�aÑsÖtr   c                óî  a a€ S P                  R 4       S P                  R 4      p/ o\        P                  ! VV 3R lR7      pVP	                  4        S P                  VR 4      R,          pRRRVR,          RR	. //pS P                  S P                  R
RV4      ^ ,          ^Ê4       VP                  ^
4       S P                  RSR,          ^,          R,          R,          ^ ,          R,          4       R# )rZ   c            
      óV   <€ S P                  SP                  R RRRR/ /^	R7      R7      # )rZ   r  r   Ú
ask_clientr  r  )Úr©ÚupdaterÁ   ©Úboxr   s   €€r	   r   Ú[BridgeTest.test_server_to_client_requests_are_answered_through_the_bridge.<locals>.<lambda>  sA   ø€ °·±¸d¿h¹hÀvÈ|Ð^dÐfrÐtð  BDð  ^Eð  KL¸hó  ?M°ô  2Nr   ©rV   c                 ó`   € V R ,          R8H  ;'       d    V R,          P                  R4      R8H  # )r)   r  r   ú
roots/listr  r  s   &r	   r   rN  !  s.   € ¨¨6­°iÑ)?×)nÐ)nÀAÀiÅL×DTÑDTÐU]ÓD^ÐbnÑDnÐ)nr   r  r   r   r   r   Úrootsr½   rû   úclient answeredrI  r8  rf   N)
r   rE   r„   r…   r‡   rä   rÈ   r™   rB   rï   )r   r×   ÚcallerÚaskÚanswerrM  s   f    @r	   Ú>test_server_to_client_requests_are_answered_through_the_bridgeÚIBridgeTest.test_server_to_client_requests_are_answered_through_the_bridge  sÌ   ù€ Ø�‰˜ÔØ�K‰K˜ÓˆØˆÜ×!Ò!õ  *Nô  OˆØ�‰ŒØ�m‰m˜AÑnÓoÐpyÕzˆØ˜U D¨#¨d­)°XÀÈ¸}ÐMˆØ×Ñ˜Ÿ™ fÐ.AÀ6ÓJÈ1ÕMÈsÔSØ�‰�BŒØ�‰Ð'¨¨S­°!­°XÕ)>¸yÕ)IÈ!Õ)LÈVÕ)TÖUr   c                óh  a a€ S P                  R 4       / o\        P                  ! VV 3R lR7      pVP                  4        \        P
                  ! R4       S P                  R RRRRR^R	^//^R
7      w  r#VP                  ^
4       S P                  W#R,          VR,          R,          ^ ,          R,          3R4       S P                  SR,          ^ ,          ^È4       S P                  SR,          ^,          R,          SR,          ^,          R,          R,          ^ ,          R,          3R4       R# )rZ   c                  óZ   <€ S P                  SP                  R RRRRR^//^R7      R7      # )rZ   r  r   Úslowr  Úsecondsr  )r[  rJ  rL  s   €€r	   r   ÚXBridgeTest.test_the_same_id_from_two_clients_does_not_mix_up_responses.<locals>.<lambda>+  sQ   ø€ ¨s¯z©z¸t¿x¹xÈÐP\Ð_eÐgmÐozð  ~Gð  IJð  }Kð  _Lð  RS¸xó  @T¨zô  0Ur   rO  rÞ   r  r   r5  r  r6  r7  r  r   r   r8  rf   r[  N)éÈ   é   Ú2)r_  z	slept 1 s)	r   r„   r…   r‡   rß   ÚsleeprÁ   rB   rÈ   )r   r[  rž   ÚfastrM  s   f   @r	   Ú;test_the_same_id_from_two_clients_does_not_mix_up_responsesÚFBridgeTest.test_the_same_id_from_two_clients_does_not_mix_up_responses'  sÿ   ù€ à�‰˜ÔØˆÜ×Òõ  (Uô  VˆØ�
‰
ŒÜ�
Š
�3ŒØ—x‘x ¨°v¸uÀkÐTWÐYZÐ\_ÐabÐScÐ6dÐjk�xÓl‰ˆØ�	‰	�"ŒØ×Ñ˜& t¥*¨d°8­n¸YÕ.GÈÕ.JÈ6Õ.RÐSÐUbÔcØ×Ñ˜˜V� Q�¨Ô-Ø×Ñ˜#˜f�+ a�.¨Õ.°°Fµ¸Aµ¸xÕ0HÈÕ0SÐTUÕ0VÐW]Õ0^Ð_ÐaqÖrr   c                ó¶   € V P                  R 4      pV P                  R R^R7      w  r#V P                  W#R,          3^ÈRR/34       V P                  VR 4       R# )r_   rü   r  r   ÚokTc                 óB   € V R ,          R8H  ;'       d    RV R,          9   # )r)   r@  õ   è¶…è¿‡rÖ   r   r  s   &r	   r   ÚJBridgeTest.test_over_long_lines_are_dropped_and_reported.<locals>.<lambda>8  s!   €  1 V¥9°Ñ#8×#RÐ#R¸XÈÈ6ÍÑ=RÐ#Rr   Nr)  ©r   r×   rž   rÉ   s   &   r	   Ú-test_over_long_lines_are_dropped_and_reportedÚ8BridgeTest.test_over_long_lines_are_dropped_and_reported4  sU   € Ø�K‰K˜Ó ˆØŸ™ ¨&°a˜Ó8‰ˆØ×Ñ˜&¨¥/Ð2°S¸4À¸,Ð4GÔHØ�‰�aÑRÖSr   c           	     ó¸   € V P                  R 4       V P                  R RRRRR^//^R7      w  rV P                  VR4       V P                  RVR	,          4       R
# )r\   r  r   r[  r  r\  r  iø  u   ç§’å†…æ²¡æœ‰æ”¶åˆ°å“�åº”rî   N)r   rÁ   rÈ   rï   ©r   rž   rÉ   s   &  r	   Útest_slow_responses_time_outÚ'BridgeTest.test_slow_responses_time_out:  sZ   € Ø�‰˜Ô ØŸ™ ¨,¸ÀÈÐW`ÐbcÐVdÐ8eÐkl˜Óm‰ˆØ×Ñ˜ Ô%Ø�‰Ð0°%¸µ.ÖAr   c                óâ   € V P                  R 4       V P                  R RRRR/ /^R7      w  rV P                  VRV4       V P                  V P                  R 4      R,          R,          R4       R	# )
rZ   r  r   Úcrashr  r  iö  r   r1  N©r   rÁ   rÈ   rn  s   &  r	   Ú4test_crashed_server_is_restarted_on_the_next_requestÚ?BridgeTest.test_crashed_server_is_restarted_on_the_next_request@  sf   € Ø�‰˜ÔØŸ™ ¨¸ÀÈÐVXÐ7YÐ_`˜Óa‰ˆØ×Ñ˜  eÔ,Ø×Ñ˜Ÿ™¨Ó0°Õ>¸vÕFÈÖUr   c                ón   € V P                  R RRVRV/VR7      w  rEV P                  V^È4       VR,          # )r&   r  r   r  r  r   rÇ   )r   r   r   r¿   rž   rÉ   s   &&&&  r	   Úcall_cliÚBridgeTest.call_cliH  s?   € ØŸ™ ¨,¸ÀÀ{ÐTXÐ8YÐ_b˜Óc‰ˆØ×Ñ˜ Ô%Ø�X�Ðr   c                ó<  € V P                  R 4       V P                  R R^R7      w  rVR,          R ,           Uu. uF  q3R,          NK  	  ppV P                  V. R	O4       V P                  VR,          R ,          ^ ,          R,          R,          R.4       R# u upi )
r&   r2  r  r   r   r(   rh   rf   N)	rb   r   rj   rl   rm   rn   ro   rp   rq   rs  )r   rŸ   rÉ   ÚtÚnamess   &    r	   Ú&test_cli_tools_are_listed_as_mcp_toolsÚ1BridgeTest.test_cli_tools_are_listed_as_mcp_toolsM  s‰   € Ø�‰˜Ô Ø—8‘8˜G \°q�8Ó9‰ˆØ$)¨(¥O°GÖ$<Ó=Ñ$<˜q�6—�Ñ$<ˆÐ=Ø×Ñ˜Ò rÔsØ×Ñ˜˜x�¨Õ1°!Õ4°]ÕCÀJÕOÐRXÐQYÖZùò >s   ºBc                óð   € R pV P                  RRV/4      pV P                  VR,          ^ ,          R,          P                  4       \        \	        V4      4      4       V P                  VR,          4       R# )z'a; echo pwned $(id) `id` | cat > /tmp/xrb   rf   r8  ÚisErrorN)rw  rÈ   Ústripr=   r>   ÚassertFalse)r   Úpayloadr   s   &  r	   Ú&test_cli_arguments_never_reach_a_shellÚ1BridgeTest.test_cli_arguments_never_reach_a_shellT  s`   € Ø;ˆØ—‘˜x¨&°'Ð):Ó;ˆØ×Ñ˜ 	Õ*¨1Õ-¨fÕ5×;Ñ;Ó=¼sÄ3ÀwÃ<Ó?PÔQØ×Ñ˜ 	Õ*Ö+r   c           	     ó²  € V P                  V P                  R R^RR/4      R,          ^ ,          R,          P                  4       R4       V P                  V P                  R / 4      R,          ^ ,          R,          P                  4       RR4       V P                  V P                  R	RR
/4      R,          ^ ,          R,          P                  4       R4       R# )r   ÚnÚflagTr8  rf   z['fixed', '--n=5', 'true']z	['fixed']z(elements with missing values are droppedrj   ÚhelloÚHELLON)rÈ   rw  r€  r÷   s   &r	   Ú-test_cli_placeholders_optional_args_and_stdinÚ8BridgeTest.test_cli_placeholders_optional_args_and_stdinZ  sÀ   € Ø×Ñ˜Ÿ™ v°°Q¸ÀÐ/EÓFÀyÕQÐRSÕTÐU[Õ\×bÑbÓdð  gCô  	DØ×Ñ˜Ÿ™ v¨rÓ2°9Õ=¸aÕ@ÀÕH×NÑNÓPÐR]ð  `Jô  	KØ×Ñ˜Ÿ™ w°¸Ð0AÓBÀ9ÕMÈaÕPÐQWÕX×^Ñ^Ó`ÐbiÖjr   c                óÄ  € V P                  R / 4      pV P                  VR,          4       V P                  VR,          R,          ^4       V P                  RVR,          ^,          R,          4       V P                  RV P                  R/ 4      R,          ^ ,          R,          4       V P                  R	V P                  R
/ 4      R,          ^ ,          R,          4       R# )rl   r  ÚstructuredContentÚexitCodeÚoopsr8  rf   rh  rm   u   æ‰¾ä¸�åˆ°ç¨‹åº�rn   N)rw  rç   rÈ   rï   ©r   rI  s   & r	   Ú!test_cli_failures_are_tool_errorsÚ,BridgeTest.test_cli_failures_are_tool_errors_  s«   € Ø�M‰M˜' 2Ó&ˆØ�‰˜˜)�Ô%Ø×Ñ˜Ð.Õ/°
Õ;¸QÔ?Ø�‰�f˜a 	�l¨1�o¨fÕ5Ô6Ø�‰�h §¡¨h¸Ó ;¸IÕ FÀqÕ IÈ&Õ QÔRØ�‰Ð'¨¯©°yÀ"Ó)EÀiÕ)PÐQRÕ)SÐTZÕ)[Ö\r   c                óØ   € V P                  R / 4      pV P                  \        VR,          ^ ,          R,          4      R4       V P                  RVR,          R,          R,          4       R# )ro   r8  rf   u   æˆªæ–­Ni‡ éÿÿÿÿ)rw  ÚassertLessEqualr>   rï   r�  s   & r	   Útest_cli_output_is_cappedÚ$BridgeTest.test_cli_output_is_cappedg  sP   € Ø�M‰M˜' 2Ó&ˆØ×ÑœS  9¥¨a¥°Õ!8Ó9¸=ÔIØ�‰�h  )¥¨RÕ 0°Õ 8Ö9r   c                ó   € V P                  R RR/4      pV P                  VR,          4       V P                  RVR,          ^ ,          R,          4       V P                  V P                  R RR/4      R,          ^ ,          R,          P	                  4       R4       V P                  V P                  R	R
R/4      R,          ^ ,          R,          P	                  4       RR4       V P                  V P                  R RR/4      R,          R4       R# )rp   Úpatternz--upload-pack=evilr  Ú-r8  rf   za-bz['a-b']rq   r†  z-5z['-5']zopted inznumbers are not optionsNéýÿÿÿ)rw  rç   rï   rÈ   r€  r�  r�  s   & r	   Ú2test_option_like_values_are_refused_unless_allowedÚ=BridgeTest.test_option_like_values_are_refused_unless_allowedl  sÝ   € Ø�M‰M˜& 9Ð.BÐ"CÓDˆØ�‰˜˜)�Ô%Ø�‰�c˜1˜Y�<¨�?¨6Õ2Ô3Ø×Ñ˜Ÿ™ v°	¸5Ð/AÓBÀ9ÕMÈaÕPÐQWÕX×^Ñ^Ó`ÐbkÔlØ×Ñ˜Ÿ™ v°°T¨{Ó;¸IÕFÀqÕIÈ&ÕQ×WÑWÓYÐ[cÐeoÔpØ×Ñ˜Ÿ™ v°	¸2¨Ó?À	ÕJÐLeÖfr   c                óZ  € V P                  R 4      pV P                  V P                  R 4      R,          R,          R4       V P                  R R^R7      w  r#V P                  V^ÈV4       V P                  VR,          R,          ^ ,          R,          R 4       V P	                  VR 4       R	# )
r'   r   r   r   r2  r  r   r&   c                 ó€   € V R ,          R8H  ;'       d,    V R,          P                  R/ 4      P                  R4      R8H  # )r)   r  r!   r$   r%   r  r  s   &r	   r   ÚGBridgeTest.test_http_server_session_and_sse_responses.<locals>.<lambda>|  s<   €  1 V¥9°	Ñ#9×#vÐ#v¸aÀ	½l×>NÑ>NÈxÐY[Ó>\×>`Ñ>`ÐagÓ>hÐlvÑ>vÐ#vr   N)rE   rÈ   r   rÁ   rä   rj  s   &   r	   Ú*test_http_server_session_and_sse_responsesÚ5BridgeTest.test_http_server_session_and_sse_responsesv  s�   € Ø�K‰K˜Ó!ˆØ×Ñ˜Ÿ™¨Ó2°<Õ@ÀÕHÈ&ÔQØŸ™ ¨<¸Q˜Ó?‰ˆØ×Ñ˜  eÔ,Ø×Ñ˜˜x�¨Õ1°!Õ4°VÕ<¸hÔGØ�‰�aÑvÖwr   r   )NTNNé
   )Nr_  Fr   )r£  )r_  )'rH   rI   rJ   rK   Úclassmethodr    r¥   r™   rÁ   r   rE   rä   ré   rð   rø   rþ   r  r  r  r$  r+  r.  r<  rD  rW  rc  rk  ro  rt  rw  r|  rƒ  rŠ  r‘  r–  rœ  r¡  rM   rN   rO   s   @r	   rR   rR   S   së   ø‡ € Øñ#Aó ð#AðJ ñó ðð ó:ó ð:ô"<òôô*	3ò0ò
;ò
rò
OòòòBò	@ò`ò
^òFòuò
VòsòTòBòVôò
[ò,òkò
]ò:ò
g÷xð xr   rR   rV   c                   ó:   a € ] tR tRt o RtR tRR ltR tRtV t	R# )	Ú	StdioPeeri‚  zATalk to an MCP server over stdio directly, one request at a time.c           	     óœ   € \         P                  ! V\         P                  \         P                  \         P                  R RR7      V n        R# )Trs   )rk   Ústdoutr@  rf   rt   N)Ú
subprocessÚPopenÚPIPEÚDEVNULLÚproc)r   Úargvs   &&r	   Ú__init__ÚStdioPeer.__init__…  s6   € Ü×$Ò$ T´·±ÌÏÉÔak×asÑasÐz~ð  JQô  RˆŽ	r   Nc                ó¦  € R RRVRV/Ve   RV/M/ CpV P                   P                  P                  \        P                  ! V4      R,           4       V P                   P                  P                  4         \        P                  ! V P                   P                  P                  4       4      pVP                  R4      V8X  g   KQ  RV9  g   KZ  V# )r   r   r   r   r!   rÏ   )
r­  rk   r@   r.   r/   Úflushr4   r¨  ÚreadlinerA   )r   r¿   r   r!   rC   rÉ   s   &&&&  r	   r™   ÚStdioPeer.requestˆ  sž   € Ø˜%  s¨H°fÐsÐW]ÒWiÀ(ÈFÑASÐoqÐsˆØ�	‰	�‰×ÑœdŸjšj¨›o°Õ4Ô5Ø�	‰	�‰×ÑÔØÜ—J’J˜tŸy™y×/Ñ/×8Ñ8Ó:Ó;ˆEØ�y‰y˜‹ #Ö%¨(¸%Ö*?Ø�r   c                óÌ   € V P                   P                  P                  4        V P                   P                  ^
4       V P                   P                  P                  4        R# )r£  N)r­  rk   rµ   Úwaitr¨  r÷   s   &r	   rµ   ÚStdioPeer.close‘  s<   € Ø�	‰	�‰×ÑÔØ�	‰	�‰�rÔØ�	‰	×Ñ×ÑÖ r   )r­  r   )
rH   rI   rJ   rK   rL   r¯  r™   rµ   rM   rN   rO   s   @r	   r¦  r¦  ‚  s   ø‡ € ÙKòRô÷!ð !r   r¦  c                óP  € \         P                  ! V 4      ^Rr2pV\        V4      8  di   \        P	                  WV^,            R4      pW^,           V^,            R8X  d!   W1V^,           V^,           V,            ,          pV^V,           ,          pKx  \
        P                  ! V4      # )zFThe decompressed IDAT of a PNG (the two servers compress differently).r   Úbigs   IDAT)Úbase64Ú	b64decoder>   r7   Ú
from_bytesÚzlibÚ
decompress)Úb64r$   ÚposÚidatr†  s   &    r	   Ú
png_pixelsrÂ  —  sˆ   € ä×&Ò& sÓ+¨Q°ˆt€DØ
”�D“	Œ/Ü�N‰N˜4 C¨!¥GÐ,¨eÓ4ˆØ�a•˜˜a�Ð  GÔ+Ø˜˜q�  q¥¨1¥Ð-Õ-ˆDØˆr�A�v�ŠÜ�?Š?˜4Ó Ð r   c                   óD  a € ] tR tRt o RtR;ttR-RRR/3RRR/3RR	R
RRRR^//3RR	RRR^(RR//3RR	RRRR.R^//3RR	RR/ /3RR	RRRR//3RR	RRR^//3RR	RR/ /3RR	R
R/ /3R/R0RRR/3RRR/3RRR/3R1RR	R RR!R"R#R$//3RR	R R/ /3R2R%R&R'/3R3.tR( tR) t	R* t
R+ tR,tV tR# )4ÚDemoTwinChecksi¢  zœA demo server in another language answers like scripts/mcp_demo_server.py.
Subclasses set BINARY (skipped until it is built) and NAME (its serverInfo name).Nr2  Úcursorr4  Ú6r  r   Úechor  rf   u   ä½ å¥½Útimesr5  r6  r7  g      @rá   r[  r\  gš™™™™™¹?r  r  Únopezresources/readÚurizdemo://readmezdemo://notes/x yzdemo://missingzprompts/getÚreviewÚcodezfn main() {}ÚlanguageÚRustzlogging/setLevelr"   r#   c                ó6  € \        \        \        \        R ,          4      .4      V n        \        \        V P
                  4      .4      V n        V P                  V P                  P                  4       V P                  V P                  P                  4       R# )rX   N)	r¦  rˆ   r=   r‰   ÚpyÚBINARYÚrsrÛ   rµ   r÷   s   &r	   ÚsetUpÚDemoTwinChecks.setUp¹  s^   € ÜœR¤¤TÐ,@Õ%@Ó!AÐBÓCˆŒÜœS §¡Ó-Ð.Ó/ˆŒØ�‰˜Ÿ™Ÿ™Ô&Ø�‰˜Ÿ™Ÿ™Ö&r   c           	     óÔ  € R RR/ RRRRR//pV P                   P                  ^RV4      R	,          V P                  P                  ^RV4      R	,          r2V P                  VR
,          R,          V P                  4       V P                  VR ,          VR,          3VR ,          VR,          34       \        V P                  ^R7       F�  w  pw  rVV P                   P                  WEV4      V P                  P                  WEV4      r2RV9   dE   V P                  VP                  R/ 4      P                  R4      VR,          R,          WVV34       KŠ  V P                  W2WV34       KŸ  	  R# )r   z
2025-03-26r   rÄ   r   rz  r   rÆ   r   r   r   )r‡   rî   rÌ  N)rÐ  r™   rÒ  rÈ   ÚNAMEÚ	enumerateÚREQUESTSrA   )r   ÚinitrÐ  rÒ  r¿   r   r!   s   &      r	   Ú$test_answers_match_the_python_serverÚ3DemoTwinChecks.test_answers_match_the_python_server¿  s>  € Ø! <°ÀÀ\ÐTZÐ\_ÐajÐloÐSpÐqˆØ—‘—‘  L°$Ó7¸ÕAÀ4Ç7Á7Ç?Á?ÐSTÐVbÐdhÓCiÐjrÕCsˆBØ×Ñ˜˜LÕ)¨&Õ1°4·9±9Ô=Ø×Ñ˜"Ð.Õ/°°NÕ1CÐDÀrÐJ[ÕG\Ð^`ÐaoÕ^pÐFqÔrÜ%.¨t¯}©}ÀA×%FÑ!ˆCÑ!�&Ø—W‘W—_‘_ S°&Ó9¸4¿7¹7¿?¹?È3ÐX^Ó;_�Ø˜"Œ}Ø× Ñ  §¡¨°Ó!4×!8Ñ!8¸Ó!@À"ÀWÅ+ÈfÕBUÐX^ÐhjÐWkÖlà× Ñ  ¨&Ð)9Ö:ó &Gr   c                óœ  € R RRRR//pV P                   P                  ^RV4      R,          V P                  P                  ^RV4      R,          r2V P                  \	        VR,          ^ ,          R,          4      \	        VR,          ^ ,          R,          4      4       V P                  VR,          ^,          VR,          ^,          4       R	# )
r   Úimager  ÚcolorÚgreenr  r   r8  r$   N)rÐ  r™   rÒ  rÈ   rÂ  )r   r   rÐ  rÒ  s   &   r	   Útest_image_has_the_same_pixelsÚ-DemoTwinChecks.test_image_has_the_same_pixelsË  s¦   € Ø˜ ¨w¸Ð.@ÐAˆØ—‘—‘  L°$Ó7¸ÕAÀ4Ç7Á7Ç?Á?ÐSTÐVbÐdhÓCiÐjrÕCsˆBØ×Ñœ B y¥M°!Õ$4°VÕ$<Ó=¼zÈ"ÈYÍ-ÐXYÕJZÐ[aÕJbÓ?cÔdØ×Ñ˜˜I� qÕ)¨2¨i­=¸Õ+;Ö<r   c                ó   € V P                   P                  P                  P                  \        P
                  ! R RR^RRRRRR/ //4      R	,           4       V P                   P                  P                  P                  4        \        P                  ! V P                   P                  P                  P                  4       4      pV P                  VR,          R
4       V P                   P                  P                  P                  \        P
                  ! R RRVR,          RR. //4      R	,           4       V P                   P                  P                  P                  4        V P                  R\        P                  ! V P                   P                  P                  P                  4       4      R,          R,          ^ ,          R,          4       V P                   P                  P                  P                  \        P
                  ! R RR^RRRRRR/ //4      R	,           4       V P                   P                  P                  P                  4        V P                  V P                   P                  P                  ^
4      ^4       R# )r   r   r   r   r  r!   r   rH  r  rÏ   rQ  r   rR  rS  r8  rf   rr  N)rÒ  r­  rk   r@   r.   r/   r²  r4   r¨  r³  rÈ   rï   r¶  )r   rU  s   & r	   Ú$test_ask_client_round_trip_and_crashÚ3DemoTwinChecks.test_ask_client_round_trip_and_crashÑ  s  € Ø�‰�‰×Ñ× Ñ ¤§¢¨Y¸¸tÀQÈÐR^Ð`hÐkqÐsð  BMð  OQð  kRð  -Só  "Tð  W[õ  "[ô  	\Ø�‰�‰×Ñ× Ñ Ô"Ü�jŠj˜Ÿ™Ÿ™×,Ñ,×5Ñ5Ó7Ó8ˆØ×Ñ˜˜X�¨Ô5Ø�‰�‰×Ñ× Ñ ¤§¢¨Y¸¸tÀSÈÅYÐPXÐ[bÐdfÐZgÐ,hÓ!iÐlpÕ!pÔqØ�‰�‰×Ñ× Ñ Ô"Ø�‰Ð'¬¯ª°D·G±G·L±L×4GÑ4G×4PÑ4PÓ4RÓ)SÐT\Õ)]Ð^gÕ)hÐijÕ)kÐlrÕ)sÔtØ�‰�‰×Ñ× Ñ ¤§¢¨Y¸¸tÀQÈÐR^Ð`hÐkqÐszð  }Hð  JLð  kMð  -Nó  "Oð  RVõ  "Vô  	WØ�‰�‰×Ñ× Ñ Ô"Ø×Ñ˜Ÿ™Ÿ™×*Ñ*¨2Ó.°Ö2r   )rÐ  rÒ  )r2  Nr”  )zresources/listN)zresources/templates/listN)zprompts/listN)rü   N)zno/such/methodN)rH   rI   rJ   rK   rL   rÑ  rÖ  rØ  rÓ  rÚ  rà  rã  rM   rN   rO   s   @r	   rÄ  rÄ  ¢  sq  ø‡ € ñYàÐ€FˆTð 	˜|¨h¸¨_Ð=ÀÈxÐY\ÈoÐ?^Ø	˜ ¨°f¸hÈÐQRÐ5SÐTÐUØ	˜  {°S¸"¸cÀ3Ð4GÐHÐIØ	˜  {°S¸"¸cÀ1Ð4EÐFÐGØ	˜ ¨°RÐ8Ð9Ø	˜ ¨°iÀÐ5EÐFÐGØ	˜ ¨+¸À°|ÐDÐEØ	˜ ¨°RÐ8Ð9Ø	˜ ¨°RÐ8Ð9Ø Ð"DØ	˜E ?Ð3Ð4Ð7GÈ%ÐQcÐIdÐ6eØ	˜EÐ#3Ð4Ð5Ø °¸À;ÐQWÐYgÐisÐu{ÐP|Ð0}Ð ~Ø	˜ ¨;¸Ð;Ð<ØÐ+¨g°vÐ->Ð?ÐAYð€Hò$'ò
;ò=÷
3ð 
3r   rÄ  u&   build it first (docs/INSTALL.md Â§3.2)ÚreleaseÚexamplesÚdemo_serverc                   óJ   € ] tR tRt]R,          R,          R,          RuttRtR# )ÚRustDemoServerTestiá  rå  ræ  rç  zwebtt-demo-rustr   N©rH   rI   rJ   rK   ÚTARGETrÑ  rÖ  rM   r   r   r	   ré  ré  á  s   † à˜IÕ%¨
Õ2°]ÕBÐDU€L€FŒDr   ré  úmcp-demoúdemo-goc                   ó<   € ] tR tRt]R,          R,          RuttRtR# )ÚGoDemoServerTestiæ  rì  rí  zwebtt-demo-gor   Nrê  r   r   r	   rï  rï  æ  s   † à˜JÕ&¨Õ2°O€L€FŒDr   rï  údemo-zigc                   ó<   € ] tR tRt]R,          R,          RuttRtR# )ÚZigDemoServerTestië  rì  rð  zwebtt-demo-zigr   Nrê  r   r   r	   rò  rò  ë  s   † à˜JÕ&¨Õ3Ð5E€L€FŒDr   rò  c                   ó2   a € ] tR tRt o R tR tR tRtV tR# )Ú
ConfigTestið  c                ó²  € \         P                  ! R RRR7      ;_uu_ 4       p\        P                  ! RV/V4       RRR4        \        P
                  ! XP                  4      \        P                  ! VP                  4      P                  4        #   + '       g   i     L_; i  \        P                  ! XP                  4      P                  4        i ; i)Úwz.jsonF)ÚsuffixÚdeleterY   N)
r~   ÚNamedTemporaryFiler.   Údumpr�   Úload_configr   r�   rŽ   Úunlink)r   rY   Úfs   && r	   ÚcheckÚConfigTest.checkñ  sˆ   € Ü×(Ò(¨°WÀU×KÕKÈqÜ�IŠI�y 'Ð*¨AÔ.÷ Lð	*Ü×)Ò)¨!¯&©&Ó1ä�LŠL˜Ÿ™Ó ×'Ñ'Õ)÷ L×Kûô
 �LŠL˜Ÿ™Ó ×'Ñ'Õ)ús   ¢BÁB& ÂB#	Â&0Cc                ó>  € R RRR./.R RRR./R RRR./.R R/.R RRR/.R RRR/.R RRR.RR/.R RR	R
RRR././.R RR	R
RRRR././.3 F<  pV P                  \        VR7      ;_uu_ 4        V P                  V4       RRR4       K>  	  R#   + '       g   i     KS  ; i)r   za br[   Úxr6  Úyr^   zftp://xzhttp://xra   r   zbad namerz  z	{program})rC   N)ÚassertRaisesÚ
ValueErrorrþ  )r   Úbads   & r	   Ú!test_invalid_configs_are_rejectedÚ,ConfigTest.test_invalid_configs_are_rejectedù  s  € Ø˜E 9¨s¨eÐ4Ð5¸¸sÀIÐPSÈuÐ8UÐX\Ð^aÐclÐorÐnsÐWtÐ7uØ˜C�[�M T¨3°	¸3Ð$?Ð#@ÀDÈ#ÈuÐV_ÐC`ÐBaØ˜C ¨S¨E°5¸*ÐEÐFÈ$ÐPSÐUZÐ^dÐfpÐr{ð  Bð  ~Cð  ^Dð  ]Eð  JFð  IGØ˜C ¨&°#°yÀ;ÐPSÐBTÐ)UÐ(VÐWÐXóZˆCð ×"Ñ"¤:°3Ð"×7Õ7Ø—
‘
˜3”÷ 8Ñ7ó	Z÷ 8×7Ð7ús   Á+BÂBc           	     ód   € V P                  \        P                  ! . RORRR^/4      . RO4       R# )Úpr6  úv wr7  N)r	  z{a}z--x={b}z{c})r	  r
  z--x=2)rÈ   r�   Úargv_forr÷   s   &r	   Útest_argv_templateÚConfigTest.test_argv_template  s-   € Ø×Ñœ×,Ò,Ò-KÈcÐSXÐZ]Ð_`ÐMaÓbÒdyÖzr   r   N)	rH   rI   rJ   rK   rþ  r  r  rM   rN   rO   s   @r	   rô  rô  ð  s   ø‡ € ò*ò ÷{ð {r   rô  Ú__main__)/rL   rº  Úhttp.clientr�   Úhttp.serverr.   r�   rÙ   r©  Úsysr~   r„   rß   Úunittestr½  rŽ   Ú__file__ÚresolveÚparentr‰   r�   Úinsertr=   r�   r•   Ú
executablerˆ   r‹   rŒ   r‚   ÚBaseHTTPRequestHandlerr   ÚTestCaserR   rë  r¦  rÂ  rÄ  Ú
BUILD_HINTÚ
skipUnlessÚexistsré  rï  rò  rô  rH   Úmainr   r   r	   Ú<module>r     sê  ðñó
 Û Û Û Û Û Û Û 
Û Û Û Û Û à‡|‚|�HÓ×%Ñ%Ó'×.Ñ.€Ø ‡�‡��‘3�t“9Ô Û Û à‡^�^€ðÐ ð	€ô�$—+‘+×4Ñ4ô ôDix�×"Ñ"ô ixðX	 
�‰�xÕ	€÷!ñ !ò*!÷93ñ 93ðx 6€
ð 
×Ò�f˜yÕ(¨:Õ5¸ÕE×MÑMÓOÐQ[Ó\ôV˜¨×):Ñ):ó Vó ]ðVð 
×Ò�f˜zÕ)¨IÕ5×=Ñ=Ó?ÀÓLôD�~ x×'8Ñ'8ó Dó MðDð 
×Ò�f˜zÕ)¨JÕ6×>Ñ>Ó@À*ÓMôF˜¨×(9Ñ(9ó Fó NðFô{�×"Ñ"ô {ð* ˆzÔØ‡M‚M†Oñ r   