פרוטוקול שיחת מודל (MCP) שיפר באופן משמעותי את האופן שבו עוזרי AI אינטראקציה עם כלים חיצוניים, ומאפשר יישומים חזקים יותר וגמישים יותר, עם זאת, קיים מגבלת מפתח בתוך יישום MCP סטנדרטי: שיחות כלים הן למעשה פעולות "קופסת שחורה" ללא ממשק משתמש מובנה לאינטראקציה.
במאמר זה, אחקור גישה חדשנית שפיתחנו ב21 הקסם MCPכדי להתגבר על הגבלה זו על ידי יצירת ממשק מבוסס דפדפן עבור תקשורת MCP, המתמקד במיוחד על ייצור רכיב UI עם 21st.dev האינטגרציה שלנו.
בעיה: אינטראקציה מוגבלת עם משתמשים ב- MCP
Model Calling Protocol מאפשר לעוזרי AI להזמין כלים חיצוניים כדי לבצע משימות מיוחדות.
הגבלה זו היא בעייתית במיוחד בעת יצירת רכיבי UI.כאשר AI מציעה רכיב UI, משתמשים צריכים לעתים קרובות:
-
See various design options
-
Compare different implementations
-
Customize details before integration
-
Make informed choices based on visual representation
הגישה הסטנדרטית של MCP אינה מציעה מנגנון מובנה לסוג זה של מעגל משוב אינטראקטיבי.
פתרון: תקשורת MCP מבוססת דפדפן
כדי להתמודד עם הגבלה זו, פיתחנו מערכת המאפשרת תקשורת עם MCP באמצעות ממשק דפדפן.
- יוצר MCP מקומי שיכול לארח חבילה ולפתוח דפדפן אינטרנט
- משרת חבילה מקומית לצד MCP ב- NPM
- פותח אוטומטית דפדפן שמפנה מחדש לממשק משתמש
- מאפשר למשתמשים לקיים אינטראקציה ולבחור מהאפשרויות הזמינות
- סוגרים את השרת ומחזירים את הביצוע עם בחירת המשתמש
התוצאה היא אינטגרציה אלגנטית שמחזיקה בכוחו של MCP תוך הוספת משוב ויזואלי ויכולות אינטראקציה המשתמשים צריכים.
יישום טכני
בואו נראה איך זה מתבצע.
שרת Callback
ליבה של הפתרון שלנו הוא שרת Callback המאפשר תקשורת בין MCP לבין ממשק הדפדפן:
export class CallbackServer {
private server: Server | null = null;
private port: number;
private sessionId = Math.random().toString(36).substring(7);
// ... other properties
async promptUser(
config: CallbackServerConfig = {}
): Promise<CallbackResponse> {
const { initialData = null, timeout = 300000 } = config;
this.config = config;
try {
const availablePort = await this.findAvailablePort();
this.server = createServer(this.handleRequest);
this.server.listen(availablePort, "127.0.0.1");
// Set up promise to handle user selection
return new Promise<CallbackResponse>((resolve, reject) => {
this.promiseResolve = resolve;
this.promiseReject = reject;
// ... server setup code
// Open browser with unique session ID
const url = `http://127.0.0.1:${availablePort}?id=${this.sessionId}`;
open(url).catch((error) => {
console.warn("Failed to open browser:", error);
resolve({ data: { browserOpenFailed: true } });
this.shutdown();
});
});
} catch (error) {
await this.shutdown();
throw error;
}
}
}
על השרת הזה:
- מציאת דלת זמינה באופן דינמי
- יצירת מזהה פגישה ייחודי עבור כל בקשה
- תגית: UI Bundle
- פתח את הדפדפן כדי להציג אפשרויות
- מקבל את הבחירה של המשתמש באמצעות שיחה חזרה
- פותר את ההבטחה עם הנתונים שנבחרו
Integration with MCP tool
היינו מיישמים גישה זו כדי לשפר את כלי 21st_magic_component_builder שלנו, אשר מייצר רכיבי UI:
export class CreateUiTool extends BaseTool {
name = UI_TOOL_NAME;
description = UI_TOOL_DESCRIPTION;
// ... schema definition
async execute({
message,
searchQuery,
absolutePathToCurrentFile,
context,
}: z.infer<typeof this.schema>): Promise<{
content: Array<{ type: "text"; text: string }>;
}> {
try {
// Fetch UI component variations from API
const response = await twentyFirstClient.post<{
data1: { text: string };
data2: { text: string };
data3: { text: string };
}>("/api/create-ui-variation", {
message,
searchQuery,
fileContent: await getContentOfFile(absolutePathToCurrentFile),
context,
});
// Handle billing or error cases
if (response.status !== 200) {
open("https://21st.dev/settings/billing");
return {
content: [
{
type: "text" as const,
text: response.data.text as string,
},
],
};
}
// Create server and prompt user through browser
const server = new CallbackServer();
const { data } = await server.promptUser({
initialData: {
data1: response.data.data1,
data2: response.data.data2,
data3: response.data.data3,
},
});
// Process user selection and return formatted response
const componentData = data || {
text: "No component data received. Please try again.",
};
// Return formatted response to user
// ...
} catch (error) {
console.error("Error executing tool", error);
throw error;
}
}
}
חווית משתמש Flow
הנה כיצד חווית המשתמש זורמת בעת בקשת רכיב UI:
- הזמנה של כלי: עוזר ה-AI מזמין את כלי 21st_magic_component_builder כאשר משתמש מבקש רכיב UI חדש.
- בקשת API: הכלי שולח בקשה ל- 21st.dev API כדי ליצור מגוונות מרובות של רכיבי ה- UI בהתבסס על המסר והקשר של המשתמש.
- הפעלת דפדפן: שרת מקומי נפתח וחלון הדפדפן נפתח באופן אוטומטי, המציג את אפשרויות הרכיב UI שנוצרו.
- אינטראקציה עם המשתמש: המשתמש יכול להציג, לקיים אינטראקציה עם, ולבחור את מגוון הרכיבים המועדף עליו.
- קלטת בחירה: כאשר המשתמש מבצע בחירה, הדפדפן שולח את הבחירה בחזרה לשרת השיחה.
- חידוש ביצוע: השרת נסגר והביצוע חוזר עם הנתונים של הרכיב שנבחר.
- מדריך לאינטגרציה: עוזר ה-AI מקבל את הרכיב שנבחר ומספק הדרכה על שילובו למסד הקוד של המשתמש.
גישה זו יוצרת חוויה חלקה המאפשרת למשתמשים לקבל החלטות מודעות לגבי רכיבי ה- UI תוך שמירה על זרימת העבודה הכוללת של MCP.
חששות אבטחה ופרטיות
היישום שלנו לוקח מספר אמצעי אבטחה:
- Local Hosting: All communication happens locally on the user's machine (127.0.0.1)
- מזהה פגישה ייחודי: לכל פגישה בדפדפן יש מזהה ייחודי למניעת הפרעות בין הפגישות
- מנגנון הפסקת זמן: הפגישות ייגמרו באופן אוטומטי לאחר תקופה מוגדרת (כפופות 5 דקות)
- אבטחת נמל: השרת מוצא באופן דינמי נמל זמין כדי למנוע קונפליקטים
מסקנה
הגישה המבוססת על דפדפן לתקשורת MCP מייצגת שיפור משמעותי בחוויית המשתמש בעת עבודה עם כלים המועילים באינטראקציה חזותית. על ידי חיבור בין הפער בין היכולות החזקות של MCP לבין האופי האינטראקטיבי של ממשקי האינטרנט, יצרנו זרימת עבודה אינטואיטיבית יותר למשתמשים. גישה זו היא בעלת ערך במיוחד עבור ייצור רכיבי UI, שם ייצוג חזותי הוא קריטי לקבלת החלטות מודעות.
קוד המקור זמין בGithub.