MCPcopy Create free account
hub / github.com/UsefulSoftwareCo/executor / configureServer

Function configureServer

apps/host-selfhost/vite.config.ts:66–179  ·  view source on GitHub ↗
(server)

Source from the content-addressed store, hash-verified

64 name: "executor-selfhost-api",
65 apply: "serve",
66 configureServer(server) {
67 server.watcher.on("change", (path) => {
68 if (path.includes("/src/") || path.endsWith("/executor.config.ts")) handlerPromise = null;
69 });
70 server.middlewares.use(async (req, res, next) => {
71 let rawUrl = req.url ?? "/";
72 // The "Connect an agent" card prints `/<organizationId>/mcp`; self-host
73 // serves the bare `/mcp`, so rewrite it here (prod does the same in
74 // serve.ts) — otherwise this org-pinned path isn't recognized as an MCP
75 // path and falls through to the SPA as a 404. Mirrors ./src/mcp/org-path.
76 const devOrigin = `http://${req.headers.host ?? `localhost:${DEV_PORT}`}`;
77 const originalPathname = new URL(rawUrl, devOrigin).pathname;
78 const pathname = stripMcpOrgSegment(originalPathname) ?? "";
79 // Carries the ORIGINAL org-scoped pathname through to the handler (see
80 // ./src/mcp/auth.ts) so the protected-resource metadata can echo it
81 // back to a client that dialed org-scoped — mirrors serve.ts's prod
82 // middleware. Set only when we ourselves rewrote this request; any
83 // client-supplied value is dropped below so it can't be spoofed.
84 let originalPathHeader: string | null = null;
85 if (pathname !== "") {
86 const original = new URL(rawUrl, devOrigin);
87 rawUrl = `${pathname}${original.search}`;
88 originalPathHeader = originalPathname;
89 }
90 // Match on PATHNAME, not a raw-URL prefix: `/mcp` must NOT swallow the
91 // SPA route `/mcp-consent`, or the dev server misroutes it to the API
92 // handler and returns a 404.
93 const path = new URL(rawUrl, devOrigin).pathname;
94 const handled =
95 path === "/api" ||
96 path.startsWith("/api/") ||
97 path === "/mcp" ||
98 path.startsWith("/mcp/") ||
99 path === "/docs" ||
100 path.startsWith("/docs/") ||
101 // Un-prefixed app-level routes (e.g. `/v1/app/npm/dist-tags`, which the
102 // shell's update check fetches). Served by the Effect router in prod;
103 // without this the SPA index.html fallback answers 200-with-HTML and
104 // the JSON parse fails, so the UpdateCard never appears.
105 path === "/v1" ||
106 path.startsWith("/v1/") ||
107 // RFC 9728 / RFC 8414 OAuth discovery the MCP client fetches before
108 // auth. Served by the Effect router in prod; without this the SPA
109 // index.html fallback answers 200-with-HTML and breaks discovery.
110 path.startsWith("/.well-known/");
111 if (!handled) {
112 // SPA document navigations must receive the app shell, not a module.
113 // A browser navigating to a route like `/login` (Better Auth's
114 // MCP-OAuth `loginPage` 302s here as a real document GET) sends an
115 // extensionless request that Vite's transform middleware would resolve
116 // to a colliding web-root module (`web/login.tsx` shadows `/login`,
117 // `web/setup.tsx` shadows `/setup`) and serve as text/javascript, so
118 // the page renders as raw JS and the OAuth login never appears. Rewrite
119 // genuine page navigations to the index so Vite's html fallback serves
120 // index.html; the SPA reads window.location and renders the right
121 // route. Module/asset/HMR requests carry a file extension or a
122 // non-document fetch destination, so they fall through untouched. This
123 // is dev-only: the production static server already serves index.html

Callers

nothing calls this directly

Calls 9

stripMcpOrgSegmentFunction · 0.90
getHandlerFunction · 0.85
setMethod · 0.80
endMethod · 0.80
errorMethod · 0.80
deleteMethod · 0.65
getReaderMethod · 0.65
nextFunction · 0.50
handlerFunction · 0.50

Tested by

no test coverage detected