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

Function createMcpRequestHandler

apps/local/src/mcp.ts:142–326  ·  view source on GitHub ↗
(
  input: ExecutorMcpServerConfig | LocalMcpRequestHandlerConfig,
)

Source from the content-addressed store, hash-verified

140};
141
142export const createMcpRequestHandler = (
143 input: ExecutorMcpServerConfig | LocalMcpRequestHandlerConfig,
144): McpRequestHandler => {
145 const handlerConfig = normalizeHandlerConfig(input);
146 const transports = new Map<string, WebStandardStreamableHTTPServerTransport>();
147 const servers = new Map<string, McpServer>();
148 const resources = new Map<string, McpResource>();
149 const sessionEngines = new Map<string, AnyExecutionEngine>();
150 const sessionClosers = new Map<string, () => Promise<void>>();
151 const approvals = makeInProcessBrowserApprovalStore();
152 const defaultEngine = engineFromConfig(handlerConfig.defaultConfig);
153
154 const pausedDetail = (
155 sessionId: string,
156 executionId: string,
157 ): Promise<ReturnType<typeof formatPausedExecution> | null> =>
158 (sessionEngines.get(sessionId) ?? defaultEngine)
159 ? Effect.runPromise(
160 (sessionEngines.get(sessionId) ?? defaultEngine)!.getPausedExecution(executionId).pipe(
161 Effect.map((paused) => (paused ? formatPausedExecution(paused) : null)),
162 Effect.orElseSucceed(() => null),
163 ),
164 )
165 : Promise.resolve(null);
166
167 const configForResource = async (resource: McpResource): Promise<LocalMcpServerConfig> => {
168 if (!handlerConfig.createConfigForResource) return { config: handlerConfig.defaultConfig };
169 return handlerConfig.createConfigForResource(resource);
170 };
171
172 const dispose = async (id: string, opts: { transport?: boolean; server?: boolean } = {}) => {
173 const t = transports.get(id);
174 const s = servers.get(id);
175 const close = sessionClosers.get(id);
176 transports.delete(id);
177 servers.delete(id);
178 resources.delete(id);
179 sessionEngines.delete(id);
180 sessionClosers.delete(id);
181 if (opts.transport) await ignoreClose(t ? () => t.close() : undefined);
182 if (opts.server) await ignoreClose(s ? () => s.close() : undefined);
183 await ignoreClose(close);
184 };
185
186 return {
187 handleRequest: async (request) => {
188 const resource = resourceFromRequest(request);
189 if (!resource) return jsonError(404, -32001, "MCP resource not found");
190 const sessionId = request.headers.get("mcp-session-id");
191
192 if (sessionId) {
193 const transport = transports.get(sessionId);
194 if (!transport) return jsonError(404, -32001, "Session not found");
195 const sessionResource = resources.get(sessionId);
196 if (!sessionResource || mcpResourceKey(sessionResource) !== mcpResourceKey(resource)) {
197 return jsonError(403, -32003, "Session belongs to a different MCP resource");
198 }
199 return transport.handleRequest(request);

Callers 3

makeMcpFetchFunction · 0.90
postFunction · 0.90
createServerHandlersFunction · 0.90

Calls 15

readElicitationModeFunction · 0.90
createExecutorMcpServerFunction · 0.90
readArtifactsEnabledFunction · 0.90
readSearchToolsEnabledFunction · 0.90
readToolModeFunction · 0.90
buildResumeApprovalUrlFunction · 0.90
normalizeHandlerConfigFunction · 0.85
engineFromConfigFunction · 0.85
resourceFromRequestFunction · 0.85
jsonErrorFunction · 0.85
mcpResourceKeyFunction · 0.85

Tested by 2

makeMcpFetchFunction · 0.72
postFunction · 0.72