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

Function openSession

packages/hosts/mcp/src/in-memory-session-store.ts:391–438  ·  view source on GitHub ↗
(
    principal: Principal,
    resource: McpResource,
    request: Request,
  )

Source from the content-addressed store, hash-verified

389
390 /** Open a new session: build the server, connect a transport, drive the request. */
391 const openSession = (
392 principal: Principal,
393 resource: McpResource,
394 request: Request,
395 ): Effect.Effect<McpDispatchResult> => {
396 let createdSessionId: string | null = null;
397 return buildServer(principal, {
398 ...buildOptionsFor(request, () => createdSessionId),
399 resource,
400 }).pipe(
401 Effect.flatMap(({ mcpServer, engine }) =>
402 Effect.gen(function* () {
403 const transport = new WebStandardStreamableHTTPServerTransport({
404 sessionIdGenerator: () => crypto.randomUUID(),
405 enableJsonResponse: true,
406 onsessioninitialized: (sid) => {
407 createdSessionId = sid;
408 transports.set(sid, transport);
409 servers.set(sid, mcpServer);
410 owners.set(sid, { principal, resource });
411 engines.set(sid, engine);
412 lastSeen.set(sid, Date.now());
413 },
414 onsessionclosed: (sid) => void dispose(sid, { server: true }),
415 });
416 transport.onclose = () => {
417 const sid = transport.sessionId;
418 if (sid) void dispose(sid, { server: true });
419 };
420 yield* Effect.promise(() => mcpServer.connect(transport));
421 // The session id is minted on the first (initialize) request, so we
422 // drive `handleRequest` here; if no id results we close eagerly.
423 return yield* runHandleRequest(transport, request, () => {
424 // Nothing was ever registered under a session id, so `dispose` has
425 // no entry to work from — release the three handles by hand, engine
426 // included.
427 void ignoreClose(null, "transport", () => transport.close());
428 void ignoreClose(null, "server", () => mcpServer.close());
429 void shutdownEngine(null, engine);
430 });
431 }),
432 ),
433 // A build failure has nowhere typed to go in the envelope; render a 500.
434 Effect.catchTag("McpEngineBuildError", () =>
435 Effect.succeed(jsonRpcError(500, -32603, "Internal server error")),
436 ),
437 );
438 };
439
440 /**
441 * The session-less POST path: answer a probe for anything but `initialize`

Callers 1

createFunction · 0.70

Calls 10

buildServerFunction · 0.85
buildOptionsForFunction · 0.85
runHandleRequestFunction · 0.85
shutdownEngineFunction · 0.85
disposeFunction · 0.70
ignoreCloseFunction · 0.70
jsonRpcErrorFunction · 0.70
setMethod · 0.65
connectMethod · 0.65
closeMethod · 0.65

Tested by

no test coverage detected