feat: add tool index and server entry point with stdio + HTTP transport

This commit is contained in:
2026-03-30 13:58:17 +02:00
parent 1b9c5ac2b0
commit d3697d5d23
2 changed files with 99 additions and 0 deletions
+88
View File
@@ -0,0 +1,88 @@
#!/usr/bin/env node
/**
* Novu MCP Server
*
* An MCP server providing full coverage of the Novu notification
* infrastructure API. Supports stdio and Streamable HTTP transports.
*/
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import express from "express";
import { getApiKey } from "./constants.js";
import {
registerEventsTools,
registerSubscribersTools,
registerTopicsTools,
registerWorkflowsTools,
registerNotificationsTools,
registerMessagesTools,
registerIntegrationsTools,
registerEnvironmentsTools,
registerTranslationsTools,
registerContextsTools,
registerChannelsTools,
} from "./tools/index.js";
// Validate API key early so we fail fast with a clear message
getApiKey();
const server = new McpServer({
name: "novu-mcp-server",
version: "1.0.0",
});
// Register all tool domains
registerEventsTools(server);
registerSubscribersTools(server);
registerTopicsTools(server);
registerWorkflowsTools(server);
registerNotificationsTools(server);
registerMessagesTools(server);
registerIntegrationsTools(server);
registerEnvironmentsTools(server);
registerTranslationsTools(server);
registerContextsTools(server);
registerChannelsTools(server);
async function runStdio(): Promise<void> {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("novu-mcp-server running via stdio");
}
async function runHttp(): Promise<void> {
const app = express();
app.use(express.json());
app.post("/mcp", async (req, res) => {
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined,
enableJsonResponse: true,
});
res.on("close", () => {
transport.close();
});
await server.connect(transport);
await transport.handleRequest(req, res, req.body);
});
const port = parseInt(process.env.PORT || "3000", 10);
app.listen(port, () => {
console.error(`novu-mcp-server running on http://localhost:${port}/mcp`);
});
}
const transport = process.env.TRANSPORT || "stdio";
if (transport === "http") {
runHttp().catch((err) => {
console.error("Fatal:", err);
process.exit(1);
});
} else {
runStdio().catch((err) => {
console.error("Fatal:", err);
process.exit(1);
});
}
+11
View File
@@ -0,0 +1,11 @@
export { registerEventsTools } from "./events.js";
export { registerSubscribersTools } from "./subscribers.js";
export { registerTopicsTools } from "./topics.js";
export { registerWorkflowsTools } from "./workflows.js";
export { registerNotificationsTools } from "./notifications.js";
export { registerMessagesTools } from "./messages.js";
export { registerIntegrationsTools } from "./integrations.js";
export { registerEnvironmentsTools } from "./environments.js";
export { registerTranslationsTools } from "./translations.js";
export { registerContextsTools } from "./contexts.js";
export { registerChannelsTools } from "./channels.js";