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

Function selfHostHttpMiddleware

apps/host-selfhost/src/serve.ts:53–108  ·  view source on GitHub ↗
(betterAuth: BetterAuthHandle)

Source from the content-addressed store, hash-verified

51// aside from scrubbing any client-supplied value of that header so it can't be
52// spoofed into an unrewritten request.
53const selfHostHttpMiddleware = (betterAuth: BetterAuthHandle) =>
54 HttpMiddleware.make((httpApp) =>
55 Effect.gen(function* () {
56 const request = yield* HttpServerRequest.HttpServerRequest;
57 const url = new URL(request.url, "http://host.internal");
58 // Streamable HTTP does not define HEAD. Reject it before the SPA's
59 // GET/HEAD fallback can claim `/mcp` and return a misleading empty
60 // `200 application/octet-stream` response. The shared MCP envelope
61 // rejects unsupported methods the same way, but the static route wins
62 // HEAD routing at the composed production-server boundary.
63 if (request.method === "HEAD" && isMcpServingPath(url.pathname)) {
64 const response = jsonRpcErrorBody(405, -32001, "Method not allowed");
65 return HttpServerResponse.raw(response, {
66 status: response.status,
67 statusText: response.statusText,
68 headers: response.headers,
69 });
70 }
71 if (
72 url.pathname === OAUTH_CALLBACK_PATH &&
73 (request.method === "GET" || request.method === "HEAD")
74 ) {
75 const headers = new Headers(request.headers as Record<string, string>);
76 const webRequest = new Request(url, { method: request.method, headers });
77 const location = yield* Effect.promise(() =>
78 oauthCallbackSignInRedirectLocation(webRequest, betterAuth.auth),
79 );
80 if (location) return HttpServerResponse.redirect(location, { status: 302 });
81 }
82
83 const rewritten = stripMcpOrgSegment(url.pathname);
84 if (rewritten === null) {
85 // Never let a client dictate the org-scoped echo below by smuggling
86 // this header in directly — it's only ever trustworthy when WE set it
87 // a few lines down, for a request we ourselves just rewrote.
88 if (!EffectHeaders.has(request.headers, MCP_ORIGINAL_PATH_HEADER)) return yield* httpApp;
89 return yield* httpApp.pipe(
90 Effect.provideService(
91 HttpServerRequest.HttpServerRequest,
92 request.modify({
93 headers: EffectHeaders.remove(request.headers, MCP_ORIGINAL_PATH_HEADER),
94 }),
95 ),
96 );
97 }
98 return yield* httpApp.pipe(
99 Effect.provideService(
100 HttpServerRequest.HttpServerRequest,
101 request.modify({
102 url: `${rewritten}${url.search}`,
103 headers: EffectHeaders.set(request.headers, MCP_ORIGINAL_PATH_HEADER, url.pathname),
104 }),
105 ),
106 );
107 }),
108 );
109
110export const startServer = async (): Promise<void> => {

Callers 1

startServerFunction · 0.85

Calls 6

isMcpServingPathFunction · 0.90
stripMcpOrgSegmentFunction · 0.90
jsonRpcErrorBodyFunction · 0.85
setMethod · 0.80
removeMethod · 0.65

Tested by

no test coverage detected