Skip to content

fix(descope): Fixes two bugs in the Descope plugin, updates relevant docs - #611

Draft
joshwertheim wants to merge 4 commits into
basementstudio:canaryfrom
joshwertheim:descope-plugin-update
Draft

fix(descope): Fixes two bugs in the Descope plugin, updates relevant docs#611
joshwertheim wants to merge 4 commits into
basementstudio:canaryfrom
joshwertheim:descope-plugin-update

Conversation

@joshwertheim

@joshwertheim joshwertheim commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes two bugs in the @xmcp-dev/descope plugin that together broke JWT authentication for any project using the modern Agentic Identity Hub setup flow: a middleware call with a mismatched argument count that dropped the real Descope SDK client, and a project-ID parser that misread the newer /v1/apps/agentic/<projectId>/<mcpServerId> issuer URL format. Adds an optional projectId config field so callers can bypass URL parsing entirely, and updates the plugin README, the descope-http example, and the website docs to match. This includes fixing a stale legacy-format issuer URL placeholder and an unrelated scopesSupported string/array type mismatch found along the way.

Verified the new changes with a live end-to-end test using the included descope-http example and called the whoami tool with the following result:

data: {"result":{"content":[{"type":"text","text":"{\n  \"userId\": \"<userId>\",\n  \"loginIds\": [],\n  \"permissions\": [],\n  \"roles\": [],\n  \"tenants\": {},\n  \"expiresAt\": \"2026-07-08T02:04:39.000Z\"\n}"}]},"jsonrpc":"2.0","id":1}

Type of Change

  • Bug fixing
  • Adding a feature
  • Improving documentation
  • Adding or updating examples
  • Performance - bundle size improvement (if applicable)

Affected Packages

  • xmcp (core framework)
  • create-xmcp-app
  • init-xmcp
  • Plugins
  • Documentation
  • Examples

Contributor Checklist

  • I read AGENTS.md and the scoped rules for the areas I touched.
  • I kept this PR focused on the stated change.
  • I ran the relevant build, lint, test, or example checks.
  • I updated docs and a runnable example for user-facing behavior, or explained why an example does not fit.
  • I checked REVIEW_RULES.md for logging, timers, config shape, wrappers, compiler/loader changes, and stale examples.

Screenshots/Examples

Related Issues

https://github.com/descope/etc/issues/16798

Unfortunately when the original branch was merged, perhaps due to a faulty rebase an earlier change was left in. When tested end-to-end, a cached working build was used rather than a newly built copy of the plugin. So verification of everything working as expected before OK'ing the branch's PR as ready for review wasn't complete...

Detailed notes for this commit:

Bug fixes (packages/plugins/descope/src/provider.ts):
1. descopeMiddleware(config, sdk) changes to descopeMiddleware(sdk) - an arity mismatch (function took 1 param, was called with 2) that made tsc fail to compile, and when emitted anyway, silently bound the wrong value to sdk, breaking JWT validation for every request.
2. `parseProjectId` now handles Agentic Identity Hub issuer URLs (https://api.descope.com/v1/apps/agentic/<projectId>/<mcpServerId>) by locating the segment after "agentic", instead of always grabbing segments[0] (which returned "v1" for this URL shape) — confirmed against Descope's own docs. Falls back to segments[0] for the legacy plain issuer URL format.

New config option (packages/plugins/descope/src/types.ts, provider.ts):
* Added optional projectId?: string to DescopeConfig. When provided, it's used directly (config.projectId ??
parseProjectId(config.issuerURL)), letting callers skip URL parsing entirely.

Example updated (examples/descope-http/):
1. src/middleware.ts - now passes projectId: process.env.DESCOPE_PROJECT_ID.
2. .env.example - added DESCOPE_PROJECT_ID=your-project-id.
3. README.md - updated the .env setup snippet to the correct Agentic Identity Hub issuer URL shape, added DESCOPE_PROJECT_ID, and a note that it's optional (falls back to parsing).

Docs updated (packages/plugins/descope/README.md, apps/website/content/docs/integrations/descope.mdx):
1. Both READMEs' API reference tables/config option lists now document projectId.
2. Both READMEs' quick-start code snippets and .env examples updated to include DESCOPE_PROJECT_ID and the correct issuer URL shape.
3. Website docs: fixed scopesSupported: process.env.SCOPES_SUPPORTED changes to process.env.SCOPES_SUPPORTED?.split(","), since scopesSupported is typed as string[] but the env var is a comma-separated string.
@vercel

vercel Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

@joshwertheim is attempting to deploy a commit to the xmcp Team on Vercel.

A member of the Team first needs to authorize it.

…claims into permissions

scopesSupported now falls back to fetching scopes_supported from Descope's
OIDC discovery document instead of a hardcoded default when the config
option is omitted. session.permissions now merges the RBAC permissions
claim with the OAuth scope claim so Agentic Identity Hub policy grants
show up alongside RBAC role/tenant grants.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant