@mgsoftwarebv/mg-dashboard-mcp 2.3.0 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,9 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
3
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
- import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
4
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
5
+ import { ListToolsRequestSchema, CallToolRequestSchema, isInitializeRequest } from '@modelcontextprotocol/sdk/types.js';
6
+ import { createServer } from 'http';
7
+ import { randomUUID, createHash, randomBytes, createCipheriv, createDecipheriv } from 'crypto';
5
8
  import { createClient } from '@supabase/supabase-js';
6
- import { createHash, randomBytes, createCipheriv, createDecipheriv } from 'crypto';
7
9
  import { Client } from 'ssh2';
8
10
 
9
11
  // src/trigger-tools.ts
@@ -1213,6 +1215,8 @@ var supabaseKey = getArg("supabase-key") || process.env.SUPABASE_SERVICE_ROLE_KE
1213
1215
  var encryptionKey = getArg("encryption-key") || process.env.ENCRYPTION_KEY;
1214
1216
  var mijnhostApiKey = getArg("mijnhost-api-key") || process.env.MIJNHOST_API_KEY;
1215
1217
  var agentWorkspaceId = getArg("workspace-id") || process.env.AGENT_WORKSPACE_ID || null;
1218
+ var httpMode = args.includes("--http");
1219
+ var httpPort = Number(getArg("port")) || 3100;
1216
1220
  if (!apiKey) {
1217
1221
  console.error("API key is required. Use --api-key=dk_xxx or set MG_DASHBOARD_API_KEY");
1218
1222
  process.exit(1);
@@ -2474,11 +2478,8 @@ var TOOLS = [
2474
2478
  // ----- Agent Reporting -----
2475
2479
  ...AGENT_TOOLS
2476
2480
  ];
2477
- var server = new Server(
2478
- { name: "mg-dashboard-mcp", version: "2.2.0" },
2479
- { capabilities: { tools: {} } }
2480
- );
2481
- server.setRequestHandler(ListToolsRequestSchema, async () => {
2481
+ var MCP_VERSION = "2.3.1";
2482
+ async function handleListTools() {
2482
2483
  if (!authContext) return { tools: TOOLS };
2483
2484
  const accessible = TOOLS.filter((tool) => {
2484
2485
  const requiredModule = TOOL_MODULE_MAP[tool.name];
@@ -2486,8 +2487,8 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
2486
2487
  return authContext.permissions.modules[requiredModule] === true;
2487
2488
  });
2488
2489
  return { tools: accessible };
2489
- });
2490
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
2490
+ }
2491
+ async function handleCallTool(request) {
2491
2492
  if (!authContext) {
2492
2493
  return { content: [{ type: "text", text: "Error: not authenticated" }] };
2493
2494
  }
@@ -2935,7 +2936,17 @@ ${lines.join("\n")}` }] };
2935
2936
  const message = err instanceof Error ? err.message : String(err);
2936
2937
  return { content: [{ type: "text", text: `Error: ${message}` }] };
2937
2938
  }
2938
- });
2939
+ }
2940
+ function createMcpServer() {
2941
+ const s = new Server(
2942
+ { name: "mg-dashboard-mcp", version: MCP_VERSION },
2943
+ { capabilities: { tools: {} } }
2944
+ );
2945
+ s.setRequestHandler(ListToolsRequestSchema, handleListTools);
2946
+ s.setRequestHandler(CallToolRequestSchema, handleCallTool);
2947
+ return s;
2948
+ }
2949
+ var server = createMcpServer();
2939
2950
  async function main() {
2940
2951
  console.error("Starting MG Dashboard MCP Server...");
2941
2952
  authContext = await validateApiKey(apiKey);
@@ -2943,10 +2954,71 @@ async function main() {
2943
2954
  console.error("API key validation failed");
2944
2955
  process.exit(1);
2945
2956
  }
2946
- console.error("API key validated. Starting stdio transport...");
2947
- const transport = new StdioServerTransport();
2948
- await server.connect(transport);
2949
- console.error("MCP Server ready. Tools available: " + TOOLS.map((t) => t.name).join(", "));
2957
+ const toolNames = TOOLS.map((t) => t.name).join(", ");
2958
+ if (httpMode) {
2959
+ console.error(`API key validated. Starting Streamable HTTP transport on port ${httpPort}...`);
2960
+ const transports = /* @__PURE__ */ new Map();
2961
+ const httpServer = createServer(async (req, res) => {
2962
+ const url = new URL(req.url ?? "/", `http://localhost:${httpPort}`);
2963
+ if (url.pathname !== "/mcp") {
2964
+ res.writeHead(404, { "Content-Type": "text/plain" });
2965
+ res.end("Not found");
2966
+ return;
2967
+ }
2968
+ if (req.method === "OPTIONS") {
2969
+ res.writeHead(204, {
2970
+ "Access-Control-Allow-Origin": "*",
2971
+ "Access-Control-Allow-Methods": "GET, POST, DELETE, OPTIONS",
2972
+ "Access-Control-Allow-Headers": "Content-Type, mcp-session-id",
2973
+ "Access-Control-Expose-Headers": "mcp-session-id"
2974
+ });
2975
+ res.end();
2976
+ return;
2977
+ }
2978
+ res.setHeader("Access-Control-Allow-Origin", "*");
2979
+ res.setHeader("Access-Control-Expose-Headers", "mcp-session-id");
2980
+ const sessionId = req.headers["mcp-session-id"];
2981
+ let body;
2982
+ if (req.method === "POST") {
2983
+ const chunks = [];
2984
+ for await (const chunk of req) chunks.push(chunk);
2985
+ try {
2986
+ body = JSON.parse(Buffer.concat(chunks).toString());
2987
+ } catch {
2988
+ res.writeHead(400, { "Content-Type": "text/plain" });
2989
+ res.end("Invalid JSON");
2990
+ return;
2991
+ }
2992
+ }
2993
+ if (sessionId && transports.has(sessionId)) {
2994
+ await transports.get(sessionId).handleRequest(req, res, body);
2995
+ return;
2996
+ }
2997
+ if (req.method === "POST" && body && (Array.isArray(body) ? body.some(isInitializeRequest) : isInitializeRequest(body))) {
2998
+ const transport = new StreamableHTTPServerTransport({
2999
+ sessionIdGenerator: () => randomUUID()
3000
+ });
3001
+ transport.onclose = () => {
3002
+ if (transport.sessionId) transports.delete(transport.sessionId);
3003
+ };
3004
+ const sessionServer = createMcpServer();
3005
+ await sessionServer.connect(transport);
3006
+ if (transport.sessionId) transports.set(transport.sessionId, transport);
3007
+ await transport.handleRequest(req, res, body);
3008
+ return;
3009
+ }
3010
+ res.writeHead(400, { "Content-Type": "text/plain" });
3011
+ res.end("Bad request \u2014 missing or invalid session");
3012
+ });
3013
+ httpServer.listen(httpPort, () => {
3014
+ console.error(`MCP HTTP server ready on port ${httpPort}. Tools: ${toolNames}`);
3015
+ });
3016
+ } else {
3017
+ console.error("API key validated. Starting stdio transport...");
3018
+ const transport = new StdioServerTransport();
3019
+ await server.connect(transport);
3020
+ console.error(`MCP Server ready. Tools: ${toolNames}`);
3021
+ }
2950
3022
  }
2951
3023
  main().catch((err) => {
2952
3024
  console.error("Fatal error:", err);