Skip to main content
Glama
index.ts1.76 kB
import 'dotenv/config'; import express from 'express'; import pinoHttp from 'pino-http'; import { logger } from './utils/logger'; import { registry } from './utils/metrics'; import { errorHandler } from './middleware/error-handler'; import { createRpcHandler } from './handlers/rpc'; import { createStreamHandler } from './handlers/stream'; import { createWebhookHandler } from './handlers/webhook'; import { SSEManager } from './services/sse-manager'; import { LinearService } from './services/linear-service'; const app = express(); const PORT = process.env.PORT || 3000; const sseManager = new SSEManager( parseInt(process.env.SSE_HEARTBEAT_INTERVAL_MS || '15000') ); const linearService = new LinearService( process.env.LINEAR_API_KEY || '', sseManager ); app.use(express.json({ limit: '10mb' })); app.use(pinoHttp({ logger })); app.get('/health', (_req, res) => { res.json({ status: 'ok', timestamp: new Date().toISOString() }); }); app.get('/metrics', async (_req, res) => { try { res.set('Content-Type', registry.contentType); res.end(await registry.metrics()); } catch (error) { res.status(500).end(); } }); app.post('/rpc', createRpcHandler(linearService)); app.get('/stream', createStreamHandler(sseManager)); app.post('/webhook', createWebhookHandler(sseManager, linearService)); app.use(errorHandler); const server = app.listen(PORT, () => { logger.info({ port: PORT }, 'MCP server started'); }); process.on('SIGTERM', () => { logger.info('SIGTERM received, shutting down gracefully'); server.close(() => { sseManager.shutdown(); logger.info('Server closed'); process.exit(0); }); setTimeout(() => { logger.error('Forced shutdown after timeout'); process.exit(1); }, 30000); });

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/bleugreen/linear-mcp'

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