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

Function createMcpRequestHandler

apps/local/src/mcp.ts:135–375  ·  view source on GitHub ↗
(
  input: ExecutorMcpToolConfig | LocalMcpRequestHandlerConfig,
)

Source from the content-addressed store, hash-verified

133): LocalMcpRequestHandlerConfig => ("defaultConfig" in input ? input : { defaultConfig: input });
134
135export const createMcpRequestHandler = (
136 input: ExecutorMcpToolConfig | LocalMcpRequestHandlerConfig,
137): McpRequestHandler => {
138 const handlerConfig = normalizeHandlerConfig(input);
139 const transports = new Map<string, WebStandardStreamableHTTPServerTransport>();
140 const servers = new Map<string, McpServer>();
141 const resources = new Map<string, McpResource>();
142 const sessionEngines = new Map<string, AnyExecutionEngine>();
143 const sessionClosers = new Map<string, () => Promise<void>>();
144 const modernHandlers = new Map<string, McpHttpHandler>();
145 const modernRequestBodies = new WeakMap<Request, unknown>();
146 const approvals = makeInProcessBrowserApprovalStore();
147 const defaultEngine = engineFromConfig(handlerConfig.defaultConfig);
148 let requestStateSigningKey: Uint8Array | undefined;
149
150 const signingKey = (): Uint8Array =>
151 (requestStateSigningKey ??= crypto.getRandomValues(new Uint8Array(32)));
152
153 const pausedDetail = (
154 sessionId: string,
155 executionId: string,
156 ): Promise<ReturnType<typeof formatPausedExecution> | null> =>
157 (sessionEngines.get(sessionId) ?? defaultEngine)
158 ? Effect.runPromise(
159 (sessionEngines.get(sessionId) ?? defaultEngine)!.getPausedExecution(executionId).pipe(
160 Effect.map((paused) => (paused ? formatPausedExecution(paused) : null)),
161 Effect.orElseSucceed(() => null),
162 ),
163 )
164 : Promise.resolve(null);
165
166 const configForResource = async (resource: McpResource): Promise<LocalMcpServerConfig> => {
167 if (!handlerConfig.createConfigForResource) return { config: handlerConfig.defaultConfig };
168 return handlerConfig.createConfigForResource(resource);
169 };
170
171 const dispose = async (id: string, opts: { transport?: boolean; server?: boolean } = {}) => {
172 const t = transports.get(id);
173 const s = servers.get(id);
174 const close = sessionClosers.get(id);
175 transports.delete(id);
176 servers.delete(id);
177 resources.delete(id);
178 sessionEngines.delete(id);
179 sessionClosers.delete(id);
180 if (opts.transport) await ignoreClose(t ? () => t.close() : undefined);
181 if (opts.server) await ignoreClose(s ? () => s.close() : undefined);
182 await ignoreClose(close);
183 };
184
185 const modernHandlerFor = (resource: McpResource): McpHttpHandler => {
186 const key = mcpResourceKey(resource);
187 const cached = modernHandlers.get(key);
188 if (cached) return cached;
189
190 const handler = createMcpHandler(
191 (context) => {
192 const request = context.requestInfo;

Callers 3

makeMcpFetchFunction · 0.90
createServerHandlersFunction · 0.90
mcp-modern.test.tsFile · 0.90

Calls 15

requestBodyFromRequestFunction · 0.90
readElicitationModeFunction · 0.90
buildMcpServerFunction · 0.90
readArtifactsEnabledFunction · 0.90
approvalUrlForRequestFunction · 0.90
normalizeHandlerConfigFunction · 0.85
engineFromConfigFunction · 0.85
resourceFromRequestFunction · 0.85
jsonErrorFunction · 0.85
modernHandlerForFunction · 0.85

Tested by 1

makeMcpFetchFunction · 0.72