@exaudeus/workrail 1.16.1 → 1.17.0
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/manifest.json +38 -6
- package/dist/mcp/server.d.ts +18 -0
- package/dist/mcp/server.js +8 -1
- package/dist/mcp/transports/http-entry.d.ts +1 -0
- package/dist/mcp/transports/http-entry.js +87 -0
- package/dist/mcp/transports/http-listener.d.ts +9 -0
- package/dist/mcp/transports/http-listener.js +64 -0
- package/dist/mcp/transports/stdio-entry.d.ts +1 -0
- package/dist/mcp/transports/stdio-entry.js +92 -0
- package/dist/mcp/transports/transport-mode.d.ts +7 -0
- package/dist/mcp/transports/transport-mode.js +18 -0
- package/dist/mcp-server.js +21 -5
- package/package.json +1 -1
package/dist/manifest.json
CHANGED
|
@@ -598,8 +598,8 @@
|
|
|
598
598
|
"bytes": 67
|
|
599
599
|
},
|
|
600
600
|
"mcp-server.js": {
|
|
601
|
-
"sha256": "
|
|
602
|
-
"bytes":
|
|
601
|
+
"sha256": "bf97a81d9bc5bb40d10ec8a06c73b322320e0a0afdaa88f19730efe781ace7cf",
|
|
602
|
+
"bytes": 1135
|
|
603
603
|
},
|
|
604
604
|
"mcp/error-mapper.d.ts": {
|
|
605
605
|
"sha256": "c6e9db65c565063726442b73a4a0cf1a1c07d54c778a85cf0122c4c04ea6a5a9",
|
|
@@ -842,12 +842,12 @@
|
|
|
842
842
|
"bytes": 12115
|
|
843
843
|
},
|
|
844
844
|
"mcp/server.d.ts": {
|
|
845
|
-
"sha256": "
|
|
846
|
-
"bytes":
|
|
845
|
+
"sha256": "782a9a50797cac9c5f30e79556f809351d7eb176a16d7c603c09a5133cc25303",
|
|
846
|
+
"bytes": 882
|
|
847
847
|
},
|
|
848
848
|
"mcp/server.js": {
|
|
849
|
-
"sha256": "
|
|
850
|
-
"bytes":
|
|
849
|
+
"sha256": "5086b482d2eb3c42caac637282a5361b4db6e5d14aaeeb7c5ffdf75d211af0d8",
|
|
850
|
+
"bytes": 13422
|
|
851
851
|
},
|
|
852
852
|
"mcp/tool-description-provider.d.ts": {
|
|
853
853
|
"sha256": "1d46abc3112e11b68e57197e846f5708293ec9b2281fa71a9124ee2aad71e41b",
|
|
@@ -881,6 +881,38 @@
|
|
|
881
881
|
"sha256": "aa364f3e613fc61a39fc7336a723231da06852d92ec7840a95327aa370e42e1c",
|
|
882
882
|
"bytes": 8360
|
|
883
883
|
},
|
|
884
|
+
"mcp/transports/http-entry.d.ts": {
|
|
885
|
+
"sha256": "35d313b120dcf38643de9462559163581b89943fe432706986252e8b698b9507",
|
|
886
|
+
"bytes": 70
|
|
887
|
+
},
|
|
888
|
+
"mcp/transports/http-entry.js": {
|
|
889
|
+
"sha256": "3ecf3a39d4eb2d4b844e83296cf04238acfc7c91e9eca0e10c1e8a0fbae71721",
|
|
890
|
+
"bytes": 4279
|
|
891
|
+
},
|
|
892
|
+
"mcp/transports/http-listener.d.ts": {
|
|
893
|
+
"sha256": "5c512d31f001bd65eaaca5421ca8f80e614896fdfe803773aa1f6c893257f20e",
|
|
894
|
+
"bytes": 316
|
|
895
|
+
},
|
|
896
|
+
"mcp/transports/http-listener.js": {
|
|
897
|
+
"sha256": "9e055636c281b5fe09623aa017d2e773462ddbe65e42c0938ed897cac606bb62",
|
|
898
|
+
"bytes": 2555
|
|
899
|
+
},
|
|
900
|
+
"mcp/transports/stdio-entry.d.ts": {
|
|
901
|
+
"sha256": "4ced3c9e00ef67555781dea74315290eea8a9dbffd38155bc00c3fb07b0c1794",
|
|
902
|
+
"bytes": 59
|
|
903
|
+
},
|
|
904
|
+
"mcp/transports/stdio-entry.js": {
|
|
905
|
+
"sha256": "a1f75205084e632b78e1ec28fb82498f04ecdb66fa4a9d9678d885268b0ed885",
|
|
906
|
+
"bytes": 4509
|
|
907
|
+
},
|
|
908
|
+
"mcp/transports/transport-mode.d.ts": {
|
|
909
|
+
"sha256": "1c59128ab0174bd2a113fff17521e6339ca367f2b8980c2f2c164ec393c10518",
|
|
910
|
+
"bytes": 206
|
|
911
|
+
},
|
|
912
|
+
"mcp/transports/transport-mode.js": {
|
|
913
|
+
"sha256": "6627303319e87e047caf99d910626a331742089b90db180f6031aa9a1afc98eb",
|
|
914
|
+
"bytes": 747
|
|
915
|
+
},
|
|
884
916
|
"mcp/types.d.ts": {
|
|
885
917
|
"sha256": "2ef7f9c1bffbe365b06469dfad43b45c4ae3b5292dd269b33423bf1c8c9c7c43",
|
|
886
918
|
"bytes": 4355
|
package/dist/mcp/server.d.ts
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
1
|
import type { ToolContext } from './types.js';
|
|
2
|
+
import { WorkspaceRootsManager } from './workspace-roots-manager.js';
|
|
3
|
+
import { type ToolAnnotations } from './tool-factory.js';
|
|
4
|
+
import type { WrappedToolHandler } from './types/workflow-tool-edition.js';
|
|
5
|
+
interface Tool {
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
inputSchema: Record<string, unknown>;
|
|
9
|
+
annotations?: ToolAnnotations;
|
|
10
|
+
}
|
|
2
11
|
export declare function createToolContext(): Promise<ToolContext>;
|
|
12
|
+
export interface ComposedServer {
|
|
13
|
+
readonly server: import('@modelcontextprotocol/sdk/server/index.js').Server;
|
|
14
|
+
readonly ctx: ToolContext;
|
|
15
|
+
readonly rootsManager: WorkspaceRootsManager;
|
|
16
|
+
readonly tools: readonly Tool[];
|
|
17
|
+
readonly handlers: Record<string, WrappedToolHandler>;
|
|
18
|
+
}
|
|
19
|
+
export declare function composeServer(): Promise<ComposedServer>;
|
|
3
20
|
export declare function startServer(): Promise<void>;
|
|
21
|
+
export {};
|
package/dist/mcp/server.js
CHANGED
|
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.createToolContext = createToolContext;
|
|
37
|
+
exports.composeServer = composeServer;
|
|
37
38
|
exports.startServer = startServer;
|
|
38
39
|
const zod_to_json_schema_js_1 = require("./zod-to-json-schema.js");
|
|
39
40
|
const container_js_1 = require("../di/container.js");
|
|
@@ -134,7 +135,7 @@ function toMcpTool(tool) {
|
|
|
134
135
|
annotations: tool.annotations,
|
|
135
136
|
};
|
|
136
137
|
}
|
|
137
|
-
async function
|
|
138
|
+
async function composeServer() {
|
|
138
139
|
await (0, container_js_1.bootstrap)({ runtimeMode: { kind: 'production' } });
|
|
139
140
|
const ctx = await createToolContext();
|
|
140
141
|
if (ctx.v2 && ctx.httpServer && ctx.v2.dataDir && ctx.v2.directoryListing) {
|
|
@@ -204,6 +205,12 @@ async function startServer() {
|
|
|
204
205
|
: ctx;
|
|
205
206
|
return handler(args ?? {}, requestCtx);
|
|
206
207
|
});
|
|
208
|
+
return { server, ctx, rootsManager, tools, handlers };
|
|
209
|
+
}
|
|
210
|
+
async function startServer() {
|
|
211
|
+
const { server, ctx, rootsManager } = await composeServer();
|
|
212
|
+
const { StdioServerTransport } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/server/stdio.js')));
|
|
213
|
+
const { RootsListChangedNotificationSchema, } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/types.js')));
|
|
207
214
|
server.setNotificationHandler(RootsListChangedNotificationSchema, async () => {
|
|
208
215
|
try {
|
|
209
216
|
const result = await server.listRoots();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function startHttpServer(port: number): Promise<void>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.startHttpServer = startHttpServer;
|
|
40
|
+
const server_js_1 = require("../server.js");
|
|
41
|
+
const http_listener_js_1 = require("./http-listener.js");
|
|
42
|
+
const container_js_1 = require("../../di/container.js");
|
|
43
|
+
const tokens_js_1 = require("../../di/tokens.js");
|
|
44
|
+
const crypto = __importStar(require("crypto"));
|
|
45
|
+
const express_1 = __importDefault(require("express"));
|
|
46
|
+
async function startHttpServer(port) {
|
|
47
|
+
const { server, ctx } = await (0, server_js_1.composeServer)();
|
|
48
|
+
const listener = (0, http_listener_js_1.createHttpListener)(port);
|
|
49
|
+
const { StreamableHTTPServerTransport } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/server/streamableHttp.js')));
|
|
50
|
+
const transport = new StreamableHTTPServerTransport({
|
|
51
|
+
sessionIdGenerator: () => crypto.randomUUID(),
|
|
52
|
+
enableJsonResponse: true,
|
|
53
|
+
});
|
|
54
|
+
listener.app.use(express_1.default.json());
|
|
55
|
+
listener.app.post('/mcp', (req, res) => transport.handleRequest(req, res, req.body));
|
|
56
|
+
listener.app.get('/mcp', (req, res) => transport.handleRequest(req, res));
|
|
57
|
+
listener.app.delete('/mcp', (req, res) => transport.handleRequest(req, res));
|
|
58
|
+
await listener.start();
|
|
59
|
+
await server.connect(transport);
|
|
60
|
+
const boundPort = listener.getBoundPort();
|
|
61
|
+
console.error('[Transport] WorkRail MCP Server running on HTTP');
|
|
62
|
+
console.error(`[Transport] MCP endpoint: http://localhost:${boundPort}/mcp`);
|
|
63
|
+
const shutdownEvents = container_js_1.container.resolve(tokens_js_1.DI.Runtime.ShutdownEvents);
|
|
64
|
+
const processSignals = container_js_1.container.resolve(tokens_js_1.DI.Runtime.ProcessSignals);
|
|
65
|
+
const terminator = container_js_1.container.resolve(tokens_js_1.DI.Runtime.ProcessTerminator);
|
|
66
|
+
processSignals.on('SIGINT', () => shutdownEvents.emit({ kind: 'shutdown_requested', signal: 'SIGINT' }));
|
|
67
|
+
processSignals.on('SIGTERM', () => shutdownEvents.emit({ kind: 'shutdown_requested', signal: 'SIGTERM' }));
|
|
68
|
+
processSignals.on('SIGHUP', () => shutdownEvents.emit({ kind: 'shutdown_requested', signal: 'SIGHUP' }));
|
|
69
|
+
let shutdownStarted = false;
|
|
70
|
+
shutdownEvents.onShutdown((event) => {
|
|
71
|
+
if (shutdownStarted)
|
|
72
|
+
return;
|
|
73
|
+
shutdownStarted = true;
|
|
74
|
+
void (async () => {
|
|
75
|
+
try {
|
|
76
|
+
console.error(`[Shutdown] Requested by ${event.signal}. Stopping services...`);
|
|
77
|
+
await listener.stop();
|
|
78
|
+
await ctx.httpServer?.stop();
|
|
79
|
+
terminator.terminate({ kind: 'success' });
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
console.error('[Shutdown] Error while stopping services:', err);
|
|
83
|
+
terminator.terminate({ kind: 'failure' });
|
|
84
|
+
}
|
|
85
|
+
})();
|
|
86
|
+
});
|
|
87
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Application } from 'express';
|
|
2
|
+
export interface HttpListener {
|
|
3
|
+
readonly app: Application;
|
|
4
|
+
readonly requestedPort: number;
|
|
5
|
+
getBoundPort(): number | null;
|
|
6
|
+
start(): Promise<void>;
|
|
7
|
+
stop(): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
export declare function createHttpListener(requestedPort: number): HttpListener;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createHttpListener = createHttpListener;
|
|
7
|
+
const express_1 = __importDefault(require("express"));
|
|
8
|
+
const http_1 = require("http");
|
|
9
|
+
function createHttpListener(requestedPort) {
|
|
10
|
+
const app = (0, express_1.default)();
|
|
11
|
+
let state = { kind: 'not_started' };
|
|
12
|
+
return {
|
|
13
|
+
app,
|
|
14
|
+
requestedPort,
|
|
15
|
+
getBoundPort() {
|
|
16
|
+
return state.kind === 'running' ? state.boundPort : null;
|
|
17
|
+
},
|
|
18
|
+
async start() {
|
|
19
|
+
if (state.kind === 'running') {
|
|
20
|
+
throw new Error('[HttpListener] Already started');
|
|
21
|
+
}
|
|
22
|
+
if (state.kind === 'stopped') {
|
|
23
|
+
throw new Error('[HttpListener] Cannot restart a stopped listener');
|
|
24
|
+
}
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
const server = (0, http_1.createServer)(app);
|
|
27
|
+
server.on('error', (err) => {
|
|
28
|
+
if (err.code === 'EADDRINUSE') {
|
|
29
|
+
reject(new Error(`[HttpListener] Port ${requestedPort} is already in use. ` +
|
|
30
|
+
`Set WORKRAIL_HTTP_PORT to a different port or stop the conflicting process.`));
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
reject(err);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
server.listen(requestedPort, () => {
|
|
37
|
+
const addr = server.address();
|
|
38
|
+
const boundPort = addr && typeof addr === 'object' ? addr.port : requestedPort;
|
|
39
|
+
state = { kind: 'running', server, boundPort };
|
|
40
|
+
console.error(`[HttpListener] MCP HTTP transport listening on port ${boundPort}`);
|
|
41
|
+
resolve();
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
async stop() {
|
|
46
|
+
if (state.kind !== 'running') {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const serverToClose = state.server;
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
serverToClose.close((err) => {
|
|
52
|
+
if (err) {
|
|
53
|
+
reject(err);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
state = { kind: 'stopped' };
|
|
57
|
+
console.error(`[HttpListener] MCP HTTP transport stopped`);
|
|
58
|
+
resolve();
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function startStdioServer(): Promise<void>;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.startStdioServer = startStdioServer;
|
|
37
|
+
const server_js_1 = require("../server.js");
|
|
38
|
+
const container_js_1 = require("../../di/container.js");
|
|
39
|
+
const tokens_js_1 = require("../../di/tokens.js");
|
|
40
|
+
async function startStdioServer() {
|
|
41
|
+
const { server, ctx, rootsManager } = await (0, server_js_1.composeServer)();
|
|
42
|
+
const { StdioServerTransport } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/server/stdio.js')));
|
|
43
|
+
const { RootsListChangedNotificationSchema, } = await Promise.resolve().then(() => __importStar(require('@modelcontextprotocol/sdk/types.js')));
|
|
44
|
+
server.setNotificationHandler(RootsListChangedNotificationSchema, async () => {
|
|
45
|
+
try {
|
|
46
|
+
const result = await server.listRoots();
|
|
47
|
+
rootsManager.updateRootUris(result.roots.map((r) => r.uri));
|
|
48
|
+
console.error(`[Roots] Updated workspace roots: ${result.roots.map((r) => r.uri).join(', ') || '(none)'}`);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
console.error('[Roots] Failed to fetch updated roots after change notification');
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
const transport = new StdioServerTransport();
|
|
55
|
+
await server.connect(transport);
|
|
56
|
+
try {
|
|
57
|
+
const result = await server.listRoots();
|
|
58
|
+
rootsManager.updateRootUris(result.roots.map((r) => r.uri));
|
|
59
|
+
console.error(`[Roots] Initial workspace roots: ${result.roots.map((r) => r.uri).join(', ') || '(none)'}`);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
console.error('[Roots] Client does not support roots/list; workspace context will use server CWD fallback');
|
|
63
|
+
}
|
|
64
|
+
console.error('[Transport] WorkRail MCP Server running on stdio');
|
|
65
|
+
const shutdownEvents = container_js_1.container.resolve(tokens_js_1.DI.Runtime.ShutdownEvents);
|
|
66
|
+
const processSignals = container_js_1.container.resolve(tokens_js_1.DI.Runtime.ProcessSignals);
|
|
67
|
+
const terminator = container_js_1.container.resolve(tokens_js_1.DI.Runtime.ProcessTerminator);
|
|
68
|
+
processSignals.on('SIGINT', () => shutdownEvents.emit({ kind: 'shutdown_requested', signal: 'SIGINT' }));
|
|
69
|
+
processSignals.on('SIGTERM', () => shutdownEvents.emit({ kind: 'shutdown_requested', signal: 'SIGTERM' }));
|
|
70
|
+
processSignals.on('SIGHUP', () => shutdownEvents.emit({ kind: 'shutdown_requested', signal: 'SIGHUP' }));
|
|
71
|
+
process.stdin.on('end', () => {
|
|
72
|
+
console.error('[MCP] stdin closed, initiating shutdown');
|
|
73
|
+
shutdownEvents.emit({ kind: 'shutdown_requested', signal: 'SIGHUP' });
|
|
74
|
+
});
|
|
75
|
+
let shutdownStarted = false;
|
|
76
|
+
shutdownEvents.onShutdown((event) => {
|
|
77
|
+
if (shutdownStarted)
|
|
78
|
+
return;
|
|
79
|
+
shutdownStarted = true;
|
|
80
|
+
void (async () => {
|
|
81
|
+
try {
|
|
82
|
+
console.error(`[Shutdown] Requested by ${event.signal}. Stopping services...`);
|
|
83
|
+
await ctx.httpServer?.stop();
|
|
84
|
+
terminator.terminate({ kind: 'success' });
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
console.error('[Shutdown] Error while stopping services:', err);
|
|
88
|
+
terminator.terminate({ kind: 'failure' });
|
|
89
|
+
}
|
|
90
|
+
})();
|
|
91
|
+
});
|
|
92
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveTransportMode = resolveTransportMode;
|
|
4
|
+
function resolveTransportMode(env) {
|
|
5
|
+
const transport = env.WORKRAIL_TRANSPORT ?? 'stdio';
|
|
6
|
+
if (transport === 'http') {
|
|
7
|
+
const portStr = env.WORKRAIL_HTTP_PORT ?? '3100';
|
|
8
|
+
const port = parseInt(portStr, 10);
|
|
9
|
+
if (isNaN(port) || port <= 0 || port > 65535) {
|
|
10
|
+
throw new Error(`Invalid WORKRAIL_HTTP_PORT: "${portStr}". Must be a number between 1-65535.`);
|
|
11
|
+
}
|
|
12
|
+
return { kind: 'http', port };
|
|
13
|
+
}
|
|
14
|
+
if (transport !== 'stdio') {
|
|
15
|
+
throw new Error(`Invalid WORKRAIL_TRANSPORT: "${transport}". Must be 'stdio' or 'http'.`);
|
|
16
|
+
}
|
|
17
|
+
return { kind: 'stdio' };
|
|
18
|
+
}
|
package/dist/mcp-server.js
CHANGED
|
@@ -2,10 +2,26 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.startServer = void 0;
|
|
5
|
+
const transport_mode_js_1 = require("./mcp/transports/transport-mode.js");
|
|
6
|
+
const stdio_entry_js_1 = require("./mcp/transports/stdio-entry.js");
|
|
7
|
+
const http_entry_js_1 = require("./mcp/transports/http-entry.js");
|
|
8
|
+
const assert_never_js_1 = require("./runtime/assert-never.js");
|
|
5
9
|
var server_js_1 = require("./mcp/server.js");
|
|
6
10
|
Object.defineProperty(exports, "startServer", { enumerable: true, get: function () { return server_js_1.startServer; } });
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
const mode = (0, transport_mode_js_1.resolveTransportMode)(process.env);
|
|
12
|
+
switch (mode.kind) {
|
|
13
|
+
case 'stdio':
|
|
14
|
+
(0, stdio_entry_js_1.startStdioServer)().catch((error) => {
|
|
15
|
+
console.error('[stdio] Fatal error:', error);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
});
|
|
18
|
+
break;
|
|
19
|
+
case 'http':
|
|
20
|
+
(0, http_entry_js_1.startHttpServer)(mode.port).catch((error) => {
|
|
21
|
+
console.error('[http] Fatal error:', error);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
});
|
|
24
|
+
break;
|
|
25
|
+
default:
|
|
26
|
+
(0, assert_never_js_1.assertNever)(mode);
|
|
27
|
+
}
|