MCP ή CLI είναι λάθος ερώτηση. Ρωτήστε πού ζει η κατάσταση.

Ο Tobi Lütke λέει ότι η αντιπαράθεση MCP έναντι CLI γίνεται στο λάθος επίπεδο: και τα δύο λειτουργούν μόλις η κατάσταση διατηρείται ανάμεσα στα βήματα. Συμφωνούμε. Σε έναν συγχρονισμό, αυτή η κατάσταση είναι οι ίδιες οι εγγραφές της ενοποίησης, όχι το heap ενός REPL, και γι' αυτό τα εργαλεία MCP του Tajo δεν κρατούν τίποτα σε συνεδρία.

mcp ή cli

Πρέπει ένας πράκτορας AI να χρησιμοποιεί MCP ή CLI;

Ο Lütke έχει δίκιο ότι το MCP έναντι CLI είναι το λάθος επίπεδο: και τα δύο λειτουργούν μόλις η κατάσταση διατηρείται ανάμεσα στα βήματα, και το bash κερδίζει μόνο επειδή το σύστημα αρχείων είναι αυτή η κατάσταση. Σε έναν συγχρονισμό όμως, η κατάσταση δεν είναι το heap ενός REPL. Είναι οι ίδιες οι εγγραφές της ενοποίησης: ένας κέρσορας, μια εκκρεμής πρόταση, ένα lease, ένα πλάνο. Γι' αυτό τα εργαλεία MCP του Tajo δεν κρατούν τίποτα σε συνεδρία: οποιοσδήποτε πράκτορας, από οποιονδήποτε client, συνεχίζει από τις εγγραφές. Το Tajo δεν εκτελεί σήμερα κώδικα πελατών και δεν έχει REPL, και το λέμε καθαρά παρακάτω.

Μάθετε περισσότερα
Σε αυτή τη σελίδα

Στις 21 Σεπτεμβρίου 2026, στις 00:33 UTC, ο Tobi Lütke δημοσίευσε το εξής: «Το MCP έναντι CLI για τα LLM είναι λάθος συζήτηση. Οι άνθρωποι διαφωνούν στο λάθος επίπεδο». Έπειτα, στις 23 Οκτωβρίου, έδειξε ένα νέο αποθετήριο με όνομα dquickts. Είναι ένα fork του QuickJS που μπορεί να παγώσει ένα πρόγραμμα στη μέση ενός βρόχου for, να γράψει ολόκληρο το heap του σε bytes και να το συνεχίσει σε άλλη διεργασία. «Εξαιρετικό περιβάλλον για code mode», έγραψε.

Έχει δίκιο για το επίπεδο. Θέλω πρώτα να συμφωνήσω μαζί του, με τα δικά του λόγια, και μετά να στενέψω τον ισχυρισμό μέχρι να λέει κάτι που μπορεί να χρησιμοποιήσει ένας συγχρονισμός.

Το επίπεδο που εννοεί

Ιδού το επιχείρημα όπως το διατύπωσε ο ίδιος, γιατί μόνο έτσι είναι δίκαιο να παραθέτει κανείς ένα επιχείρημα που σκοπεύει να λυγίσει:

Και τα δύο λειτουργούν απίστευτα καλά, αρκεί να εκτελούνται μέσα από ένα περιβάλλον τύπου REPL που μπορεί να διατηρεί κατάσταση. Το αστείο με το CLI είναι ότι στα εργαλεία CLI συνήθως έχουμε πρόσβαση μέσω του BASH, που τυχαίνει να είναι ένα REPL με μόνιμη κατάσταση (το σύστημα αρχείων), γι’ αυτό το CLI λειτουργεί πολύ καλύτερα από το MCP. Αλλά αυτό δεν είναι ούτε κατά διάνοια εγγενής ιδιότητα του MCP. Σημαίνει απλώς ότι χρειαζόμαστε καλύτερα harnesses.

Αυτό είναι σωστό, και εξηγεί μια παρατήρηση που πολλοί έχουν κάνει χωρίς να την εξηγήσουν. Ένας πράκτορας που παίρνει ένα CLI γράφει ένα αρχείο, το ξαναδιαβάζει τρία βήματα αργότερα, ψάχνει μέσα του με grep, το περνά σε pipe. Ένας πράκτορας που παίρνει έναν γυμνό MCP server παίρνει ένα αποτέλεσμα ανά κλήση και πρέπει να κουβαλά όλα τα υπόλοιπα στο παράθυρο συμφραζομένων του. Το CLI δεν κέρδισε χάρη στο πρωτόκολλο. Κέρδισε επειδή το bash ερχόταν με ένα μέρος για να βάζεις πράγματα.

Το στοίχημά του προκύπτει από αυτό. Κάποιος φτιάχνει μια ενσωματώσιμη μηχανή, σε στιλ SQLite, που μετατρέπει bash, TypeScript ή κλήσεις εργαλείων σε ένα ενιαίο πλάνο, ελεγμένο πριν εκτελεστεί και φτιαγμένο για ανθεκτική εκτέλεση. Το dquickts είναι ένα βήμα προς αυτό. Το README του περιγράφει ένα REPL «του οποίου οι συναρτήσεις και οι μεταβλητές επιβιώνουν από επανεκκινήσεις». Περιγράφει επίσης μια ανθεκτική κλήση προς τον host: «ένα script καλεί μια συνάρτηση του host της οποίας η απάντηση φτάνει ώρες αργότερα. Η διεργασία αποθηκεύει το script και τερματίζει».

Ως εδώ, πλήρης συμφωνία. Τώρα το στένεμα.

Ποια κατάσταση, για ποια δουλειά

Το «διατήρηση κατάστασης» κρύβει μια ερώτηση: ποιανού η κατάσταση και σε ποια μορφή; Για έναν πράκτορα προγραμματισμού, η κατάσταση είναι το αποθετήριο και το shell, και ένα REPL που επιβιώνει από επανεκκινήσεις είναι καλή απάντηση. Για έναν πράκτορα που χτίζει συγχρονισμό ανάμεσα σε δύο συστήματα SaaS, η κατάσταση που χρειάζεται ανάμεσα στα βήματα ορίζεται ήδη από τη δουλειά. Τη μεταφέρουν τέσσερις εγγραφές, και καμία δεν είναι μεταβλητή σε ένα script.

Ο κέρσορας. Ένας συγχρονισμός διαβάζει μια πηγή σε παράθυρα και πρέπει να ξέρει πού τελείωσε το τελευταίο παράθυρο. Στη μηχανή συγχρονισμού του Tajo αυτό είναι ένας αποθηκευμένος κέρσορας ανά συγχρονισμό και εύρος, που γράφεται μετά από κάθε παρτίδα χωρίς καμία αποτυχημένη εγγραφή, και η επόμενη εκτέλεση συνεχίζει από αυτόν. Μια προγραμματισμένη εκτέλεση αποθηκεύει το σημείο εκκίνησής της πριν κάνει οτιδήποτε άλλο, ώστε αν μια πρώτη εκτέλεση αποτύχει, η επόμενη να διαβάζει από το ίδιο σημείο. Η αρχή πίσω από αυτό, στείλτε τη διαφορά (delta) και ποτέ τον πίνακα, εξηγείται στον οδηγό για το reverse ETL. Αφήνω τον κέρσορα εκεί.

Η εκκρεμής πρόταση. Στα εργαλεία MCP των connectors του Tajo, μια εγγραφή είναι δύο κλήσεις. Το brevo_propose επικυρώνει την είσοδο έναντι της δηλωμένης ενέργειας και καταγράφει μια πρόταση. Δεν αποστέλλεται τίποτα. Το αποτέλεσμα περιέχει ένα αναγνωριστικό πρότασης και, όταν πρέπει να αποφασίσει ένας άνθρωπος, τη σελίδα όπου την εγκρίνει. Το brevo_apply εκτελεί με τη σειρά τις εγκεκριμένες εγγραφές εκείνης της σύνδεσης και σταματά στην πρώτη που ακόμη περιμένει έναν άνθρωπο. Η εγγραφή ανάμεσα είναι η κατάσταση. Περιέχει την είσοδο και ένα digest της, ώστε μια εγκεκριμένη εγγραφή να μην μπορεί να αλλάξει ανάμεσα στην απόφαση και την εφαρμογή. Δεν περιέχει τις τιμές της απάντησης του παρόχου, επειδή μια εγγραφή έγκρισης μόνο προσθήκης (append-only) δεν πρέπει να γίνει αποθήκη προσωπικών δεδομένων.

Το lease. Μια εκτέλεση συγχρονισμού κατέχει ένα αποκλειστικό lease για όλη τη διάρκεια ζωής της, με token κατόχου, προεπιλεγμένο χρονικό όριο δεκαπέντε λεπτών και ανανέωση. Ένας ληγμένος κάτοχος δεν μπορεί να απελευθερώσει ένα νεότερο lease. Αν η αποθήκη των lease δεν είναι προσβάσιμη, η εκτέλεση αρνείται να ξεκινήσει αντί να μαντέψει. Ποιος worker κατέχει την εκτέλεση είναι γεγονός καταγεγραμμένο στο lease, όχι στη μνήμη κάποιας διεργασίας.

Το πλάνο. Το syncs.dryRun διαβάζει το επόμενο παράθυρο από τον κέρσορα, υπολογίζει για κάθε εγγραφή εισαγωγή, ενημέρωση, διαγραφή ή καμία αλλαγή, και γράφει ακριβώς μία γραμμή: το πλάνο, που διατηρείται για μία ώρα. Δεν μετακινεί κανέναν κέρσορα και δεν γράφει τίποτα σε κανένα από τα δύο συστήματα. Το syncs.apply γράφει αυτό το πλάνο μία φορά. Αρνείται αν ο κέρσορας έχει μετακινηθεί ή αν στο μεταξύ άλλαξε περισσότερο από ένα ανεκτό ποσοστό των εγγραφών. Μια επανάληψη επιστρέφει το πρώτο αποτέλεσμα αντί να γράψει ξανά.

Αυτή είναι η κατάσταση ανάμεσα στα βήματα: τέσσερις εγγραφές με αναγνωριστικά, αναγνώσιμες από κάθε πράκτορα που έχει δικαίωμα να τις βλέπει.

Γιατί η πλευρά MCP δεν κρατά τίποτα σε συνεδρία

Μόλις η κατάσταση βρίσκεται στις εγγραφές, σε μια συνεδρία δεν μένει τίποτα να κρατήσει. Γι’ αυτό τα endpoints MCP του Tajo δεν κρατούν συνεδρία. Κάθε αίτημα παίρνει νέο server και μεταφορά χωρίς αναγνωριστικό συνεδρίας. Οι αναγνώσεις είναι ένα αίτημα ανά κλήση, με αποτελέσματα περιορισμένου μεγέθους ώστε μία απάντηση να μην μπορεί να πλημμυρίσει έναν γύρο. Οι εγγραφές είναι πρώτα πρόταση και μετά εφαρμογή, και αυτό που κουβαλάτε είναι το αναγνωριστικό της πρότασης.

Το πρωτόκολλο κινήθηκε προς την ίδια κατεύθυνση. Η αναθεώρηση 2026-07-28 της προδιαγραφής MCP αφαίρεσε τις συνεδρίες σε επίπεδο πρωτοκόλλου και την κεφαλίδα Mcp-Session-Id από τη μεταφορά Streamable HTTP. Ένας server που χρειάζεται συνέχεια εκδίδει πλέον το δικό του αναγνωριστικό και το παίρνει πίσω ως κανονικό όρισμα. Αυτό ακριβώς είναι ένα αναγνωριστικό πρότασης. Το άρθρο Τι είναι ένας MCP server καλύπτει αυτή την αναθεώρηση και το πώς μια κλήση εργαλείου διαφέρει από έναν ανθεκτικό συγχρονισμό. Το παρόν κείμενο αφορά μόνο το πού πηγαίνει η κατάσταση.

Η συνέπεια είναι αυτή που μετρά για τη δουλειά ενοποίησης. Ας πούμε ότι ένας πράκτορας στο Claude Code προτείνει μια εγγραφή και η συνεδρία του τελειώνει. Ο άνθρωπος την εγκρίνει μία ώρα αργότερα. Ένας πράκτορας σε άλλον client, ή ο ίδιος την επόμενη μέρα, καλεί το apply με το αναγνωριστικό και η εγγραφή εφαρμόζεται, μία φορά. Ένας πράκτορας που κατέρρευσε χάνει το παράθυρο συμφραζομένων του και τίποτε άλλο. Τίποτα δεν είχε ανασταλεί, οπότε τίποτα δεν χρειάστηκε να συνεχιστεί.

Τι δεν έχουμε και τι κοστίζει

Η τίμια ένσταση έρχεται από την πλευρά του REPL και λέει περίπου: «Εντάξει, οι εγγραφές σας επιβιώνουν. Όμως κάθε κλήση ξαναδιαβάζει ό,τι είχε ήδη η προηγούμενη. Ένα script θα έφερνε τις επαφές μία φορά, θα τις ένωνε, θα τις φιλτράριζε και θα επέστρεφε έναν αριθμό. Ο πράκτοράς σας κάνει πέντε κλήσεις και πληρώνει για την καθεμία». Η ένσταση έχει δίκιο για τον μηχανισμό, και εμείς δεν έχουμε μετρήσει το κόστος. Η αξιολόγηση που θα μετρούσε τις κλήσεις ανά εργασία με και χωρίς μεταφερόμενη κατάσταση δεν έχει φτιαχτεί. Μέχρι να φτιαχτεί, ο ισχυρισμός ότι η λειτουργία με κλήσεις κοστίζει περισσότερα tokens μένει αναπάντητος.

Τρία ακόμη πράγματα πρέπει να ειπωθούν καθαρά, γιατί ένας αναγνώστης που τελειώνει αυτό το άρθρο δεν πρέπει να τα φανταστεί:

  • Σήμερα δεν εκτελείται κώδικας γραμμένος από πελάτες. Οι αναγνώσεις των connectors είναι ένα αίτημα ανά κλήση, χωρίς sandbox στη διαδρομή. Στο stack μας υπάρχει ένας εκτελεστής κώδικα, και είναι εσωτερικό εργαλείο. Σε παραγωγή είναι απενεργοποιημένος εκτός αν έχουν οριστεί δύο ξεχωριστές σημαίες, και απαντά μόνο σε διαχειριστές. Κάθε κλήση παίρνει νέο πλαίσιο, συνδέσεις που επιτρέπουν μόνο αναγνώσεις, και προϋπολογισμό δύο δευτερολέπτων για σύγχρονο κώδικα. Η ίδια η κεφαλίδα του λέει με κεφαλαία ότι είναι όριο ορθότητας, όχι ασφάλειας.
  • Κανένα REPL. Τίποτα από όσα υπολογίζει ένας πράκτορας σε μια κλήση δεν είναι διαθέσιμο στην επόμενη, εκτός αν γράφτηκε ως εγγραφή με αναγνωριστικό.
  • Καμία μόνιμη συνεδρία πράκτορα. Ο client κρατά τη συνομιλία του. Το Tajo κρατά τις προτάσεις, τα πλάνα, τους κέρσορες και τα lease. Τρίτο πράγμα δεν υπάρχει.

Σε τι χρησιμεύει μια ανθεκτική μηχανή

Τίποτα από αυτά δεν είναι επιχείρημα κατά του dquickts. Το README του απαριθμεί σε τι χρησιμεύουν τα snapshots, και η λίστα είναι καλή. Αδρανοποιείτε ένα αδρανές script και ελευθερώνετε τη μνήμη του. Εκτελείτε έναν μακρύ υπολογισμό σε τμήματα σε όποιον worker είναι ελεύθερος. Κάνετε θερμή εκκίνηση κάθε στιγμιότυπου από ένα snapshot αντί να επαναλαμβάνετε τη ρύθμιση. Σταθμεύετε ένα script σε μια κλήση προς τον host της οποίας η απάντηση φτάνει αργότερα. Για τον χώρο εργασίας ενός πράκτορα προγραμματισμού, ή για ένα notebook που πρέπει να επιβιώσει από μια επανεκκίνηση, αυτό είναι το σωστό εργαλείο.

Ένας συγχρονισμός όμως δεν πρέπει να εξαρτάται από μια τέτοια μηχανή, για τρεις λόγους που μου δίνει το ίδιο το README. Πρώτον: «Ένα αρχείο συνεδρίας φορτώνεται μόνο στο build του qjs που το έγραψε». Ένα heap γραμμένο από μια έκδοση της μηχανής είναι νεκρό αρχείο μετά από μια αναβάθμιση. Ένας κέρσορας είναι μια συμβολοσειρά. Δεύτερον: «Τα snapshots είναι έμπιστη είσοδος, όπως το bytecode», και «τα κακόβουλα δεν ανιχνεύονται». Ένα αποθηκευμένο heap είναι κάτι που πρέπει να προστατεύετε, όχι κάτι που μπορείτε να ελέγξετε. Μια πρόταση είναι μια γραμμή που διαβάζει ένας άνθρωπος πριν την εγκρίνει. Τρίτον, ένα snapshot περιέχει ό,τι είχε διαβάσει το script, μαζί και εγγραφές πελατών. Οι εγγραφές παραπάνω είναι φτιαγμένες ανάποδα: το πλάνο αποθηκεύει digests, όχι τιμές, και η εγγραφή της πρότασης δεν αποθηκεύει ποτέ την απάντηση του παρόχου.

Ένας από τους κανόνες με τους οποίους χτίζουμε είναι ότι το ντετερμινιστικό νικά το έξυπνο. Ένα heap που συνεχίζει στη μέση ενός βρόχου είναι έξυπνο. Ένας κέρσορας, μια πρόταση, ένα lease και ένα πλάνο είναι βαρετά, ελέγξιμα, και ίδια σε κάθε μηχανή, σε κάθε client, μετά από κάθε κατάρρευση.

Ο Lütke έθεσε τη σωστή ερώτηση. Πού ζει η κατάσταση; Σε έναν συγχρονισμό, η απάντηση δεν θα μπορούσε ποτέ να βρίσκεται στη διεργασία. Θα βρισκόταν πάντα στις εγγραφές, γιατί εκεί πρέπει να μπορεί να τη διαβάσει ο άνθρωπος που εγκρίνει την εγγραφή.

Έχετε Ερωτήσεις; Έχουμε Απαντήσεις

Είναι καλύτερο το MCP ή ένα CLI για τους πράκτορες AI;

Κανένα από τα δύο, από μόνο του. Η θέση του Tobi Lütke από τις 21 Σεπτεμβρίου 2026 ισχύει: και τα δύο λειτουργούν μόλις οι κλήσεις περνούν μέσα από κάτι που διατηρεί την κατάσταση ανάμεσα στα βήματα. Ένα CLI μοιάζει καλύτερο σήμερα επειδή το bash κρατά την κατάσταση στο σύστημα αρχείων. Η διαφορά δεν είναι το πρωτόκολλο, αλλά το περιβάλλον εκτέλεσης (harness).

Ποια κατάσταση χρειάζεται ένας πράκτορας ανάμεσα στα βήματα ενός συγχρονισμού;

Τις ίδιες τις εγγραφές της ενοποίησης: έναν κέρσορα που δείχνει πού σταμάτησε η τελευταία εκτέλεση, μια πρόταση που περιμένει την έγκριση ενός ανθρώπου, ένα lease που δείχνει ποιος worker κατέχει την εκτέλεση, και ένα πλάνο dry-run με το οποίο πρέπει να ταιριάζει η εφαρμογή. Τίποτα από αυτά δεν είναι μεταβλητή σε ένα script. Είναι γραμμές με αναγνωριστικά.

Γιατί ο MCP server του Tajo δεν κρατά τίποτα σε συνεδρία;

Κάθε αίτημα παίρνει νέο server και μεταφορά χωρίς αναγνωριστικό συνεδρίας. Ό,τι χρειάζεται η επόμενη κλήση είναι μια εγγραφή: ένα αναγνωριστικό πρότασης, ένα αναγνωριστικό πλάνου, ένας κέρσορας. Έτσι ένας δεύτερος πράκτορας, σε άλλον client, μπορεί να συνεχίσει από εκεί που σταμάτησε ο πρώτος, και ένας πράκτορας που κατέρρευσε δεν χάνει τίποτα πέρα από το δικό του παράθυρο συμφραζομένων.

Εκτελεί το Tajo κώδικα γραμμένο από πράκτορες;

Όχι για πελάτες. Οι αναγνώσεις μέσω των εργαλείων των connectors είναι ένα αίτημα ανά κλήση, χωρίς sandbox. Ο εκτελεστής κώδικα που υπάρχει είναι εσωτερικό εργαλείο πίσω από δύο σημαίες (flags), προσβάσιμο μόνο από διαχειριστές, με συνδέσεις (bindings) μόνο για ανάγνωση και νέο πλαίσιο σε κάθε κλήση. Για τον εαυτό του λέει ότι δεν αποτελεί όριο ασφάλειας. Δεν υπάρχει REPL ούτε μόνιμη συνεδρία.

Σε τι χρησιμεύει μια ανθεκτική μηχανή JavaScript όπως το dquickts;

Το README του κατονομάζει τις χρήσεις: αδρανοποίηση ενός αδρανούς script, τεμαχισμός ενός μακρού υπολογισμού ανάμεσα σε workers, θερμή εκκίνηση από snapshot, και στάθμευση ενός script σε μια κλήση προς τον host της οποίας η απάντηση φτάνει ώρες αργότερα. Όλες είναι πραγματικές. Ένας συγχρονισμός όμως δεν πρέπει να εξαρτάται από μια τέτοια μηχανή: ένα snapshot φορτώνεται μόνο στο build της μηχανής που το έγραψε, είναι αδιαφανές για όποιον το ελέγχει και περιέχει όσα δεδομένα πελατών διάβασε το script.

Ζητήστε πρώιμη πρόσβαση

Συμπληρώστε το μικρό σας όνομα και τη διεύθυνση email σας. Θα σας στείλουμε σύνδεσμο για να επιβεβαιώσετε το αίτημα πρόσβασης στο Tajo.

Αποκτήστε Brevo

Αυτή η σελίδα ως Markdown: mcp-or-cli-is-the-wrong-question.md

Φόρτωση Markdown…
Άνοιγμα στο Claude Άνοιγμα στο ChatGPT