MCPcopy Create free account
hub / github.com/Mnexa-AI/e2a / handleClientRequest

Function handleClientRequest

mcp/src/http-server.ts:193–259  ·  view source on GitHub ↗
(
  req: Request,
  res: Response,
  cache: ResolveCache,
  opts: HttpServerOptions,
)

Source from the content-addressed store, hash-verified

191}
192
193async function handleClientRequest(
194 req: Request,
195 res: Response,
196 cache: ResolveCache,
197 opts: HttpServerOptions,
198): Promise<void> {
199 const bearer = extractBearer(req);
200 if (!bearer) {
201 res.setHeader("WWW-Authenticate", bearerChallenge(req, opts));
202 res.status(401).json(jsonRpcError(req.body, -32001, "missing bearer token"));
203 return;
204 }
205
206 // Resolve the credential's scope + bound agent. A cache hit skips the
207 // backend round-trip; a miss probes `whoami` once and caches the result.
208 // A revoked/expired bearer surfaces as 401 here (InvalidBearerError).
209 let principal = cache.get(bearer);
210 if (!principal) {
211 let resolved: { value: ResolvedPrincipal; cacheable: boolean };
212 try {
213 resolved = await resolvePrincipal(opts, bearer);
214 } catch (err) {
215 if (err instanceof InvalidBearerError) {
216 res.setHeader(
217 "WWW-Authenticate",
218 `${bearerChallenge(req, opts)}, error="invalid_token"`,
219 );
220 res.status(401).json(jsonRpcError(req.body, -32001, "invalid bearer token"));
221 return;
222 }
223 throw err;
224 }
225 principal = resolved.value;
226 // Only cache a genuine whoami result. A transient backend failure yields a
227 // least-privilege fallback that must NOT stick — re-probe next request so
228 // the session self-corrects once the backend recovers.
229 if (resolved.cacheable) cache.set(bearer, principal);
230 }
231
232 // The cold-path whoami probe above is awaited, so the client may have
233 // disconnected meanwhile. If so, `res`'s "close" has already fired — bail
234 // before building a transport whose teardown listener would never run.
235 if (res.closed) return;
236
237 // Stateless: a fresh server + transport per request, torn down when the
238 // response closes. The SDK forbids reusing a stateless transport across
239 // requests (message-id collisions), and a fresh transport with
240 // sessionIdGenerator=undefined skips all session/initialize gating, so a
241 // bare tools/call dispatches without a prior initialize on this instance.
242 const client = buildClient(opts, bearer, principal);
243 const server = buildServer({ client });
244 const transport = new StreamableHTTPServerTransport({
245 sessionIdGenerator: undefined,
246 });
247 res.on("close", () => {
248 void transport.close();
249 void server.close();
250 });

Callers 1

buildAppFunction · 0.85

Calls 11

extractBearerFunction · 0.85
bearerChallengeFunction · 0.85
jsonRpcErrorFunction · 0.85
resolvePrincipalFunction · 0.85
buildServerFunction · 0.85
setMethod · 0.80
onMethod · 0.80
connectMethod · 0.80
buildClientFunction · 0.70
getMethod · 0.45
closeMethod · 0.45

Tested by

no test coverage detected