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

Function handle

apps/cloud/src/mcp/agent-handler.ts:228–361  ·  view source on GitHub ↗
(request: Request, env: Env, ctx: ExecutionContext)

Source from the content-addressed store, hash-verified

226 const ALLOWED_METHODS = new Set(["GET", "POST", "DELETE", "OPTIONS"]);
227
228 const handle = async (request: Request, env: Env, ctx: ExecutionContext): Promise<Response> => {
229 if (request.method === "OPTIONS") {
230 return mcpCorsPreflightResponse(request.headers.get("access-control-request-headers"));
231 }
232 // Preserve the old envelope's JSON-RPC 405 before authenticating, so
233 // unsupported methods never reach the session engine.
234 if (!ALLOWED_METHODS.has(request.method)) {
235 return jsonRpcResponse(405, -32001, "Method not allowed");
236 }
237 const sessionId = request.headers.get("mcp-session-id");
238
239 const { auth, outcome } = await runTraced(request, authenticate(request, authProvider));
240 if (!Predicate.isTagged(outcome, "Authenticated")) {
241 // Destroying a live session on auth grounds requires a POSITIVE
242 // determination that access is genuinely gone — only `Forbidden` carries
243 // that (valid bearer, org absent/revoked). `Unavailable` (transient WorkOS
244 // / JWKS failure) and `Unauthorized` (retry with a fresh token) must leave
245 // the session intact, so the condemn path is gated on `Forbidden` alone.
246 if (Predicate.isTagged(outcome, "Forbidden") && sessionId) {
247 const session = mcpSessionStub(env.MCP_SESSION, sessionId);
248 await Effect.runPromise(
249 Effect.ignore(
250 session ? Effect.tryPromise(() => session._cf_scheduleDestroy()) : Effect.void,
251 ),
252 );
253 }
254 return renderAuthError(auth, request, outcome);
255 }
256
257 const parsedBody = await Effect.runPromise(requestBodyFromRequest(request));
258 const era = await classifyMcpProtocolEra(request, parsedBody);
259 if (era === "modern") {
260 if (env.MCP_2026_07_28_ENABLED === "false") {
261 return mcpModernDisabledResponse();
262 }
263 const resource = resourceFromPath(request);
264 const props = await runTraced(
265 request,
266 propsForPrincipal(request, outcome.principal, resource),
267 );
268 (ctx as ExecutionContext & { props?: McpSessionProps }).props = props;
269 const forwarded = withVerifiedIdentityHeaders(
270 request,
271 {
272 accountId: outcome.principal.accountId,
273 organizationId: outcome.principal.organizationId,
274 },
275 resource,
276 );
277 return modern.fetch({
278 request: forwarded,
279 parsedBody,
280 principal: outcome.principal,
281 resource,
282 props,
283 requestStateSigningKey: requireMcpRequestStateKey(env.MCP_REQUEST_STATE_KEY),
284 builder: options.makeModernServerBuilder(props.session),
285 sessions: env.MCP_SESSION,

Callers 3

makeHarnessFunction · 0.70
makeCloudMcpAgentHandlerFunction · 0.70
traceCloudMcpRequestFunction · 0.50

Calls 15

mcpCorsPreflightResponseFunction · 0.90
mcpSessionStubFunction · 0.90
requestBodyFromRequestFunction · 0.90
classifyMcpProtocolEraFunction · 0.90
withPropagationHeadersFunction · 0.90
createMcpSessionStubFunction · 0.90
withMcpResponseHeadersFunction · 0.90
wrapMcpSseResponseFunction · 0.90

Tested by 1

makeHarnessFunction · 0.56