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

Function configureServer

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

Source from the content-addressed store, hash-verified

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

Tested by

no test coverage detected