Skip to content

Commit b70e273

Browse files
DeRaowlclaude
andcommitted
revert: restore src/index.ts to main
Removes HTTP/remote-MCP transport plumbing added in aaa844c and subsequent edits in 2cb224b from this file only. Other files from those commits are unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 29feef6 commit b70e273

1 file changed

Lines changed: 8 additions & 128 deletions

File tree

β€Žsrc/index.tsβ€Ž

Lines changed: 8 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
#!/usr/bin/env node
22

33
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4-
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
54
import { createRequire } from "module";
65
const require = createRequire(import.meta.url);
76
const packageJson = require("../package.json");
87
import "dotenv/config";
9-
import http from "http";
10-
import { randomUUID } from "crypto";
118
import logger from "./logger.js";
129
import { BrowserStackMcpServer } from "./server-factory.js";
1310

@@ -18,6 +15,11 @@ async function main() {
1815
);
1916

2017
const remoteMCP = process.env.REMOTE_MCP === "true";
18+
if (remoteMCP) {
19+
logger.info("Running in remote MCP mode");
20+
return;
21+
}
22+
2123
const username = process.env.BROWSERSTACK_USERNAME;
2224
const accessKey = process.env.BROWSERSTACK_ACCESS_KEY;
2325

@@ -29,136 +31,14 @@ async function main() {
2931
throw new Error("BROWSERSTACK_ACCESS_KEY environment variable is required");
3032
}
3133

34+
const transport = new StdioServerTransport();
35+
3236
const mcpServer = new BrowserStackMcpServer({
3337
"browserstack-username": username,
3438
"browserstack-access-key": accessKey,
3539
});
3640

37-
if (remoteMCP) {
38-
// ── HTTP Transport (Remote MCP) ──────────────────────────────────────
39-
const port = parseInt(process.env.MCP_PORT || "3100", 10);
40-
41-
// Create a new transport for each session
42-
const transports = new Map<string, StreamableHTTPServerTransport>();
43-
44-
const httpServer = http.createServer(async (req, res) => {
45-
// CORS headers for browser clients
46-
res.setHeader("Access-Control-Allow-Origin", "*");
47-
res.setHeader(
48-
"Access-Control-Allow-Methods",
49-
"GET, POST, DELETE, OPTIONS",
50-
);
51-
res.setHeader(
52-
"Access-Control-Allow-Headers",
53-
"Content-Type, mcp-session-id",
54-
);
55-
res.setHeader("Access-Control-Expose-Headers", "mcp-session-id");
56-
57-
if (req.method === "OPTIONS") {
58-
res.writeHead(204);
59-
res.end();
60-
return;
61-
}
62-
63-
const url = new URL(req.url || "/", `http://localhost:${port}`);
64-
65-
// Health check
66-
if (url.pathname === "/health" || url.pathname === "/healthz") {
67-
res.writeHead(200, { "Content-Type": "application/json" });
68-
res.end(JSON.stringify({ status: "ok", version: packageJson.version }));
69-
return;
70-
}
71-
72-
// MCP endpoint
73-
if (url.pathname === "/mcp") {
74-
// Check for existing session
75-
const sessionId = req.headers["mcp-session-id"] as string | undefined;
76-
77-
if (sessionId && transports.has(sessionId)) {
78-
// Existing session β€” reuse transport
79-
const transport = transports.get(sessionId)!;
80-
await transport.handleRequest(req, res);
81-
return;
82-
}
83-
84-
if (req.method === "POST" && !sessionId) {
85-
// New session β€” create transport and connect server
86-
const transport = new StreamableHTTPServerTransport({
87-
sessionIdGenerator: () => randomUUID(),
88-
});
89-
90-
transport.onclose = () => {
91-
if (transport.sessionId) {
92-
transports.delete(transport.sessionId);
93-
logger.info("Session closed: %s", transport.sessionId);
94-
}
95-
};
96-
97-
// Connect to a NEW server instance for this session
98-
const sessionServer = new BrowserStackMcpServer({
99-
"browserstack-username": username!,
100-
"browserstack-access-key": accessKey!,
101-
});
102-
103-
await sessionServer.getInstance().connect(transport);
104-
105-
if (transport.sessionId) {
106-
transports.set(transport.sessionId, transport);
107-
logger.info("New session: %s", transport.sessionId);
108-
}
109-
110-
await transport.handleRequest(req, res);
111-
return;
112-
}
113-
114-
// Invalid request
115-
res.writeHead(400, { "Content-Type": "application/json" });
116-
res.end(
117-
JSON.stringify({
118-
error: "Invalid request. POST to /mcp to start a session.",
119-
}),
120-
);
121-
return;
122-
}
123-
124-
// Root β€” info page
125-
if (url.pathname === "/") {
126-
res.writeHead(200, { "Content-Type": "application/json" });
127-
res.end(
128-
JSON.stringify({
129-
name: "BrowserStack MCP Server",
130-
version: packageJson.version,
131-
endpoint: `http://localhost:${port}/mcp`,
132-
health: `http://localhost:${port}/health`,
133-
instructions: "Connect your MCP client to the /mcp endpoint.",
134-
}),
135-
);
136-
return;
137-
}
138-
139-
res.writeHead(404);
140-
res.end("Not found");
141-
});
142-
143-
httpServer.listen(port, () => {
144-
logger.info("Remote MCP server running at http://localhost:%d/mcp", port);
145-
console.log(`\nπŸš€ BrowserStack MCP Server (Remote Mode)`);
146-
console.log(` Version: ${packageJson.version}`);
147-
console.log(` Endpoint: http://localhost:${port}/mcp`);
148-
console.log(` Health: http://localhost:${port}/health`);
149-
console.log(
150-
`\n Connect from any MCP client using the endpoint URL above.`,
151-
);
152-
console.log(
153-
` In VS Code: Add MCP Server β†’ HTTP β†’ http://localhost:${port}/mcp`,
154-
);
155-
console.log(` In Claude Code: /mcp add http://localhost:${port}/mcp\n`);
156-
});
157-
} else {
158-
// ── Stdio Transport (Local MCP β€” default) ────────────────────────────
159-
const transport = new StdioServerTransport();
160-
await mcpServer.getInstance().connect(transport);
161-
}
41+
await mcpServer.getInstance().connect(transport);
16242
}
16343

16444
main().catch(console.error);

0 commit comments

Comments
Β (0)