Skip to main content
Glama

Glif

Official
by glifxyz
index.ts7.44 kB
import type { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { CallToolRequestSchema, type CallToolResult, ErrorCode, ListToolsRequestSchema, McpError, } from "@modelcontextprotocol/sdk/types.js"; import { z } from "zod"; import { GLIF_IDS } from "../config.js"; import { getSavedGlifs, type SavedGlif } from "../saved-glifs.js"; import { env } from "../utils/env.js"; // Types for tool structure export type ToolDefinition = { name: string; description: string; inputSchema: { type: string; properties: Record<string, unknown>; required?: string[]; }; }; // Use the official MCP ContentBlock types for multimedia support export type ToolResponse = CallToolResult; export type ToolHandler = ( request: z.infer<typeof CallToolRequestSchema> ) => Promise<ToolResponse>; export type Tool = { definition: ToolDefinition; handler: ToolHandler; schema: z.ZodType; }; export type ToolGroup = { [key: string]: Tool; }; // Import core tools import * as glifInfo from "./glif-info.js"; // Bot tools - beta, disabled by default import * as listBots from "./list-bots.js"; // Import discovery tools import * as listFeaturedGlifs from "./list-featured-glifs.js"; import * as listSavedGlifTools from "./list-saved-glif-tools.js"; import * as loadBot from "./load-bot.js"; import * as myGlifUserInfo from "./my-glif-user-info.js"; import * as myGlifs from "./my-glifs.js"; import * as removeAllGlifTools from "./remove-all-glif-tools.js"; import * as removeGlifTool from "./remove-glif-tool.js"; import * as runGlif from "./run-glif.js"; import * as saveBotSkillsAsTools from "./save-bot-skills-as-tools.js"; // Import metaskill tools import * as saveGlifAsTool from "./save-glif-as-tool.js"; import * as searchGlifs from "./search-glifs.js"; import * as showBotInfo from "./show-bot-info.js"; // Tool groupings const CORE_TOOLS: ToolGroup = { [glifInfo.definition.name]: glifInfo, [runGlif.definition.name]: runGlif, }; // Will add these as we implement the tools const DISCOVERY_TOOLS: ToolGroup = { [listFeaturedGlifs.definition.name]: listFeaturedGlifs, [searchGlifs.definition.name]: searchGlifs, [myGlifs.definition.name]: myGlifs, [myGlifUserInfo.definition.name]: myGlifUserInfo, }; const METASKILL_TOOLS: ToolGroup = { [saveGlifAsTool.definition.name]: saveGlifAsTool, [removeGlifTool.definition.name]: removeGlifTool, [removeAllGlifTools.definition.name]: removeAllGlifTools, [listSavedGlifTools.definition.name]: listSavedGlifTools, }; // Bot tools - beta, disabled by default const BOT_TOOLS: ToolGroup = { [listBots.definition.name]: listBots, [saveBotSkillsAsTools.definition.name]: saveBotSkillsAsTools, [loadBot.definition.name]: loadBot, [showBotInfo.definition.name]: showBotInfo, }; // Helper to create a tool definition from a saved glif function createToolFromSavedGlif(glif: SavedGlif): ToolDefinition { return { name: glif.toolName, description: `${glif.name}: ${glif.description}`, inputSchema: { type: "object", properties: { inputs: { type: "array", items: { type: "string", }, description: "Array of input values for the glif", }, }, required: ["inputs"], }, }; } // Helper to create a tool definition from a glif ID function createToolFromGlifId(glifId: string) { return { name: `glif_${glifId}`, description: `Run glif ${glifId}`, inputSchema: { type: "object", properties: { inputs: { type: "array", items: { type: "string", }, description: "Array of input values for the glif", }, }, required: ["inputs"], }, }; } export async function getTools(): Promise<{ tools: ToolDefinition[] }> { const tools: ToolDefinition[] = []; // 1. Add CORE tools (always available) tools.push(...Object.values(CORE_TOOLS).map((t) => t.definition)); // 2. Add DISCOVERY tools (unless disabled) if (env.discovery.enabled()) { tools.push(...Object.values(DISCOVERY_TOOLS).map((t) => t.definition)); } // 3. Add METASKILL tools (unless disabled) if (env.metaskill.enabled()) { tools.push(...Object.values(METASKILL_TOOLS).map((t) => t.definition)); } // 4. Add BOT tools (disabled by default) if (env.bots.enabled()) { tools.push(...Object.values(BOT_TOOLS).map((t) => t.definition)); } // 5. Add SAVED_GLIFS tools (unless disabled) if (env.savedGlifs.enabled()) { const savedGlifs = await getSavedGlifs(); if (savedGlifs) { tools.push(...savedGlifs.map(createToolFromSavedGlif)); } } // 5. Add SERVER_CONFIG_GLIFS tools (always available) tools.push(...GLIF_IDS.map(createToolFromGlifId)); return { tools }; } export function setupToolHandlers(server: Server) { console.error( "[DEBUG] Setting up tool handlers V2.0 (MCP multimedia support)" ); // Register tool definitions including saved glifs server.setRequestHandler(ListToolsRequestSchema, async () => getTools()); // Handle tool calls server.setRequestHandler(CallToolRequestSchema, async (request) => { console.error("[DEBUG] Tool call received:", { name: request.params.name, args: request.params.arguments, }); // Check if this is a saved glif tool if (env.savedGlifs.enabled()) { const savedGlifs = await getSavedGlifs(); const savedGlif = savedGlifs?.find( (g) => g.toolName === request.params.name ); if (savedGlif && request.params.arguments) { const args = z .object({ inputs: z.array(z.string()) }) .parse(request.params.arguments); return runGlif.handler({ ...request, params: { ...request.params, arguments: { id: savedGlif.id, inputs: args.inputs, }, }, }); } } // Check if this is a server config glif tool const glifIdMatch = request.params.name.match(/^glif_(.+)$/); const glifId = glifIdMatch?.[1]; if ( glifIdMatch && glifId && GLIF_IDS.includes(glifId) && request.params.arguments ) { const args = z .object({ inputs: z.array(z.string()) }) .parse(request.params.arguments); return runGlif.handler({ ...request, params: { ...request.params, arguments: { id: glifId, inputs: args.inputs, }, }, }); } // Handle core tools const coreTool = CORE_TOOLS[request.params.name]; if (coreTool) { return coreTool.handler(request); } // Handle discovery tools if (env.discovery.enabled()) { const discoveryTool = DISCOVERY_TOOLS[request.params.name]; if (discoveryTool) { return discoveryTool.handler(request); } } // Handle metaskill tools if (env.metaskill.enabled()) { const metaskillTool = METASKILL_TOOLS[request.params.name]; if (metaskillTool) { return metaskillTool.handler(request); } } // Handle bot tools if (env.bots.enabled()) { const botTool = BOT_TOOLS[request.params.name]; if (botTool) { return botTool.handler(request); } } throw new McpError( ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}` ); }); }

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/glifxyz/glif-mcp-server'

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