feat: register public Notion OAuth integration for remote proxy #6

Open
opened 2026-04-21 01:30:30 +00:00 by forgejo_admin · 2 comments
Contributor

Type

Feature

Lineage

Standalone — scoped from project-notion-mcp-remote. Prerequisite for the claude.ai OAuth round-trip.

Repo

forgejo_admin/notion-mcp-remote

User Story

As a claude.ai user
I want a public Notion OAuth integration backing the proxy
So that I can complete Notion OAuth via the public URL and claude.ai obtains a per-user access token.

Context

The remote proxy does three-legged OAuth: claude.ai ↔ notion-mcp-remote ↔ Notion. The middle leg requires a Public Notion integration (distinct from the Internal integration-token flow used by the local stdio server). This yields CLIENT_ID and CLIENT_SECRET values that feed NOTION_OAUTH_CLIENT_ID / NOTION_OAUTH_CLIENT_SECRET env vars in the pod.

Manual UI step — Notion's "Develop or manage integrations" page has no public API for integration creation. Redirect URI must match exactly what the running service advertises via its OAuth metadata endpoint.

File Targets

No repo file changes expected. This is credential provisioning. The captured values land in:

  • ~/secrets/notion-mcp-remote/credentials.env — keys NOTION_OAUTH_CLIENT_ID, NOTION_OAUTH_CLIENT_SECRET
  • Cluster secret notion-mcp-remote (provisioned by a sibling issue)

Files NOT to touch:

  • server.py, requirements.txt — already consume the env vars

Acceptance Criteria

  • Public Notion integration exists in the Daily workspace's "Develop or manage integrations" UI
  • Distribution is Public (not Internal)
  • Redirect URI set to https://notion-mcp-remote.tail5b443a.ts.net/oauth/callback
  • NOTION_OAUTH_CLIENT_ID and NOTION_OAUTH_CLIENT_SECRET captured in ~/secrets/notion-mcp-remote/credentials.env
  • Manual smoke: curl -s "https://api.notion.com/v1/oauth/authorize?client_id=<id>&redirect_uri=https%3A%2F%2Fnotion-mcp-remote.tail5b443a.ts.net%2Foauth%2Fcallback&response_type=code&owner=user" returns the consent HTML, not an error

Test Expectations

  • Consent URL renders Notion's consent page in a browser
  • Run command: manual browser test with the authorize URL above

Constraints

  • Must be a Public integration (Internal integrations can't be installed by external users via OAuth)
  • Redirect URI must be exact (case, trailing slash, path) — Notion rejects close matches. The shared mcp-remote-auth library registers and validates /oauth/callback (see mcp_remote_auth/routes.py:41 and provider.py:125,151)
  • Do not commit the CLIENT_SECRET to any git repo
  • Follow-up: when the onboarding flow story lands, decide whether to register /onboard/callback as a secondary redirect URI on this same integration (avoids a second UI trip) or create a separate integration

Checklist

  • Integration created
  • Credentials stored in ~/secrets/notion-mcp-remote/
  • Smoke test passes
  • No unrelated changes
  • project-notion-mcp-remote
  • story-notion-mcp-remote-claude-ai-connect
  • arch-dataflow-notion-mcp-remote (OAuth handshake sequence)
### Type Feature ### Lineage Standalone — scoped from `project-notion-mcp-remote`. Prerequisite for the claude.ai OAuth round-trip. ### Repo `forgejo_admin/notion-mcp-remote` ### User Story As a claude.ai user I want a public Notion OAuth integration backing the proxy So that I can complete Notion OAuth via the public URL and claude.ai obtains a per-user access token. ### Context The remote proxy does three-legged OAuth: claude.ai ↔ notion-mcp-remote ↔ Notion. The middle leg requires a **Public** Notion integration (distinct from the Internal integration-token flow used by the local stdio server). This yields `CLIENT_ID` and `CLIENT_SECRET` values that feed `NOTION_OAUTH_CLIENT_ID` / `NOTION_OAUTH_CLIENT_SECRET` env vars in the pod. Manual UI step — Notion's "Develop or manage integrations" page has no public API for integration creation. Redirect URI must match exactly what the running service advertises via its OAuth metadata endpoint. ### File Targets No repo file changes expected. This is credential provisioning. The captured values land in: - `~/secrets/notion-mcp-remote/credentials.env` — keys `NOTION_OAUTH_CLIENT_ID`, `NOTION_OAUTH_CLIENT_SECRET` - Cluster secret `notion-mcp-remote` (provisioned by a sibling issue) Files NOT to touch: - `server.py`, `requirements.txt` — already consume the env vars ### Acceptance Criteria - [ ] Public Notion integration exists in the Daily workspace's "Develop or manage integrations" UI - [ ] Distribution is Public (not Internal) - [ ] Redirect URI set to `https://notion-mcp-remote.tail5b443a.ts.net/oauth/callback` - [ ] `NOTION_OAUTH_CLIENT_ID` and `NOTION_OAUTH_CLIENT_SECRET` captured in `~/secrets/notion-mcp-remote/credentials.env` - [ ] Manual smoke: `curl -s "https://api.notion.com/v1/oauth/authorize?client_id=<id>&redirect_uri=https%3A%2F%2Fnotion-mcp-remote.tail5b443a.ts.net%2Foauth%2Fcallback&response_type=code&owner=user"` returns the consent HTML, not an error ### Test Expectations - [ ] Consent URL renders Notion's consent page in a browser - Run command: manual browser test with the authorize URL above ### Constraints - Must be a Public integration (Internal integrations can't be installed by external users via OAuth) - Redirect URI must be exact (case, trailing slash, path) — Notion rejects close matches. The shared `mcp-remote-auth` library registers and validates `/oauth/callback` (see `mcp_remote_auth/routes.py:41` and `provider.py:125,151`) - Do not commit the CLIENT_SECRET to any git repo - Follow-up: when the onboarding flow story lands, decide whether to register `/onboard/callback` as a secondary redirect URI on this same integration (avoids a second UI trip) or create a separate integration ### Checklist - [ ] Integration created - [ ] Credentials stored in `~/secrets/notion-mcp-remote/` - [ ] Smoke test passes - [ ] No unrelated changes ### Related - `project-notion-mcp-remote` - `story-notion-mcp-remote-claude-ai-connect` - `arch-dataflow-notion-mcp-remote` (OAuth handshake sequence)
Author
Contributor

Scope Review: NEEDS_REFINEMENT

Review note: review-1046-2026-04-21

Scope is solid overall — template complete, traceability mostly intact, file targets verified against codebase — but two fixable issues block promotion to todo.

Blocking:

  • [BODY] Redirect URI path is wrong. Ticket specifies /callback but the service registers /oauth/callback (see mcp-remote-auth/src/mcp_remote_auth/routes.py:41, provider.py:125, provider.py:151). If Notion is configured with /callback, the token exchange will fail silently. Fix AC #3, the smoke curl URL in AC #5, and any Constraints references: https://notion-mcp-remote.tail5b443a.ts.net/callbackhttps://notion-mcp-remote.tail5b443a.ts.net/oauth/callback.
  • [SCOPE] arch:notion-oauth label has no backing note. search_notes("arch-notion-oauth") returned no results; the OAuth handshake is actually documented in arch-dataflow-notion-mcp-remote. Either relabel the board item to arch:dataflow-notion-mcp-remote (lighter, preferred) or create a dedicated arch-notion-oauth component note.

Optional (non-blocking):

  • [BODY] Also register /onboard/callback if the same Public integration will back the onboarding flow (future story).
  • [BODY] Correct the blocker references — per the board, this ticket unblocks #7 (secret provisioning) and #9 (E2E verify), not #5 / #8 as implied elsewhere.

No decomposition needed (1 pt, 5 ACs, single UI flow).

## Scope Review: NEEDS_REFINEMENT Review note: `review-1046-2026-04-21` Scope is solid overall — template complete, traceability mostly intact, file targets verified against codebase — but two fixable issues block promotion to `todo`. **Blocking:** - `[BODY]` **Redirect URI path is wrong.** Ticket specifies `/callback` but the service registers `/oauth/callback` (see `mcp-remote-auth/src/mcp_remote_auth/routes.py:41`, `provider.py:125`, `provider.py:151`). If Notion is configured with `/callback`, the token exchange will fail silently. Fix AC #3, the smoke curl URL in AC #5, and any Constraints references: `https://notion-mcp-remote.tail5b443a.ts.net/callback` → `https://notion-mcp-remote.tail5b443a.ts.net/oauth/callback`. - `[SCOPE]` **`arch:notion-oauth` label has no backing note.** `search_notes("arch-notion-oauth")` returned no results; the OAuth handshake is actually documented in `arch-dataflow-notion-mcp-remote`. Either relabel the board item to `arch:dataflow-notion-mcp-remote` (lighter, preferred) or create a dedicated `arch-notion-oauth` component note. **Optional (non-blocking):** - `[BODY]` Also register `/onboard/callback` if the same Public integration will back the onboarding flow (future story). - `[BODY]` Correct the blocker references — per the board, this ticket unblocks #7 (secret provisioning) and #9 (E2E verify), not #5 / #8 as implied elsewhere. No decomposition needed (1 pt, 5 ACs, single UI flow).
Author
Contributor

Refinement applied per review-1046-2026-04-21

Issue body updated to resolve NEEDS_REFINEMENT verdict. Per consolidated-spec convention, the body is the single source of truth — this comment documents what changed and why.

Changes

  1. Redirect URI path corrected: /callback/oauth/callback

    • Affected: AC #3, AC #5 smoke-test curl (both redirect_uri= occurrences), and Constraints section.
    • Reason: the shared mcp-remote-auth library registers and validates /oauth/callback at mcp_remote_auth/routes.py:41 and provider.py:125,151. The prior /callback path would have failed Notion's exact-match redirect check at runtime.
  2. Constraints: added library citation for the redirect path requirement so the dev executing the UI step can verify without tracing through the code.

  3. Constraints: added follow-up note flagging the /onboard/callback decision for when the onboarding flow story lands. Opted for the flag (reviewer's "if uncertain" option) rather than pre-registering a second redirect URI, since no onboarding story exists in pal-e-docs yet and expanding scope without explicit direction isn't warranted.

Not changed

  • File targets, points, AC structure, dependency list — all preserved per review instructions.
  • "Related Architecture" reference — already correctly cited arch-dataflow-notion-mcp-remote; no stale arch-notion-oauth reference existed in the body.
  • Board label — handled separately per review note.

Ready for re-review.

## Refinement applied per `review-1046-2026-04-21` Issue body updated to resolve NEEDS_REFINEMENT verdict. Per consolidated-spec convention, the body is the single source of truth — this comment documents what changed and why. ### Changes 1. **Redirect URI path corrected: `/callback` → `/oauth/callback`** - Affected: AC #3, AC #5 smoke-test curl (both `redirect_uri=` occurrences), and Constraints section. - Reason: the shared `mcp-remote-auth` library registers and validates `/oauth/callback` at `mcp_remote_auth/routes.py:41` and `provider.py:125,151`. The prior `/callback` path would have failed Notion's exact-match redirect check at runtime. 2. **Constraints: added library citation** for the redirect path requirement so the dev executing the UI step can verify without tracing through the code. 3. **Constraints: added follow-up note** flagging the `/onboard/callback` decision for when the onboarding flow story lands. Opted for the flag (reviewer's "if uncertain" option) rather than pre-registering a second redirect URI, since no onboarding story exists in pal-e-docs yet and expanding scope without explicit direction isn't warranted. ### Not changed - File targets, points, AC structure, dependency list — all preserved per review instructions. - "Related Architecture" reference — already correctly cited `arch-dataflow-notion-mcp-remote`; no stale `arch-notion-oauth` reference existed in the body. - Board label — handled separately per review note. Ready for re-review.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ldraney/notion-mcp-remote#6
No description provided.