This commit is contained in:
2026-07-09 01:12:40 +03:00
parent cefb27349c
commit 4d621e0a54
6 changed files with 1193 additions and 74 deletions
+53 -20
View File
@@ -1,6 +1,6 @@
import { McpServer } from "@modelcontextprotocol/server"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { serveStdio } from "@modelcontextprotocol/server/stdio"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { NodeStreamableHTTPServerTransport } from "@modelcontextprotocol/node"; import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
import { Command } from "commander"; import { Command } from "commander";
import http from "node:http"; import http from "node:http";
import crypto from "node:crypto"; import crypto from "node:crypto";
@@ -32,22 +32,14 @@ function buildServer(): McpServer {
return server; return server;
} }
async function main() { async function runStdio() {
const transportType: string = options.transport; const server = buildServer();
const transport = new StdioServerTransport();
if (transportType === "stdio") { await server.connect(transport);
serveStdio(buildServer);
return;
} }
if (transportType === "sse") { async function runSSE() {
const server = buildServer(); const transports = new Map<string, SSEServerTransport>();
const mcpTransport = new NodeStreamableHTTPServerTransport({
sessionIdGenerator: () => crypto.randomUUID(),
});
await server.connect(mcpTransport);
const httpServer = http.createServer(async (req, res) => { const httpServer = http.createServer(async (req, res) => {
if (options.tokenHash) { if (options.tokenHash) {
@@ -71,7 +63,37 @@ async function main() {
return; return;
} }
await mcpTransport.handleRequest(req, res); const url = new URL(req.url || "/", `http://${req.headers.host}`);
if (req.method === "GET") {
const sessionId = crypto.randomUUID();
const transport = new SSEServerTransport("/message", res);
transports.set(sessionId, transport);
res.on("close", () => {
transports.delete(sessionId);
});
const server = buildServer();
await server.connect(transport);
return;
}
if (req.method === "POST" && url.pathname === "/message") {
const sessionId = url.searchParams.get("sessionId") || "";
const transport = transports.get(sessionId);
if (!transport) {
res.writeHead(404, { "Content-Type": "text/plain" });
res.end("Session not found");
return;
}
await transport.handlePostMessage(req, res);
return;
}
res.writeHead(404);
res.end("Not found");
}); });
const port = Number(options.port); const port = Number(options.port);
@@ -80,12 +102,23 @@ async function main() {
console.error( console.error(
`Exchange MCP Server running via SSE on http://${options.host}:${port}`, `Exchange MCP Server running via SSE on http://${options.host}:${port}`,
); );
return;
} }
console.error(`Unsupported transport: ${transportType}. Use "stdio" or "sse".`); async function main() {
const transportType: string = options.transport;
switch (transportType) {
case "stdio":
await runStdio();
break;
case "sse":
await runSSE();
break;
default:
console.error(`Unsupported transport: "${transportType}". Use "stdio" or "sse".`);
process.exit(1); process.exit(1);
} }
}
main().catch((error) => { main().catch((error) => {
console.error("Fatal error:", error); console.error("Fatal error:", error);
+1111 -24
View File
File diff suppressed because it is too large Load Diff
+1 -2
View File
@@ -7,8 +7,7 @@
"format": "dprint fmt" "format": "dprint fmt"
}, },
"dependencies": { "dependencies": {
"@modelcontextprotocol/node": "^2.0.0-beta.2", "@modelcontextprotocol/sdk": "^1.29.0",
"@modelcontextprotocol/server": "^2.0.0-beta.2",
"commander": "^15.0.0", "commander": "^15.0.0",
"fast-xml-parser": "^5.2.0", "fast-xml-parser": "^5.2.0",
"httpntlm": "^1.8.13", "httpntlm": "^1.8.13",
+1 -1
View File
@@ -1,6 +1,6 @@
import { z } from "zod/v4"; import { z } from "zod/v4";
import { EwsClient, loadConfig, saveConfig, clearConfig } from "../ews_client.ts"; import { EwsClient, loadConfig, saveConfig, clearConfig } from "../ews_client.ts";
import { type McpServer } from "@modelcontextprotocol/server"; import { type McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
export function registerAuthTools(server: McpServer): void { export function registerAuthTools(server: McpServer): void {
server.registerTool( server.registerTool(
+1 -1
View File
@@ -1,6 +1,6 @@
import { z } from "zod/v4"; import { z } from "zod/v4";
import { EwsClient, loadConfig } from "../ews_client.ts"; import { EwsClient, loadConfig } from "../ews_client.ts";
import { type McpServer } from "@modelcontextprotocol/server"; import { type McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
function getClient(): EwsClient { function getClient(): EwsClient {
return new EwsClient(loadConfig()); return new EwsClient(loadConfig());
+1 -1
View File
@@ -1,6 +1,6 @@
import { z } from "zod/v4"; import { z } from "zod/v4";
import { EwsClient, loadConfig } from "../ews_client.ts"; import { EwsClient, loadConfig } from "../ews_client.ts";
import { type McpServer } from "@modelcontextprotocol/server"; import { type McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
export function registerFolderTools(server: McpServer): void { export function registerFolderTools(server: McpServer): void {
server.registerTool( server.registerTool(