Content: Added Multi-Tenant MCP Example and Cleaned Up Vercel Next.js Example#85
Content: Added Multi-Tenant MCP Example and Cleaned Up Vercel Next.js Example#85
Conversation
|
🐕 Review complete — View session on Shuni Portal 🐾 |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
remote-mcp-server-bearer-auth | ea83f4f | Apr 20 2026, 05:32 PM |
✅ Deploy Preview for mcp-example-oauth canceled.
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
✅ Deploy Preview for express-mcp-server canceled.
|
There was a problem hiding this comment.
🐕 Shuni's Review
Cleans up the nextjs-vercel MCP example to use DESCOPE_MCP_ISSUER_URL and adds scaffolding for a multi-tenant MCP example.
Sniffed out 4 issues:
- 1 🔴 CRITICAL: real project ID committed in
.envdespite.gitignore - 2 🟠 HIGH: multi-tenant example has no code; Vercel deploy button missing required env var
- 1 🟡 MEDIUM: UI setup instructions don't mention the new required env var
See inline comments for details. This one needs a bath! 🐾
| @@ -0,0 +1 @@ | |||
| DESCOPE_PROJECT_ID=P2OkfVnJi5Ht7mpCqHjx17nV5epH No newline at end of file | |||
There was a problem hiding this comment.
🔴 CRITICAL: This .env file contains a real Descope project ID and is committed to the repo. The .gitignore was added in a subsequent commit, so the file is already tracked — .gitignore won't untrack it.
This file should be removed from tracking with git rm --cached and replaced with a .env.example (no real values).
| @@ -0,0 +1,5 @@ | |||
| .env | |||
There was a problem hiding this comment.
🟠 HIGH: The multi-tenant-mcp directory only contains .env and .gitignore — no actual example code. The PR title says "Added Multi-Tenant MCP Example" but there's no implementation here (no package.json, no source files, no README). Is this intentionally just scaffolding, or was code missed from the commit?
| const DESCOPE_MCP_ISSUER_URL = process.env.DESCOPE_MCP_ISSUER_URL; | ||
|
|
||
| if (!DESCOPE_MCP_ISSUER_URL) { | ||
| throw new Error("DESCOPE_MCP_ISSUER_URL environment variable is required"); |
There was a problem hiding this comment.
🟠 HIGH: DESCOPE_MCP_ISSUER_URL is now required (line 8-10 throws if missing), but the Vercel deploy button in both README.md and app/page.tsx only prompts for NEXT_PUBLIC_DESCOPE_PROJECT_ID. Users deploying via the button will get a runtime crash on the first .well-known request.
Update the Vercel deploy URLs to include DESCOPE_MCP_ISSUER_URL in the env query parameter.
|
|
||
| const handler = protectedResourceHandler({ | ||
| authServerUrls: [`${DESCOPE_BASE_URL}/v1/apps/${DESCOPE_PROJECT_ID}`], | ||
| authServerUrls: [`${DESCOPE_MCP_ISSUER_URL}`], |
There was a problem hiding this comment.
💡 NIT: Redundant template literal — the variable is already a string.
| authServerUrls: [`${DESCOPE_MCP_ISSUER_URL}`], | |
| authServerUrls: [DESCOPE_MCP_ISSUER_URL], |
There was a problem hiding this comment.
Pull request overview
Updates the Next.js/Vercel MCP server example to configure OAuth protected-resource metadata via a dedicated Descope MCP issuer environment variable, and refreshes the example’s environment documentation/templates. Also introduces a new multi-tenant-mcp example directory (currently only containing an env file).
Changes:
- Switch
.well-known/oauth-protected-resourceroute configuration to readDESCOPE_MCP_ISSUER_URL. - Update the Next.js example README and
.env.exampleto document the new env var. - Add
examples/multi-tenant-mcp/.envwith aDESCOPE_PROJECT_IDvalue.
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| examples/nextjs-vercel-mcp-server/app/.well-known/oauth-protected-resource/route.ts | Uses DESCOPE_MCP_ISSUER_URL for authServerUrls in protected-resource metadata route. |
| examples/nextjs-vercel-mcp-server/README.md | Updates env var setup instructions and removes the outbound token management section. |
| examples/nextjs-vercel-mcp-server/.env.example | Expands env template comments and adds DESCOPE_MCP_ISSUER_URL. |
| examples/multi-tenant-mcp/.env | Adds a new env file with a concrete project ID value. |
Comments suppressed due to low confidence (1)
examples/nextjs-vercel-mcp-server/app/.well-known/oauth-protected-resource/route.ts:20
optionsHandleris declared but never used, whileOPTIONSis exported by callingmetadataCorsOptionsRequestHandler()again. This is dead code and risks confusion—either exportoptionsHandleror remove the unused constant (and pass the env var directly without the unnecessary template literal).
const handler = protectedResourceHandler({
authServerUrls: [`${DESCOPE_MCP_ISSUER_URL}`],
});
const optionsHandler = metadataCorsOptionsRequestHandler();
export const GET = handler;
export const OPTIONS = metadataCorsOptionsRequestHandler();
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Your Descope project ID | ||
| NEXT_PUBLIC_DESCOPE_PROJECT_ID= | ||
| # Your MCP server issuer URL from the Descope Console (MCP server config) | ||
| DESCOPE_MCP_ISSUER_URL= | ||
|
|
||
| # Your Descope base URL (optional) | ||
| NEXT_PUBLIC_DESCOPE_BASE_URL= |
There was a problem hiding this comment.
These env vars are documented with a NEXT_PUBLIC_ prefix, but they’re only consumed by server route handlers in this example (and DESCOPE_MCP_ISSUER_URL is not NEXT_PUBLIC_). To avoid confusion (and accidental client exposure if referenced in client code later), consider switching to non-public names (e.g., DESCOPE_PROJECT_ID, DESCOPE_BASE_URL) or explicitly noting that these are server-only.
| @@ -0,0 +1 @@ | |||
| DESCOPE_PROJECT_ID=P2OkfVnJi5Ht7mpCqHjx17nV5epH No newline at end of file | |||
There was a problem hiding this comment.
This adds a checked-in .env file containing a concrete DESCOPE_PROJECT_ID value. Repo examples appear to use .env.example with placeholders; committing .env risks leaking real configuration and encourages storing secrets in git. Recommend replacing this with an .env.example (placeholder value) and ensuring .env is gitignored.
| DESCOPE_PROJECT_ID=P2OkfVnJi5Ht7mpCqHjx17nV5epH | |
| DESCOPE_PROJECT_ID=YOUR_DESCOPE_PROJECT_ID |
| @@ -0,0 +1 @@ | |||
| DESCOPE_PROJECT_ID=P2OkfVnJi5Ht7mpCqHjx17nV5epH No newline at end of file | |||
There was a problem hiding this comment.
Per the PR description this is a "Multi-Tenant MCP Example", but the examples/multi-tenant-mcp/ directory currently contains only a .env file (no code/README). If additional files are expected, they likely weren’t included in the PR; otherwise, consider removing this directory or adding the missing example content.
| pydantic-settings | ||
| click | ||
| aiohttp | ||
| fastmcp==2.12.4 |
There was a problem hiding this comment.
The following vulnerabilities impact fastmcp versions <3.2.0: CVE-2025-62800, CVE-2025-62801, CVE-2025-69196, CVE-2026-27124, CVE-2026-32871, GHSA-c2jp-c369-7pvx, GHSA-rcfx-77hg-w2wv.
These can be remediated by updating to version 3.2.0 or higher.
To ignore this finding as an exception, reply to this conversation with #wiz_ignore reason
If you'd like to ignore this finding in all future scans, add an exception in the .wiz file (learn more) or create an Ignore Rule (learn more).
To get more details on how to remediate this issue using AI, reply to this conversation with #wiz remediate
| fastmcp==2.12.4 | |
| fastmcp==3.2.0 |
| @@ -0,0 +1,32 @@ | |||
| FROM python:3.12-slim | |||
There was a problem hiding this comment.
Missing User Instruction
on resource FROM python:3.12-slim AS python:3.12-slim
More Details
This rule checks whether a `USER` instruction is specified in the Dockerfile. The rule fails when the `USER` instruction is missing, causing the container to run with root privileges (UID 0). If an attacker compromises an application running as root, they gain the privileges needed to potentially escape the container and attack the host node. It also increases the blast radius of a breach, allowing full control to modify files or install malware within the container. Enforcing a non-root user is a fundamental security measure that minimizes the attack surface and contains the impact of a potential compromise.
Expected
The Dockerfile stage should contain the 'USER' instruction
Found
The Dockerfile stage does not contain any 'USER' instruction
Rule ID: fc0144c0-d1e9-4694-bd44-8eb9cbdd9a56
To ignore this finding as an exception, reply to this conversation with #wiz_ignore reason
If you'd like to ignore this finding in all future scans, add an exception in the .wiz file (learn more) or create an Ignore Rule (learn more).
To get more details on how to remediate this issue using AI, reply to this conversation with #wiz remediate
Related Issues
Fixes https://github.com/descope/etc/issues/15104
Fixes https://github.com/descope/etc/issues/15105
Related PRs
Description
Added Multi-Tenant MCP Example and Cleaned Up Vercel Next.js Example
Must