Skip to main content
Glama

Spline MCP Server

by aydinfer
api-webhook-tools.js10.3 kB
import { z } from 'zod'; import apiClient from '../utils/api-client.js'; import openaiClient from '../utils/openai-client.js'; /** * API and Webhook management tools for Spline.design * @param {object} server - MCP server instance */ export const registerApiWebhookTools = (server) => { // Configure API connection server.tool( 'configureApi', { sceneId: z.string().min(1).describe('Scene ID'), name: z.string().min(1).describe('API name'), method: z.enum(['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS', 'PATCH']) .describe('HTTP method'), url: z.string().url().describe('API endpoint URL'), headers: z.record(z.string()).optional().describe('HTTP headers'), body: z.record(z.any()).optional().describe('Request body (for POST, PUT, PATCH)'), queryParams: z.record(z.string()).optional().describe('URL query parameters'), requestOnStart: z.boolean().optional().default(false) .describe('Whether to call API when scene loads'), variableMappings: z.array(z.object({ responseField: z.string().describe('Field from API response'), variableName: z.string().describe('Spline variable name'), variableType: z.enum(['string', 'number', 'boolean']).describe('Variable type'), })).optional().describe('Mappings from API response to Spline variables'), }, async ({ sceneId, name, method, url, headers, body, queryParams, requestOnStart, variableMappings }) => { try { const apiConfig = { name, method, url, ...(headers && { headers }), ...(body && { body }), ...(queryParams && { queryParams }), requestOnStart: requestOnStart || false, ...(variableMappings && { variableMappings }), }; const result = await apiClient.configureApi(sceneId, apiConfig); return { content: [ { type: 'text', text: `API connection configured successfully with ID: ${result.id}` } ] }; } catch (error) { return { content: [ { type: 'text', text: `Error configuring API: ${error.message}` } ], isError: true }; } } ); // Get all API connections in a scene server.tool( 'getApis', { sceneId: z.string().min(1).describe('Scene ID'), }, async ({ sceneId }) => { try { const apis = await apiClient.getApis(sceneId); return { content: [ { type: 'text', text: JSON.stringify(apis, null, 2) } ] }; } catch (error) { return { content: [ { type: 'text', text: `Error retrieving APIs: ${error.message}` } ], isError: true }; } } ); // Delete an API connection server.tool( 'deleteApi', { sceneId: z.string().min(1).describe('Scene ID'), apiId: z.string().min(1).describe('API connection ID'), }, async ({ sceneId, apiId }) => { try { await apiClient.deleteApi(sceneId, apiId); return { content: [ { type: 'text', text: `API connection ${apiId} deleted successfully` } ] }; } catch (error) { return { content: [ { type: 'text', text: `Error deleting API connection: ${error.message}` } ], isError: true }; } } ); // Create a webhook server.tool( 'createWebhook', { sceneId: z.string().min(1).describe('Scene ID'), name: z.string().min(1).describe('Webhook name'), parameterMappings: z.array(z.object({ paramName: z.string().describe('Parameter name in webhook'), variableName: z.string().describe('Spline variable name'), variableType: z.enum(['string', 'number', 'boolean']).describe('Variable type'), })).optional().describe('Parameter mappings'), }, async ({ sceneId, name, parameterMappings }) => { try { const webhookData = { name, ...(parameterMappings && { parameterMappings }), }; const result = await apiClient.createWebhook(sceneId, webhookData); return { content: [ { type: 'text', text: `Webhook created successfully with ID: ${result.id} and URL: ${result.url}` } ] }; } catch (error) { return { content: [ { type: 'text', text: `Error creating webhook: ${error.message}` } ], isError: true }; } } ); // Get all webhooks in a scene server.tool( 'getWebhooks', { sceneId: z.string().min(1).describe('Scene ID'), }, async ({ sceneId }) => { try { const webhooks = await apiClient.getWebhooks(sceneId); return { content: [ { type: 'text', text: JSON.stringify(webhooks, null, 2) } ] }; } catch (error) { return { content: [ { type: 'text', text: `Error retrieving webhooks: ${error.message}` } ], isError: true }; } } ); // Delete a webhook server.tool( 'deleteWebhook', { sceneId: z.string().min(1).describe('Scene ID'), webhookId: z.string().min(1).describe('Webhook ID'), }, async ({ sceneId, webhookId }) => { try { await apiClient.deleteWebhook(sceneId, webhookId); return { content: [ { type: 'text', text: `Webhook ${webhookId} deleted successfully` } ] }; } catch (error) { return { content: [ { type: 'text', text: `Error deleting webhook: ${error.message}` } ], isError: true }; } } ); // Trigger a webhook manually server.tool( 'triggerWebhook', { sceneId: z.string().min(1).describe('Scene ID'), webhookId: z.string().min(1).describe('Webhook ID'), data: z.record(z.any()).describe('Data to send with the webhook'), }, async ({ sceneId, webhookId, data }) => { try { await apiClient.triggerWebhook(sceneId, webhookId, data); return { content: [ { type: 'text', text: `Webhook ${webhookId} triggered successfully` } ] }; } catch (error) { return { content: [ { type: 'text', text: `Error triggering webhook: ${error.message}` } ], isError: true }; } } ); // Configure OpenAI for text generation server.tool( 'configureOpenAI', { sceneId: z.string().min(1).describe('Scene ID'), model: z.enum(['gpt-3.5-turbo', 'gpt-4-turbo', 'gpt-4o-mini', 'gpt-4o']) .default('gpt-3.5-turbo').describe('OpenAI model to use'), apiKey: z.string().optional().describe('OpenAI API key (uses env var if not provided)'), prompt: z.string().min(1).describe('System prompt/behavior for the AI'), requestOnStart: z.boolean().optional().default(false) .describe('Whether to call OpenAI when scene loads'), variableMappings: z.array(z.object({ responseField: z.string().describe('Field from API response'), variableName: z.string().describe('Spline variable name'), })).optional().describe('Mappings from OpenAI response to Spline variables'), }, async ({ sceneId, model, apiKey, prompt, requestOnStart, variableMappings }) => { try { const openaiConfig = { model, apiKey: apiKey || process.env.OPENAI_API_KEY, prompt, requestOnStart: requestOnStart || false, ...(variableMappings && { variableMappings }), }; const result = await apiClient.request('POST', `/scenes/${sceneId}/openai`, openaiConfig); return { content: [ { type: 'text', text: `OpenAI integration configured successfully with ID: ${result.id}` } ] }; } catch (error) { return { content: [ { type: 'text', text: `Error configuring OpenAI: ${error.message}` } ], isError: true }; } } ); // Generate text with OpenAI (direct use, not through Spline) server.tool( 'generateTextWithOpenAI', { prompt: z.string().min(1).describe('Prompt for text generation'), model: z.enum(['gpt-3.5-turbo', 'gpt-4-turbo', 'gpt-4o-mini', 'gpt-4o']) .default('gpt-3.5-turbo').describe('OpenAI model to use'), maxTokens: z.number().min(1).max(4096).default(256) .describe('Maximum number of tokens to generate'), temperature: z.number().min(0).max(2).default(0.7) .describe('Temperature for text generation (0-2)'), }, async ({ prompt, model, maxTokens, temperature }) => { try { const generatedText = await openaiClient.generateText( prompt, model, maxTokens, temperature ); return { content: [ { type: 'text', text: generatedText } ] }; } catch (error) { return { content: [ { type: 'text', text: `Error generating text: ${error.message}` } ], isError: true }; } } ); };

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/aydinfer/spline-mcp-server'

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