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 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
- const port = Number(process.env.PORT || process.env.AUDIT_PORT || 5000);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-optimizer",
3
- "version": "0.0.2-alpha.1",
3
+ "version": "0.0.4-alpha.1",
4
4
  "description": "An MCP server that runs Lighthouse audits and enables LLMs to automatically optimize your code.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
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
- const port = Number(process.env.PORT || process.env.AUDIT_PORT || 5000);
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 () => {