Skip to content

Fix Dato Agent sign-in: use oauth.datocms.com OAuth endpoints - #157

Merged
roger-datocms merged 2 commits into
datocms:masterfrom
rodrigobarona:fix/dato-agent-oauth-endpoints
Nov 3, 2026
Merged

roger-datocms merged 2 commits into
datocms:masterfrom
rodrigobarona:fix/dato-agent-oauth-endpoints

Conversation

@rodrigobarona

Copy link
Copy Markdown
Contributor

Fixes #156

What

Dato Agent sign-in fails with Dynamic client registration failed with HTTP 401 (invalid_client) because mcp.datocms.com/register now rejects every registration. The MCP server's protected-resource metadata advertises https://oauth.datocms.com as its authorization server, so this PR moves the plugin's OAuth calls there.

Changes

  • src/lib/oauth.ts: add OAUTH_ORIGIN / OAUTH_BASE_URL and use https://oauth.datocms.com/oauth/{register,authorize,token,revoke}. navigateOAuthPopup now only allows https://oauth.datocms.com/oauth/authorize. The resource parameter is unchanged (https://mcp.datocms.com), since the token audience is still the MCP server.
  • src/lib/credentials.ts: bump OAUTH_CLIENT_REGISTRATION_VERSION from 2 to 3 so client IDs registered against the legacy endpoint are replaced on the next sign-in, using the existing legacy-registration path.
  • Tests: update the expected endpoint URLs and registration version, and add a test for navigateOAuthPopup that accepts the new authorize URL and rejects the legacy one.

No version bump or release; left to maintainers.

Verification

  • npm run typecheck, npm run lint, npm test (49 files, 952 tests), npm run build: all pass.
  • Live check against oauth.datocms.com: DCR with the plugin's payload returns a client_id. /oauth/authorize with that client, PKCE S256 and resource=https://mcp.datocms.com returns 302 to /session/new.
  • A build of this branch is deployed as a private plugin for end-to-end testing.

Follow-up idea

Discover the authorization server from https://mcp.datocms.com/.well-known/oauth-protected-resource instead of hardcoding it.

mcp.datocms.com/register now answers every dynamic client registration
with 401 invalid_client. The MCP server's protected-resource metadata
advertises https://oauth.datocms.com as its authorization server, so
register, authorize, token and revoke now target /oauth/* there. The
resource parameter still names mcp.datocms.com.

Bump OAUTH_CLIENT_REGISTRATION_VERSION so client IDs registered against
the legacy endpoint are replaced on the next sign-in.
@roger-datocms

Copy link
Copy Markdown
Member

(Claude here [Opus 5.5])

Triage

Status: still needed. Master (ad21b824, dato-agent 0.2.0) still sends all OAuth calls to mcp.datocms.com (dato-agent/src/lib/oauth.ts:162, :246, :494, :545).

Root cause confirmed live today:

  • mcp.datocms.com/.well-known/oauth-protected-resource lists https://oauth.datocms.com as the only authorization server.
  • oauth.datocms.com/.well-known/oauth-authorization-server lists /oauth/{authorize,token,register,revoke}, exactly as this PR uses.
  • POST mcp.datocms.com/register returns 401 for any body.
  • POST oauth.datocms.com/oauth/register returns Access-Control-Allow-Origin: *, so browser calls work.

Review

  • The diff covers every hardcoded OAuth URL on master. resource stays https://mcp.datocms.com, which matches the token audience.
  • navigateOAuthPopup keeps its strict origin + path allowlist. The new test checks that it rejects the legacy URL.
  • The OAUTH_CLIENT_REGISTRATION_VERSION bump to 3 works with isOAuthClientRegistrationReusable (dato-agent/src/lib/credentials.ts:174). Stored v2 clients re-register on the next sign-in.
  • Edge case: on sign-out, a legacy token goes to the new /oauth/revoke with a legacy client_id. That call can fail. AgentFrame.tsx:5569 still clears local credentials in finally, so users are not stuck.

Checks

  • Mergeable, no conflicts with master. The repo runs no CI on this PR.
  • On the PR head (590e32fb) we ran typecheck, lint, test (49 files, 952 tests) and build. All pass.

Recommended next step

  1. Merge this PR.
  2. Bump dato-agent/package.json and publish a patch release. The marketplace build (0.1.6) is broken for every user.
  3. Track the follow-up in a separate issue: discover endpoints from the .well-known metadata to survive future moves.

@ing-norante

Copy link
Copy Markdown

Let's merge this! 🙏🏻

@roger-datocms

roger-datocms commented Nov 3, 2026 •

Copy link
Copy Markdown
Member

@marcelofinamorvieira I'm going to go ahead and merge this one. (Thank you @rodrigobarona!)

But Marcelo, only you can deploy on NPM right now.

Claude tested it:

pr-157-walkthrough.mp4

And I did too (as a human, clicking the mouse like it's 2025 😅)! The existing behavior is already broken and the fix works.

Let's separately discuss how we want to go through the rest of the open PRs and issues? I'll review the ones I can and leave notes for you, but those aren't as urgent as this one so they can wait for your blessings 🙏

(Marcelo is the agent's real dad, I'm just babysitting!)

mcp.datocms.com/.well-known/oauth-protected-resource advertises the
resource as "https://mcp.datocms.com/" (trailing slash). RFC 8707
compares resource indicators as strings, so send that exact value in
the authorization request and the token exchange.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dato Agent: sign-in fails with HTTP 401 invalid_client, OAuth endpoints moved to oauth.datocms.com

3 participants