MCP, alebo CLI? Nesprávna otázka. Pýtajte sa, kde žije stav.

Tobi Lütke hovorí, že spor MCP verzus CLI sa vedie na nesprávnej vrstve: oboje funguje, keď stav pretrvá medzi krokmi. Súhlas. Pri synchronizácii sú týmto stavom vlastné záznamy integrácie, nie halda REPL, a preto MCP nástroje Tajo neuchovávajú v relácii nič.

mcp vs cli

Má AI agent používať MCP, alebo CLI?

Lütke má pravdu, že MCP verzus CLI je nesprávna vrstva: oboje funguje, keď stav pretrvá medzi krokmi, a bash vyhráva iba preto, že týmto stavom je súborový systém. Pri synchronizácii však stav nie je halda REPL. Sú to vlastné záznamy integrácie: kurzor, čakajúci návrh, zámok (lease), plán. Preto MCP nástroje Tajo neuchovávajú v relácii nič: akýkoľvek agent z akéhokoľvek klienta pokračuje zo záznamov. Tajo dnes nespúšťa žiadny zákaznícky kód a nemá REPL, a nižšie to hovoríme na rovinu.

Zistiť viac
Na tejto stránke

Dňa 21. septembra 2026 o 00:33 UTC Tobi Lütke zverejnil toto: „MCP vs CLI pre LLM je nesprávna diskusia. Ľudia sa hádajú na nesprávnej vrstve.“ Potom 23. októbra upozornil na nový repozitár dquickts. Je to fork QuickJS, ktorý dokáže pozastaviť program uprostred cyklu for, zapísať celú jeho haldu do bajtov a obnoviť ho v inom procese. „Výborné prostredie pre code mode,“ napísal.

Pokiaľ ide o vrstvu, má pravdu. Chcem s ním najprv súhlasiť, jeho vlastnými slovami, a potom tvrdenie zúžiť tak, aby hovorilo niečo, čo môže využiť synchronizácia.

Vrstva, ktorú má na mysli

Tu je argument tak, ako ho sformuloval, čo je jediný férový spôsob, ako citovať argument, ktorý sa chystám ohnúť:

Oboje funguje neuveriteľne dobre, pokiaľ to beží v prostredí podobnom REPL, ktoré dokáže uchovávať stav. Na CLI je zábavné, že k nástrojom CLI sa zvyčajne pristupuje cez BASH, ktorý je zhodou okolností REPL s perzistentným stavom (súborovým systémom), a preto CLI funguje oveľa lepšie ako MCP. Ale to ani zďaleka nie je vnútorná vlastnosť MCP. Znamená to len, že potrebujeme lepšie behové prostredia.

To je správne a vysvetľuje to pozorovanie, ktoré urobilo veľa ľudí bez toho, aby ho vysvetlili. Agent, ktorý dostane CLI, zapíše súbor, o tri kroky neskôr ho načíta späť, prehľadá ho grepom, pošle ho rúrou ďalej. Agent, ktorý dostane holý MCP server, dostane na každé volanie jeden výsledok a všetko ostatné musí niesť vo svojom kontextovom okne. CLI nevyhralo protokolom. Vyhralo preto, že bash prišiel s miestom, kam veci odložiť.

Jeho stávka z toho vyplýva. Niekto postaví vložiteľný engine v štýle SQLite, ktorý z bashu, TypeScriptu alebo volaní nástrojov urobí jeden plán, skontrolovaný pred spustením a postavený na trvalé (durable) vykonávanie. dquickts je krok týmto smerom. Jeho README opisuje REPL, „ktorého funkcie a premenné prežijú reštarty“. Opisuje aj trvalé volanie hostiteľa: „skript zavolá funkciu hostiteľa, ktorej odpoveď príde o niekoľko hodín. Proces skript uloží a ukončí sa.“

Zatiaľ úplná zhoda. Teraz to zúženie.

Ktorý stav a pre akú prácu

„Uchovávať stav“ skrýva otázku: čí stav a v akej podobe? Pre programovacieho agenta je stavom repozitár a shell a REPL, ktorý prežije reštarty, je dobrá odpoveď. Pre agenta, ktorý stavia synchronizáciu medzi dvoma SaaS systémami, je stav, ktorý potrebuje medzi krokmi, už daný samotnou prácou. Nesú ho štyri záznamy a žiadny z nich nie je premenná v skripte.

Kurzor. Synchronizácia číta zdroj po oknách a musí vedieť, kde skončilo posledné okno. V synchronizačnom engine Tajo je to uložený kurzor pre každú synchronizáciu a rozsah, zapísaný po každej dávke bez jediného neúspešného záznamu, a ďalší beh na neho nadväzuje. Plánovaný beh si uloží svoj východiskový bod skôr, než urobí čokoľvek iné, takže keď prvý beh zlyhá, ďalší číta z rovnakého miesta. Princíp, na ktorom to stojí, posielať rozdiel a nikdy nie celú tabuľku, nájdete vo vysvetlení reverse ETL. Kurzor tam nechám.

Čakajúci návrh. V MCP nástrojoch konektorov Tajo je zápis dvojica volaní. brevo_propose overí vstup voči deklarovanej akcii a zaznamená návrh. Nič sa neodošle. Výsledok nesie id návrhu a, keď musí rozhodnúť človek, stránku, kde ho schváli. brevo_apply vykoná schválené zápisy daného pripojenia v poradí a zastaví sa pri prvom, ktorý stále čaká na človeka. Záznam medzi tým je ten stav. Obsahuje vstup a jeho digest, takže schválený zápis nemožno upraviť medzi rozhodnutím a vykonaním. Neobsahuje hodnoty z odpovede poskytovateľa, pretože záznam o schválení, do ktorého sa iba pridáva, sa nesmie zmeniť na úložisko osobných údajov.

Zámok (lease). Beh synchronizácie drží počas celého svojho trvania jeden výhradný zámok s tokenom vlastníka, časovým limitom štandardne pätnásť minút a obnovovaním. Zastaraný vlastník nemôže uvoľniť novší zámok. Ak je úložisko zámkov nedostupné, beh odmietne začať, namiesto toho, aby hádal. Ktorý worker beh drží, je fakt uložený v zámku, nie v pamäti nejakého procesu.

Plán. syncs.dryRun načíta z kurzora ďalšie okno, pre každý záznam určí vloženie, aktualizáciu, zmazanie alebo bez zmeny a zapíše presne jeden riadok: plán, uchovaný jednu hodinu. Neposunie žiadny kurzor a nič nezapíše do žiadneho z oboch systémov. syncs.apply zapíše tento plán raz. Odmietne, ak sa kurzor posunul, alebo ak sa medzitým zmenil väčší než tolerovaný podiel záznamov. Opakované volanie vráti prvý výsledok, namiesto toho, aby zapisovalo znova.

To je stav medzi krokmi: štyri záznamy s id, čitateľné pre každého agenta, ktorý ich smie vidieť.

Prečo strana MCP nič nedrží v relácii

Keď je stav v záznamoch, relácia už nemá čo držať. Preto MCP endpointy Tajo žiadnu reláciu nedržia. Každá požiadavka dostane nový server a transport bez id relácie. Čítanie je jedna požiadavka na volanie, s obmedzenou veľkosťou výsledkov, aby jedna odpoveď nemohla zahltiť ťah. Zápisy sú návrh, potom vykonanie, a to, čo nesiete ďalej, je id návrhu.

Protokol sa posunul rovnakým smerom. Revízia špecifikácie MCP z 2026-07-28 odstránila z transportu Streamable HTTP relácie na úrovni protokolu aj hlavičku Mcp-Session-Id. Server, ktorý potrebuje kontinuitu, si teraz vytvorí vlastný identifikátor a dostane ho späť ako bežný argument. Presne tým je id návrhu. Čo je MCP server opisuje túto revíziu a to, ako sa volanie nástroja líši od trvalej synchronizácie; tento text sa týka len toho, kam patrí stav.

Dôsledok je ten, na ktorom pri integračnej práci záleží. Povedzme, že agent v Claude Code navrhne zápis a jeho relácia skončí. Človek ho o hodinu neskôr schváli. Agent v inom klientovi, alebo ten istý zajtra, zavolá apply s id a zápis prebehne, raz. Spadnutý agent stratí svoje kontextové okno a nič iné. Nič nebolo pozastavené, takže nič nebolo treba obnovovať.

Čo nemáme a čo to stojí

Úprimná námietka prichádza zo strany REPL a znie takto: „Dobre, vaše záznamy prežijú. Ale každé volanie znova číta to, čo predchádzajúce volanie už malo. Skript by kontakty načítal raz, spojil ich, vyfiltroval a vrátil číslo. Váš agent urobí päť volaní a za každé zaplatí.“ Tá námietka má pravdu, pokiaľ ide o mechanizmus, a cenu sme nezmerali. Vyhodnotenie, ktoré by počítalo volania na úlohu s prenášaným stavom a bez neho, nie je postavené. Kým nebude, tvrdenie, že režim volaní stojí viac tokenov, zostáva nezodpovedané.

Ďalšie tri veci treba povedať na rovinu, pretože čitateľ, ktorý dočíta tento článok, by si ich nemal domýšľať:

  • Dnes nebeží žiadny kód napísaný zákazníkmi. Čítanie cez konektory je jedna požiadavka na volanie, bez sandboxu v ceste. V našom stacku existuje spúšťač kódu a je to interný nástroj. V produkcii je vypnutý, pokiaľ nie sú nastavené dva samostatné príznaky, a odpovedá iba administrátorom. Každé volanie dostane nový kontext, väzby, ktoré povoľujú iba čítanie, a rozpočet dvoch sekúnd pre synchrónny kód. Jeho vlastná hlavička veľkými písmenami uvádza, že je hranicou správnosti, nie bezpečnosti.
  • Žiadny REPL. Nič, čo agent vypočíta v jednom volaní, nie je k dispozícii v ďalšom, pokiaľ to nebolo zapísané ako záznam s id.
  • Žiadna perzistentná relácia agenta. Klient si drží svoju konverzáciu. Tajo drží návrhy, plány, kurzory a zámky. Žiadna tretia vec neexistuje.

Na čo je trvalý engine

Nič z toho nie je argument proti dquickts. Jeho README vymenúva, na čo sú snapshoty, a ten zoznam je dobrý. Uspať nečinný skript a uvoľniť jeho pamäť. Spúšťať dlhý výpočet po častiach na ktoromkoľvek voľnom workeri. Teplo štartovať každú inštanciu zo snapshotu namiesto opakovania prípravy. Odstaviť skript na volaní hostiteľa, ktorého odpoveď príde neskôr. Pre pracovný priestor programovacieho agenta alebo notebook, ktorý má prežiť reštart, je to správny nástroj.

Synchronizácia by od neho napriek tomu nemala závisieť, z troch dôvodov, ktoré mi dáva samotné README. Po prvé: „Súbor relácie sa načíta iba do zostavenia qjs, ktoré ho zapísalo.“ Halda zapísaná jednou verziou enginu je po upgrade mŕtvy súbor; kurzor je reťazec. Po druhé: „Snapshoty sú dôveryhodný vstup, rovnako ako bajtkód“ a „škodlivé snapshoty sa nedetegujú“. Uloženú haldu musíte chrániť, skontrolovať ju nemôžete; návrh je riadok, ktorý si človek prečíta, než ho schváli. Po tretie, snapshot obsahuje všetko, čo skript prečítal, vrátane záznamov zákazníkov. Záznamy opísané vyššie sú postavené naopak: plán ukladá digesty, nie hodnoty, a záznam návrhu nikdy neukladá odpoveď poskytovateľa.

Jedno z pravidiel, podľa ktorých staviame, hovorí, že deterministické víťazí nad šikovným. Halda, ktorá pokračuje uprostred cyklu, je šikovná. Kurzor, návrh, zámok a plán sú nudné, dajú sa prezrieť a sú rovnaké na každom engine, v každom klientovi, po každom páde.

Lütke položil správnu otázku. Kde žije stav? Pri synchronizácii odpoveď nikdy nemohla byť v procese. Vždy musela byť v záznamoch, pretože práve tam ho musí vedieť prečítať človek, ktorý zápis schvaľuje.

Často Kladené Otázky

Je pre AI agentov lepšie MCP, alebo CLI?

Samo osebe ani jedno. Postreh Tobiho Lütkeho z 21. septembra 2026 platí: oboje funguje, keď volania bežia cez niečo, čo medzi krokmi uchováva stav. CLI dnes pôsobí lepšie, pretože bash uchováva stav v súborovom systéme. Rozdiel nie je v protokole, ale v behovom prostredí.

Aký stav potrebuje agent medzi krokmi synchronizácie?

Vlastné záznamy integrácie: kurzor, ktorý hovorí, kde skončil posledný beh, návrh čakajúci na schválenie človekom, zámok (lease), ktorý hovorí, ktorý worker beh drží, a plán z dry runu, ktorému musí vykonanie zodpovedať. Nič z toho nie je premenná v skripte. Sú to riadky s id.

Prečo MCP server Tajo neuchováva v relácii nič?

Každá požiadavka dostane nový server a transport bez id relácie. Čokoľvek potrebuje ďalšie volanie, je záznam: id návrhu, id plánu, kurzor. Druhý agent v inom klientovi tak môže nadviazať tam, kde prvý skončil, a spadnutý agent stratí iba svoje kontextové okno.

Spúšťa Tajo kód napísaný agentmi?

Pre zákazníkov nie. Čítanie cez nástroje konektorov je jedna požiadavka na volanie, bez sandboxu. Spúšťač kódu, ktorý existuje, je interný nástroj za dvoma príznakmi, dostupný iba administrátorom, s väzbami iba na čítanie a novým kontextom pre každé volanie. Sám o sebe uvádza, že nie je bezpečnostnou hranicou. Neexistuje žiadny REPL ani perzistentná relácia.

Na čo je dobrý trvalý JavaScriptový engine, ako je dquickts?

Jeho README uvádza použitia: uspať nečinný skript, rozdeliť dlhý výpočet medzi workerov, teplo naštartovať zo snapshotu a odstaviť skript na volaní hostiteľa, ktorého odpoveď príde o niekoľko hodín. To všetko je reálne. Synchronizácia by od neho napriek tomu nemala závisieť: snapshot sa načíta iba do zostavenia enginu, ktoré ho zapísalo, pre recenzenta je nepriehľadný a obsahuje všetky zákaznícke dáta, ktoré skript prečítal.

Požiadajte o skorý prístup

Zadajte svoje meno a e-mailovú adresu. Pošleme vám odkaz na potvrdenie žiadosti o prístup k Tajo.

Získať Brevo

Táto stránka ako Markdown: mcp-or-cli-is-the-wrong-question.md

Načítava sa Markdown…
Otvoriť v Claude Otvoriť v ChatGPT