fix(mcp): bundle build with esbuild so plugin cache never needs node_modules

Claude Code spawns plugin MCP servers straight from the read-only
git-content plugin cache, which never gets an npm install for mcp/. The
old tsc-multi-file build imported bare specifiers that only resolved
via mcp/node_modules, so every fresh plugin install/update produced a
-32000 reconnect failure. Bundle mcp/src into a single dependency-free
build/index.js instead; the one CJS-heavy import (express, only used
by --transport=http) is now dynamic so the stdio path never evaluates it.
This commit is contained in:
2026-08-19 10:36:36 +07:00
parent 2fe465e36f
commit dce54c8a3a
29 changed files with 49260 additions and 3885 deletions
+4 -1
View File
@@ -46,7 +46,6 @@ import { DashboardApiClient } from "./clients/dashboard-api-client.js";
import { loadConfig, type TransportMode } from "./config/app-config.js";
import { Logger } from "./core/logger.js";
import { buildServer } from "./server.js";
import { startHttpServer } from "./transports/http-server.js";
import { startRepl } from "./transports/repl.js";
import { collectAllTools } from "./transports/tool-collector.js";
import { printBanner, printServerInfo, printReady, printShutdown } from "./ui/banner.js";
@@ -116,6 +115,10 @@ async function main() {
// ── HTTP mode (SSE + Streamable HTTP) ───────────────────────
else if (transport === "http") {
// Dynamic import: this is the only module pulling in `express`, which
// the plugin build's bundle would otherwise ship even for the stdio
// path every real MCP host actually uses.
const { startHttpServer } = await import("./transports/http-server.js");
const toolEntries = collectAllTools(config, api, logger);
const { shutdown } = await startHttpServer(
config,