Skip to main content
Glama
index.js3 kB
import express from "express"; import helmet from "helmet"; import dotenv from "dotenv"; import postRoutes from "./routes/postRoutes.js"; // Import post routes import imageRoutes from "./routes/imageRoutes.js"; // Import image routes import tagRoutes from "./routes/tagRoutes.js"; // Import tag routes import { startMCPServer } from "./mcp_server.js"; // Import MCP server start function import { createContextLogger } from "./utils/logger.js"; // Load environment variables from .env file dotenv.config(); // Initialize logger for main server const logger = createContextLogger('main'); const app = express(); const restApiPort = process.env.PORT || 3000; const mcpPort = process.env.MCP_PORT || 3001; // Allow configuring MCP port // Apply security headers with Helmet (OWASP recommended) app.use(helmet({ contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], styleSrc: ["'self'", "'unsafe-inline'"], scriptSrc: ["'self'"], imgSrc: ["'self'", "data:", "https:"], connectSrc: ["'self'"], fontSrc: ["'self'"], objectSrc: ["'none'"], mediaSrc: ["'self'"], frameSrc: ["'none'"], }, }, hsts: { maxAge: 31536000, includeSubDomains: true, preload: true } })) // Middleware to parse JSON bodies with size limits app.use(express.json({ limit: '1mb', strict: true, type: 'application/json' })); // Middleware to parse URL-encoded bodies with size limits app.use(express.urlencoded({ extended: true, limit: '1mb', parameterLimit: 100 })); // Health check endpoint app.get("/health", (req, res) => { res.status(200).json({ status: "ok", message: "Server is running" }); }); // Mount the post routes app.use("/api/posts", postRoutes); // All post routes will be prefixed with /api/posts // Mount the image routes app.use("/api/images", imageRoutes); // Mount the tag routes app.use("/api/tags", tagRoutes); // Global error handler for Express app.use((err, req, res, next) => { const statusCode = err.statusCode || err.response?.status || 500; logger.error('Express error handler triggered', { error: err.message, statusCode, stack: err.stack, url: req.url, method: req.method, type: 'express_error' }); res.status(statusCode).json({ message: err.message || "Internal Server Error", // Optionally include stack trace in development stack: process.env.NODE_ENV === "development" ? err.stack : undefined, }); }); // Start both servers const startServers = async () => { // Start Express server app.listen(restApiPort, () => { logger.info('Express REST API server started', { port: restApiPort, url: `http://localhost:${restApiPort}`, type: 'server_start' }); }); // Start MCP server await startMCPServer(mcpPort); }; startServers().catch((error) => { logger.error('Failed to start servers', { error: error.message, stack: error.stack, type: 'server_start_error' }); process.exit(1); });

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/jgardner04/Ghost-MCP-Server'

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