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

Function createServerHandlers

apps/local/src/main.ts:70–128  ·  view source on GitHub ↗
(token: string)

Source from the content-addressed store, hash-verified

68};
69
70export const createServerHandlers = async (token: string): Promise<ServerHandlers> => {
71 let apiHandler: ServerHandlers["api"] | null = null;
72 let mcp: McpRequestHandler | null = null;
73
74 // oxlint-disable-next-line executor/no-try-catch-or-throw -- boundary: handler boot owns the shared executor; partial startup failure must release it before rethrowing
75 try {
76 // The typed `/api` web-handler comes from `ExecutorApp.make` (./app.ts). The
77 // boot bearer token is the authoritative `/api` gate (see `identity.ts`).
78 apiHandler = await makeLocalApiHandler(token);
79
80 // The in-process MCP server runs over the SAME boot executor, with its own
81 // engine instance (the browser-approval + stdio surface is local-only and not
82 // part of the shared API). Reuse the shared boot bundle so the MCP executor is
83 // byte-identical to the one the API serves.
84 const { executor } = await getExecutorBundle();
85 const engine = createExecutionEngine({
86 executor,
87 codeExecutor: makeQuickJsExecutor(),
88 });
89 mcp = createMcpRequestHandler({
90 defaultConfig: { engine },
91 createConfigForResource: async (resource) => {
92 if (resource.kind === "default") return { config: { engine } };
93 const handle = await createExecutorHandle({
94 activeToolkitSlug: resource.slug,
95 });
96 const toolkitEngine = createExecutionEngine({
97 executor: handle.executor,
98 codeExecutor: makeQuickJsExecutor(),
99 });
100 return {
101 config: { engine: toolkitEngine },
102 close: handle.dispose,
103 };
104 },
105 });
106
107 return { api: apiHandler, mcp };
108 } catch (cause) {
109 const partialApiHandler = apiHandler;
110 const partialMcp = mcp;
111 await Effect.runPromise(
112 Effect.gen(function* () {
113 yield* Effect.all(
114 [
115 partialApiHandler
116 ? ignoreDisposeFailure("api.dispose", () => partialApiHandler.dispose())
117 : Effect.void,
118 partialMcp ? ignoreDisposeFailure("mcp.close", () => partialMcp.close()) : Effect.void,
119 ],
120 { concurrency: "unbounded" },
121 );
122 yield* ignoreDisposeFailure("disposeExecutor", () => disposeExecutor());
123 }),
124 );
125 // oxlint-disable-next-line executor/no-try-catch-or-throw -- boundary: async factory must reject with the original handler boot failure after cleanup
126 throw cause;
127 }

Callers 1

getServerHandlersRuntimeFunction · 0.85

Calls 10

makeLocalApiHandlerFunction · 0.90
getExecutorBundleFunction · 0.90
createExecutionEngineFunction · 0.90
makeQuickJsExecutorFunction · 0.90
createMcpRequestHandlerFunction · 0.90
createExecutorHandleFunction · 0.90
disposeExecutorFunction · 0.90
ignoreDisposeFailureFunction · 0.85
disposeMethod · 0.80
closeMethod · 0.65

Tested by

no test coverage detected