Skip to content

Ask Codex for the service's own OAuth scopes - #2

Merged
olihou merged 1 commit into
mainfrom
oli/codex-mcp-scopes
Oct 17, 2026
Merged

olihou merged 1 commit into
mainfrom
oli/codex-mcp-scopes

Conversation

@olihou

@olihou olihou commented Oct 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Codex users could install the plugin and sign in, but every Nutrient tool call then failed.

Without scopes in .mcp.json, Codex asks for every scope the authorization server lists (11, including product:ai_gateway and email). It ignores the service's sign-in challenge and its protected-resource metadata. Hosted grants all 11, and the service's token exchange then refuses that grant, so every call fails. Claude Code asks for mcp:invoke offline_access, from the service's sign-in challenge, and works.

  • .mcp.json: the server now declares "scopes": ["mcp:invoke", "offline_access"]. Codex uses it for sign-in. Claude Code ignores it, and it loads and validates as before.
  • ci/check.py: checks that the scopes stay.
  • README: names each client's sign-in step: /mcp in Claude Code, and codex mcp login nutrient followed by a new session in Codex.
  • AGENTS.md: explains why scopes must stay.
  • Version: 1.0.1, so existing installs pick up the change.

Hosted is also being fixed on its side, for clients that add the server without the plugin: https://github.com/PSPDFKit/PSPDFKit/pull/60487. This change works without waiting for that deploy.

Testing

  • python3 ci/check.py, claude plugin validate ./plugins/nutrient and python3 ci/package_openai.py pass. The package is now nutrient-openai-1.0.1.zip.

  • Claude Code (2.1.263 and 2.1.301): the plugin installs from this branch, and plugin:nutrient:nutrient shows "Needs authentication" as before.

  • Codex 0.162.0, in a clean sandbox with ChatGPT apps off:

    • the plugin installs from this branch,
    • codex mcp login nutrient asks for scope=mcp:invoke offline_access with resource=https://mcp.nutrient.io/mcp,
    • the production sign-in succeeds,
    • a new session calls get_account_usage successfully.

    Before this change, the same steps gave invalid_grant on every call.

🤖 Generated with Claude Code

Without scopes in .mcp.json, Codex requests every scope the authorization
server lists. Hosted grants them, and the service's token exchange then
refuses the grant, so every Nutrient tool call failed in Codex. The plugin
now asks for mcp:invoke and offline_access, the scope Claude Code takes from
the service's sign-in challenge, and ci/check.py keeps it.

The README names each client's sign-in step, and the version is 1.0.1 so
existing installs pick up the change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@olihou
olihou merged commit e5f76e0 into main Oct 17, 2026
1 check passed
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