(executionStack: McpExecutionStackLayer, hostOptions?: McpBuildHostOptions)
| 42 | */ |
| 43 | export const makeMcpBuildServer = |
| 44 | (executionStack: McpExecutionStackLayer, hostOptions?: McpBuildHostOptions): McpBuildServer => |
| 45 | (principal: Principal, options?: McpBuildServerOptions) => |
| 46 | Effect.gen(function* () { |
| 47 | const { engine, executor } = yield* makeExecutionStack( |
| 48 | principal.accountId, |
| 49 | principal.organizationId, |
| 50 | principal.organizationName, |
| 51 | { |
| 52 | mcpResource: options?.resource, |
| 53 | orgWrites: "request", |
| 54 | }, |
| 55 | ).pipe(Effect.withSpan("mcp.execution_stack.build")); |
| 56 | // Read inside the provided boundary: `webBaseUrl` is a host seam, and |
| 57 | // hosts that can't know their public URL at boot leave it unset — in |
| 58 | // which case artifacts still persist but carry no deep link. |
| 59 | const hostConfig = yield* HostConfig; |
| 60 | return { engine, executor, webBaseUrl: hostConfig.webBaseUrl }; |
| 61 | }).pipe( |
| 62 | // Pin browser-handoff URLs to the principal's org slug when present; |
| 63 | // absent slug leaves the service unprovided and the URL stays bare. |
| 64 | principal.organizationSlug !== undefined |
| 65 | ? Effect.provideService(RequestOrgSlug, { slug: principal.organizationSlug }) |
| 66 | : (effect) => effect, |
| 67 | Effect.provide(executionStack), |
| 68 | Effect.mapError((cause) => new McpEngineBuildError({ cause })), |
| 69 | Effect.flatMap(({ engine, executor, webBaseUrl }) => |
| 70 | createExecutorMcpServer({ |
| 71 | engine, |
| 72 | artifacts: executor.artifacts, |
| 73 | connections: executor.connections, |
| 74 | ...(hostOptions?.loadAppShellHtml |
| 75 | ? { loadAppShellHtml: hostOptions.loadAppShellHtml } |
| 76 | : {}), |
| 77 | ...(hostOptions?.smokeRenderArtifact |
| 78 | ? { smokeRenderArtifact: hostOptions.smokeRenderArtifact } |
| 79 | : {}), |
| 80 | ...(hostOptions?.onArtifactUsage ? { onArtifactUsage: hostOptions.onArtifactUsage } : {}), |
| 81 | // Same org pinning as `RequestOrgSlug` above: self-host serves its |
| 82 | // console under `/<org-slug>` (`default` when unconfigured), so the |
| 83 | // deep link carries the principal's slug rather than relying on the |
| 84 | // browser's active org to canonicalize a bare path after landing. |
| 85 | ...(webBaseUrl |
| 86 | ? { artifactUrl: artifactUrlFor(webBaseUrl, principal.organizationSlug) } |
| 87 | : {}), |
| 88 | ...(options ?? {}), |
| 89 | }).pipe( |
| 90 | Effect.withSpan("mcp.server.create"), |
| 91 | Effect.map((mcpServer) => ({ mcpServer, engine })), |
| 92 | ), |
| 93 | ), |
| 94 | ); |
| 95 | |
| 96 | /** Per-host (not per-session) MCP wiring. Kept separate from |
| 97 | * `McpBuildServerOptions`, which the session store fills in per request. */ |
no test coverage detected