Skip to main content
Glama

Clipboard to Supabase MCP Helper

server-http.ts4.03 kB
import express from 'express'; import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'; import { config } from 'dotenv'; import { startClipboardListener, uploadCurrentClipboardImage } from './daemon.js'; import logger from './utils/logger.js'; import { registerGlobalErrorHandlers } from './utils/error-handler.js'; import { randomUUID } from 'crypto'; import { cleanupOldFiles } from './utils/cleanup.js'; // Load environment variables config(); // Register global error handlers registerGlobalErrorHandlers(); // Start the clipboard listener try { startClipboardListener(); } catch (error) { logger.error(`Failed to start clipboard listener: ${error instanceof Error ? error.message : 'Unknown error'}`); process.exit(1); } // Initialize MCP server with metadata const server = new McpServer({ name: "clipboard-helper", version: "0.1.0" }); // Register the upload_clipboard_image tool server.tool( "upload_clipboard_image", {}, // empty object for no parameters async () => { try { const url = await uploadCurrentClipboardImage(); logger.info(`MCP tool called: upload_clipboard_image → ${url}`); return { content: [ { type: "text", text: url } ] }; } catch (error) { const errorMessage = `Error uploading clipboard image: ${error instanceof Error ? error.message : 'Unknown error'}`; logger.error(errorMessage); return { content: [ { type: "text", text: `Error: Failed to upload image` } ] }; } } ); // Register the cleanup_old_files tool server.tool( "cleanup_old_files", { type: "object", properties: { days: { type: "integer", description: "Number of days to keep files" } } }, async ({ days }) => { try { // Use the configured retention period if no days parameter provided const retentionDays = days || parseInt(process.env.RETENTION_DAYS || '30', 10); logger.info(`MCP tool called: cleanup_old_files with retention period of ${retentionDays} days`); const result = await cleanupOldFiles(retentionDays); return { content: [ { type: "text", text: `Cleanup completed: Deleted ${result.success} files older than ${retentionDays} days. Failed: ${result.errors}.` } ] }; } catch (error) { const errorMessage = `Error cleaning up old files: ${error instanceof Error ? error.message : 'Unknown error'}`; logger.error(errorMessage); return { content: [ { type: "text", text: `Error: Failed to cleanup old files` } ] }; } } ); // Create Express app const app = express(); app.use(express.json()); // Handle MCP requests app.post("/mcp", async (req: express.Request, res: express.Response) => { try { // Create a transport with session ID generator const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), enableJsonResponse: false }); await server.connect(transport); await transport.handleRequest(req, res, req.body); } catch (error) { logger.error(`Error handling MCP request: ${error instanceof Error ? error.message : 'Unknown error'}`); res.status(500).json({ error: "Internal server error" }); } }); // Add a health check endpoint app.get("/health", (req: express.Request, res: express.Response) => { res.status(200).json({ status: "healthy" }); }); // Start the HTTP server const port = parseInt(process.env.MCP_PORT || '3333', 10); app.listen(port, () => { logger.info(`MCP Clipboard Helper HTTP server listening on port ${port}`); }); // Handle graceful shutdown process.on('SIGINT', () => { logger.info('Shutting down MCP server...'); process.exit(0); }); process.on('SIGTERM', () => { logger.info('Shutting down MCP server...'); process.exit(0); });

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/martinbowling/clipboard-to-supabase-mcp-helper'

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