Skip to main content
Glama
Ripnrip

Quake Coding Arena MCP

by Ripnrip
index.js5.2 kB
import express from "express"; import path from "node:path"; import { fileURLToPath } from "node:url"; import dotenv from "dotenv"; import OpenAI from "openai"; import { Client as McpClient } from "@modelcontextprotocol/sdk/client/index.js"; import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); dotenv.config(); const PORT = Number(process.env.PORT ?? 4173); const MCP_SERVER_URL = process.env.MCP_SERVER_URL ?? "http://localhost:3000/mcp"; const OPENAI_MODEL = process.env.OPENAI_MODEL ?? "gpt-4o-mini"; if (!process.env.OPENAI_API_KEY) { console.warn("⚠️ OPENAI_API_KEY is not set. /chat endpoint will fail until you provide a key."); } const openai = process.env.OPENAI_API_KEY ? new OpenAI({ apiKey: process.env.OPENAI_API_KEY }) : null; const app = express(); app.use(express.json()); app.use(express.static(path.join(__dirname, "../public"))); app.get("/health", (_req, res) => { res.json({ status: "ok", openai: Boolean(openai), mcpServer: MCP_SERVER_URL }); }); app.post("/chat", async (req, res) => { const { message } = req.body ?? {}; if (!message || typeof message !== "string") { return res.status(400).json({ error: "message field is required" }); } if (!openai) { return res.status(500).json({ error: "OPENAI_API_KEY missing" }); } try { const completion = await openai.chat.completions.create({ model: OPENAI_MODEL, temperature: 0.4, messages: [ { role: "system", content: "You are the Quake Coding Arena co-pilot. Respond concisely and include fun arena commentary when appropriate.", }, { role: "user", content: message }, ], }); const reply = completion.choices?.[0]?.message?.content?.trim() ?? "I couldn't craft a response this time, sorry!"; const quakeSound = pickAchievement({ userText: message, reply }); res.json({ reply, quakeSound }); } catch (error) { console.error("Failed to call OpenAI", error); res.status(500).json({ error: "Failed to reach ChatGPT", details: error.message ?? String(error) }); } }); app.get("/quake-sound", async (req, res) => { const achievement = typeof req.query.achievement === "string" ? req.query.achievement : undefined; const voiceGender = typeof req.query.voiceGender === "string" ? req.query.voiceGender : undefined; const volumeRaw = typeof req.query.volume === "string" ? req.query.volume : undefined; if (!achievement) { return res.status(400).json({ error: "achievement query param required" }); } try { const volume = volumeRaw ? clampVolume(Number(volumeRaw)) : undefined; await triggerQuakeAchievement({ achievement, voiceGender, volume }); res.json({ success: true }); } catch (error) { console.error("Failed to trigger achievement", error); res.status(500).json({ error: "Failed to call MCP server", details: error.message ?? String(error) }); } }); app.get("*", (_req, res) => { res.sendFile(path.join(__dirname, "../public/index.html")); }); app.listen(PORT, () => { console.log(`⚡️ Chat widget server on http://localhost:${PORT}`); console.log(`🤖 MCP server target: ${MCP_SERVER_URL}`); }); function pickAchievement({ userText, reply }) { const text = `${userText} ${reply}`.toLowerCase(); if (/deploy|ship|release/.test(text)) return "GODLIKE"; if (/bug|fix|squash/.test(text)) return "HEADSHOT"; if (/test|coverage|unit/.test(text)) return "PERFECT"; if (/refactor|cleanup|massive/.test(text)) return "MONSTER KILL"; if (/start|ready|prep/.test(text)) return "PREPARE TO FIGHT"; if (/awesome|excellent|great|amazing/.test(text)) return "EXCELLENT"; return undefined; } function clampVolume(value) { if (Number.isNaN(value)) return undefined; return Math.max(0, Math.min(100, value)); } let quakeClientPromise; async function getQuakeClient() { if (quakeClientPromise) return quakeClientPromise; quakeClientPromise = (async () => { const client = new McpClient({ name: "quake-chat-widget", version: "0.1.0", }); const transport = new StreamableHTTPClientTransport(new URL(MCP_SERVER_URL)); await client.connect(transport); return { client, transport }; })().catch((error) => { quakeClientPromise = undefined; throw error; }); return quakeClientPromise; } async function triggerQuakeAchievement({ achievement, voiceGender, volume }) { const normalized = achievement.trim(); const { client } = await getQuakeClient(); const args = { achievement: normalized }; if (voiceGender) args.voiceGender = voiceGender; if (typeof volume === "number") args.volume = volume; await client.callTool({ name: "play_enhanced_quake_sound", arguments: args, }); } process.on("SIGINT", async () => { console.log("\nShutting down chat widget server..."); try { const clientState = await Promise.resolve(quakeClientPromise); await clientState?.transport?.close?.(); } catch (error) { console.error("Failed to close MCP transport", error); } process.exit(0); });

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/Ripnrip/Quake-Coding-Arena-MCP'

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