Skip to content

feat(mcp): drop scopes_supported from RFC 9728 protected-resource metadata (feature-flagged) #57530

@MattBro

Description

@MattBro

Context

Once #57529 ships RFC 6750 `insufficient_scope` challenges and #57528 confirms client behavior, MCP no longer needs to publish its own `scopes_supported`. The AS becomes the single source of truth. Linear/Notion/Cloudflare/Stripe already ship without it.

This is the architecture from Matt's #56835 review comment:

Better fix is probably dropping scopes_supported from the resource metadata entirely. RFC 9728 makes it optional, the MCP spec says clients must omit scope when it's absent, and Linear/Notion/Cloudflare/Stripe already ship without it. One list (the AS), no drift.

Change

Drop `scopes_supported: OAUTH_SCOPES_SUPPORTED` from `services/mcp/src/index.ts:243`. Reframe the `OAUTH_SCOPES_SUPPORTED completeness` test in `tool-filtering.test.ts` to assert against the AS list (which the existing generated file already mirrors). Delete `bin/build-mcp-oauth-scopes.py` and `services/mcp/src/lib/oauth-scopes.generated.ts` once nothing else depends on them.

Feature-flagged rollout

The field's presence is gated by a server-side flag:

```ts
scopes_supported: SCOPES_SUPPORTED_PUBLISHED_FLAG
? OAUTH_SCOPES_SUPPORTED
: undefined,
```

(Filtered out of the JSON if undefined.) Default off in dev/preview, off in canary, then full. Allows fast rollback without a deploy if a real-world client breaks.

Pre-conditions

Why

Reaches the spec-clean architecture: AS is the only place `scopes_supported` is published. Any future PostHog resource server (partner SDKs, etc.) inherits "don't publish" by default. The drift class is killed across all surfaces.

Acceptance

  • `scopes_supported` field absent from MCP metadata response when flag is off
  • Codegen (`bin/build-mcp-oauth-scopes.py`) and generated file deleted, completeness test reframed
  • Feature flag wired in, defaulted off, documented rollout plan
  • Post-rollout: 0 `invalid_scope` errors in MCP auth logs over 7-day window vs. baseline

Tracking

Parent: #57524
Blocked by: #57525, #57526, #57527, #57528, #57529
Project: https://github.com/orgs/PostHog/projects/194

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions