⁦MCP⁩ لوكلاء البرمجة

⁦text mcp⁩: أتح لوكلاء البرمجة التنقل وضغط المفاتيح وقراءة الإطارات عبر بروتوكول سياق النموذج.

يشغّل text mcp دليل app/ دون واجهة، داخل العملية نفسها، ويتيحه عبر بروتوكول سياق النموذج لتستخدمه وكلاء البرمجة دون 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

أو أضفه إلى مستودع الفريق:

.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 قيد التنفيذ، ولا تثبيت تغييرات أو إطار خلال 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