@forumone/throughline 2.2.0 → 2.3.0-pr-315-e1a501e

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/audit/types.d.ts +1 -1
  3. package/dist/audit/types.d.ts.map +1 -1
  4. package/dist/audit/types.js +2 -0
  5. package/dist/audit/types.js.map +1 -1
  6. package/dist/editorial/palette/ReportsNav.d.ts +3 -1
  7. package/dist/editorial/palette/ReportsNav.d.ts.map +1 -1
  8. package/dist/editorial/palette/ReportsNav.js +3 -3
  9. package/dist/editorial/palette/ReportsNav.js.map +1 -1
  10. package/dist/exports/rsc.d.ts +1 -0
  11. package/dist/exports/rsc.d.ts.map +1 -1
  12. package/dist/exports/rsc.js +2 -0
  13. package/dist/exports/rsc.js.map +1 -1
  14. package/dist/mcp-oauth/admin/McpClientActions.d.ts +15 -0
  15. package/dist/mcp-oauth/admin/McpClientActions.d.ts.map +1 -0
  16. package/dist/mcp-oauth/admin/McpClientActions.js +79 -0
  17. package/dist/mcp-oauth/admin/McpClientActions.js.map +1 -0
  18. package/dist/mcp-oauth/admin/styles.d.ts +2 -0
  19. package/dist/mcp-oauth/admin/styles.d.ts.map +1 -0
  20. package/dist/mcp-oauth/admin/styles.js +27 -0
  21. package/dist/mcp-oauth/admin/styles.js.map +1 -0
  22. package/dist/mcp-oauth/admin/views.d.ts +4 -0
  23. package/dist/mcp-oauth/admin/views.d.ts.map +1 -0
  24. package/dist/mcp-oauth/admin/views.js +99 -0
  25. package/dist/mcp-oauth/admin/views.js.map +1 -0
  26. package/dist/mcp-oauth/auth.d.ts +12 -0
  27. package/dist/mcp-oauth/auth.d.ts.map +1 -0
  28. package/dist/mcp-oauth/auth.js +56 -0
  29. package/dist/mcp-oauth/auth.js.map +1 -0
  30. package/dist/mcp-oauth/cimd.d.ts +13 -0
  31. package/dist/mcp-oauth/cimd.d.ts.map +1 -0
  32. package/dist/mcp-oauth/cimd.js +93 -0
  33. package/dist/mcp-oauth/cimd.js.map +1 -0
  34. package/dist/mcp-oauth/clients.d.ts +42 -0
  35. package/dist/mcp-oauth/clients.d.ts.map +1 -0
  36. package/dist/mcp-oauth/clients.js +151 -0
  37. package/dist/mcp-oauth/clients.js.map +1 -0
  38. package/dist/mcp-oauth/collections.d.ts +10 -0
  39. package/dist/mcp-oauth/collections.d.ts.map +1 -0
  40. package/dist/mcp-oauth/collections.js +236 -0
  41. package/dist/mcp-oauth/collections.js.map +1 -0
  42. package/dist/mcp-oauth/crypto.d.ts +29 -0
  43. package/dist/mcp-oauth/crypto.d.ts.map +1 -0
  44. package/dist/mcp-oauth/crypto.js +91 -0
  45. package/dist/mcp-oauth/crypto.js.map +1 -0
  46. package/dist/mcp-oauth/endpoints.d.ts +11 -0
  47. package/dist/mcp-oauth/endpoints.d.ts.map +1 -0
  48. package/dist/mcp-oauth/endpoints.js +365 -0
  49. package/dist/mcp-oauth/endpoints.js.map +1 -0
  50. package/dist/mcp-oauth/index.d.ts +10 -0
  51. package/dist/mcp-oauth/index.d.ts.map +1 -0
  52. package/dist/mcp-oauth/index.js +6 -0
  53. package/dist/mcp-oauth/index.js.map +1 -0
  54. package/dist/mcp-oauth/metadata.d.ts +45 -0
  55. package/dist/mcp-oauth/metadata.d.ts.map +1 -0
  56. package/dist/mcp-oauth/metadata.js +84 -0
  57. package/dist/mcp-oauth/metadata.js.map +1 -0
  58. package/dist/mcp-oauth/plugin.d.ts +37 -0
  59. package/dist/mcp-oauth/plugin.d.ts.map +1 -0
  60. package/dist/mcp-oauth/plugin.js +90 -0
  61. package/dist/mcp-oauth/plugin.js.map +1 -0
  62. package/dist/mcp-oauth/runtime.d.ts +124 -0
  63. package/dist/mcp-oauth/runtime.d.ts.map +1 -0
  64. package/dist/mcp-oauth/runtime.js +111 -0
  65. package/dist/mcp-oauth/runtime.js.map +1 -0
  66. package/dist/mcp-oauth/store.d.ts +75 -0
  67. package/dist/mcp-oauth/store.d.ts.map +1 -0
  68. package/dist/mcp-oauth/store.js +408 -0
  69. package/dist/mcp-oauth/store.js.map +1 -0
  70. package/dist/migrate/exports.json +29 -0
  71. package/package.json +7 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @forumone/throughline
2
2
 
3
+ ## 2.3.0-pr-315-e1a501e
4
+
5
+ ### Minor Changes
6
+
7
+ - e1a501e: `@forumone/throughline/mcp-oauth`: people connect Claude, Claude Code or ChatGPT to `/api/mcp` by signing in, not by being handed an API key (forumone-2026#838).
8
+
9
+ - `mcpOAuth()` adds an OAuth 2.1 authorization server for `/api/mcp`, with discovery, client ID metadata documents and dynamic registration, PKCE S256, `iss` in the response, rotating refresh tokens and reuse detection, plus revocation. Apps are recognised by an allowlist of their redirect URIs. Its `overrideAuth` goes to `mcpPlugin`.
10
+ - An admin-only **MCP access** global decides which apps may connect and which tools administrators and everyone else are offered. Connections and their tools are re-read on every request, so a policy change, a revoked connection or a lost role takes effect at the next call.
11
+ - **Connect MCP** (`/admin/connect-mcp`) shows the address, a button for Claude, the Claude Code command and the ChatGPT steps, and lists the person's connected apps with Disconnect. The consent screen names the app by the callback it matched, not by what it calls itself.
12
+ - API keys keep working beside it. By default the person behind a key is now held to the same `eligible` rule on every request.
13
+ - `AUDIT_ACTIONS` gains `mcp.connected` and `mcp.disconnected`. **This is an enum migration in the host.** `ReportsNav` takes an optional `label`.
14
+
15
+ ### Patch Changes
16
+
17
+ - @forumone/throughline-design-system@2.3.0-pr-315-e1a501e
18
+
3
19
  ## 2.2.0
4
20
 
5
21
  ### Minor Changes
@@ -3,7 +3,7 @@
3
3
  * actions from this list rather than introducing free-form strings, so
4
4
  * audit queries (C8) can build on a known taxonomy.
5
5
  */
6
- export declare const AUDIT_ACTIONS: readonly ["content.find", "content.create", "content.update", "content.delete", "design.list", "design.suggest", "design.validate", "design.get_contract", "design.find_anti_pattern", "publishing.draft", "publishing.publish", "publishing.unpublish", "publishing.schedule", "publishing.rollback", "approval.requested", "approval.granted", "approval.declined", "approval.changes_requested", "approval.expired", "approval.discussed", "form.created", "form.updated", "form.submission_received", "integration.synced", "integration.failed", "system.error", "system.healthcheck"];
6
+ export declare const AUDIT_ACTIONS: readonly ["content.find", "content.create", "content.update", "content.delete", "design.list", "design.suggest", "design.validate", "design.get_contract", "design.find_anti_pattern", "publishing.draft", "publishing.publish", "publishing.unpublish", "publishing.schedule", "publishing.rollback", "approval.requested", "approval.granted", "approval.declined", "approval.changes_requested", "approval.expired", "approval.discussed", "form.created", "form.updated", "form.submission_received", "integration.synced", "integration.failed", "system.error", "system.healthcheck", "mcp.connected", "mcp.disconnected"];
7
7
  export type AuditAction = (typeof AUDIT_ACTIONS)[number];
8
8
  /**
9
9
  * MCP server identifiers: the `mcp_server` enum on the audit collection. A
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/audit/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,aAAa,6jBA4BhB,CAAA;AAEV,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAA;AAExD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,iKAapB,CAAA;AAEV,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/audit/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,aAAa,kmBA8BhB,CAAA;AAEV,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAA;AAExD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,iKAapB,CAAA;AAEV,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAA"}
@@ -31,6 +31,8 @@ export const AUDIT_ACTIONS = [
31
31
  'integration.failed',
32
32
  'system.error',
33
33
  'system.healthcheck',
34
+ 'mcp.connected',
35
+ 'mcp.disconnected',
34
36
  ];
35
37
  /**
36
38
  * MCP server identifiers: the `mcp_server` enum on the audit collection. A
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/audit/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,cAAc;IACd,gBAAgB;IAChB,gBAAgB;IAChB,gBAAgB;IAChB,aAAa;IACb,gBAAgB;IAChB,iBAAiB;IACjB,qBAAqB;IACrB,0BAA0B;IAC1B,kBAAkB;IAClB,oBAAoB;IACpB,sBAAsB;IACtB,qBAAqB;IACrB,qBAAqB;IACrB,oBAAoB;IACpB,kBAAkB;IAClB,mBAAmB;IACnB,4BAA4B;IAC5B,kBAAkB;IAClB,oBAAoB;IACpB,cAAc;IACd,cAAc;IACd,0BAA0B;IAC1B,oBAAoB;IACpB,oBAAoB;IACpB,cAAc;IACd,oBAAoB;CACZ,CAAA;AAIV;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,SAAS;IACT,WAAW;IACX,YAAY;IACZ,WAAW;IACX,OAAO;IACP,OAAO;IACP,cAAc;IACd,WAAW;IACX,YAAY;IACZ,QAAQ;IACR,eAAe;IACf,SAAS;CACD,CAAA"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/audit/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,cAAc;IACd,gBAAgB;IAChB,gBAAgB;IAChB,gBAAgB;IAChB,aAAa;IACb,gBAAgB;IAChB,iBAAiB;IACjB,qBAAqB;IACrB,0BAA0B;IAC1B,kBAAkB;IAClB,oBAAoB;IACpB,sBAAsB;IACtB,qBAAqB;IACrB,qBAAqB;IACrB,oBAAoB;IACpB,kBAAkB;IAClB,mBAAmB;IACnB,4BAA4B;IAC5B,kBAAkB;IAClB,oBAAoB;IACpB,cAAc;IACd,cAAc;IACd,0BAA0B;IAC1B,oBAAoB;IACpB,oBAAoB;IACpB,cAAc;IACd,oBAAoB;IACpB,eAAe;IACf,kBAAkB;CACV,CAAA;AAIV;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,SAAS;IACT,WAAW;IACX,YAAY;IACZ,WAAW;IACX,OAAO;IACP,OAAO;IACP,cAAc;IACd,WAAW;IACX,YAAY;IACZ,QAAQ;IACR,eAAe;IACf,SAAS;CACD,CAAA"}
@@ -1,5 +1,7 @@
1
1
  import type { Report } from './sources.js';
2
- export declare function ReportsNav({ reports }: {
2
+ export declare function ReportsNav({ reports, label, }: {
3
3
  reports?: Report[];
4
+ /** The group's heading. `mcpOAuth` reuses this for its own link. */
5
+ label?: string;
4
6
  }): import("react").JSX.Element | null;
5
7
  //# sourceMappingURL=ReportsNav.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ReportsNav.d.ts","sourceRoot":"","sources":["../../../src/editorial/palette/ReportsNav.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAiB1C,wBAAgB,UAAU,CAAC,EAAE,OAAY,EAAE,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,sCAiClE"}
1
+ {"version":3,"file":"ReportsNav.d.ts","sourceRoot":"","sources":["../../../src/editorial/palette/ReportsNav.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAiB1C,wBAAgB,UAAU,CAAC,EACzB,OAAY,EACZ,KAAiB,GAClB,EAAE;IACD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,sCAiCA"}
@@ -16,15 +16,15 @@ forumone-2026's `admin/ReportsNav.tsx`.
16
16
  registered and any the site adds: the sidebar is where editors go to reach
17
17
  content, and a report above Content pushed it down.
18
18
  */
19
- export function ReportsNav({ reports = [] }) {
19
+ export function ReportsNav({ reports = [], label = 'Reports', }) {
20
20
  const pathname = usePathname();
21
21
  const { config: { routes: { admin }, }, } = useConfig();
22
22
  if (reports.length === 0)
23
23
  return null;
24
- return (_jsx(NavGroup, { label: "Reports", children: reports.map(({ path, label }) => {
24
+ return (_jsx(NavGroup, { label: label, children: reports.map(({ path, label: text }) => {
25
25
  const href = `${admin}${path}`;
26
26
  const active = pathname === href || pathname.startsWith(`${href}/`);
27
- const content = (_jsxs(_Fragment, { children: [active && _jsx("div", { className: "nav__link-indicator" }), _jsx("span", { className: "nav__link-label", children: label })] }));
27
+ const content = (_jsxs(_Fragment, { children: [active && _jsx("div", { className: "nav__link-indicator" }), _jsx("span", { className: "nav__link-label", children: text })] }));
28
28
  return pathname === href ? (_jsx("div", { className: "nav__link", children: content }, path)) : (_jsx(Link, { className: "nav__link", href: href, prefetch: false, children: content }, path));
29
29
  }) }));
30
30
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ReportsNav.js","sourceRoot":"","sources":["../../../src/editorial/palette/ReportsNav.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,cAAc,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGhD,+EAA+E;AAC/E,sCAAsC;AACtC,MAAM,IAAI,GAAG,SAAS,IAAI,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAA;AAElF;;;;;;;;;EASE;AAEF,MAAM,UAAU,UAAU,CAAC,EAAE,OAAO,GAAG,EAAE,EAA0B;IACjE,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC9B,MAAM,EACJ,MAAM,EAAE,EACN,MAAM,EAAE,EAAE,KAAK,EAAE,GAClB,GACF,GAAG,SAAS,EAAE,CAAA;IAEf,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAErC,OAAO,CACL,KAAC,QAAQ,IAAC,KAAK,EAAC,SAAS,YACtB,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;YAC/B,MAAM,IAAI,GAAG,GAAG,KAAK,GAAG,IAAI,EAAE,CAAA;YAC9B,MAAM,MAAM,GAAG,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,CAAA;YACnE,MAAM,OAAO,GAAG,CACd,8BACG,MAAM,IAAI,cAAK,SAAS,EAAC,qBAAqB,GAAG,EAClD,eAAM,SAAS,EAAC,iBAAiB,YAAE,KAAK,GAAQ,IAC/C,CACJ,CAAA;YACD,OAAO,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,CACzB,cAAgB,SAAS,EAAC,WAAW,YAClC,OAAO,IADA,IAAI,CAER,CACP,CAAC,CAAC,CAAC,CACF,KAAC,IAAI,IAAY,SAAS,EAAC,WAAW,EAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,YAC/D,OAAO,IADC,IAAI,CAER,CACR,CAAA;QACH,CAAC,CAAC,GACO,CACZ,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"ReportsNav.js","sourceRoot":"","sources":["../../../src/editorial/palette/ReportsNav.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,cAAc,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGhD,+EAA+E;AAC/E,sCAAsC;AACtC,MAAM,IAAI,GAAG,SAAS,IAAI,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAA;AAElF;;;;;;;;;EASE;AAEF,MAAM,UAAU,UAAU,CAAC,EACzB,OAAO,GAAG,EAAE,EACZ,KAAK,GAAG,SAAS,GAKlB;IACC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC9B,MAAM,EACJ,MAAM,EAAE,EACN,MAAM,EAAE,EAAE,KAAK,EAAE,GAClB,GACF,GAAG,SAAS,EAAE,CAAA;IAEf,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAErC,OAAO,CACL,KAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YACnB,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE;YACrC,MAAM,IAAI,GAAG,GAAG,KAAK,GAAG,IAAI,EAAE,CAAA;YAC9B,MAAM,MAAM,GAAG,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,CAAA;YACnE,MAAM,OAAO,GAAG,CACd,8BACG,MAAM,IAAI,cAAK,SAAS,EAAC,qBAAqB,GAAG,EAClD,eAAM,SAAS,EAAC,iBAAiB,YAAE,IAAI,GAAQ,IAC9C,CACJ,CAAA;YACD,OAAO,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,CACzB,cAAgB,SAAS,EAAC,WAAW,YAClC,OAAO,IADA,IAAI,CAER,CACP,CAAC,CAAC,CAAC,CACF,KAAC,IAAI,IAAY,SAAS,EAAC,WAAW,EAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,YAC/D,OAAO,IADC,IAAI,CAER,CACR,CAAA;QACH,CAAC,CAAC,GACO,CACZ,CAAA;AACH,CAAC"}
@@ -14,4 +14,5 @@ export { HealthSummary } from '../editorial/health/HealthSummary.js';
14
14
  export { ContentCalendarView } from '../editorial/calendar/ContentCalendarView.js';
15
15
  export { ContentCalendarReport } from '../editorial/calendar/ContentCalendarReport.js';
16
16
  export { YourWorkDashboard, YourWorkReport } from '../editorial/work/YourWork.js';
17
+ export { ConnectMcpView, McpAuthorizeView } from '../mcp-oauth/admin/views.js';
17
18
  //# sourceMappingURL=rsc.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rsc.d.ts","sourceRoot":"","sources":["../../src/exports/rsc.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAG1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAA;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAA;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,8CAA8C,CAAA;AAClF,OAAO,EAAE,qBAAqB,EAAE,MAAM,gDAAgD,CAAA;AACtF,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA"}
1
+ {"version":3,"file":"rsc.d.ts","sourceRoot":"","sources":["../../src/exports/rsc.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAG1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAA;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAA;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,8CAA8C,CAAA;AAClF,OAAO,EAAE,qBAAqB,EAAE,MAAM,gDAAgD,CAAA;AACtF,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAGjF,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA"}
@@ -16,4 +16,6 @@ export { HealthSummary } from '../editorial/health/HealthSummary.js';
16
16
  export { ContentCalendarView } from '../editorial/calendar/ContentCalendarView.js';
17
17
  export { ContentCalendarReport } from '../editorial/calendar/ContentCalendarReport.js';
18
18
  export { YourWorkDashboard, YourWorkReport } from '../editorial/work/YourWork.js';
19
+ // MCP sign-in
20
+ export { ConnectMcpView, McpAuthorizeView } from '../mcp-oauth/admin/views.js';
19
21
  //# sourceMappingURL=rsc.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rsc.js","sourceRoot":"","sources":["../../src/exports/rsc.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,QAAQ;AACR,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAE1D,YAAY;AACZ,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAA;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAA;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,8CAA8C,CAAA;AAClF,OAAO,EAAE,qBAAqB,EAAE,MAAM,gDAAgD,CAAA;AACtF,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA"}
1
+ {"version":3,"file":"rsc.js","sourceRoot":"","sources":["../../src/exports/rsc.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,QAAQ;AACR,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAE1D,YAAY;AACZ,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAA;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAA;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,8CAA8C,CAAA;AAClF,OAAO,EAAE,qBAAqB,EAAE,MAAM,gDAAgD,CAAA;AACtF,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAEjF,cAAc;AACd,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA"}
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ export declare function CopyValue({ value, label }: {
3
+ value: string;
4
+ label?: string;
5
+ }): React.ReactNode;
6
+ export declare function ConsentActions({ request, allow, clientLabel, }: {
7
+ request: string;
8
+ /** False when the person may not connect: only Cancel is offered. */
9
+ allow?: boolean;
10
+ clientLabel: string;
11
+ }): React.ReactNode;
12
+ export declare function RevokeConnectionButton({ id }: {
13
+ id: number | string;
14
+ }): React.ReactNode;
15
+ //# sourceMappingURL=McpClientActions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpClientActions.d.ts","sourceRoot":"","sources":["../../../src/mcp-oauth/admin/McpClientActions.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAcvC,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,KAAK,CAAC,SAAS,CAoB9F;AAED,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,KAAY,EACZ,WAAW,GACZ,EAAE;IACD,OAAO,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;CACpB,GAAG,KAAK,CAAC,SAAS,CA4ClB;AAED,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,EAAE,EAAE;IAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAAG,KAAK,CAAC,SAAS,CA+CvF"}
@@ -0,0 +1,79 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useState } from 'react';
4
+ import { Button, useConfig } from '@payloadcms/ui';
5
+ import { useRouter } from 'next/navigation.js';
6
+ /*
7
+ The three things on the MCP pages that need the browser: copying, answering
8
+ the consent screen, and revoking a connection.
9
+
10
+ The consent answer is a `fetch` followed by `location.assign`, not a form post
11
+ that redirects. A form post's redirect to claude.ai or chatgpt.com is governed by
12
+ the page's `form-action` CSP, which a site is right to keep to `'self'`; a
13
+ navigation the script starts is not.
14
+ */
15
+ export function CopyValue({ value, label }) {
16
+ const [copied, setCopied] = useState(false);
17
+ return (_jsxs("div", { className: "tl-mcp__copy", children: [_jsx("code", { className: "tl-mcp__value", children: value }), _jsx(Button, { buttonStyle: "secondary", size: "small", margin: false, onClick: () => {
18
+ void navigator.clipboard.writeText(value).then(() => {
19
+ setCopied(true);
20
+ setTimeout(() => setCopied(false), 2000);
21
+ });
22
+ }, children: copied ? 'Copied' : (label ?? 'Copy') })] }));
23
+ }
24
+ export function ConsentActions({ request, allow = true, clientLabel, }) {
25
+ const { config } = useConfig();
26
+ const [busy, setBusy] = useState(false);
27
+ const [error, setError] = useState(null);
28
+ async function answer(decision) {
29
+ setBusy(true);
30
+ setError(null);
31
+ try {
32
+ const response = await fetch(`${config.serverURL ?? ''}${config.routes.api}/oauth/consent`, {
33
+ method: 'POST',
34
+ credentials: 'same-origin',
35
+ headers: { 'content-type': 'application/json' },
36
+ body: JSON.stringify({ request, decision }),
37
+ });
38
+ const body = (await response.json());
39
+ if (body.redirect) {
40
+ window.location.assign(body.redirect);
41
+ return;
42
+ }
43
+ setError(body.error ?? 'Something went wrong. Start again from the app.');
44
+ }
45
+ catch {
46
+ setError('Something went wrong. Start again from the app.');
47
+ }
48
+ setBusy(false);
49
+ }
50
+ return (_jsxs("div", { className: "tl-mcp__actions", children: [allow && (_jsxs(Button, { buttonStyle: "primary", disabled: busy, onClick: () => void answer('allow'), children: ["Allow ", clientLabel] })), _jsx(Button, { buttonStyle: "secondary", disabled: busy, onClick: () => void answer('deny'), children: "Cancel" }), error && (_jsx("p", { className: "tl-mcp__error", role: "alert", children: error }))] }));
51
+ }
52
+ export function RevokeConnectionButton({ id }) {
53
+ const { config } = useConfig();
54
+ const router = useRouter();
55
+ const [busy, setBusy] = useState(false);
56
+ const [error, setError] = useState(null);
57
+ return (_jsxs(_Fragment, { children: [_jsx(Button, { buttonStyle: "secondary", size: "small", margin: false, disabled: busy, onClick: () => {
58
+ setBusy(true);
59
+ setError(null);
60
+ void fetch(`${config.serverURL ?? ''}${config.routes.api}/oauth/grants/${String(id)}/revoke`, {
61
+ method: 'POST',
62
+ credentials: 'same-origin',
63
+ })
64
+ .then(async (response) => {
65
+ if (!response.ok) {
66
+ const body = (await response.json().catch(() => ({})));
67
+ setError(body.error ?? 'Could not disconnect it.');
68
+ setBusy(false);
69
+ return;
70
+ }
71
+ router.refresh();
72
+ })
73
+ .catch(() => {
74
+ setError('Could not disconnect it.');
75
+ setBusy(false);
76
+ });
77
+ }, children: "Disconnect" }), error && (_jsx("span", { className: "tl-mcp__error", role: "alert", children: error }))] }));
78
+ }
79
+ //# sourceMappingURL=McpClientActions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpClientActions.js","sourceRoot":"","sources":["../../../src/mcp-oauth/admin/McpClientActions.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const MCP_CSS = "\n.tl-mcp { max-width: 52rem; padding-bottom: calc(var(--base) * 3); }\n.tl-mcp h1 { margin-bottom: calc(var(--base) * 0.5); }\n.tl-mcp__lede { font-size: 1.05rem; color: var(--theme-elevation-800); }\n.tl-mcp__section { margin-top: calc(var(--base) * 2); padding-top: var(--base); border-top: 1px solid var(--theme-elevation-100); }\n.tl-mcp__section h2 { font-size: 1.15rem; margin-bottom: calc(var(--base) * 0.5); }\n.tl-mcp__section ol, .tl-mcp__section ul { padding-left: 1.25rem; }\n.tl-mcp__section li { margin-bottom: calc(var(--base) * 0.4); }\n.tl-mcp__copy { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--base) * 0.5); margin: calc(var(--base) * 0.5) 0; }\n.tl-mcp__value { padding: calc(var(--base) * 0.4) calc(var(--base) * 0.6); border: 1px solid var(--theme-elevation-150); border-radius: var(--style-radius-s); background: var(--theme-elevation-50); font-size: 0.9rem; overflow-wrap: anywhere; }\n.tl-mcp__button { display: inline-block; padding: calc(var(--base) * 0.4) calc(var(--base) * 0.9); border-radius: var(--style-radius-s); background: var(--theme-elevation-900); color: var(--theme-elevation-0); text-decoration: none; font-weight: 600; }\n.tl-mcp__button:hover, .tl-mcp__button:focus-visible { background: var(--theme-elevation-750); color: var(--theme-elevation-0); }\n.tl-mcp__note { color: var(--theme-elevation-600); font-size: 0.9rem; }\n.tl-mcp__notice { padding: calc(var(--base) * 0.6) var(--base); border-left: 3px solid var(--theme-warning-500); background: var(--theme-warning-50, var(--theme-elevation-50)); }\n.tl-mcp__error { color: var(--theme-error-500); margin: 0; }\n.tl-mcp__actions { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--base) * 0.5); margin-top: calc(var(--base) * 1.5); }\n.tl-mcp__tools { list-style: none; padding: 0; }\n.tl-mcp__tools li { margin-bottom: calc(var(--base) * 0.4); }\n.tl-mcp__table { width: 100%; border-collapse: collapse; }\n.tl-mcp__table th, .tl-mcp__table td { text-align: left; padding: calc(var(--base) * 0.4) calc(var(--base) * 0.5); border-bottom: 1px solid var(--theme-elevation-100); vertical-align: middle; }\n.tl-mcp__table th { font-weight: 600; color: var(--theme-elevation-700); }\n";
2
+ //# sourceMappingURL=styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/mcp-oauth/admin/styles.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,OAAO,mrEAqBnB,CAAA"}
@@ -0,0 +1,27 @@
1
+ /*
2
+ The MCP pages' styles, in Payload's tokens, rendered as a React 19
3
+ `<style href precedence>` like the editorial views'.
4
+ */
5
+ export const MCP_CSS = `
6
+ .tl-mcp { max-width: 52rem; padding-bottom: calc(var(--base) * 3); }
7
+ .tl-mcp h1 { margin-bottom: calc(var(--base) * 0.5); }
8
+ .tl-mcp__lede { font-size: 1.05rem; color: var(--theme-elevation-800); }
9
+ .tl-mcp__section { margin-top: calc(var(--base) * 2); padding-top: var(--base); border-top: 1px solid var(--theme-elevation-100); }
10
+ .tl-mcp__section h2 { font-size: 1.15rem; margin-bottom: calc(var(--base) * 0.5); }
11
+ .tl-mcp__section ol, .tl-mcp__section ul { padding-left: 1.25rem; }
12
+ .tl-mcp__section li { margin-bottom: calc(var(--base) * 0.4); }
13
+ .tl-mcp__copy { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--base) * 0.5); margin: calc(var(--base) * 0.5) 0; }
14
+ .tl-mcp__value { padding: calc(var(--base) * 0.4) calc(var(--base) * 0.6); border: 1px solid var(--theme-elevation-150); border-radius: var(--style-radius-s); background: var(--theme-elevation-50); font-size: 0.9rem; overflow-wrap: anywhere; }
15
+ .tl-mcp__button { display: inline-block; padding: calc(var(--base) * 0.4) calc(var(--base) * 0.9); border-radius: var(--style-radius-s); background: var(--theme-elevation-900); color: var(--theme-elevation-0); text-decoration: none; font-weight: 600; }
16
+ .tl-mcp__button:hover, .tl-mcp__button:focus-visible { background: var(--theme-elevation-750); color: var(--theme-elevation-0); }
17
+ .tl-mcp__note { color: var(--theme-elevation-600); font-size: 0.9rem; }
18
+ .tl-mcp__notice { padding: calc(var(--base) * 0.6) var(--base); border-left: 3px solid var(--theme-warning-500); background: var(--theme-warning-50, var(--theme-elevation-50)); }
19
+ .tl-mcp__error { color: var(--theme-error-500); margin: 0; }
20
+ .tl-mcp__actions { display: flex; flex-wrap: wrap; align-items: center; gap: calc(var(--base) * 0.5); margin-top: calc(var(--base) * 1.5); }
21
+ .tl-mcp__tools { list-style: none; padding: 0; }
22
+ .tl-mcp__tools li { margin-bottom: calc(var(--base) * 0.4); }
23
+ .tl-mcp__table { width: 100%; border-collapse: collapse; }
24
+ .tl-mcp__table th, .tl-mcp__table td { text-align: left; padding: calc(var(--base) * 0.4) calc(var(--base) * 0.5); border-bottom: 1px solid var(--theme-elevation-100); vertical-align: middle; }
25
+ .tl-mcp__table th { font-weight: 600; color: var(--theme-elevation-700); }
26
+ `;
27
+ //# sourceMappingURL=styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../src/mcp-oauth/admin/styles.ts"],"names":[],"mappings":"AAAA;;;EAGE;AACF,MAAM,CAAC,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;CAqBtB,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { AdminViewServerProps } from 'payload';
2
+ export declare function ConnectMcpView(props: AdminViewServerProps): Promise<import("react").JSX.Element>;
3
+ export declare function McpAuthorizeView(props: AdminViewServerProps): Promise<import("react").JSX.Element>;
4
+ //# sourceMappingURL=views.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"views.d.ts","sourceRoot":"","sources":["../../../src/mcp-oauth/admin/views.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AA6FnD,wBAAsB,cAAc,CAAC,KAAK,EAAE,oBAAoB,wCA8N/D;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,oBAAoB,wCA0EjE"}
@@ -0,0 +1,99 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { DefaultTemplate } from '@payloadcms/next/templates';
3
+ import { Gutter } from '@payloadcms/ui';
4
+ import { redirect } from 'next/navigation.js';
5
+ import { isLoopback, MCP_CLIENT_RULES } from '../clients.js';
6
+ import { unseal } from '../crypto.js';
7
+ import { keys, mcpOAuthRuntime, MCP_ACCESS_SLUG, MCP_OAUTH_GRANTS_SLUG, readPolicy, toolsFor, } from '../runtime.js';
8
+ import { resolveClient } from '../store.js';
9
+ import { ConsentActions, CopyValue, RevokeConnectionButton } from './McpClientActions.js';
10
+ import { MCP_CSS } from './styles.js';
11
+ function Styles() {
12
+ return (_jsx("style", { href: "throughline-mcp", precedence: "default", children: MCP_CSS }));
13
+ }
14
+ function Page({ props, children }) {
15
+ const { initPageResult, params, searchParams, payload, i18n } = props;
16
+ const { req, permissions, locale, visibleEntities } = initPageResult;
17
+ return (_jsxs(DefaultTemplate, { i18n: i18n, ...(locale ? { locale } : {}), ...(params ? { params } : {}), payload: payload, permissions: permissions, req: req, ...(searchParams ? { searchParams } : {}), user: req.user, visibleEntities: visibleEntities, children: [_jsx(Styles, {}), _jsx(Gutter, { className: "tl-mcp", children: children })] }));
18
+ }
19
+ function signedInOrLogin(props, here) {
20
+ const user = props.initPageResult.req.user;
21
+ if (!user) {
22
+ const admin = props.payload.config.routes.admin;
23
+ redirect(`${admin}/login?redirect=${encodeURIComponent(here)}`);
24
+ }
25
+ return user;
26
+ }
27
+ function firstSentence(text) {
28
+ const match = /^(.+?[.!?])(\s|$)/.exec(text);
29
+ return (match?.[1] ?? text).trim();
30
+ }
31
+ function when(value) {
32
+ if (typeof value !== 'string')
33
+ return '—';
34
+ const date = new Date(value);
35
+ return Number.isNaN(date.getTime())
36
+ ? '—'
37
+ : date.toLocaleString('en-US', { dateStyle: 'medium', timeStyle: 'short' });
38
+ }
39
+ function claudeAddUrl(runtime) {
40
+ // Claude's add-connector form, filled in. Two spellings of the parameters
41
+ // are in use; both are sent, and an unknown one is ignored.
42
+ const url = new URL('https://claude.ai/customize/connectors');
43
+ url.searchParams.set('modal', 'add-custom-connector');
44
+ url.searchParams.set('connectorName', runtime.serverName);
45
+ url.searchParams.set('connectorUrl', runtime.resource);
46
+ url.searchParams.set('mcpName', runtime.serverName);
47
+ url.searchParams.set('mcpServerUrl', runtime.resource);
48
+ return url.toString();
49
+ }
50
+ export async function ConnectMcpView(props) {
51
+ const { payload } = props;
52
+ const runtime = mcpOAuthRuntime(payload.config);
53
+ const admin = payload.config.routes.admin;
54
+ const user = signedInOrLogin(props, `${admin}${runtime.connectPath}`);
55
+ const policy = await readPolicy(payload, runtime);
56
+ const verdict = runtime.eligible(user);
57
+ const isAdmin = runtime.isAdmin(user);
58
+ const { docs: connections } = await payload.find({
59
+ collection: MCP_OAUTH_GRANTS_SLUG,
60
+ where: {
61
+ and: [{ user: { equals: user['id'] } }, { status: { not_equals: 'pending' } }],
62
+ },
63
+ sort: '-connectedAt',
64
+ limit: 50,
65
+ depth: 0,
66
+ overrideAccess: true,
67
+ });
68
+ const tools = toolsFor(user, policy, runtime);
69
+ return (_jsxs(Page, { props: props, children: [_jsx("h1", { children: "Connect MCP" }), _jsxs("p", { className: "tl-mcp__lede", children: ["Connect Claude", policy.clients.chatgpt ? ', ChatGPT' : '', " or Claude Code to", ' ', runtime.serverName, ", and draft, check and publish content by asking. The app works as you: it can do what you can do here, and everything it does is recorded under your name."] }), verdict !== true ? (_jsxs("p", { className: "tl-mcp__notice", children: ["You can\u2019t connect an app yet. ", verdict] })) : (_jsxs(_Fragment, { children: [_jsxs("section", { className: "tl-mcp__section", children: [_jsx("h2", { children: "The server\u2019s address" }), _jsxs("p", { children: ["Every app asks for this. You sign in with your usual ", runtime.serverName, " login; there is no key to copy."] }), _jsx(CopyValue, { value: runtime.resource, label: "Copy address" })] }), policy.clients.claude && (_jsxs("section", { className: "tl-mcp__section", children: [_jsx("h2", { children: "Claude \u2014 on the web, the desktop app and mobile" }), runtime.claudeConnector === 'organization' ? (_jsxs("ol", { children: [_jsx("li", { children: _jsx("a", { className: "tl-mcp__button", href: "https://claude.ai/customize/connectors", target: "_blank", rel: "noopener noreferrer", children: "Open Claude\u2019s connectors" }) }), _jsxs("li", { children: ["Find ", _jsx("strong", { children: runtime.serverName }), ", marked ", _jsx("em", { children: "Custom" }), ", and click", ' ', _jsx("strong", { children: "Connect" }), "."] }), _jsxs("li", { children: ["Claude sends you here to sign in. Check what it asks for and click", ' ', _jsx("strong", { children: "Allow" }), "."] })] })) : (_jsxs("ol", { children: [_jsxs("li", { children: [_jsxs("a", { className: "tl-mcp__button", href: claudeAddUrl(runtime), target: "_blank", rel: "noopener noreferrer", children: ["Add ", runtime.serverName, " to Claude"] }), ' ', "\u2014 the form opens with the name and address filled in. If it opens empty, paste the address above."] }), _jsxs("li", { children: ["Click ", _jsx("strong", { children: "Add" }), ", then ", _jsx("strong", { children: "Connect" }), "."] }), _jsxs("li", { children: ["Claude sends you here to sign in. Check what it asks for and click", ' ', _jsx("strong", { children: "Allow" }), "."] })] })), _jsxs("p", { className: "tl-mcp__note", children: ["One connection works everywhere you use Claude: claude.ai, the desktop app and the mobile apps.", runtime.claudeConnector === 'organization' && (_jsxs(_Fragment, { children: [' ', "Using a personal Claude account instead?", ' ', _jsx("a", { href: claudeAddUrl(runtime), target: "_blank", rel: "noopener noreferrer", children: "Add it to your own account" }), "."] }))] })] })), policy.clients.claudeCode && (_jsxs("section", { className: "tl-mcp__section", children: [_jsx("h2", { children: "Claude Code" }), _jsx("p", { children: "In a terminal:" }), _jsx(CopyValue, { value: `claude mcp add --transport http ${runtime.claudeCodeName} ${runtime.resource}` }), _jsxs("p", { children: ["Then, inside Claude Code, run ", _jsx("code", { children: "/mcp" }), ", choose", ' ', _jsx("strong", { children: runtime.claudeCodeName }), " and sign in. Your browser opens here; click ", _jsx("strong", { children: "Allow" }), "."] })] })), policy.clients.chatgpt && (_jsxs("section", { className: "tl-mcp__section", children: [_jsx("h2", { children: "ChatGPT" }), _jsx("p", { children: "ChatGPT has no install link, so this takes a few steps, once:" }), _jsxs("ol", { children: [_jsxs("li", { children: ["In ChatGPT, open ", _jsx("strong", { children: "Settings \u2192 Apps" }), " (or", ' ', _jsx("strong", { children: "Apps & Connectors" }), ") \u2192 ", _jsx("strong", { children: "Advanced settings" }), ", and turn on ", _jsx("strong", { children: "Developer mode" }), "."] }), _jsxs("li", { children: ["Back in ", _jsx("strong", { children: "Apps" }), ", choose ", _jsx("strong", { children: "Create" }), ". Name it", ' ', runtime.serverName, ", paste the address above as the", ' ', _jsx("strong", { children: "MCP server URL" }), ", and choose ", _jsx("strong", { children: "OAuth" }), " for authentication."] }), _jsxs("li", { children: ["ChatGPT sends you here to sign in. Check what it asks for and click", ' ', _jsx("strong", { children: "Allow" }), "."] })] }), _jsx("p", { className: "tl-mcp__note", children: "ChatGPT asks you to confirm before each change it makes. Content you work on goes to your ChatGPT account, under its own data settings." })] })), _jsxs("section", { className: "tl-mcp__section", children: [_jsx("h2", { children: "What a connected app can use" }), _jsx("p", { children: tools.length === 0
70
+ ? 'Nothing yet: an administrator has not chosen any tools for your role.'
71
+ : tools.join(', ') })] })] })), _jsxs("section", { className: "tl-mcp__section", children: [_jsx("h2", { children: "Your connected apps" }), connections.length === 0 ? (_jsx("p", { children: "None yet." })) : (_jsxs("table", { className: "tl-mcp__table", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "App" }), _jsx("th", { children: "Connected" }), _jsx("th", { children: "Last used" }), _jsx("th", { children: "Status" }), _jsx("th", {})] }) }), _jsx("tbody", { children: connections.map((grant) => (_jsxs("tr", { children: [_jsx("td", { children: String(grant['clientName']) }), _jsx("td", { children: when(grant['connectedAt']) }), _jsx("td", { children: when(grant['lastUsedAt']) }), _jsx("td", { children: grant['status'] === 'active'
72
+ ? 'Connected'
73
+ : `Disconnected${grant['revokedReason'] ? ` — ${String(grant['revokedReason'])}` : ''}` }), _jsx("td", { children: grant['status'] === 'active' && (_jsx(RevokeConnectionButton, { id: grant['id'] })) })] }, String(grant['id'])))) })] }))] }), isAdmin && (_jsxs("section", { className: "tl-mcp__section", children: [_jsx("h2", { children: "For administrators" }), _jsxs("ul", { children: [_jsxs("li", { children: [_jsx("a", { href: `${admin}/collections/${MCP_OAUTH_GRANTS_SLUG}`, children: "Everyone\u2019s connected apps" }), ' ', "\u2014 and disconnect any of them."] }), _jsxs("li", { children: [_jsx("a", { href: `${admin}/globals/${MCP_ACCESS_SLUG}`, children: "MCP access" }), " \u2014 which apps may connect, and which tools each role gets."] }), _jsxs("li", { children: [_jsx("a", { href: `${admin}/collections/payload-mcp-api-keys`, children: "API keys" }), " \u2014 for scripts, and for choosing tools key by key."] })] })] }))] }));
74
+ }
75
+ export async function McpAuthorizeView(props) {
76
+ const { payload, searchParams } = props;
77
+ const runtime = mcpOAuthRuntime(payload.config);
78
+ const admin = payload.config.routes.admin;
79
+ const sealed = typeof searchParams?.['request'] === 'string' ? searchParams['request'] : undefined;
80
+ const here = `${admin}${runtime.connectPath}/authorize${sealed ? `?request=${encodeURIComponent(sealed)}` : ''}`;
81
+ const user = signedInOrLogin(props, here);
82
+ const request = unseal(keys(payload).request, sealed);
83
+ if (!request) {
84
+ return (_jsxs(Page, { props: props, children: [_jsx("h1", { children: "This sign-in link has expired" }), _jsx("p", { children: "Go back to the app and connect again." })] }));
85
+ }
86
+ const policy = await readPolicy(payload, runtime);
87
+ const client = await resolveClient(payload, policy, request.clientId);
88
+ if ('error' in client) {
89
+ return (_jsxs(Page, { props: props, children: [_jsx("h1", { children: "This app can\u2019t connect" }), _jsx("p", { children: client.error })] }));
90
+ }
91
+ const label = MCP_CLIENT_RULES[client.kind].label;
92
+ const verdict = runtime.eligible(user);
93
+ const served = new Map(runtime.tools.map((tool) => [tool.name, tool.description ?? '']));
94
+ const tools = toolsFor(user, policy, runtime);
95
+ const name = String(user['name'] ?? user['email'] ?? 'you');
96
+ const host = new URL(request.redirectUri).host;
97
+ return (_jsxs(Page, { props: props, children: [_jsxs("h1", { children: ["Connect ", label, " to ", runtime.serverName, "?"] }), verdict !== true ? (_jsx("p", { className: "tl-mcp__notice", children: verdict })) : (_jsxs(_Fragment, { children: [_jsxs("p", { className: "tl-mcp__lede", children: [label, " will work as ", _jsx("strong", { children: name }), ". It can do what you can do in", ' ', runtime.serverName, ", through the tools below, and everything it does is recorded under your name. Publishing still follows your role and any approval a page needs."] }), isLoopback(request.redirectUri) && (_jsx("p", { className: "tl-mcp__notice", children: "This connection signs in through an app on your own computer. Only allow it if you have just started connecting from Claude Code, or another app you trust." })), _jsx("ul", { className: "tl-mcp__tools", children: tools.map((tool) => (_jsxs("li", { children: [_jsx("code", { children: tool }), " ", firstSentence(served.get(tool) ?? '')] }, tool))) }), _jsxs("p", { className: "tl-mcp__note", children: ["After you allow it, you go back to ", _jsx("strong", { children: host }), ". You can disconnect it at any time from ", _jsx("a", { href: `${admin}${runtime.connectPath}`, children: "Connect MCP" }), "."] })] })), _jsx(ConsentActions, { request: sealed, allow: verdict === true, clientLabel: label })] }));
98
+ }
99
+ //# sourceMappingURL=views.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"views.js","sourceRoot":"","sources":["../../../src/mcp-oauth/admin/views.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type PayloadRequest } from 'payload';
2
+ import { type McpOAuthRuntime } from './runtime.js';
3
+ /** The shape `plugin-mcp` resolves a request to. Declared structurally: it is not a dependency here. */
4
+ export interface McpAccessSettings {
5
+ user: Record<string, unknown>;
6
+ 'payload-mcp-tool'?: Record<string, boolean>;
7
+ 'payload-mcp-prompt'?: Record<string, boolean>;
8
+ [key: string]: unknown;
9
+ }
10
+ export type OverrideAuth = (req: PayloadRequest, getDefaultMcpAccessSettings: (overrideApiKey?: null | string) => Promise<McpAccessSettings>) => Promise<McpAccessSettings>;
11
+ export declare function createOverrideAuth(runtime: McpOAuthRuntime): OverrideAuth;
12
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/mcp-oauth/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,SAAS,CAAA;AAGhE,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,cAAc,CAAA;AA0BrB,wGAAwG;AACxG,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC5C,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,MAAM,MAAM,YAAY,GAAG,CACzB,GAAG,EAAE,cAAc,EACnB,2BAA2B,EAAE,CAAC,cAAc,CAAC,EAAE,IAAI,GAAG,MAAM,KAAK,OAAO,CAAC,iBAAiB,CAAC,KACxF,OAAO,CAAC,iBAAiB,CAAC,CAAA;AAyB/B,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,GAAG,YAAY,CAiCzE"}
@@ -0,0 +1,56 @@
1
+ import { UnauthorizedError } from 'payload';
2
+ import { TOKEN_PREFIX } from './crypto.js';
3
+ import { protectedResourceMetadataUrl } from './metadata.js';
4
+ import { MCP_OAUTH_STRATEGY, readPolicy, toCamelCase, toolsFor, } from './runtime.js';
5
+ import { authenticateAccessToken } from './store.js';
6
+ function challenge(req, runtime, error, description) {
7
+ const parts = [
8
+ ...(error ? [`error="${error}"`] : []),
9
+ // A header value is Latin-1; a site's refusal may be prose with curly quotes.
10
+ ...(description
11
+ ? [
12
+ `error_description="${description.replace(/[’‘]/g, "'").replace(/[^\x20-\x7e]|["\\]/g, '')}"`,
13
+ ]
14
+ : []),
15
+ `resource_metadata="${protectedResourceMetadataUrl(runtime)}"`,
16
+ 'scope="mcp"',
17
+ ];
18
+ const headers = req.responseHeaders ?? new Headers();
19
+ headers.set('WWW-Authenticate', `Bearer ${parts.join(', ')}`);
20
+ req.responseHeaders = headers;
21
+ throw new UnauthorizedError();
22
+ }
23
+ export function createOverrideAuth(runtime) {
24
+ return async (req, getDefault) => {
25
+ const header = req.headers.get('authorization') ?? '';
26
+ const bearer = header.startsWith('Bearer ') ? header.slice('Bearer '.length).trim() : '';
27
+ if (!bearer)
28
+ challenge(req, runtime);
29
+ if (bearer.startsWith(TOKEN_PREFIX.access)) {
30
+ const policy = await readPolicy(req.payload, runtime);
31
+ const result = await authenticateAccessToken(req.payload, runtime, policy, bearer);
32
+ if ('reason' in result)
33
+ challenge(req, runtime, 'invalid_token', result.reason);
34
+ const tools = toolsFor(result.user, policy, runtime);
35
+ return {
36
+ user: { ...result.user, collection: runtime.users, _strategy: MCP_OAUTH_STRATEGY },
37
+ 'payload-mcp-tool': Object.fromEntries(tools.map((name) => [toCamelCase(name), true])),
38
+ 'payload-mcp-prompt': Object.fromEntries(runtime.prompts.map((prompt) => [toCamelCase(prompt.name), true])),
39
+ };
40
+ }
41
+ let settings;
42
+ try {
43
+ settings = await getDefault();
44
+ }
45
+ catch {
46
+ challenge(req, runtime, 'invalid_token', 'The token is not valid.');
47
+ }
48
+ if (runtime.recheckApiKeyHolders) {
49
+ const verdict = runtime.eligible(settings.user);
50
+ if (verdict !== true)
51
+ challenge(req, runtime, 'invalid_token', verdict);
52
+ }
53
+ return settings;
54
+ };
55
+ }
56
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/mcp-oauth/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export interface ClientMetadataDocument {
2
+ client_id: string;
3
+ client_name?: string;
4
+ redirect_uris: string[];
5
+ }
6
+ /** Whether `clientId` is the kind of URL this server will fetch. */
7
+ export declare function isMetadataDocumentUrl(clientId: string): boolean;
8
+ export type FetchLike = (url: string, init: RequestInit) => Promise<Response>;
9
+ /** The document at `clientId`, or why it could not be used. */
10
+ export declare function fetchClientMetadata(clientId: string, fetchImpl?: FetchLike): Promise<ClientMetadataDocument | {
11
+ error: string;
12
+ }>;
13
+ //# sourceMappingURL=cimd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cimd.d.ts","sourceRoot":"","sources":["../../src/mcp-oauth/cimd.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,EAAE,CAAA;CACxB;AAKD,oEAAoE;AACpE,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAgB/D;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAE7E,+DAA+D;AAC/D,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,SAAiB,GAC3B,OAAO,CAAC,sBAAsB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAqDrD"}