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

Function createServerHandlers

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

Source from the content-addressed store, hash-verified

73};
74
75export const createServerHandlers = async (token: string): Promise<ServerHandlers> => {
76 let apiHandler: ServerHandlers["api"] | null = null;
77 let mcp: McpRequestHandler | null = null;
78
79 // 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
80 try {
81 // The typed `/api` web-handler comes from `ExecutorApp.make` (./app.ts). The
82 // boot bearer token is the authoritative `/api` gate (see `identity.ts`).
83 apiHandler = await makeLocalApiHandler(token);
84
85 // The in-process MCP server runs over the SAME boot executor, with its own
86 // engine instance (the browser-approval + stdio surface is local-only and not
87 // part of the shared API). Reuse the shared boot bundle so the MCP executor is
88 // byte-identical to the one the API serves.
89 const { executor, webBaseUrl } = await getExecutorBundle();
90 // Both engines below serve MCP endpoints, so the wrap binds the "mcp"
91 // plane structurally; the toolkit-scoped engine additionally marks
92 // `toolkit` (the slug itself is a user label and never recorded).
93 const engine = withExecutionAnalytics(
94 createExecutionEngine({
95 executor,
96 codeExecutor: makeQuickJsExecutor(),
97 }),
98 localAnalytics,
99 { plane: "mcp", toolkit: false },
100 );
101 // The generative-UI surface, shared by every resource this daemon serves.
102 // Each toolkit gets its own executor, so `artifacts` is bound per resource
103 // below rather than hoisted with the rest.
104 //
105 // Including the create-time smoke render, on the same terms as every other
106 // host. This daemon is a dependency of `apps/cli`, whose build does not
107 // configure `jsx`, and the renderer used to be unusable here for that
108 // reason — TypeScript resolved its dynamic `import()` of the `.tsx`
109 // component barrel eagerly and dragged the whole React graph (plus a
110 // duplicate `@types/react`) into the CLI and desktop trees. It renders
111 // inside a QuickJS sandbox now, so there is no `.tsx` in its graph and no
112 // React in this process; the cost is one lazily-loaded string constant.
113 const appsConfig = {
114 loadAppShellHtml: loadMcpAppsShellHtml,
115 smokeRenderArtifact,
116 artifactUrl: artifactUrlFor(webBaseUrl),
117 // Artifact operations on this surface come from an agent's MCP tools.
118 onArtifactUsage: (action: "created" | "viewed" | "updated") =>
119 localAnalytics.record(`artifact_${action}`, { via: "agent" }),
120 };
121 mcp = createMcpRequestHandler({
122 defaultConfig: {
123 engine,
124 artifacts: executor.artifacts,
125 connections: executor.connections,
126 ...appsConfig,
127 },
128 createConfigForResource: async (resource) => {
129 if (resource.kind === "default") {
130 return {
131 config: {
132 engine,

Callers 1

getServerHandlersRuntimeFunction · 0.85

Calls 12

makeLocalApiHandlerFunction · 0.90
getExecutorBundleFunction · 0.90
withExecutionAnalyticsFunction · 0.90
createExecutionEngineFunction · 0.90
makeQuickJsExecutorFunction · 0.90
artifactUrlForFunction · 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