Skip to main content
Glama
index_not_good_20250401100453.ts9.42 kB
#!/usr/bin/env node import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, Tool, } from "@modelcontextprotocol/sdk/types.js"; const READ_SCENARIO_BLUEPRINT_TOOL: Tool = { name: "read_make_dot_com_scenario_blueprint", description: "Reads the JSON blueprint of a Make.com scenario. Returns the complete blueprint structure including flow, connections, and metadata.", inputSchema: { type: "object", properties: { scenario_id: { type: "number", description: "Scenario ID to retrieve the blueprint for", }, draft: { type: "boolean", description: "If true, retrieves the draft version. If false, retrieves the live version.", default: false, }, }, required: ["scenario_id"], }, }; const LIST_SCENARIOS_TOOL: Tool = { name: "list_make_dot_com_scenarios", description: "Lists all available Make.com scenarios with their IDs, names, and scheduling types.", inputSchema: { type: "object", properties: {}, }, }; const DESCRIBE_MAKE_MODULE_TOOL: Tool = { name: "describe_make_dot_com_module", description: "Describes the configuration and parameters of a module inside a Make.com scenario.", inputSchema: { type: "object", properties: { scenario_id: { type: "number", description: "ID of the scenario containing the module", }, module_id: { type: "number", description: "ID of the module to describe", }, draft: { type: "boolean", description: "If true, retrieve from the draft version", default: false, }, }, required: ["scenario_id", "module_id"], }, }; const CREATE_SCENARIO_TOOL: Tool = { name: "create_make_dot_com_scenario", description: "Creates a new Make.com scenario with optional folder and description", inputSchema: { type: "object", properties: { name: { type: "string", description: "Name of the new scenario" }, folderId: { type: "number", description: "Folder ID to create scenario in" }, description: { type: "string", description: "Optional scenario description" }, }, required: ["name"], }, }; const server = new Server( { name: "mcp-server-make-dot-com", version: "0.1.0", }, { capabilities: { tools: {}, }, } ); const MAKE_API_KEY = process.env.MAKE_DOT_COM_API_KEY!; const MAKE_BASE_URL = process.env.MAKE_DOT_COM_BASE_URL || "eu2.make.com"; const MAKE_TEAM_ID = process.env.MAKE_DOT_COM_TEAM_ID; if (!MAKE_API_KEY) { console.error("Error: MAKE_DOT_COM_API_KEY environment variable is required"); process.exit(1); } if (!MAKE_TEAM_ID) { console.error("Error: MAKE_DOT_COM_TEAM_ID environment variable is required"); process.exit(1); } interface MakeBlueprint { code: string; response: { blueprint: { flow: Array<{ id: number; module: string; version: number; parameters: Record<string, unknown>; mapper?: Record<string, unknown>; metadata?: Record<string, any>; [key: string]: unknown; }>; [key: string]: unknown; }; }; } interface MakeScenario { id: number; name: string; scheduling: { type: string; }; } function isMakeScenarioBlueprintArgs( args: unknown ): args is { scenario_id: number; draft?: boolean } { return ( typeof args === "object" && args !== null && "scenario_id" in args && typeof (args as { scenario_id: number }).scenario_id === "number" ); } function isDescribeModuleArgs( args: unknown ): args is { scenario_id: number; module_id: number; draft?: boolean } { return ( typeof args === "object" && args !== null && "scenario_id" in args && typeof (args as any).scenario_id === "number" && "module_id" in args && typeof (args as any).module_id === "number" ); } async function getScenarioBlueprint( scenarioId: number, draft: boolean = false ): Promise<MakeBlueprint["response"]["blueprint"]> { const url = `https://${MAKE_BASE_URL}/api/v2/scenarios/${scenarioId}/blueprint?includeDraft=${draft}&teamId=${MAKE_TEAM_ID}`; const response = await fetch(url, { headers: { Authorization: `Token ${MAKE_API_KEY}`, "Content-Type": "application/json", Accept: "application/json", }, }); if (!response.ok) { throw new Error( `Make.com API error: ${response.status} ${response.statusText}\n${await response.text()}` ); } const data = (await response.json()) as MakeBlueprint; return data.response.blueprint; } async function listScenarios(): Promise<string> { const url = `https://${MAKE_BASE_URL}/api/v2/scenarios?teamId=${MAKE_TEAM_ID}`; const response = await fetch(url, { headers: { Authorization: `Token ${MAKE_API_KEY}`, "Content-Type": "application/json", Accept: "application/json", }, }); if (!response.ok) { throw new Error( `Make.com API error: ${response.status} ${response.statusText}\n${await response.text()}` ); } const data = await response.json(); const scenarios = data.scenarios as MakeScenario[]; const summary = scenarios.map((s) => `• ${s.name} (ID: ${s.id}, Type: ${s.scheduling.type})`).join("\n"); return summary || "No scenarios found."; } function describeModule(blueprint: MakeBlueprint["response"]["blueprint"], module_id: number): string { const mod = blueprint.flow.find((m) => m.id === module_id); if (!mod) { throw new Error(`Module with ID ${module_id} not found in scenario.`); } const lines: string[] = [ `📦 Module: ${mod.module} (id: ${mod.id})`, mod.metadata?.interface ? `🔧 Inputs: ${mod.metadata.interface.map((i: any) => `${i.name} (${i.type})${i.required ? ' *' : ''}`).join(", ")}` : `🔧 Parameters: ${Object.keys(mod.parameters).join(", ")}`, mod.mapper ? `🧠 Mapper Fields: ${Object.keys(mod.mapper).join(", ")}` : "(No mapping info)" ]; return lines.join("\n"); } async function createScenario(name: string, folderId?: number, description?: string): Promise<string> { const url = `https://${MAKE_BASE_URL}/api/v2/scenarios`; const response = await fetch(url, { method: "POST", headers: { Authorization: `Token ${MAKE_API_KEY}`, "Content-Type": "application/json", Accept: "application/json", }, body: JSON.stringify({ name, description, folderId, teamId: MAKE_TEAM_ID, }), }); if (!response.ok) { throw new Error(`Failed to create scenario: ${response.status} ${response.statusText}\n${await response.text()}`); } const data = await response.json(); return `✅ Scenario created: ${data.name} (ID: ${data.id})`; } server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [READ_SCENARIO_BLUEPRINT_TOOL, LIST_SCENARIOS_TOOL, DESCRIBE_MAKE_MODULE_TOOL, CREATE_SCENARIO_TOOL], })); server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args = {} } = request.params; if (name === READ_SCENARIO_BLUEPRINT_TOOL.name) { if (!isMakeScenarioBlueprintArgs(args)) { console.error("Invalid arguments for read_make_dot_com_scenario_blueprint"); throw new Error("Invalid arguments"); } try { const blueprint = await getScenarioBlueprint(args.scenario_id, args.draft); return { content: [{ type: "text", text: JSON.stringify(blueprint, null, 2) }], }; } catch (error) { console.error(`Error processing scenario ${args.scenario_id}:`, error); throw error; } } if (name === LIST_SCENARIOS_TOOL.name) { try { const result = await listScenarios(); return { content: [{ type: "text", text: result }], }; } catch (error) { console.error("Error listing scenarios:", error); throw error; } } if (name === DESCRIBE_MAKE_MODULE_TOOL.name) { if (!isDescribeModuleArgs(args)) { console.error("Invalid arguments for describe_make_dot_com_module"); throw new Error("Invalid arguments"); } try { const blueprint = await getScenarioBlueprint(args.scenario_id, args.draft); const description = describeModule(blueprint, args.module_id); return { content: [{ type: "text", text: description }], }; } catch (error) { console.error("Error describing module:", error); throw error; } } if (name === CREATE_SCENARIO_TOOL.name) { if (typeof args.name !== 'string') { throw new Error("Scenario name must be a string"); } try { const message = await createScenario(args.name, args.folderId, args.description as string | undefined); return { content: [{ type: "text", text: message }], }; } catch (error) { console.error("Error creating scenario:", error); throw error; } } console.error(`Unknown tool requested: ${name}`); throw new Error(`Unknown tool: ${name}`); }); async function runServer() { const transport = new StdioServerTransport(); await server.connect(transport); console.error("Make.com MCP Server running on stdio"); } runServer().catch((error) => { console.error("Fatal error running server:", error); process.exit(1); });

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/sparxHub/mcp-makesync'

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