⁦MCP⁩ לסוכני קוד

⁦text mcp⁩: לאפשר לסוכני קוד לנווט, ללחוץ על מקשים ולקרוא פריימים דרך ⁦Model Context Protocol⁩.

text mcp מריץ את הספרייה app/ ללא ממשק גרפי, בתוך התהליך, ומגיש אותה דרך פרוטוקול ⁦Model Context⁩ כדי שסוכני תכנות יוכלו להשתמש בה ללא DevTools. הסוכן מנווט, לוחץ על מקשים, קורא פריימים כטקסט רגיל וקורא למטפלי נתיבים.

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

text mcp דורש Bun. כשהוא מופעל עם Node, הוא מריץ את עצמו מחדש עם Bun אם bun נמצא ב-PATH, ואחרת נכשל עם TX019. לקוחות MCP מפעילים אותו, כך שלעיתים רחוקות יש צורך להריץ אותו ידנית.

הגדרה

כל לקוח מפעיל את text mcp מתוך ספריית הפרויקט. יש להשתמש ב-bunx --bun כדי שקובצי הנתיבים ירוצו כ-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

או לשמור אותו ב-commit עבור הצוות:

.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"] }  }}

לפרויקט בספריית משנה, יש להוסיף את הנתיב לסוף: ["--bun", "text", "mcp", "apps/console"].

כלים

כליתיאור
list_routesדפים ומטפלי נתיבים בספרייה app/, והמיקום הנוכחי
navigateהוספה או החלפה של נתיב, או מעבר back / forward
read_frameהפריים כטקסט, עם נתיב, גודל, מיקוד וסמן. styles: true מוסיף צבעים ומאפיינים לכל span
pressצירופי מקשים: "down", "ctrl+k", "shift+tab", "tab tab enter", "down*3"
typeהקלדת טקסט במקש אחד לכל תו (עד 2,000; לכמות גדולה יותר יש להשתמש ב-paste). submit: true לוחץ על Enter לאחר מכן
pasteאירוע הדבקה אחד, כמו ⌘V
scrollגלילה בגלגלת העכבר לפי rows (וגם cols). רכיב <ScrollBox> גולל באמצעות הגלגלת ללא מיקוד מקלדת
resizeהגדרת גודל הרשת בעמודות ובשורות
inspect_treeעץ הרכיבים עם הגבולות על המסך, וכל מזהה שניתן למקד
findהגבולות של כל התאמה, והרכיב שמתחתיה
wait_forהמתנה להופעת טקסט או להיעלמותו, או למעבר האפליקציה למצב סרק
logsפלט console.* שנלכד ושגיאות React
fetchקריאה למטפל route.ts בתוך התהליך. גופי הודעות נקראים עד maxBytes; זרמי אירועים נקראים למשך streamMs, ואז מבוטלים
reloadייבוא מחדש של האפליקציה לאחר עריכת קבצים

כלי הקלט מחזירים את הפריים החדש, כך שהסוכן אינו זקוק לקריאת read_frame נפרדת אחרי כל מקש. הפריים הנוכחי ורשימת הנתיבים זמינים גם כמשאבים text://frame ו-text://routes.

חילופי הודעות אופייניים:

→ 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  …

פריימים ומצב סרק

לפני שכלי כלשהו קורא פריים, הוא ממתין שהאפליקציה תעבור למצב סרק: אין פריים מתוזמן, אין fetch פעיל, ולא התרחש commit או פריים במשך 50 ms. כך הסוכן רואה את תוצאת הקלט שלו, ולא פריים באמצע עדכון.

רכיב <Spinner> או תרשים שמתעדכן פעם בשנייה עדיין נחשבים במצב סרק בין עדכונים, כך שדפים עם הנפשות נשארים קריאים. אפליקציה שמרנדרת בתדירות גבוהה מפעם בכל 50 ms לעולם אינה עוברת למצב סרק. פעולות הקריאה מפסיקות להמתין אחרי 1.5 שניות (settleMs משנה זאת), מוציאות את הפריים האחרון ומסמנות אותו כ-busy. wait_for ללא טקסט ממתין למצב סרק, עם quietMs משלו, ומחזיר שגיאה אם מצב הסרק אינו מגיע.

הקואורדינטות הן תאים שהמספור שלהם מתחיל באפס: x הוא העמודה, y הוא השורה. תווים רחבים כמו CJK ואימוג'י תופסים שתי עמודות.

שגיאות ויומנים

⁦stdout⁩ מעביר את הפרוטוקול. פלט console.* של האפליקציה, קריאות מזדמנות ל-process.stdout.write ושגיאות React מועברים במקום זאת ל-logs, עם מספור שמאפשר לסוכן לבקש רק רשומות חדשות באמצעות since. אם נרשמו שגיאות מאז הקריאה האחרונה, כותרת הפריים הבא מציינת זאת.

כשלים מוחזרים כשגיאות כלי, ולעולם אינם גורמים לקריסה. כלי שחורג ממגבלת הזמן מבוטל לפני שהקריאה הבאה רצה, כך שקריאה איטית לעולם אינה מקלידה לתוך הפריים של הקריאה הבאה. שגיאות עם קוד Text.js שומרות עליו, למשל TX007 למקש לא מוכר. אם טעינת האפליקציה נכשלת, כל כלי מסביר מדוע. יש לתקן את הקובץ ולקרוא ל-reload.

אפשרויות

אפשרותתיאור
--path <pathname>הנתיב הראשון (ברירת מחדל /)
--cols / --rowsגודל הרשת (ברירת מחדל: viewport בקובץ text.config.ts, אחרת ⁦100×32⁩)
--theme <name>ערכת נושא מוגדרת מראש
--no-configהתעלמות מהקובץ text.config.ts
--verboseכתיבת יומנים שנלכדו גם ל-stderr

אופן הפעולה

text mcp מריץ את האפליקציה באותו אופן כמו text run: כל מודול נתיב מיובא מראש, ה-⁦App Router⁩ משתמש בהיסטוריה בזיכרון, וקריאות fetch("/api/…") לאותו מקור מריצות את המטפלים בתוך התהליך. הפריימים מועברים לרשת תאים מחוץ למסך במקום לטרמינל. דפים שמרונדרים בצד השרת (export const runtime = "server") ורכיבי ה-async function שלהם מרונדרים בתוך התהליך, כמו ב-text dev, והפריים נקרא לאחר שהם מסיימים.

reload מסיר את האפליקציה מעץ הרכיבים, מנקה כל מודול של הפרויקט ממטמון המודולים של Bun (כולל קבצים מחוץ ל-app/), סורק שוב את app/ ומרכיב מחדש במיקום הנוכחי.

כדי להטמיע את השרת בתהליך משלכם, או להשתמש בתעבורה אחרת:

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();

מגבלות

  • האפליקציה רצה ב-Bun, ולא בדפדפן. window ו-document אינם מוגדרים, כמו ב-text run.
  • כל שרת מריץ אפליקציה אחת עם רשת אחת. כל לקוח MCP מפעיל שרת משלו.
  • text mcp מריץ עותק משלו של האפליקציה ללא ממשק גרפי. הוא אינו יכול להתחבר לכרטיסיית דפדפן שפתוחה תחת text dev.
עריכת הדף ב-GitHub