Skip to main content
Glama
index.ts4.58 kB
import dotenv from 'dotenv'; dotenv.config(); import axios from 'axios'; if (process.env.TYPEBOT_TOKEN) { axios.defaults.headers.common['Authorization'] = `Bearer ${process.env.TYPEBOT_TOKEN}`; } import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z, ZodObject, ZodRawShape } from "zod"; import { createBot, listBots, getBot, updateBot, deleteBot, publishBot, unpublishBot, listResults, startChat, } from './tools/bots'; async function main() { const server = new McpServer({ name: 'mcp-typebot', version: '1.0.0', }); const toolsMap = new Map<string, { func: (args: any) => Promise<any>; description: string; schema: ZodObject<ZodRawShape>; }>([ ['createBot', { func: createBot, description: 'Crea un nuevo Typebot. Requiere “name”, opcional “description”', schema: z.object({ workspaceId: z.string().optional(), name: z.string().min(1, "El campo 'name' es obligatorio."), description: z.string().optional(), }), }], ['listBots', { func: listBots, description: 'Lista todos los Typebots de un workspace', schema: z.object({ workspaceId: z.string().optional() }), }], ['getBot', { func: getBot, description: 'Recupera un Typebot por su ID', schema: z.object({ botId: z.string().min(1, "El campo 'botId' es obligatorio.") }), }], ['updateBot', { func: updateBot, description: 'Actualiza un Typebot existente (p.ej. cambia nombre)', schema: z.object({ botId: z.string().min(1, "El campo 'botId' es obligatorio."), typebot: z.record(z.any()).refine(x => typeof x === 'object', "El campo 'typebot' es obligatorio."), overwrite: z.boolean().optional(), }), }], ['deleteBot', { func: deleteBot, description: 'Elimina un Typebot por su ID', schema: z.object({ botId: z.string().min(1, "El campo 'botId' es obligatorio.") }), }], ['publishBot', { func: publishBot, description: 'Publica un Typebot existente', schema: z.object({ botId: z.string().min(1, "El campo 'botId' es obligatorio.") }), }], ['unpublishBot', { func: unpublishBot, description: 'Despublica un Typebot existente', schema: z.object({ botId: z.string().min(1, "El campo 'botId' es obligatorio.") }), }], ['listResults', { func: listResults, description: 'Lista resultados de un Typebot', schema: z.object({ botId: z.string().min(1, "El campo 'botId' es obligatorio."), limit: z.number().int().min(1).max(100).optional(), cursor: z.string().optional(), timeFilter: z.string().optional(), timeZone: z.string().optional(), }), }], ['startChat', { func: startChat, description: 'Inicia un chat con un Typebot. Requiere botId, opcional chat.context', schema: z.object({ botId: z.string().min(1, "El campo 'botId' es obligatorio."), chat: z.object({ context: z.record(z.any()).optional(), }).optional(), }), }], ]); for (const [name, { func, description, schema }] of toolsMap) { server.registerTool( name, { title: name, description, inputSchema: (schema as ZodObject<ZodRawShape>).shape, }, async (rawArgs: any, _extra: any) => { if (process.env.TYPEBOT_TOKEN) { axios.defaults.headers.common['Authorization'] = `Bearer ${process.env.TYPEBOT_TOKEN}`; } const parsed = schema.safeParse(rawArgs); if (!parsed.success) { return { content: [{ type: 'text' as const, text: `Error de validación en ${name}: ${parsed.error.message}` }] }; } try { const result = await func(parsed.data); return { content: [{ type: 'text' as const, text: JSON.stringify(result) }] }; } catch (e: any) { return { content: [{ type: 'text' as const, text: `Error en ${name}: ${e.message}` }] }; } } ); } const transport = new StdioServerTransport(); await server.connect(transport); } main().catch(err => { console.error('Error al arrancar MCP server:', err); process.exit(1); });

Implementation Reference

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/osdeibi/MCP-typebot'

If you have feedback or need assistance with the MCP directory API, please join our Discord server