import { HttpServerResponse } from "effect/unstable/http";import { Effect } from "effect"; import type { McpJwtVerificationError } from "../mcp-auth"; export const CORS_ALLOW_ORIGIN = { "access-control-allow-origin": "*" } as const; type UnauthorizedAuth = { readonly reason: "missing_bearer" | "invalid_token"; readonly description?: string;}; const quoteAuthParam = (value: string) => `"${value.replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`; const bearerChallenge = (auth: UnauthorizedAuth, protectedResourceMetadataUrl: string) => { const params = auth.reason === "missing_bearer" ? [`resource_metadata=${quoteAuthParam(protectedResourceMetadataUrl)}`] : [ 'error="invalid_token"', `error_description=${quoteAuthParam( auth.description ?? "The access token is invalid or expired", )}`, `resource_metadata=${quoteAuthParam(protectedResourceMetadataUrl)}`, ]; return `Bearer ${params.join(", ")}`;}; export const jsonResponse = (body: unknown, status = 200) => HttpServerResponse.jsonUnsafe(body, { status, headers: CORS_ALLOW_ORIGIN }); export const jsonRpcError = (status: number, code: number, message: string) => HttpServerResponse.jsonUnsafe( { jsonrpc: "2.0", error: { code, message }, id: null }, { status, headers: CORS_ALLOW_ORIGIN }, ); export const jsonRpcWebResponse = (status: number, code: number, message: string) => new Response(JSON.stringify({ jsonrpc: "2.0", error: { code, message }, id: null }), { status, headers: { ...CORS_ALLOW_ORIGIN, "content-type": "application/json" }, }); export const unauthorized = (auth: UnauthorizedAuth, protectedResourceMetadataUrl: string) => HttpServerResponse.jsonUnsafe( { error: "unauthorized" }, { status: 401, headers: { ...CORS_ALLOW_ORIGIN, "www-authenticate": bearerChallenge(auth, protectedResourceMetadataUrl), }, }, ); export const authTemporarilyUnavailable = (error: McpJwtVerificationError) => Effect.gen(function* () { yield* Effect.annotateCurrentSpan({ "mcp.auth.outcome": "system_error", "mcp.auth.system_error.reason": error.reason, "mcp.auth.system_error.message": String(error.cause).slice(0, 500), }); return jsonRpcError(503, -32001, "Authentication temporarily unavailable - please retry"); });
import { HttpServerResponse } from "effect/unstable/http";
import { Effect } from "effect";
import type { McpJwtVerificationError } from "../mcp-auth";
export const CORS_ALLOW_ORIGIN = { "access-control-allow-origin": "*" } as const;
type UnauthorizedAuth = {
readonly reason: "missing_bearer" | "invalid_token";
readonly description?: string;
};
const quoteAuthParam = (value: string) =>
`"${value.replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`;
const bearerChallenge = (auth: UnauthorizedAuth, protectedResourceMetadataUrl: string) => {
const params =
auth.reason === "missing_bearer"
? [`resource_metadata=${quoteAuthParam(protectedResourceMetadataUrl)}`]
: [
'error="invalid_token"',
`error_description=${quoteAuthParam(
auth.description ?? "The access token is invalid or expired",
)}`,
`resource_metadata=${quoteAuthParam(protectedResourceMetadataUrl)}`,
];
return `Bearer ${params.join(", ")}`;
};
export const jsonResponse = (body: unknown, status = 200) =>
HttpServerResponse.jsonUnsafe(body, { status, headers: CORS_ALLOW_ORIGIN });
export const jsonRpcError = (status: number, code: number, message: string) =>
HttpServerResponse.jsonUnsafe(
{ jsonrpc: "2.0", error: { code, message }, id: null },
{ status, headers: CORS_ALLOW_ORIGIN },
);
export const jsonRpcWebResponse = (status: number, code: number, message: string) =>
new Response(JSON.stringify({ jsonrpc: "2.0", error: { code, message }, id: null }), {
status,
headers: { ...CORS_ALLOW_ORIGIN, "content-type": "application/json" },
});
export const unauthorized = (auth: UnauthorizedAuth, protectedResourceMetadataUrl: string) =>
HttpServerResponse.jsonUnsafe(
{ error: "unauthorized" },
{
status: 401,
headers: {
...CORS_ALLOW_ORIGIN,
"www-authenticate": bearerChallenge(auth, protectedResourceMetadataUrl),
},
},
);
export const authTemporarilyUnavailable = (error: McpJwtVerificationError) =>
Effect.gen(function* () {
yield* Effect.annotateCurrentSpan({
"mcp.auth.outcome": "system_error",
"mcp.auth.system_error.reason": error.reason,
"mcp.auth.system_error.message": String(error.cause).slice(0, 500),
});
return jsonRpcError(503, -32001, "Authentication temporarily unavailable - please retry");
});