@upstash/context7-mcp 4.0.2 → 4.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +6 -3
- package/dist/lib/constants.js +11 -3
- package/dist/lib/jwt.js +3 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import express from "express";
|
|
|
10
10
|
import { Command } from "commander";
|
|
11
11
|
import { AsyncLocalStorage } from "async_hooks";
|
|
12
12
|
import { randomUUID } from "node:crypto";
|
|
13
|
-
import { SERVER_VERSION, RESOURCE_URL,
|
|
13
|
+
import { SERVER_VERSION, RESOURCE_URL, OAUTH_AUTH_SERVER_URL, EMA_ISSUER, OPENAI_APPS_CHALLENGE_TOKEN, } from "./lib/constants.js";
|
|
14
14
|
import { maybeElicitAuthSignIn } from "./lib/auth/auth-prompt.js";
|
|
15
15
|
import { getClientIp } from "./lib/client-ip.js";
|
|
16
16
|
/** Default HTTP server port */
|
|
@@ -372,13 +372,16 @@ async function main() {
|
|
|
372
372
|
app.get("/.well-known/oauth-protected-resource", (_req, res) => {
|
|
373
373
|
res.json({
|
|
374
374
|
resource: RESOURCE_URL,
|
|
375
|
-
|
|
375
|
+
// Each entry is an independent authorization server. Clerk handles
|
|
376
|
+
// regular authorization-code flows; Context7 handles only the
|
|
377
|
+
// enterprise-managed id-jag exchange.
|
|
378
|
+
authorization_servers: Array.from(new Set([OAUTH_AUTH_SERVER_URL, EMA_ISSUER])),
|
|
376
379
|
scopes_supported: ["profile", "email"],
|
|
377
380
|
bearer_methods_supported: ["header"],
|
|
378
381
|
});
|
|
379
382
|
});
|
|
380
383
|
app.get("/.well-known/oauth-authorization-server", async (_req, res) => {
|
|
381
|
-
const authServerUrl =
|
|
384
|
+
const authServerUrl = OAUTH_AUTH_SERVER_URL;
|
|
382
385
|
try {
|
|
383
386
|
const response = await fetch(`${authServerUrl}/.well-known/oauth-authorization-server`);
|
|
384
387
|
if (!response.ok) {
|
package/dist/lib/constants.js
CHANGED
|
@@ -6,12 +6,20 @@ const pkg = JSON.parse(readFileSync(join(__dirname, "../../package.json"), "utf-
|
|
|
6
6
|
export const SERVER_VERSION = pkg.version;
|
|
7
7
|
const CONTEXT7_BASE_URL = "https://context7.com";
|
|
8
8
|
const MCP_RESOURCE_URL = "https://mcp.context7.com";
|
|
9
|
-
|
|
9
|
+
const DEFAULT_OAUTH_AUTH_SERVER_URL = "https://clerk.context7.com";
|
|
10
10
|
export const CONTEXT7_API_BASE_URL = process.env.CONTEXT7_API_URL || `${CONTEXT7_BASE_URL}/api`;
|
|
11
11
|
export const RESOURCE_URL = process.env.RESOURCE_URL || MCP_RESOURCE_URL;
|
|
12
|
-
|
|
12
|
+
// Clerk owns the interactive OAuth flow and is the issuer returned in the
|
|
13
|
+
// authorization response. Advertising Clerk directly keeps RFC 8414 discovery
|
|
14
|
+
// and RFC 9207 response-issuer validation on the same authorization-server
|
|
15
|
+
// identity.
|
|
16
|
+
export const OAUTH_AUTH_SERVER_URL = (process.env.OAUTH_AUTH_SERVER_URL || DEFAULT_OAUTH_AUTH_SERVER_URL).replace(/\/+$/, "");
|
|
17
|
+
export const OAUTH_JWKS_URL = process.env.OAUTH_JWKS_URL || `${OAUTH_AUTH_SERVER_URL}/.well-known/jwks.json`;
|
|
13
18
|
// Enterprise-Managed Auth (id-jag): access tokens minted by the Context7
|
|
14
19
|
// authorization server, validated against its public JWKS.
|
|
15
|
-
|
|
20
|
+
// AUTH_SERVER_URL remains a backwards-compatible alias for local EMA setups;
|
|
21
|
+
// it does not move interactive user OAuth. Local end-to-end OAuth environments
|
|
22
|
+
// must set OAUTH_AUTH_SERVER_URL separately when Clerk is not the intended issuer.
|
|
23
|
+
export const EMA_ISSUER = process.env.EMA_ISSUER || process.env.AUTH_SERVER_URL || CONTEXT7_BASE_URL;
|
|
16
24
|
export const EMA_JWKS_URL = process.env.EMA_JWKS_URL || `${CONTEXT7_API_BASE_URL}/oauth/ema-jwks`;
|
|
17
25
|
export const OPENAI_APPS_CHALLENGE_TOKEN = process.env.OPENAI_APPS_CHALLENGE_TOKEN;
|
package/dist/lib/jwt.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as jose from "jose";
|
|
2
|
-
import {
|
|
3
|
-
const
|
|
4
|
-
const clerkJwks = jose.createRemoteJWKSet(new URL(`https://${CLERK_DOMAIN}/.well-known/jwks.json`));
|
|
2
|
+
import { CONTEXT7_API_BASE_URL, EMA_ISSUER, EMA_JWKS_URL, OAUTH_AUTH_SERVER_URL, OAUTH_JWKS_URL, RESOURCE_URL, } from "./constants.js";
|
|
3
|
+
const oauthJwks = jose.createRemoteJWKSet(new URL(OAUTH_JWKS_URL));
|
|
5
4
|
const emaJwks = jose.createRemoteJWKSet(new URL(EMA_JWKS_URL));
|
|
6
5
|
const ENTRA_V2_ISSUER_RE = /^https:\/\/login\.microsoftonline\.com\/[0-9a-f-]{36}\/v2\.0$/;
|
|
7
6
|
const jwksByTenant = new Map();
|
|
@@ -70,7 +69,7 @@ export async function validateJWT(token) {
|
|
|
70
69
|
await jose.jwtVerify(token, emaJwks, { issuer: EMA_ISSUER, audience: RESOURCE_URL });
|
|
71
70
|
return { valid: true };
|
|
72
71
|
}
|
|
73
|
-
await jose.jwtVerify(token,
|
|
72
|
+
await jose.jwtVerify(token, oauthJwks, { issuer: OAUTH_AUTH_SERVER_URL });
|
|
74
73
|
return { valid: true };
|
|
75
74
|
}
|
|
76
75
|
catch (error) {
|