El Protocolo de llamada de modelos (MCP) ha mejorado significativamente la forma en que los asistentes de IA interactúan con herramientas externas, permitiendo aplicaciones más potentes y versátiles. Sin embargo, existe una limitación clave dentro de la implementación estándar de MCP: las llamadas de herramientas son esencialmente operaciones de "caixa negra" sin interfaz de usuario integrada para la interacción.
En este artículo, exploraré un enfoque innovador que hemos desarrollado en21o MCP mágicopara superar esta limitación mediante la creación de una interfaz basada en el navegador para las comunicaciones MCP, específicamente enfocada en la generación de componentes de interfaz de usuario con nuestra integración 21st.dev.
Problema: Interacción limitada del usuario en MCP
Model Calling Protocol permite a los asistentes de IA invocar herramientas externas para realizar tareas especializadas.Aunque potente, la implementación estándar tiene una desventaja significativa:
Esta restricción es particularmente problemática cuando se generan componentes de interfaz de usuario.Cuando una IA sugiere un componente de interfaz de usuario, los usuarios a menudo necesitan:
-
See various design options
-
Compare different implementations
-
Customize details before integration
-
Make informed choices based on visual representation
El enfoque estándar de MCP no ofrece ningún mecanismo integrado para este tipo de loop de retroalimentación interactiva.
Solución: Comunicación MCP basada en navegador
Para abordar esta limitación, hemos desarrollado un sistema que permite la comunicación con los MCP a través de una interfaz de navegador.
- Crea un MCP local que puede alojar un paquete y abrir un navegador web
- Sirve un bundle local junto al MCP en NPM
- Abre automáticamente un navegador que redirecciona a una interfaz de usuario
- Permite a los usuarios interactuar con y seleccionar entre las opciones disponibles
- Apaga el servidor y retoma la ejecución con la selección del usuario
El resultado es una integración suave que mantiene el poder de MCP al tiempo que agrega el feedback visual y las capacidades de interacción que los usuarios necesitan.
Implementación técnica
Veamos cómo se implementa esto.
Servicio de Callback
En el núcleo de nuestra solución está un servidor de llamadas que facilita la comunicación entre el MCP y la interfaz del navegador:
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;
}
}
}
En este servidor:
- Busca dinámicamente un puerto disponible
- Crea un ID de sesión único para cada solicitud
- Sirve el bundle de UI
- Abre el navegador para mostrar opciones
- Recibe la selección del usuario a través de un llamado
- Resolve la promesa con los datos seleccionados
Integration with MCP tool
Hemos aplicado este enfoque para mejorar nuestra herramienta 21st_magic_component_builder, que genera componentes de interfaz de usuario:
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;
}
}
}
Flujo de experiencia del usuario
Aquí está cómo fluye la experiencia del usuario cuando se solicita un componente de interfaz de usuario:
- Invocación de herramientas: El asistente de IA invoca la herramienta 21st_magic_component_builder cuando un usuario solicita un nuevo componente de interfaz de usuario.
- API Request: La herramienta envía una solicitud a la API 21st.dev para generar múltiples variaciones de componentes de interfaz de usuario basadas en el mensaje y el contexto del usuario.
- Lanzamiento del navegador: se inicia un servidor local y se abre automáticamente una ventana del navegador, mostrando las opciones de componentes de la interfaz de usuario generadas.
- Interacción con el usuario: el usuario puede ver, interactuar con y seleccionar su variante de componente preferida.
- Captación de selección: Cuando el usuario hace una selección, el navegador envía la selección de vuelta al servidor de llamadas.
- Reanudación de ejecución: el servidor se cierra y la ejecución se reanuda con los datos de componentes seleccionados.
- Guía de integración: El asistente de IA recibe el componente seleccionado y proporciona orientación sobre la integración en la base de código del usuario.
Este enfoque crea una experiencia sin problemas que permite a los usuarios tomar decisiones informadas sobre los componentes de la interfaz de usuario, manteniendo el flujo de trabajo general de MCP.
Consideraciones de seguridad y privacidad
Nuestra implementación requiere varias medidas de seguridad:
- Hosting local: Toda la comunicación ocurre localmente en la máquina del usuario (127.0.0.1)
- Identificadores de sesión únicos: Cada sesión de navegador tiene un identificador único para evitar interferencias de sesión
- Mecanismo de Timeout: las sesiones se agotan automáticamente después de un período configurable (por defecto 5 minutos)
- Seguridad de puertos: el servidor encuentra dinámicamente un puerto disponible para evitar conflictos
Conclusión
El enfoque basado en el navegador para la comunicación MCP representa una mejora significativa para la experiencia del usuario cuando se trabaja con herramientas que benefician de la interacción visual. Al cerrar la brecha entre las potentes capacidades de MCP y la naturaleza interactiva de las interfaces web, hemos creado un flujo de trabajo más intuitivo para los usuarios. Este enfoque es particularmente valioso para la generación de componentes de interfaz de usuario, donde la representación visual es crucial para tomar decisiones informadas. Sin embargo, el patrón podría extenderse a otras herramientas que beneficiarían de la interacción del usuario durante la ejecución.
El código fuente está disponible enGitHub.