MCP untuk agen pemrograman

text mcp: izinkan agen pemrograman bernavigasi, menekan tombol, dan membaca frame melalui Model Context Protocol.

text mcp menjalankan direktori app/ Anda tanpa antarmuka, dalam proses yang sama, dan menyajikannya melalui Model Context Protocol agar agen pemrograman dapat menggunakannya tanpa DevTools. Agen menavigasi, menekan tombol, membaca frame sebagai teks biasa, dan memanggil route handler.

bunx --bun text mcp              # serve ./app over stdiobunx --bun text mcp apps/console # another project

text mcp memerlukan Bun. Jika dimulai dengan Node, perintah ini menjalankan ulang dirinya dengan Bun saat bun tersedia di PATH Anda, dan gagal dengan TX019 jika tidak. Klien MCP menjalankannya untuk Anda, jadi Anda jarang menjalankannya secara manual.

Penyiapan

Setiap klien menjalankan text mcp dari direktori proyek Anda. Gunakan bunx --bun agar file route berjalan sebagai TypeScript.

OpenCode

opencode.jsonjson
{  "$schema": "https://opencode.ai/config.json",  "mcp": {    "textjs": {      "type": "local",      "command": ["bunx", "--bun", "text", "mcp"],      "enabled": true    }  }}

Claude Code

claude mcp add textjs -- bunx --bun text mcp

Atau commit untuk tim:

.mcp.jsonjson
{  "mcpServers": {    "textjs": { "command": "bunx", "args": ["--bun", "text", "mcp"] }  }}

Cursor

.cursor/mcp.jsonjson
{  "mcpServers": {    "textjs": { "command": "bunx", "args": ["--bun", "text", "mcp"] }  }}

VS Code

.vscode/mcp.jsonjson
{  "servers": {    "textjs": { "type": "stdio", "command": "bunx", "args": ["--bun", "text", "mcp"] }  }}

Untuk proyek dalam subdirektori, tambahkan path di akhir: ["--bun", "text", "mcp", "apps/console"].

Alat

AlatDeskripsi
list_routesHalaman dan route handler dalam app/, serta lokasi saat ini
navigateTambahkan atau ganti path, atau buka back / forward
read_frameFrame sebagai teks, dengan route, ukuran, fokus, dan kursor. styles: true menambahkan warna dan atribut per span
pressKombinasi tombol: "down", "ctrl+k", "shift+tab", "tab tab enter", "down*3"
typeKetik teks dengan satu tombol per karakter (hingga 2.000; gunakan paste untuk lebih banyak). submit: true menekan Enter setelahnya
pasteSatu peristiwa tempel, seperti ⌘V
scrollGulir dengan roda mouse sebanyak rows (dan cols). <ScrollBox> bergulir dengan roda mouse tanpa fokus keyboard
resizeAtur ukuran kisi dalam kolom dan baris
inspect_treePohon komponen dengan batas layar, serta setiap id yang dapat menerima fokus
findBatas setiap kecocokan, dan komponen di bawahnya
wait_forTunggu teks muncul atau hilang, atau aplikasi menjadi idle
logsOutput console.* dan error React yang ditangkap
fetchPanggil handler route.ts dalam proses yang sama. Isi dibaca hingga maxBytes; stream peristiwa selama streamMs, lalu dibatalkan
reloadImpor ulang aplikasi setelah Anda mengedit file

Alat input mengembalikan frame baru, sehingga agen tidak memerlukan read_frame terpisah setelah setiap tombol. Frame saat ini dan daftar route juga tersedia sebagai sumber daya text://frame dan text://routes.

Contoh pertukaran:

→ navigate { "path": "/deployments" }→ press { "keys": "down down enter" }← route: /deployments/dpl_6m3ty8  (route /deployments/[id])  title: "Deployment dpl_6m3ty8 · Edge Console"  size: 100×32  frame: 6  idle  focus: _txr_c_ ScrollBox [4,12 92×18]    ▼ Edge Console   Overview   Deployments   Logs   Settings    ← Deployments  /  dpl_6m3ty8   Ready    Production  …

Frame dan idle

Sebelum alat membaca frame, alat menunggu aplikasi menjadi idle: tidak ada frame terjadwal, tidak ada fetch yang sedang berjalan, dan tidak ada commit atau frame selama 50 ms. Jadi agen melihat hasil inputnya, bukan frame di tengah pembaruan.

<Spinner> atau grafik yang diperbarui sekali per detik tetap dianggap idle di antara pembaruan, sehingga halaman dengan animasi tetap terbaca. Aplikasi yang me-render lebih sering daripada setiap 50 ms tidak pernah menjadi idle. Pembacaan berhenti menunggu setelah 1,5 detik (settleMs mengubah durasi ini), mengeluarkan frame terbaru dan menandainya sebagai busy. wait_for tanpa teks menunggu idle, dengan quietMs tersendiri, dan mengembalikan error jika kondisi idle tidak pernah tercapai.

Koordinat berupa sel berbasis nol: x adalah kolom, y adalah baris. Karakter lebar seperti CJK dan emoji menempati dua kolom.

Error dan log

stdout membawa protokol. Output console.* aplikasi Anda, panggilan process.stdout.write yang tidak semestinya, dan error React dialihkan ke logs, dengan nomor agar agen dapat meminta hanya entri baru menggunakan since. Jika ada error yang dicatat sejak pembacaan terakhir, header frame berikutnya menyatakannya.

Kegagalan dikembalikan sebagai error alat, tidak pernah sebagai crash. Alat yang melewati batas waktu dibatalkan sebelum panggilan berikutnya berjalan, sehingga panggilan yang lambat tidak pernah mengetik ke frame panggilan berikutnya. Error dengan kode Text.js tetap mempertahankan kodenya, misalnya TX007 untuk tombol yang tidak dikenal. Jika aplikasi gagal dimuat, setiap alat menjelaskan alasannya. Perbaiki file lalu panggil reload.

Opsi

OpsiDeskripsi
--path <pathname>Route pertama (default /)
--cols / --rowsUkuran kisi (default: viewport dalam text.config.ts, atau 100×32 jika tidak ada)
--theme <name>Preset tema
--no-configAbaikan text.config.ts
--verboseTulis juga log yang ditangkap ke stderr

Cara kerja

text mcp menjalankan aplikasi Anda dengan cara yang sama seperti text run: setiap modul route diimpor di awal, App Router menggunakan riwayat dalam memori, dan panggilan fetch("/api/…") dengan origin yang sama menjalankan handler Anda dalam proses yang sama. Frame dikirim ke kisi sel di luar layar, bukan ke terminal. Halaman yang di-render di server (export const runtime = "server") dan komponen async function di dalamnya me-render dalam proses yang sama, seperti pada text dev, dan frame dibaca setelah semuanya selesai.

reload melepas aplikasi, menghapus setiap modul proyek dari cache modul Bun (termasuk file di luar app/), memindai app/ lagi dan memasang ulang aplikasi di lokasi saat ini.

Untuk menyematkan server dalam proses Anda sendiri, atau menggunakan transport lain:

import { createTextMcpServer } from "@textjs/app/mcp";import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";const { server, controller } = createTextMcpServer({ root: process.cwd() });await server.connect(new StdioServerTransport());void controller.start();

Batasan

  • Aplikasi berjalan di Bun, bukan browser. window dan document tidak terdefinisi, seperti pada text run.
  • Setiap server menjalankan satu aplikasi dengan satu kisi. Setiap klien MCP memulai servernya sendiri.
  • text mcp menjalankan salinan aplikasi tersendiri tanpa antarmuka. Perintah ini tidak dapat terhubung ke tab browser yang terbuka melalui text dev.
Edit halaman ini di GitHub