mcp-optimizer 0.0.2-alpha.1 → 0.0.4-alpha.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/mcpServer.js +56 -1
- package/package.json +1 -1
- package/src/mcpServer.ts +53 -1
package/dist/mcpServer.js
CHANGED
|
@@ -39,6 +39,7 @@ const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
|
39
39
|
const zod_1 = require("zod");
|
|
40
40
|
const lighthouseRunner_1 = require("./runner/lighthouseRunner");
|
|
41
41
|
const sse_js_1 = require("@modelcontextprotocol/sdk/server/sse.js");
|
|
42
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
42
43
|
const http = __importStar(require("http"));
|
|
43
44
|
const fixer_1 = require("./fix/fixer");
|
|
44
45
|
class LighthouseMcpServer {
|
|
@@ -205,9 +206,63 @@ exports.LighthouseMcpServer = LighthouseMcpServer;
|
|
|
205
206
|
exports.default = LighthouseMcpServer;
|
|
206
207
|
async function startMcpServer() {
|
|
207
208
|
// Run HTTP/SSE server
|
|
208
|
-
|
|
209
|
+
// Prefer explicit environment variables, but also allow parsing CLI args
|
|
210
|
+
// (e.g. when launched directly without the lightweight `bin` wrapper).
|
|
211
|
+
let portEnv = process.env.PORT || process.env.AUDIT_PORT;
|
|
212
|
+
if (!portEnv) {
|
|
213
|
+
const args = process.argv.slice(2);
|
|
214
|
+
for (let i = 0; i < args.length; i++) {
|
|
215
|
+
const a = args[i];
|
|
216
|
+
if (a.includes('=') && !a.startsWith('--')) {
|
|
217
|
+
const [k, v] = a.split('=', 2);
|
|
218
|
+
if ((k === 'PORT' || k === 'AUDIT_PORT') && v !== undefined) {
|
|
219
|
+
portEnv = v;
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (a.startsWith('--port=')) {
|
|
224
|
+
portEnv = a.split('=')[1];
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
else if (a === '--port' && args[i + 1]) {
|
|
228
|
+
portEnv = args[i + 1];
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
else if (a.startsWith('--audit-port=')) {
|
|
232
|
+
portEnv = a.split('=')[1];
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
else if (a === '--audit-port' && args[i + 1]) {
|
|
236
|
+
portEnv = args[i + 1];
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const port = Number(portEnv || 5000);
|
|
209
242
|
const mcp = new LighthouseMcpServer();
|
|
210
243
|
let sseTransport = null;
|
|
244
|
+
let stdioTransport = null;
|
|
245
|
+
// If process stdin/stdout appear to be non-TTY pipes, assume we're being
|
|
246
|
+
// launched as a stdio child by an MCP host and use the stdio transport.
|
|
247
|
+
const shouldUseStdio = (process.stdin && !process.stdin.isTTY) && (process.stdout && !process.stdout.isTTY);
|
|
248
|
+
if (shouldUseStdio) {
|
|
249
|
+
try {
|
|
250
|
+
stdioTransport = new stdio_js_1.StdioServerTransport(process.stdin, process.stdout);
|
|
251
|
+
await mcp.connect(stdioTransport);
|
|
252
|
+
console.info('Stdio: connected to parent process over stdio');
|
|
253
|
+
// When running over stdio we do not start the HTTP server; stay alive
|
|
254
|
+
// and let the parent coordinate messages. Return a promise that
|
|
255
|
+
// resolves when the transport closes.
|
|
256
|
+
return new Promise((resolve, reject) => {
|
|
257
|
+
stdioTransport.onclose = () => resolve();
|
|
258
|
+
stdioTransport.onerror = (err) => reject(err);
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
catch (err) {
|
|
262
|
+
console.error('Stdio: failed to start transport, falling back to HTTP:', err);
|
|
263
|
+
stdioTransport = null;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
211
266
|
const pendingPosts = [];
|
|
212
267
|
const { Readable, Writable } = await (async () => {
|
|
213
268
|
const mod = await Promise.resolve().then(() => __importStar(require('stream')));
|
package/package.json
CHANGED
package/src/mcpServer.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { z } from "zod";
|
|
|
3
3
|
import { runLighthouseAudit } from "./runner/lighthouseRunner";
|
|
4
4
|
import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
|
|
5
5
|
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
|
6
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
7
|
import * as http from 'http';
|
|
7
8
|
import { IncomingMessage, ServerResponse } from 'http';
|
|
8
9
|
import { autoFixFromReport } from './fix/fixer';
|
|
@@ -192,9 +193,60 @@ export default LighthouseMcpServer;
|
|
|
192
193
|
|
|
193
194
|
export async function startMcpServer(): Promise<void> {
|
|
194
195
|
// Run HTTP/SSE server
|
|
195
|
-
|
|
196
|
+
// Prefer explicit environment variables, but also allow parsing CLI args
|
|
197
|
+
// (e.g. when launched directly without the lightweight `bin` wrapper).
|
|
198
|
+
let portEnv = process.env.PORT || process.env.AUDIT_PORT;
|
|
199
|
+
if (!portEnv) {
|
|
200
|
+
const args = process.argv.slice(2);
|
|
201
|
+
for (let i = 0; i < args.length; i++) {
|
|
202
|
+
const a = args[i];
|
|
203
|
+
if (a.includes('=') && !a.startsWith('--')) {
|
|
204
|
+
const [k, v] = a.split('=', 2);
|
|
205
|
+
if ((k === 'PORT' || k === 'AUDIT_PORT') && v !== undefined) {
|
|
206
|
+
portEnv = v;
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if (a.startsWith('--port=')) {
|
|
211
|
+
portEnv = a.split('=')[1];
|
|
212
|
+
break;
|
|
213
|
+
} else if (a === '--port' && args[i + 1]) {
|
|
214
|
+
portEnv = args[i + 1];
|
|
215
|
+
break;
|
|
216
|
+
} else if (a.startsWith('--audit-port=')) {
|
|
217
|
+
portEnv = a.split('=')[1];
|
|
218
|
+
break;
|
|
219
|
+
} else if (a === '--audit-port' && args[i + 1]) {
|
|
220
|
+
portEnv = args[i + 1];
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const port = Number(portEnv || 5000);
|
|
196
227
|
const mcp = new LighthouseMcpServer();
|
|
197
228
|
let sseTransport: SSEServerTransport | null = null;
|
|
229
|
+
let stdioTransport: StdioServerTransport | null = null;
|
|
230
|
+
// If process stdin/stdout appear to be non-TTY pipes, assume we're being
|
|
231
|
+
// launched as a stdio child by an MCP host and use the stdio transport.
|
|
232
|
+
const shouldUseStdio = (process.stdin && !process.stdin.isTTY) && (process.stdout && !process.stdout.isTTY);
|
|
233
|
+
if (shouldUseStdio) {
|
|
234
|
+
try {
|
|
235
|
+
stdioTransport = new StdioServerTransport(process.stdin, process.stdout);
|
|
236
|
+
await mcp.connect(stdioTransport as unknown as Transport);
|
|
237
|
+
console.info('Stdio: connected to parent process over stdio');
|
|
238
|
+
// When running over stdio we do not start the HTTP server; stay alive
|
|
239
|
+
// and let the parent coordinate messages. Return a promise that
|
|
240
|
+
// resolves when the transport closes.
|
|
241
|
+
return new Promise((resolve, reject) => {
|
|
242
|
+
stdioTransport!.onclose = () => resolve();
|
|
243
|
+
stdioTransport!.onerror = (err: any) => reject(err);
|
|
244
|
+
});
|
|
245
|
+
} catch (err) {
|
|
246
|
+
console.error('Stdio: failed to start transport, falling back to HTTP:', err);
|
|
247
|
+
stdioTransport = null;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
198
250
|
const pendingPosts: Array<{ body: string; url: string | undefined; headers: any }> = [];
|
|
199
251
|
|
|
200
252
|
const { Readable, Writable } = await (async () => {
|