MCP ili CLI je pogrešno pitanje. Pitajte gde živi stanje.

Tobi Lütke kaže da se o dilemi MCP ili CLI raspravlja na pogrešnom nivou: oboje radi čim stanje opstaje između koraka. Slažemo se. Kod sinhronizacije to stanje čine sopstveni zapisi integracije, a ne hip REPL okruženja, i zato MCP alati Tajo ne čuvaju ništa u sesiji.

mcp ili cli

Da li AI agent treba da koristi MCP ili CLI?

Lütke je u pravu da je MCP ili CLI pogrešan nivo: oboje radi čim stanje opstaje između koraka, a bash pobeđuje samo zato što je sistem datoteka to stanje. Kod sinhronizacije, međutim, stanje nije hip REPL-a. To su sopstveni zapisi integracije: kursor, predlog na čekanju, zaključavanje (lease), plan. Zato MCP alati Tajo ne čuvaju ništa u sesiji: bilo koji agent, iz bilo kog klijenta, nastavlja iz zapisa. Tajo danas ne izvršava nikakav kod korisnika i nema REPL, i to u nastavku otvoreno kažemo.

Saznajte više
Na ovoj stranici

Tobi Lütke je 21. septembra 2026. u 00:33 UTC objavio ovo: „MCP vs CLI za LLM-ove je pogrešna diskusija. Ljudi raspravljaju na pogrešnom nivou.“ Zatim je 23. oktobra ukazao na novi repozitorijum, dquickts. To je fork projekta QuickJS koji može da pauzira program usred petlje for, zapiše ceo njegov hip u bajtove i nastavi ga u drugom procesu. „Odlično okruženje za code mode“, napisao je.

Što se nivoa tiče, u pravu je. Želim prvo da se složim s njim, njegovim sopstvenim rečima, a zatim da suzim tvrdnju dok ne kaže nešto što sinhronizacija može da iskoristi.

Nivo na koji misli

Evo argumenta onako kako ga je izneo, što je jedini pošten način da se citira argument koji se namerava saviti:

Oboje radi neverovatno dobro sve dok se pokreće kroz okruženje nalik REPL-u koje može da čuva stanje. Smešno je kod CLI-ja to što se CLI alatima obično pristupa preko BASH-a, koji je slučajno REPL sa trajnim stanjem (sistemom datoteka), pa zato CLI radi mnogo bolje od MCP-a. Ali to ni izdaleka nije suštinsko svojstvo MCP-a. To samo znači da su nam potrebna bolja izvršna okruženja.

To je tačno i objašnjava zapažanje koje su mnogi izneli a da ga nisu objasnili. Agent koji dobije CLI zapiše datoteku, tri koraka kasnije je pročita, pretraži je grepom, provuče je kroz cev. Agent koji dobije goli MCP server dobija jedan rezultat po pozivu i sve ostalo mora da nosi u svom kontekstnom prozoru. CLI nije pobedio protokolom. Pobedio je zato što je bash došao sa mestom gde se stvari mogu odložiti.

Iz toga sledi njegova opklada. Neko napravi ugradivi mehanizam po uzoru na SQLite koji bash, TypeScript ili pozive alata pretvara u jedan plan, proveren pre pokretanja i napravljen za trajno (durable) izvršavanje. dquickts je korak ka tome. Njegov README opisuje REPL „čije funkcije i promenljive preživljavaju ponovna pokretanja“. Opisuje i trajni poziv domaćina: „skripta poziva funkciju domaćina čiji odgovor stiže satima kasnije. Proces čuva skriptu i izlazi.“

Za sada potpuno slaganje. Sada sužavanje.

Koje stanje, za koji posao

„Čuvati stanje“ krije pitanje: čije stanje i u kom obliku? Za agenta koji programira stanje su repozitorijum i šel, a REPL koji preživljava ponovna pokretanja je dobar odgovor. Za agenta koji gradi sinhronizaciju između dva SaaS sistema, stanje koje mu je potrebno između koraka već je određeno samim poslom. Nose ga četiri zapisa i nijedan od njih nije promenljiva u skripti.

Kursor. Sinhronizacija čita izvor u prozorima i mora da zna gde se završio poslednji prozor. U Tajo mehanizmu za sinhronizaciju to je sačuvani kursor po sinhronizaciji i opsegu, zapisan posle svake serije bez ijednog neuspelog zapisa, a sledeće pokretanje nastavlja od njega. Zakazano pokretanje čuva svoju početnu tačku pre nego što uradi bilo šta drugo, pa prvo pokretanje koje ne uspe ostavlja sledećem da čita od iste tačke. Princip iza toga, slati razliku, a nikada tabelu, nalazi se u objašnjenju reverse ETL-a. Kursor ću ostaviti tamo.

Predlog na čekanju. Na MCP alatima konektora Tajo upis se sastoji od dva poziva. brevo_propose proverava ulaz prema deklarisanoj radnji i beleži predlog. Ništa se ne šalje. Rezultat nosi id predloga i, kada čovek mora da odluči, stranicu na kojoj ga odobrava. brevo_apply redom izvršava odobrene upise te veze i zaustavlja se na prvom koji još čeka na čoveka. Zapis između toga je stanje. Sadrži ulaz i njegov sažetak (digest), pa se odobreni upis ne može izmeniti između odluke i izvršenja. Ne sadrži vrednosti iz odgovora provajdera, jer zapis odobrenja u koji se samo dodaje ne sme da se pretvori u skladište ličnih podataka.

Zaključavanje (lease). Pokretanje sinhronizacije tokom celog svog trajanja drži jedno isključivo zaključavanje, sa tokenom vlasnika, vremenskim ograničenjem od podrazumevanih petnaest minuta i obnavljanjem. Zastareli vlasnik ne može da otpusti novije zaključavanje. Ako skladište zaključavanja nije dostupno, pokretanje odbija da počne umesto da nagađa. Koji radnik (worker) drži pokretanje, činjenica je zapisana u zaključavanju, a ne u memoriji bilo kog procesa.

Plan. syncs.dryRun čita sledeći prozor od kursora, za svaki zapis utvrđuje umetanje, ažuriranje, brisanje ili bez promene i zapisuje tačno jedan red: plan, koji se čuva sat vremena. Ne pomera nijedan kursor i ništa ne upisuje ni u jedan od dva sistema. syncs.apply upisuje taj plan jednom. Odbija ako se kursor pomerio ili ako se u međuvremenu promenio veći udeo zapisa od dozvoljenog. Ponovljeni poziv vraća prvi rezultat umesto da ponovo upisuje.

To je stanje između koraka: četiri zapisa sa id-jevima, čitljiva svakom agentu kome je dozvoljeno da ih vidi.

Zašto MCP strana ne čuva ništa u sesiji

Kada je stanje u zapisima, sesija više nema šta da čuva. Zato MCP krajnje tačke Tajo ne čuvaju sesiju. Svaki zahtev dobija svež server i transport bez id-ja sesije. Čitanja su jedan zahtev po pozivu, sa ograničenim rezultatima kako jedan odgovor ne bi mogao da preplavi potez. Upisi su predlog, pa izvršenje, a ono što nosite dalje je id predloga.

Protokol se pomerio u istom smeru. Revizija MCP specifikacije od 2026-07-28 uklonila je sesije na nivou protokola i zaglavlje Mcp-Session-Id iz transporta Streamable HTTP. Server kome je potreban kontinuitet sada sam pravi sopstveni identifikator i dobija ga nazad kao običan argument. Upravo to je id predloga. Šta je MCP server obrađuje tu reviziju i po čemu se poziv alata razlikuje od trajne sinhronizacije; ovaj tekst govori samo o tome kuda ide stanje.

Posledica je ona koja je važna za integracioni rad. Recimo da agent u Claude Code predloži upis i njegova sesija se završi. Čovek ga odobri sat vremena kasnije. Agent u drugom klijentu, ili isti sutra, pozove apply sa id-jem i upis se izvrši, jednom. Srušeni agent gubi svoj kontekstni prozor i ništa drugo. Ništa nije bilo obustavljeno, pa ništa nije trebalo nastavljati.

Šta nemamo i koliko to košta

Pošten prigovor dolazi sa strane REPL-a i glasi ovako: „Dobro, vaši zapisi preživljavaju. Ali svaki poziv ponovo čita ono što je prethodni poziv već imao. Skripta bi kontakte preuzela jednom, spojila ih, filtrirala i vratila broj. Vaš agent napravi pet poziva i plaća svaki.“ Taj prigovor je u pravu kada je reč o mehanizmu, a cenu nismo izmerili. Evaluacija koja bi brojala pozive po zadatku sa prenetim stanjem i bez njega nije napravljena. Dok ne bude, tvrdnja da način rada sa pozivima troši više tokena ostaje bez odgovora.

Još tri stvari treba reći otvoreno, jer čitalac koji završi ovaj članak ne bi smeo da ih zamišlja:

  • Danas se ne izvršava nikakav kod koji su napisali korisnici. Čitanja preko konektora su jedan zahtev po pozivu, bez sandboksa na putu. U našem steku postoji izvršilac koda i to je interni alat. U produkciji je isključen osim ako nisu postavljene dve zasebne zastavice i odgovara samo administratorima. Svaki poziv dobija svež kontekst, povezivanja koja dozvoljavaju samo čitanje i budžet od dve sekunde za sinhroni kod. Njegovo sopstveno zaglavlje velikim slovima kaže da je granica ispravnosti, a ne bezbednosti.
  • Nema REPL-a. Ništa što agent izračuna u jednom pozivu nije dostupno u sledećem, osim ako nije sačuvano kao zapis sa id-jem.
  • Nema trajne sesije agenta. Klijent čuva svoj razgovor. Tajo čuva predloge, planove, kursore i zaključavanja. Treće stvari nema.

Čemu služi trajni mehanizam

Ništa od ovoga nije argument protiv dquickts. Njegov README navodi čemu služe snimci (snapshots) i taj spisak je dobar. Uspavati neaktivnu skriptu i osloboditi njenu memoriju. Izvoditi dugačak proračun u delovima na bilo kom slobodnom radniku. Toplo pokretati svaku instancu iz snimka umesto ponavljanja pripreme. Parkirati skriptu na pozivu domaćina čiji odgovor stiže kasnije. Za radni prostor agenta koji programira ili za beležnicu (notebook) koja treba da preživi ponovno pokretanje, to je pravi alat.

Sinhronizacija ipak ne bi trebalo da zavisi od njega, iz tri razloga koja mi daje sam README. Prvo: „Datoteka sesije se učitava samo u qjs build koji ju je zapisao.“ Hip koji je zapisala jedna verzija mehanizma posle nadogradnje je mrtva datoteka; kursor je niska. Drugo: „Snimci su pouzdan ulaz, kao bajtkod“ i „zlonamerni se ne otkrivaju“. Sačuvani hip morate da štitite, ne možete da ga pregledate; predlog je red koji čovek pročita pre nego što ga odobri. Treće, snimak sadrži sve što je skripta pročitala, uključujući zapise korisnika. Gore opisani zapisi napravljeni su obrnuto: plan čuva sažetke, a ne vrednosti, a zapis predloga nikada ne čuva odgovor provajdera.

Jedno od pravila po kojima gradimo kaže da determinističko pobeđuje pametno. Hip koji nastavlja usred petlje je pametan. Kursor, predlog, zaključavanje i plan su dosadni, mogu se pregledati i isti su na svakom mehanizmu, u svakom klijentu, posle svakog pada.

Lütke je postavio pravo pitanje. Gde živi stanje? Kod sinhronizacije odgovor nikada nije mogao da bude u procesu. Uvek je morao da bude u zapisima, jer upravo tamo čovek koji odobrava upis mora da može da ga pročita.

Često Postavljana Pitanja

Da li je za AI agente bolji MCP ili CLI?

Sam po sebi nijedan. Zapažanje Tobija Lütkea od 21. septembra 2026. važi: oboje radi čim pozivi prolaze kroz nešto što čuva stanje između koraka. CLI danas deluje bolje jer bash čuva stanje u sistemu datoteka. Razlika nije u protokolu, nego u izvršnom okruženju.

Koje stanje je agentu potrebno između koraka sinhronizacije?

Sopstveni zapisi integracije: kursor koji kaže gde je stalo poslednje pokretanje, predlog koji čeka odobrenje čoveka, zaključavanje (lease) koje kaže koji radnik drži pokretanje i plan probnog pokretanja (dry run) sa kojim izvršenje mora da se poklapa. Ništa od toga nije promenljiva u skripti. To su redovi sa id-jevima.

Zašto MCP server Tajo ne čuva ništa u sesiji?

Svaki zahtev dobija svež server i transport bez id-ja sesije. Sve što je sledećem pozivu potrebno je zapis: id predloga, id plana, kursor. Tako drugi agent, u drugom klijentu, može da nastavi tamo gde je prvi stao, a srušeni agent ne gubi ništa osim sopstvenog kontekstnog prozora.

Da li Tajo izvršava kod koji su napisali agenti?

Za korisnike ne. Čitanja na alatima konektora su jedan zahtev po pozivu, bez sandboksa. Izvršilac koda koji postoji je interni alat iza dve zastavice, dostupan samo administratorima, sa povezivanjima samo za čitanje i svežim kontekstom po pozivu. Za sebe kaže da nije bezbednosna granica. Nema REPL-a ni trajne sesije.

Čemu služi trajni JavaScript mehanizam poput dquickts?

Njegov README navodi namene: uspavati neaktivnu skriptu, podeliti dugačak proračun na radnike, toplo pokrenuti iz snimka i parkirati skriptu na pozivu domaćina čiji odgovor stiže satima kasnije. Sve je to stvarno. Sinhronizacija ipak ne bi trebalo da zavisi od njega: snimak se učitava samo u build mehanizma koji ga je zapisao, recenzentu je neproziran i sadrži sve podatke korisnika koje je skripta pročitala.

Zatražite rani pristup

Unesite ime i adresu e-pošte. Poslaćemo vam vezu za potvrdu zahteva za pristup Taju.

Preuzmite Brevo

Ova stranica kao Markdown: mcp-or-cli-is-the-wrong-question.md

Učitavanje Markdowna…
Otvori u Claude Otvori u ChatGPT