browser-devtools-mcp 0.0.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.
Files changed (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +652 -0
  3. package/dist/browser.js +67 -0
  4. package/dist/browser.js.map +1 -0
  5. package/dist/config.js +11 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/context.js +210 -0
  8. package/dist/context.js.map +1 -0
  9. package/dist/index.js +296 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/logger.js +97 -0
  12. package/dist/logger.js.map +1 -0
  13. package/dist/server-info.js +33 -0
  14. package/dist/server-info.js.map +1 -0
  15. package/dist/server.js +131 -0
  16. package/dist/server.js.map +1 -0
  17. package/dist/tools/content/get-as-html.js +164 -0
  18. package/dist/tools/content/get-as-html.js.map +1 -0
  19. package/dist/tools/content/get-as-text.js +76 -0
  20. package/dist/tools/content/get-as-text.js.map +1 -0
  21. package/dist/tools/content/index.js +16 -0
  22. package/dist/tools/content/index.js.map +1 -0
  23. package/dist/tools/content/save-as-pdf.js +146 -0
  24. package/dist/tools/content/save-as-pdf.js.map +1 -0
  25. package/dist/tools/content/take-aria-snapshot.js +49 -0
  26. package/dist/tools/content/take-aria-snapshot.js.map +1 -0
  27. package/dist/tools/content/take-screenshot.js +113 -0
  28. package/dist/tools/content/take-screenshot.js.map +1 -0
  29. package/dist/tools/index.js +29 -0
  30. package/dist/tools/index.js.map +1 -0
  31. package/dist/tools/interaction/click.js +29 -0
  32. package/dist/tools/interaction/click.js.map +1 -0
  33. package/dist/tools/interaction/drag.js +41 -0
  34. package/dist/tools/interaction/drag.js.map +1 -0
  35. package/dist/tools/interaction/evaluate.js +33 -0
  36. package/dist/tools/interaction/evaluate.js.map +1 -0
  37. package/dist/tools/interaction/fill.js +28 -0
  38. package/dist/tools/interaction/fill.js.map +1 -0
  39. package/dist/tools/interaction/hover.js +29 -0
  40. package/dist/tools/interaction/hover.js.map +1 -0
  41. package/dist/tools/interaction/index.js +20 -0
  42. package/dist/tools/interaction/index.js.map +1 -0
  43. package/dist/tools/interaction/press-key.js +36 -0
  44. package/dist/tools/interaction/press-key.js.map +1 -0
  45. package/dist/tools/interaction/select.js +30 -0
  46. package/dist/tools/interaction/select.js.map +1 -0
  47. package/dist/tools/monitoring/get-console-messages.js +151 -0
  48. package/dist/tools/monitoring/get-console-messages.js.map +1 -0
  49. package/dist/tools/monitoring/get-http-requests.js +216 -0
  50. package/dist/tools/monitoring/get-http-requests.js.map +1 -0
  51. package/dist/tools/monitoring/index.js +7 -0
  52. package/dist/tools/monitoring/index.js.map +1 -0
  53. package/dist/tools/navigation/go-back.js +76 -0
  54. package/dist/tools/navigation/go-back.js.map +1 -0
  55. package/dist/tools/navigation/go-forward.js +76 -0
  56. package/dist/tools/navigation/go-forward.js.map +1 -0
  57. package/dist/tools/navigation/go-to.js +80 -0
  58. package/dist/tools/navigation/go-to.js.map +1 -0
  59. package/dist/tools/navigation/index.js +8 -0
  60. package/dist/tools/navigation/index.js.map +1 -0
  61. package/dist/tools/tool-executor.js +57 -0
  62. package/dist/tools/tool-executor.js.map +1 -0
  63. package/dist/tools/types.js +3 -0
  64. package/dist/tools/types.js.map +1 -0
  65. package/dist/types.js +55 -0
  66. package/dist/types.js.map +1 -0
  67. package/dist/utils.js +47 -0
  68. package/dist/utils.js.map +1 -0
  69. package/package.json +73 -0
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BrowserType = void 0;
4
+ exports.getBrowser = getBrowser;
5
+ exports.newBrowserContext = newBrowserContext;
6
+ exports.newPage = newPage;
7
+ const config_1 = require("./config");
8
+ const playwright_1 = require("playwright");
9
+ var BrowserType;
10
+ (function (BrowserType) {
11
+ BrowserType["CHROMIUM"] = "chromium";
12
+ BrowserType["FIREFOX"] = "firefox";
13
+ BrowserType["WEBKIT"] = "webkit";
14
+ })(BrowserType || (exports.BrowserType = BrowserType = {}));
15
+ const browsers = new Map();
16
+ function _createBrowserOptions(browserType) {
17
+ return {
18
+ browserType,
19
+ executablePath: config_1.BROWSER_EXECUTABLE_PATH,
20
+ };
21
+ }
22
+ async function _createBrowser(browserOptions = {}) {
23
+ // Use the appropriate browser engine
24
+ let browserInstance;
25
+ switch (browserOptions.browserType) {
26
+ case BrowserType.FIREFOX:
27
+ browserInstance = playwright_1.firefox;
28
+ break;
29
+ case BrowserType.WEBKIT:
30
+ browserInstance = playwright_1.webkit;
31
+ break;
32
+ case BrowserType.CHROMIUM:
33
+ default:
34
+ browserInstance = playwright_1.chromium;
35
+ break;
36
+ }
37
+ return browserInstance.launch({
38
+ executablePath: browserOptions.executablePath,
39
+ handleSIGINT: false,
40
+ handleSIGTERM: false,
41
+ });
42
+ }
43
+ async function getBrowser(browserType = BrowserType.CHROMIUM) {
44
+ let browserInstance = browsers.get(browserType);
45
+ if (browserInstance && !browserInstance.isConnected()) {
46
+ try {
47
+ await browserInstance.close().catch(() => { });
48
+ }
49
+ catch (err) {
50
+ // Ignore errors when closing disconnected browser
51
+ }
52
+ // Reset browser and page references
53
+ browserInstance = undefined;
54
+ }
55
+ if (!browserInstance) {
56
+ browserInstance = await _createBrowser(_createBrowserOptions(browserType));
57
+ browsers.set(browserType, browserInstance);
58
+ }
59
+ return browserInstance;
60
+ }
61
+ async function newBrowserContext(browser, browserContextOptions = {}) {
62
+ return await browser.newContext();
63
+ }
64
+ async function newPage(browserContext, pageOptions = {}) {
65
+ return await browserContext.newPage();
66
+ }
67
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":";;;AAoDA,gCAoBC;AAED,8CAKC;AAED,0BAKC;AAtFD,qCAAmD;AAEnD,2CAAuD;AAEvD,IAAY,WAIX;AAJD,WAAY,WAAW;IACnB,oCAAqB,CAAA;IACrB,kCAAmB,CAAA;IACnB,gCAAiB,CAAA;AACrB,CAAC,EAJW,WAAW,2BAAX,WAAW,QAItB;AAWD,MAAM,QAAQ,GAA8B,IAAI,GAAG,EAAE,CAAC;AAEtD,SAAS,qBAAqB,CAAC,WAAwB;IACnD,OAAO;QACH,WAAW;QACX,cAAc,EAAE,gCAAuB;KAC1C,CAAC;AACN,CAAC;AAED,KAAK,UAAU,cAAc,CACzB,iBAAiC,EAAE;IAEnC,qCAAqC;IACrC,IAAI,eAAe,CAAC;IACpB,QAAQ,cAAc,CAAC,WAAW,EAAE,CAAC;QACjC,KAAK,WAAW,CAAC,OAAO;YACpB,eAAe,GAAG,oBAAO,CAAC;YAC1B,MAAM;QACV,KAAK,WAAW,CAAC,MAAM;YACnB,eAAe,GAAG,mBAAM,CAAC;YACzB,MAAM;QACV,KAAK,WAAW,CAAC,QAAQ,CAAC;QAC1B;YACI,eAAe,GAAG,qBAAQ,CAAC;YAC3B,MAAM;IACd,CAAC;IACD,OAAO,eAAe,CAAC,MAAM,CAAC;QAC1B,cAAc,EAAE,cAAc,CAAC,cAAc;QAC7C,YAAY,EAAE,KAAK;QACnB,aAAa,EAAE,KAAK;KACvB,CAAC,CAAC;AACP,CAAC;AAEM,KAAK,UAAU,UAAU,CAC5B,cAA2B,WAAW,CAAC,QAAQ;IAE/C,IAAI,eAAe,GAAwB,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACrE,IAAI,eAAe,IAAI,CAAC,eAAe,CAAC,WAAW,EAAE,EAAE,CAAC;QACpD,IAAI,CAAC;YACD,MAAM,eAAe,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAS,EAAE,GAAE,CAAC,CAAC,CAAC;QACxD,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,kDAAkD;QACtD,CAAC;QACD,oCAAoC;QACpC,eAAe,GAAG,SAAS,CAAC;IAChC,CAAC;IACD,IAAI,CAAC,eAAe,EAAE,CAAC;QACnB,eAAe,GAAG,MAAM,cAAc,CAClC,qBAAqB,CAAC,WAAW,CAAC,CACrC,CAAC;QACF,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,eAAe,CAAC;AAC3B,CAAC;AAEM,KAAK,UAAU,iBAAiB,CACnC,OAAgB,EAChB,wBAA+C,EAAE;IAEjD,OAAO,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;AACtC,CAAC;AAEM,KAAK,UAAU,OAAO,CACzB,cAA8B,EAC9B,cAA2B,EAAE;IAE7B,OAAO,MAAM,cAAc,CAAC,OAAO,EAAE,CAAC;AAC1C,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BROWSER_EXECUTABLE_PATH = exports.HTTP_REQUESTS_BUFFER_SIZE = exports.CONSOLE_MESSAGES_BUFFER_SIZE = exports.SESSION_CLOSE_ON_SOCKET_CLOSE = exports.SESSION_IDLE_CHECK_SECONDS = exports.SESSION_IDLE_SECONDS = exports.PORT = void 0;
4
+ exports.PORT = Number(process.env.PORT) || 3000;
5
+ exports.SESSION_IDLE_SECONDS = Number(process.env.SESSION_IDLE_SECONDS) || 300;
6
+ exports.SESSION_IDLE_CHECK_SECONDS = Number(process.env.SESSION_IDLE_CHECK_SECONDS) || 30;
7
+ exports.SESSION_CLOSE_ON_SOCKET_CLOSE = process.env.SESSION_CLOSE_ON_SOCKET_CLOSE === 'true';
8
+ exports.CONSOLE_MESSAGES_BUFFER_SIZE = Number(process.env.CONSOLE_MESSAGES_BUFFER_SIZE) || 1_000;
9
+ exports.HTTP_REQUESTS_BUFFER_SIZE = Number(process.env.HTTP_REQUESTS_BUFFER_SIZE) || 1_000;
10
+ exports.BROWSER_EXECUTABLE_PATH = process.env.BROWSER_EXECUTABLE_PATH;
11
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;AAAa,QAAA,IAAI,GAAW,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;AAChD,QAAA,oBAAoB,GAC7B,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,GAAG,CAAC;AACvC,QAAA,0BAA0B,GACnC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,IAAI,EAAE,CAAC;AAC5C,QAAA,6BAA6B,GACtC,OAAO,CAAC,GAAG,CAAC,6BAA6B,KAAK,MAAM,CAAC;AAC5C,QAAA,4BAA4B,GACrC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,IAAI,KAAK,CAAC;AACjD,QAAA,yBAAyB,GAClC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,IAAI,KAAK,CAAC;AAC9C,QAAA,uBAAuB,GAChC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC"}
@@ -0,0 +1,210 @@
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.McpSessionContext = void 0;
37
+ const config_1 = require("./config");
38
+ const logger = __importStar(require("./logger"));
39
+ const types_1 = require("./types");
40
+ class McpSessionContext {
41
+ consoleMessages = [];
42
+ httpRequests = [];
43
+ sessionIdProvider;
44
+ closed = false;
45
+ browser;
46
+ browserContext;
47
+ page;
48
+ constructor(sessionIdProvider, browser, browserContext, page) {
49
+ this.sessionIdProvider = sessionIdProvider;
50
+ this.browser = browser;
51
+ this.browserContext = browserContext;
52
+ this.page = page;
53
+ this._init();
54
+ }
55
+ _init() {
56
+ const me = this;
57
+ let consoleMessageSequenceNumber = 0;
58
+ this.page.on('console', (msg) => {
59
+ me.consoleMessages.push(me._toConsoleMessage(msg, ++consoleMessageSequenceNumber));
60
+ if (me.consoleMessages.length > config_1.CONSOLE_MESSAGES_BUFFER_SIZE) {
61
+ me.consoleMessages.splice(0, me.consoleMessages.length - config_1.CONSOLE_MESSAGES_BUFFER_SIZE);
62
+ }
63
+ });
64
+ this.page.on('pageerror', (err) => {
65
+ me.consoleMessages.push(me._errorToConsoleMessage(err, ++consoleMessageSequenceNumber));
66
+ if (me.consoleMessages.length > config_1.CONSOLE_MESSAGES_BUFFER_SIZE) {
67
+ me.consoleMessages.splice(0, me.consoleMessages.length - config_1.CONSOLE_MESSAGES_BUFFER_SIZE);
68
+ }
69
+ });
70
+ let httpRequestSequenceNumber = 0;
71
+ this.page.on('requestfinished', async (req) => {
72
+ me.httpRequests.push(await me._toHttpRequest(req, ++httpRequestSequenceNumber));
73
+ if (me.httpRequests.length > config_1.HTTP_REQUESTS_BUFFER_SIZE) {
74
+ me.httpRequests.splice(0, me.httpRequests.length - config_1.HTTP_REQUESTS_BUFFER_SIZE);
75
+ }
76
+ });
77
+ this.page.on('requestfailed', async (req) => {
78
+ me.httpRequests.push(await me._toHttpRequest(req, ++httpRequestSequenceNumber));
79
+ if (me.httpRequests.length > config_1.HTTP_REQUESTS_BUFFER_SIZE) {
80
+ me.httpRequests.splice(0, me.httpRequests.length - config_1.HTTP_REQUESTS_BUFFER_SIZE);
81
+ }
82
+ });
83
+ }
84
+ _toConsoleMessageLevelName(type) {
85
+ switch (type) {
86
+ case 'assert':
87
+ case 'error':
88
+ return types_1.ConsoleMessageLevelName.ERROR;
89
+ case 'warning':
90
+ return types_1.ConsoleMessageLevelName.WARNING;
91
+ case 'count':
92
+ case 'dir':
93
+ case 'dirxml':
94
+ case 'info':
95
+ case 'log':
96
+ case 'table':
97
+ case 'time':
98
+ case 'timeEnd':
99
+ return types_1.ConsoleMessageLevelName.INFO;
100
+ case 'clear':
101
+ case 'debug':
102
+ case 'endGroup':
103
+ case 'profile':
104
+ case 'profileEnd':
105
+ case 'startGroup':
106
+ case 'startGroupCollapsed':
107
+ case 'trace':
108
+ return types_1.ConsoleMessageLevelName.DEBUG;
109
+ default:
110
+ return types_1.ConsoleMessageLevelName.INFO;
111
+ }
112
+ }
113
+ _toConsoleMessage(message, sequenceNumber) {
114
+ const timestamp = Date.now();
115
+ const levelName = this._toConsoleMessageLevelName(message.type());
116
+ const levelCode = types_1.ConsoleMessageLevel[levelName].code;
117
+ return {
118
+ type: message.type(),
119
+ text: message.text(),
120
+ level: {
121
+ name: levelName,
122
+ code: levelCode,
123
+ },
124
+ location: {
125
+ url: message.location().url,
126
+ lineNumber: message.location().lineNumber,
127
+ columnNumber: message.location().columnNumber,
128
+ },
129
+ timestamp,
130
+ sequenceNumber,
131
+ };
132
+ }
133
+ _errorToConsoleMessage(error, sequenceNumber) {
134
+ const timestamp = Date.now();
135
+ if (error instanceof Error) {
136
+ return {
137
+ type: 'error',
138
+ text: error.message,
139
+ level: {
140
+ name: types_1.ConsoleMessageLevelName.ERROR,
141
+ code: types_1.ConsoleMessageLevelCode.ERROR,
142
+ },
143
+ timestamp,
144
+ sequenceNumber,
145
+ };
146
+ }
147
+ return {
148
+ type: 'error',
149
+ text: String(error),
150
+ level: {
151
+ name: types_1.ConsoleMessageLevelName.ERROR,
152
+ code: types_1.ConsoleMessageLevelCode.ERROR,
153
+ },
154
+ timestamp,
155
+ sequenceNumber,
156
+ };
157
+ }
158
+ async _toHttpRequest(req, sequenceNumber) {
159
+ const res = await req.response();
160
+ return {
161
+ url: req.url(),
162
+ method: req.method(),
163
+ headers: req.headers(),
164
+ body: req.postData() || undefined,
165
+ resourceType: req.resourceType(),
166
+ failure: req.failure()?.errorText,
167
+ duration: req.timing().responseEnd,
168
+ response: res
169
+ ? {
170
+ status: res.status(),
171
+ statusText: res.statusText(),
172
+ headers: res.headers(),
173
+ body: (await res.body()).toString(),
174
+ }
175
+ : undefined,
176
+ ok: res ? res.ok() : false,
177
+ timestamp: Math.floor(req.timing().startTime),
178
+ sequenceNumber,
179
+ };
180
+ }
181
+ sessionId() {
182
+ return this.sessionIdProvider();
183
+ }
184
+ getConsoleMessages() {
185
+ return this.consoleMessages;
186
+ }
187
+ getHttpRequests() {
188
+ return this.httpRequests;
189
+ }
190
+ async close() {
191
+ if (this.closed) {
192
+ return false;
193
+ }
194
+ // Page(s) owned by browser context are already closed by the browser context itself
195
+ try {
196
+ logger.debug(`Closing browser context of the MCP session with id ${this.sessionIdProvider()} ...`);
197
+ await this.browserContext.close();
198
+ }
199
+ catch (err) {
200
+ logger.debug(`Error occurred while closing browser context of the MCP session with id ${this.sessionIdProvider()} ...`, err);
201
+ }
202
+ this.consoleMessages.length = 0;
203
+ this.httpRequests.length = 0;
204
+ // We are not closing browser here as it is shared between sessions, so it should be closed on MCP server close/shutdown
205
+ this.closed = true;
206
+ return true;
207
+ }
208
+ }
209
+ exports.McpSessionContext = McpSessionContext;
210
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,296 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ const config = __importStar(require("./config"));
41
+ const logger = __importStar(require("./logger"));
42
+ const server_1 = require("./server");
43
+ const crypto_1 = __importDefault(require("crypto"));
44
+ const mcp_1 = require("@hono/mcp");
45
+ const node_server_1 = require("@hono/node-server");
46
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
47
+ const commander_1 = require("commander");
48
+ const hono_1 = require("hono");
49
+ const cors_1 = require("hono/cors");
50
+ const MCP_TEMPLATE = {
51
+ jsonrpc: '2.0',
52
+ error: {
53
+ code: 0,
54
+ message: 'N/A',
55
+ },
56
+ id: null,
57
+ };
58
+ const MCP_ERRORS = {
59
+ get sessionNotFound() {
60
+ return _buildMCPErrorResponse(-32001, 'Session Not Found');
61
+ },
62
+ get unauthorized() {
63
+ return _buildMCPErrorResponse(-32001, 'Unauthorized');
64
+ },
65
+ get internalServerError() {
66
+ return _buildMCPErrorResponse(-32603, 'Internal Server Error');
67
+ },
68
+ };
69
+ const sessions = new Map();
70
+ function _buildMCPErrorResponse(code, message) {
71
+ const result = { ...MCP_TEMPLATE };
72
+ result.error.code = code;
73
+ result.error.message = message;
74
+ return result;
75
+ }
76
+ function _parsePort(value) {
77
+ const n = Number(value);
78
+ if (!Number.isInteger(n) || n < 1 || n > 65535) {
79
+ throw new commander_1.InvalidOptionArgumentError('port must be an integer between 1 and 65535');
80
+ }
81
+ return n;
82
+ }
83
+ function _getOptions() {
84
+ const program = new commander_1.Command()
85
+ .addOption(new commander_1.Option('--transport <type>', 'transport type')
86
+ .choices(['stdio', 'streamable-http'])
87
+ .default('stdio'))
88
+ .addOption(new commander_1.Option('--port <number>', 'port for Streamable HTTP transport')
89
+ .argParser(_parsePort)
90
+ .default(config.PORT))
91
+ .allowUnknownOption()
92
+ .parse(process.argv);
93
+ return program.opts();
94
+ }
95
+ function _getConfig() {
96
+ return {};
97
+ }
98
+ async function _startStdioServer() {
99
+ await (0, server_1.createSession)(_getConfig(), new stdio_js_1.StdioServerTransport());
100
+ }
101
+ async function _createMCPServerSession(ctx) {
102
+ let session;
103
+ // Get MCP server config
104
+ const serverConfig = _getConfig();
105
+ // Create new instances of MCP Server and Transport for each incoming request
106
+ const transport = new mcp_1.StreamableHTTPTransport({
107
+ // Change to `false` if you want to enable SSE in responses.
108
+ enableJsonResponse: true,
109
+ sessionIdGenerator: () => crypto_1.default.randomUUID(),
110
+ onsessioninitialized: async (sessionId) => {
111
+ sessions.set(sessionId, session);
112
+ session.initialized = true;
113
+ logger.debug(`MCP session initialized with id ${sessionId}`);
114
+ },
115
+ onsessionclosed: async (sessionId) => {
116
+ logger.debug(`Closing MCP session closed with id ${sessionId} ...`);
117
+ await transport.close();
118
+ logger.debug(`MCP session closed with id ${sessionId}`);
119
+ },
120
+ });
121
+ // Create MCP session with MCP server
122
+ session = await (0, server_1.createSession)(serverConfig, transport);
123
+ // Register hook to close the associated MCP session on socket close
124
+ const socket = ctx.env.incoming.socket;
125
+ if (!socket._mcpRegistered) {
126
+ socket._mcpRegistered = true;
127
+ socket.on('close', async () => {
128
+ logger.debug(`Socket, which is for MCP session with id ${transport.sessionId}, has been closed`);
129
+ if (config.SESSION_CLOSE_ON_SOCKET_CLOSE) {
130
+ await transport.close();
131
+ }
132
+ });
133
+ }
134
+ // Register MCP session close hook to gracefully close it
135
+ _registerMCPSessionClose(transport, session.server);
136
+ logger.debug(`Created MCP server session with id ${transport.sessionId}`);
137
+ return session;
138
+ }
139
+ async function _getMCPServerSession(sessionId) {
140
+ return sessions.get(sessionId);
141
+ }
142
+ async function _getOrCreateMCPServerSession(ctx) {
143
+ const sessionId = ctx.req.header('mcp-session-id');
144
+ if (sessionId) {
145
+ const session = sessions.get(sessionId);
146
+ if (session) {
147
+ logger.debug(`Reusing MCP session with id ${sessionId}`);
148
+ }
149
+ else {
150
+ logger.debug(`No MCP session could be found with id ${sessionId}`);
151
+ }
152
+ return session;
153
+ }
154
+ return await _createMCPServerSession(ctx);
155
+ }
156
+ function _registerMCPSessionClose(transport, mcpServer) {
157
+ let closed = false;
158
+ transport.onclose = async () => {
159
+ logger.debug(`Closing MCP session with id ${transport.sessionId} ...`);
160
+ if (closed) {
161
+ logger.debug(`MCP session with id ${transport.sessionId} has already been closed`);
162
+ return;
163
+ }
164
+ closed = true;
165
+ try {
166
+ await mcpServer.close();
167
+ logger.debug('Closed MCP server');
168
+ }
169
+ catch (err) {
170
+ logger.error('Error occurred while closing MCP server', err);
171
+ }
172
+ if (transport.sessionId) {
173
+ const session = sessions.get(transport.sessionId);
174
+ if (session) {
175
+ session.closed = true;
176
+ try {
177
+ await session.context.close();
178
+ }
179
+ catch (err) {
180
+ logger.error('Error occurred while closing MCP session context', err);
181
+ }
182
+ }
183
+ sessions.delete(transport.sessionId);
184
+ }
185
+ logger.debug(`Closing MCP session with id ${transport.sessionId} ...`);
186
+ };
187
+ }
188
+ function _scheduleIdleSessionCheck() {
189
+ const sessionCheck = () => {
190
+ const currentTime = Date.now();
191
+ for (const [sessionId, session] of sessions) {
192
+ logger.debug(`Checking whether session with id ${sessionId} is idle or not ...`);
193
+ if (currentTime - session.lastActiveAt >
194
+ config.SESSION_IDLE_SECONDS * 1000) {
195
+ logger.debug(`Session with id ${sessionId} is idle, so it will be closing ...`);
196
+ session.transport
197
+ .close()
198
+ .then(() => {
199
+ logger.debug(`Session with id ${sessionId} was idle, so it has been closed`);
200
+ })
201
+ .catch((err) => {
202
+ logger.error(`Unable to delete idle session with id ${sessionId}`, err);
203
+ });
204
+ }
205
+ }
206
+ };
207
+ setInterval(sessionCheck, config.SESSION_IDLE_CHECK_SECONDS * 1000);
208
+ }
209
+ const app = new hono_1.Hono();
210
+ async function _startStreamableHTTPServer(port) {
211
+ // Global CORS
212
+ app.use('*', (0, cors_1.cors)({
213
+ origin: '*',
214
+ allowMethods: ['GET', 'POST', 'OPTIONS'],
215
+ allowHeaders: [
216
+ 'Content-Type',
217
+ 'Authorization',
218
+ 'MCP-Protocol-Version',
219
+ ],
220
+ }));
221
+ // MCP Health
222
+ app.get('/health', (ctx) => ctx.json({ status: 'ok' }));
223
+ // MCP Ping
224
+ app.get('/ping', (ctx) => ctx.json({ status: 'ok', message: 'pong' }));
225
+ // MCP Get info
226
+ app.get('/mcp', (ctx) => ctx.json({
227
+ status: 'ok',
228
+ protocol: 'model-context-protocol',
229
+ version: '1.0',
230
+ }));
231
+ // MCP Post message
232
+ app.post('/mcp', async (ctx) => {
233
+ try {
234
+ const mcpSession = await _getOrCreateMCPServerSession(ctx);
235
+ if (!mcpSession) {
236
+ return ctx.json(MCP_ERRORS.sessionNotFound, 400);
237
+ }
238
+ mcpSession.lastActiveAt = Date.now();
239
+ return await mcpSession.transport.handleRequest(ctx);
240
+ }
241
+ catch (err) {
242
+ logger.error('Error occurred while handling MCP request', err);
243
+ return ctx.json(MCP_ERRORS.internalServerError, 500);
244
+ }
245
+ });
246
+ // MCP Delete session
247
+ app.delete('/mcp', async (ctx) => {
248
+ try {
249
+ const sessionId = ctx.req.header('mcp-session-id');
250
+ if (!sessionId) {
251
+ return ctx.json(MCP_ERRORS.sessionNotFound, 400);
252
+ }
253
+ const mcpSession = await _getMCPServerSession(sessionId);
254
+ if (!mcpSession) {
255
+ return ctx.json(MCP_ERRORS.sessionNotFound, 400);
256
+ }
257
+ await mcpSession.transport.close();
258
+ return ctx.json({ ok: true }, 200);
259
+ }
260
+ catch (err) {
261
+ logger.error('Error occurred while deleting MCP session', err);
262
+ return ctx.json(MCP_ERRORS.internalServerError, 500);
263
+ }
264
+ });
265
+ // 404
266
+ app.notFound((ctx) => ctx.json({ error: 'Not Found', status: 404 }, 404));
267
+ // Listener for Node
268
+ (0, node_server_1.serve)({
269
+ fetch: app.fetch,
270
+ port,
271
+ }, () => logger.info(`Listening on port ${port}`));
272
+ // Schedule background task to check (and remove) idle sessions
273
+ _scheduleIdleSessionCheck();
274
+ }
275
+ async function main() {
276
+ const options = _getOptions();
277
+ if (options.transport === 'stdio') {
278
+ logger.disable();
279
+ await _startStdioServer();
280
+ }
281
+ else if (options.transport === 'streamable-http') {
282
+ logger.info('Starting MCP server...');
283
+ await _startStreamableHTTPServer(options.port);
284
+ logger.info('Started MCP Server');
285
+ }
286
+ else {
287
+ logger.error(`Invalid transport: ${options.transport}`);
288
+ process.exit(1);
289
+ }
290
+ }
291
+ main().catch((err) => {
292
+ logger.enable();
293
+ logger.error('MCP server error', err);
294
+ process.exit(1);
295
+ });
296
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}