History

extend instrumentation

Rhys Sullivan committed 6 months ago

Commit 3f791571 parent 88ad3581 file · +49 −10Browse files

Unified · Split

apps/cloud/src/mcp.ts+49−10
@@ -88,22 +88,36 @@ export class McpAuth extends Context.Tag("@executor/cloud/McpAuth")< · 87 unmodified lines
88 88
89export const McpAuthLive = Layer.succeed(McpAuth, {89export const McpAuthLive = Layer.succeed(McpAuth, {
90 verifyBearer: (request) =>90 verifyBearer: (request) =>
91 Effect.promise(async () => {91 Effect.gen(function* () {
92 const authHeader = request.headers.get("authorization");92 const authHeader = request.headers.get("authorization");
93 if (!authHeader?.startsWith(BEARER_PREFIX)) return null;93 if (!authHeader?.startsWith(BEARER_PREFIX)) {
94 yield* Effect.annotateCurrentSpan({ "mcp.auth.outcome": "missing_bearer" });
95 return null;
96 }
94 try {97 try {
95 const { payload } = await jwtVerify(authHeader.slice(BEARER_PREFIX.length), jwks, {98 const { payload } = yield* Effect.promise(() =>
96 issuer: AUTHKIT_DOMAIN,99 jwtVerify(authHeader.slice(BEARER_PREFIX.length), jwks, {
97 });100 issuer: AUTHKIT_DOMAIN,
98 if (!payload.sub) return null;101 }),
99 return {102 ).pipe(Effect.withSpan("mcp.auth.jwt_verify"));
103 if (!payload.sub) {
104 yield* Effect.annotateCurrentSpan({ "mcp.auth.outcome": "missing_subject" });
105 return null;
106 }
107 const token = {
100 accountId: payload.sub,108 accountId: payload.sub,
101 organizationId: (payload.org_id as string | undefined) ?? null,109 organizationId: (payload.org_id as string | undefined) ?? null,
102 };110 };
111 yield* Effect.annotateCurrentSpan({
112 "mcp.auth.outcome": "verified",
113 "mcp.auth.has_organization": !!token.organizationId,
114 });
115 return token;
103 } catch {116 } catch {
117 yield* Effect.annotateCurrentSpan({ "mcp.auth.outcome": "invalid" });
104 return null;118 return null;
105 }119 }
106 }),120 }).pipe(Effect.withSpan("mcp.auth.verify_bearer")),
107});121});
108 122
109// ---------------------------------------------------------------------------123// ---------------------------------------------------------------------------
@@ -216,7 +230,7 @@ const readJsonRpcEnvelope = (request: Request): Effect.Effect<Option.Option<Json · 106 unmodified lines
216 } catch {230 } catch {
217 return Option.none();231 return Option.none();
218 }232 }
219 });233 }).pipe(Effect.withSpan("mcp.request.read_json_rpc"));
220 234
221const methodAttrs = (envelope: JsonRpcEnvelope): Record<string, unknown> => {235const methodAttrs = (envelope: JsonRpcEnvelope): Record<string, unknown> => {
222 const params = envelope.params ?? {};236 const params = envelope.params ?? {};
@@ -305,7 +319,14 @@ const annotateMcpRequest = ( · 82 unmodified lines
305 ...baseAttrs,319 ...baseAttrs,
306 ...rpcAttrs(envelope),320 ...rpcAttrs(envelope),
307 });321 });
308 });322 }).pipe(
323 Effect.withSpan("mcp.request.annotate", {
324 attributes: {
325 "mcp.request.method": request.method,
326 "mcp.request.parse_body": opts.parseBody,
327 },
328 }),
329 );
309 330
310// ---------------------------------------------------------------------------331// ---------------------------------------------------------------------------
311// OAuth metadata endpoints332// OAuth metadata endpoints
@@ -507,6 +528,13 @@ const forwardToExistingSession = (request: Request, sessionId: string, peek: boo · 195 unmodified lines
507 const propagated = withPropagationHeaders(request, propagation);528 const propagated = withPropagationHeaders(request, propagation);
508 const raw = yield* Effect.promise(529 const raw = yield* Effect.promise(
509 () => stub.handleRequest(propagated) as Promise<Response>,530 () => stub.handleRequest(propagated) as Promise<Response>,
531 ).pipe(
532 Effect.withSpan("mcp.do.handle_request", {
533 attributes: {
534 "mcp.request.method": request.method,
535 "mcp.request.session_id_present": true,
536 },
537 }),
510 );538 );
511 const annotated = peek ? yield* peekAndAnnotate(raw) : raw;539 const annotated = peek ? yield* peekAndAnnotate(raw) : raw;
512 return HttpServerResponse.raw(annotated);540 return HttpServerResponse.raw(annotated);
@@ -527,10 +555,21 @@ const dispatchPost = (request: Request, token: VerifiedToken) => · 14 unmodified lines
527 const propagation = yield* currentPropagationHeaders(request);555 const propagation = yield* currentPropagationHeaders(request);
528 yield* Effect.promise(() =>556 yield* Effect.promise(() =>
529 stub.init({ organizationId, userId: token.accountId }, propagation),557 stub.init({ organizationId, userId: token.accountId }, propagation),
558 ).pipe(
559 Effect.withSpan("mcp.do.init", {
560 attributes: { "mcp.request.session_id_present": false },
561 }),
530 );562 );
531 const propagated = withPropagationHeaders(request, propagation);563 const propagated = withPropagationHeaders(request, propagation);
532 const raw = yield* Effect.promise(564 const raw = yield* Effect.promise(
533 () => stub.handleRequest(propagated) as Promise<Response>,565 () => stub.handleRequest(propagated) as Promise<Response>,
566 ).pipe(
567 Effect.withSpan("mcp.do.handle_request", {
568 attributes: {
569 "mcp.request.method": request.method,
570 "mcp.request.session_id_present": false,
571 },
572 }),
534 );573 );
535 const annotated = yield* peekAndAnnotate(raw);574 const annotated = yield* peekAndAnnotate(raw);
536 return HttpServerResponse.raw(annotated);575 return HttpServerResponse.raw(annotated);