This commit is contained in:
2026-07-09 00:57:54 +03:00
parent 8d5f254728
commit cefb27349c
3 changed files with 130 additions and 1 deletions
+74 -1
View File
@@ -1,9 +1,24 @@
import { McpServer } from "@modelcontextprotocol/server";
import { serveStdio } from "@modelcontextprotocol/server/stdio";
import { NodeStreamableHTTPServerTransport } from "@modelcontextprotocol/node";
import { Command } from "commander";
import http from "node:http";
import crypto from "node:crypto";
import { registerAuthTools } from "./tools/auth.ts";
import { registerEmailTools } from "./tools/email.ts";
import { registerFolderTools } from "./tools/folders.ts";
const program = new Command()
.name("exchange-mcp")
.description("Exchange MCP Server — EWS integration via MCP")
.option("--transport <type>", "Transport: stdio or sse", "stdio")
.option("--token-hash <hash>", "SHA-256 hash of bearer token for HTTP transport auth")
.option("--host <host>", "HTTP host", "127.0.0.1")
.option("--port <port>", "HTTP port", "8000");
program.parse(process.argv);
const options = program.opts();
function buildServer(): McpServer {
const server = new McpServer({
name: "exchange-mcp",
@@ -17,4 +32,62 @@ function buildServer(): McpServer {
return server;
}
serveStdio(buildServer);
async function main() {
const transportType: string = options.transport;
if (transportType === "stdio") {
serveStdio(buildServer);
return;
}
if (transportType === "sse") {
const server = buildServer();
const mcpTransport = new NodeStreamableHTTPServerTransport({
sessionIdGenerator: () => crypto.randomUUID(),
});
await server.connect(mcpTransport);
const httpServer = http.createServer(async (req, res) => {
if (options.tokenHash) {
const auth = req.headers.authorization || "";
const token = auth.startsWith("Bearer ") ? auth.slice(7) : "";
const hash = crypto.createHash("sha256").update(token).digest("hex");
if (hash !== options.tokenHash) {
res.writeHead(401, { "Content-Type": "text/plain" });
res.end("Unauthorized");
return;
}
}
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
if (req.method === "OPTIONS") {
res.writeHead(200);
res.end();
return;
}
await mcpTransport.handleRequest(req, res);
});
const port = Number(options.port);
httpServer.listen(port, options.host);
console.error(
`Exchange MCP Server running via SSE on http://${options.host}:${port}`,
);
return;
}
console.error(`Unsupported transport: ${transportType}. Use "stdio" or "sse".`);
process.exit(1);
}
main().catch((error) => {
console.error("Fatal error:", error);
process.exit(1);
});