Skip to main content
Glama
index.ts5.1 kB
import type { Config } from '../config.js'; import type { Directus } from '../directus.js'; import type { Schema } from '../types/schema.js'; import { readItems } from '@directus/sdk'; import { extractMustacheVariables } from '../utils/prompt-helpers.js'; export interface PromptItem { id: string; name: string; description: string; systemPrompt: string; messages: Array<{ role: 'user' | 'assistant'; text: string; }>; } export interface McpPrompt { name: string; description: string; arguments: Array<{ name: string; description: string; required: boolean; }>; } /** * Fetches prompts from the Directus collection specified in the config * @param directus - The Directus client * @param config - The application config * @returns A map of prompt name to MCP prompt definition */ export async function fetchPrompts( directus: Directus, config: Config, schema: Schema, ): Promise<Record<string, McpPrompt>> { // If no prompts collection is configured, return an empty object if (!config.DIRECTUS_PROMPTS_COLLECTION) { console.error('No prompts collection configured, skipping prompt fetching'); return {}; } // If the prompts collection isn't in the schema, then throw an error because there's a permissions issue or it doesn't exist if (!schema[config.DIRECTUS_PROMPTS_COLLECTION]) { throw new Error( 'Prompts collection not found in the schema. Use the read-collections tool first. If you have already used the read-collections tool, then check the permissions of the user you are using to fetch prompts.', ); } console.error('config', config); // Check the prompts collection has the required fields const requiredFields = [ config.DIRECTUS_PROMPTS_NAME_FIELD, config.DIRECTUS_PROMPTS_DESCRIPTION_FIELD, config.DIRECTUS_PROMPTS_SYSTEM_PROMPT_FIELD, config.DIRECTUS_PROMPTS_MESSAGES_FIELD, ]; for (const field of requiredFields) { if (!schema[config.DIRECTUS_PROMPTS_COLLECTION]?.[field as keyof typeof schema[string]]) { throw new Error(`Prompt field ${field} not found in the prompts collection.`); } } try { type DirectusCollection = any; const response = (await directus.request( // @ts-expect-error - We're using a dynamic collection name readItems(config.DIRECTUS_PROMPTS_COLLECTION), )) as DirectusCollection[]; const prompts: Record<string, McpPrompt> = {}; for (const item of response) { // Still include prompts even if messages are empty or null const variables = new Set<string>(); const messagesField = config.DIRECTUS_PROMPTS_MESSAGES_FIELD as string; const systemPromptField = config.DIRECTUS_PROMPTS_SYSTEM_PROMPT_FIELD as string; // Extract variables from system prompt if it exists if (item[systemPromptField]) { for (const variable of extractMustacheVariables(item[systemPromptField])) { variables.add(variable); } } // Extract variables from messages if they exist if (item[messagesField] && Array.isArray(item[messagesField])) { for (const message of item[messagesField]) { if (message && message.text) { for (const variable of extractMustacheVariables(message.text)) { variables.add(variable); } } } } prompts[item.name] = { name: item.name, description: item.description || `Prompt: ${item.name}`, arguments: [...variables].map((name) => ({ name, description: `Value for ${name}`, required: false, })), }; } return prompts; } catch (error) { console.error('Error fetching prompts:', error); return {}; } } /** * Fetches a specific prompt by name from Directus * @param directus - The Directus client * @param config - The application config * @param promptName - The name of the prompt to fetch * @returns The prompt item if found, undefined otherwise */ export async function fetchPromptByName( directus: Directus, config: Config, promptName: string, ): Promise<PromptItem | undefined> { if (!config.DIRECTUS_PROMPTS_COLLECTION) return undefined; try { type DirectusCollection = any; const response = (await directus.request( // @ts-expect-error - We're using a dynamic collection name readItems(config.DIRECTUS_PROMPTS_COLLECTION, { filter: { [config.DIRECTUS_PROMPTS_NAME_FIELD as string]: { _eq: promptName, }, }, limit: 1, }), )) as DirectusCollection[]; if (!response || response.length === 0) return undefined; // Map Directus item to our expected format const item = response[0]; const nameField = config.DIRECTUS_PROMPTS_NAME_FIELD as string; const descriptionField = config.DIRECTUS_PROMPTS_DESCRIPTION_FIELD as string; const systemPromptField = config.DIRECTUS_PROMPTS_SYSTEM_PROMPT_FIELD as string; const messagesField = config.DIRECTUS_PROMPTS_MESSAGES_FIELD as string; return { id: item.id, name: item[nameField], description: item[descriptionField], systemPrompt: item[systemPromptField] || '', messages: item[messagesField] || [], }; } catch (error) { console.error(`Error fetching prompt ${promptName}:`, error); return undefined; } }

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/JoshTheDerf/directus-extension-mcp'

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