Skip to main content
Glama

BYOB MCP Server

by ndisidore
server.jsβ€’7.49 kB
// Universal tool runner container // Listens on port 8080 and handles multiple operations: // - Echo: echo back messages (field: message) // - Uppercase: convert text to uppercase (field: text) - "why_are_we_yelling" // - JQ: process JSON with jq filters (fields: filter, data) // - Git Clone + Summarize: clone a repo and summarize README (field: repo_url) const http = require('http'); const { spawn, exec } = require('child_process'); const fs = require('fs'); const path = require('path'); const PORT = process.env.PORT || 8080; function runJq(filter, jsonData) { return new Promise((resolve, reject) => { const jq = spawn('jq', [filter]); let stdout = ''; let stderr = ''; jq.stdout.on('data', (data) => { stdout += data.toString(); }); jq.stderr.on('data', (data) => { stderr += data.toString(); }); jq.on('close', (code) => { if (code === 0) { try { // Try to parse output as JSON const result = JSON.parse(stdout); resolve(result); } catch { // If not JSON, return as string resolve(stdout.trim()); } } else { reject(new Error(stderr || `jq exited with code ${code}`)); } }); // Write JSON data to jq's stdin jq.stdin.write(JSON.stringify(jsonData)); jq.stdin.end(); }); } function summarizeRepoReadme(repoUrl) { return new Promise((resolve, reject) => { // Create temp directory for clone const tmpDir = `/tmp/repo-${Date.now()}`; // Extract repo name from URL for better output const repoName = repoUrl.split('/').pop().replace('.git', ''); // Clone repo (shallow clone, just README) const cloneCmd = `git clone --depth 1 --single-branch ${repoUrl} ${tmpDir}`; exec(cloneCmd, (error, stdout, stderr) => { if (error) { reject(new Error(`Git clone failed: ${stderr || error.message}`)); return; } // Look for README files (case insensitive) const readmePaths = [ 'README.md', 'README.MD', 'readme.md', 'Readme.md', 'README.txt', 'README' ]; let readmeContent = null; let foundPath = null; for (const readmePath of readmePaths) { const fullPath = path.join(tmpDir, readmePath); if (fs.existsSync(fullPath)) { readmeContent = fs.readFileSync(fullPath, 'utf8'); foundPath = readmePath; break; } } // Cleanup exec(`rm -rf ${tmpDir}`, () => {}); if (!readmeContent) { reject(new Error('No README file found in repository')); return; } // Create a summary const lines = readmeContent.split('\n'); const firstLines = lines.slice(0, 50).join('\n'); // First 50 lines const totalLines = lines.length; const charCount = readmeContent.length; // Extract title (first # heading) const titleMatch = readmeContent.match(/^#\s+(.+)$/m); const title = titleMatch ? titleMatch[1] : repoName; resolve({ repo: repoName, repoUrl: repoUrl, readmeFile: foundPath, title: title, preview: firstLines, stats: { totalLines: totalLines, totalChars: charCount, previewLines: Math.min(50, totalLines) } }); }); }); } const server = http.createServer(async (req, res) => { // Set CORS headers res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); // Handle OPTIONS preflight if (req.method === 'OPTIONS') { res.writeHead(200); res.end(); return; } // Only handle POST to /execute if (req.method !== 'POST' || req.url !== '/execute') { res.writeHead(404, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Not found. Use POST /execute' })); return; } // Read request body let body = ''; req.on('data', chunk => { body += chunk.toString(); }); req.on('end', async () => { try { const input = JSON.parse(body); let response; // Determine operation based on input fields if (input.repo_url !== undefined) { // Git clone + summarize README operation try { const result = await summarizeRepoReadme(input.repo_url); response = { tool: 'summarize_repo_readme', ...result, timestamp: new Date().toISOString(), instanceId: process.env.CLOUDFLARE_DEPLOYMENT_ID || 'local' }; } catch (error) { res.writeHead(400, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Git clone or README processing failed', details: error.message })); return; } } else if (input.filter !== undefined && input.data !== undefined) { // JQ operation - process JSON with jq try { const result = await runJq(input.filter, input.data); response = { tool: 'query_json', filter: input.filter, result: result, timestamp: new Date().toISOString(), instanceId: process.env.CLOUDFLARE_DEPLOYMENT_ID || 'local' }; } catch (error) { res.writeHead(400, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'jq processing failed', details: error.message })); return; } } else if (input.text !== undefined) { // WHY_ARE_WE_YELLING operation - uppercase text response = { tool: 'why_are_we_yelling', originalText: input.text, yelledText: input.text.toUpperCase(), timestamp: new Date().toISOString(), instanceId: process.env.CLOUDFLARE_DEPLOYMENT_ID || 'local' }; } else if (input.message !== undefined) { // Echo operation - echo back the message response = { tool: 'echo_message', message: input.message, input: input, timestamp: new Date().toISOString(), instanceId: process.env.CLOUDFLARE_DEPLOYMENT_ID || 'local' }; } else { // Unknown operation res.writeHead(400, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Unknown operation', hint: 'Provide "message" (echo), "text" (uppercase), "filter"+"data" (jq), or "repo_url" (git clone + summarize)' })); return; } res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify(response)); } catch (error) { res.writeHead(400, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Invalid JSON', details: error.message })); } }); }); server.listen(PORT, () => { console.log(`Universal tool runner listening on port ${PORT}`); console.log(`Supports: echo (message), uppercase (text), jq (filter+data), git clone (repo_url)`); console.log(`Instance ID: ${process.env.CLOUDFLARE_DEPLOYMENT_ID || 'local'}`); }); // Handle graceful shutdown process.on('SIGTERM', () => { console.log('Received SIGTERM, shutting down gracefully'); server.close(() => { console.log('Server closed'); 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/ndisidore/cf-byob-mcp'

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