docs(connections): MCP-direct/DCR playbook section + Notion dry-run appendix (#11030)

## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Apps give agents governed access to external tools through catalog
connectors.
> - The connector playbook is the repeatable template for adding such
connectors.
> - Notion just shipped as the first MCP-direct connector with RFC 7591
dynamic client registration (#11009).
> - The playbook had no guidance for MCP-direct connections, OAuth
discovery, or DCR.
> - This pull request documents that path and encodes three mandatory
standards into the connector template.
> - It also adds a Notion dry-run appendix recorded from the live probe
and the shipped implementation.
> - The benefit is that the next MCP-direct connector follows a
recorded, verified path.

> [!IMPORTANT]
> **Depends on #11009.** This PR documents the Notion MCP connector that
ships in #11009 (RFC 7591 DCR, discovery-first endpoints,
`redirectConstraints` enforcement, refresh-rotation hardening).
Reviewing this doc against master before #11009 merges will show the
documented behavior as "not implemented" — that is expected. Draft until
#11009 lands, then re-review.

## What Changed

`doc/connections/CONNECTOR-PLAYBOOK.md` only (+364 lines, no code):

- New **"MCP-Direct Connections"** section: RFC 9728/8414 endpoint
discovery chain, an **RFC 7591 dynamic client registration** subsection
(public client, PKCE S256, env-client precedence, persist-and-reuse),
and a **redirect-URI constraints** subsection (`https-or-loopback-http`,
fail-fast wizard error).
- Three mandatory documentation standards encoded into the connector
template itself: a service-involvement statement (DCR providers need
neither Paperclip ID nor Paperclip Connect — instance-local per the
PAP-14828 spec §10 item 8.4; cloud and self-hosted use the same path), a
required **Connection Flow** section (sequence diagram + exact
authorize/token/registration/callback endpoints), and a required
**Administrator Setup** section.
- A **Notion dry-run appendix** mirroring the Linear appendix, recorded
from the live PAP-16649 probe: verified request sequence, redirect-URI
probe results table, sequence diagram (mermaid), shipped manifest
sketch, representative tool risk classes, admin setup (nothing to
register), governance defaults, and validation hooks.

## Verification

- Docs-only change; no code paths affected. `git diff --stat` shows
exactly one file.
- Every endpoint, error code, and constraint in the appendix was checked
against the shipped implementation on the #11009 head:
`server/src/services/tool-access.ts` (`assertOAuthRedirectConstraints`,
DCR registration metadata, refresh serialization),
`server/src/routes/tool-access.ts` (`POST
/api/tools/oauth/:connectionId/start`, `GET /api/tools/oauth/callback`),
and `packages/shared/src/app-definitions/notion.json`
(`redirectConstraints: "https-or-loopback-http"`).
- The request log mirrors the live probe record from PAP-16649
(2026-08-06/07), not vendor docs alone.
- Mermaid source renders cleanly (rendered PNG attached to PAP-16653).

## Risks

- Low: documentation only. Main risk is doc/implementation drift if
#11009 changes before merging — mitigated by the dependency note above
and re-review after #11009 lands.
- The template changes add mandatory sections for future connector
proposals; existing proposals are not retroactively invalidated.

## Model Used

Claude Fable 5 (claude-fable-5).

## Linked Issues or Issue Description

PAP-16653 (parent PAP-16637 P5). Companion catalog package landed in
paperclip-content (`integrations/catalog/platforms/notion/areas/mcp/`).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Dotta 2026-08-07 10:52:04 -05:00 committed by GitHub
parent 01b51dc0e5
commit 9abb600e72
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 29 additions and 5 deletions

View File

@ -199,10 +199,31 @@ most; the broker resolves endpoints at connect time:
dynamic registration — `registration_endpoint`.
The broker implements this in `discoverOAuthEndpoints`
(`server/src/services/tool-access.ts`); connections with transport
`mcp_remote` and `auth: "oauth"` prefer discovered endpoints over manifest
hints. Keep manifest hints current anyway so reviewers can read the expected
endpoints without running discovery.
(`server/src/services/tool-access.ts`), but discovery is **not**
unconditional. `oauthEndpointsForConnection` resolves endpoints in this
order:
1. If the manifest's method `defaults` ship a **complete** pair
(`authorizationEndpoint` **and** `tokenEndpoint`), those are used
unconditionally. `discoverOAuthEndpoints` never runs in this case, so
endpoints stored on the connection's own OAuth config and 401 challenge
hints are **not consulted at all**.
2. Otherwise, for `mcp_remote` connections, the broker calls
`discoverOAuthEndpoints`, which first checks endpoints already stored on
the connection's own OAuth config (falling back field-by-field to the 401
challenge hints); a complete stored/hinted pair is used as-is — no
`.well-known` fetch.
3. Only when neither of the above yields a complete pair does the broker run
the RFC 9728 → RFC 8414 discovery chain above.
Consequence: complete manifest endpoint hints are **authoritative, not
hints** — they override even endpoints that an earlier discovery persisted
on the connection, and if they go stale the broker keeps using them. For
discovery-capable vendors, ship only `serverUrl` in `defaults` (as
`notion.json` does) so the broker discovers fresh endpoints at connect
time; add explicit `authorizationEndpoint`/`tokenEndpoint` only for vendors
that do not publish RFC 9728/8414 metadata, and then own keeping them
current.
### Dynamic client registration (RFC 7591)
@ -497,7 +518,10 @@ alone.
- Transport: `mcp_remote`
- Endpoint: `https://mcp.notion.com/mcp` (Streamable HTTP; `/sse` fallback exists)
- Auth mode: OAuth, endpoints resolved by discovery (RFC 9728 → RFC 8414),
public client via RFC 7591 DCR with PKCE S256 mandatory.
public client via RFC 7591 DCR with PKCE S256 mandatory. Discovery runs
because `notion.json` deliberately ships only `serverUrl` — no
`authorizationEndpoint`/`tokenEndpoint` hints, which would otherwise take
precedence and be used verbatim (see "MCP-Direct Connections" above).
- Ownership modes: `dcr` (default, zero setup) and `customer`
(env-registered classic integration via
`PAPERCLIP_TOOL_OAUTH_NOTION_CLIENT_ID/_SECRET`, which always wins when set).