@se-studio/contentful-cms 3.15.3 → 3.15.4

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 (97) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/HOSTED.md +20 -0
  3. package/dist/commands/host-scaffold.d.ts.map +1 -1
  4. package/dist/commands/host-scaffold.js +5 -3
  5. package/dist/commands/host-scaffold.js.map +1 -1
  6. package/dist/contentful/cma-user-agent.d.ts +1 -1
  7. package/dist/editor-pack/load.d.ts.map +1 -1
  8. package/dist/editor-pack/load.js +14 -2
  9. package/dist/editor-pack/load.js.map +1 -1
  10. package/dist/generated/hosted-guide.d.ts +1 -1
  11. package/dist/generated/hosted-guide.d.ts.map +1 -1
  12. package/dist/generated/hosted-guide.js +1 -1
  13. package/dist/generated/hosted-guide.js.map +1 -1
  14. package/dist/generated/version.d.ts +1 -1
  15. package/dist/generated/version.js +1 -1
  16. package/dist/hosted/index.d.ts +1 -1
  17. package/dist/hosted/index.d.ts.map +1 -1
  18. package/dist/hosted/index.js +1 -1
  19. package/dist/hosted/index.js.map +1 -1
  20. package/dist/hosted/next/pages/CmsEditPage.d.ts.map +1 -1
  21. package/dist/hosted/next/pages/CmsEditPage.js +1 -1
  22. package/dist/hosted/next/pages/CmsEditPage.js.map +1 -1
  23. package/dist/hosted/next/pages/HomePage.d.ts.map +1 -1
  24. package/dist/hosted/next/pages/HomePage.js +1 -1
  25. package/dist/hosted/next/pages/HomePage.js.map +1 -1
  26. package/dist/hosted/next/routes/mcp.d.ts +1 -0
  27. package/dist/hosted/next/routes/mcp.d.ts.map +1 -1
  28. package/dist/hosted/next/routes/mcp.js +6 -1
  29. package/dist/hosted/next/routes/mcp.js.map +1 -1
  30. package/dist/hosted/next/routes/oauth-authorization-server.d.ts +1 -0
  31. package/dist/hosted/next/routes/oauth-authorization-server.d.ts.map +1 -1
  32. package/dist/hosted/next/routes/oauth-authorization-server.js +5 -1
  33. package/dist/hosted/next/routes/oauth-authorization-server.js.map +1 -1
  34. package/dist/hosted/next/routes/oauth-protected-resource-path.d.ts +13 -0
  35. package/dist/hosted/next/routes/oauth-protected-resource-path.d.ts.map +1 -0
  36. package/dist/hosted/next/routes/oauth-protected-resource-path.js +17 -0
  37. package/dist/hosted/next/routes/oauth-protected-resource-path.js.map +1 -0
  38. package/dist/hosted/next/routes/oauth-protected-resource.d.ts +1 -0
  39. package/dist/hosted/next/routes/oauth-protected-resource.d.ts.map +1 -1
  40. package/dist/hosted/next/routes/oauth-protected-resource.js +5 -1
  41. package/dist/hosted/next/routes/oauth-protected-resource.js.map +1 -1
  42. package/dist/hosted/oauth/cimd.d.ts +17 -0
  43. package/dist/hosted/oauth/cimd.d.ts.map +1 -0
  44. package/dist/hosted/oauth/cimd.js +300 -0
  45. package/dist/hosted/oauth/cimd.js.map +1 -0
  46. package/dist/hosted/oauth/complete.d.ts +1 -0
  47. package/dist/hosted/oauth/complete.d.ts.map +1 -1
  48. package/dist/hosted/oauth/complete.js +4 -0
  49. package/dist/hosted/oauth/complete.js.map +1 -1
  50. package/dist/hosted/oauth/config.d.ts +2 -0
  51. package/dist/hosted/oauth/config.d.ts.map +1 -1
  52. package/dist/hosted/oauth/config.js +4 -0
  53. package/dist/hosted/oauth/config.js.map +1 -1
  54. package/dist/hosted/oauth/cors.d.ts +4 -0
  55. package/dist/hosted/oauth/cors.d.ts.map +1 -0
  56. package/dist/hosted/oauth/cors.js +23 -0
  57. package/dist/hosted/oauth/cors.js.map +1 -0
  58. package/dist/hosted/oauth/handlers.d.ts.map +1 -1
  59. package/dist/hosted/oauth/handlers.js +57 -7
  60. package/dist/hosted/oauth/handlers.js.map +1 -1
  61. package/dist/hosted/oauth/log.d.ts +2 -0
  62. package/dist/hosted/oauth/log.d.ts.map +1 -1
  63. package/dist/hosted/oauth/log.js +4 -0
  64. package/dist/hosted/oauth/log.js.map +1 -1
  65. package/dist/hosted/oauth/redirect-hosts.d.ts +4 -0
  66. package/dist/hosted/oauth/redirect-hosts.d.ts.map +1 -0
  67. package/dist/hosted/oauth/redirect-hosts.js +47 -0
  68. package/dist/hosted/oauth/redirect-hosts.js.map +1 -0
  69. package/dist/hosted/oauth/refresh.d.ts +1 -0
  70. package/dist/hosted/oauth/refresh.d.ts.map +1 -1
  71. package/dist/hosted/oauth/refresh.js +2 -0
  72. package/dist/hosted/oauth/refresh.js.map +1 -1
  73. package/dist/hosted/oauth/scopes.d.ts +15 -0
  74. package/dist/hosted/oauth/scopes.d.ts.map +1 -0
  75. package/dist/hosted/oauth/scopes.js +21 -0
  76. package/dist/hosted/oauth/scopes.js.map +1 -0
  77. package/dist/hosted/oauth/store.d.ts +4 -0
  78. package/dist/hosted/oauth/store.d.ts.map +1 -1
  79. package/dist/hosted/oauth/store.js +3 -0
  80. package/dist/hosted/oauth/store.js.map +1 -1
  81. package/dist/mcp/server.d.ts.map +1 -1
  82. package/dist/mcp/server.js +2 -0
  83. package/dist/mcp/server.js.map +1 -1
  84. package/dist/mcp/tools/client-tools.d.ts +11 -0
  85. package/dist/mcp/tools/client-tools.d.ts.map +1 -0
  86. package/dist/mcp/tools/client-tools.js +215 -0
  87. package/dist/mcp/tools/client-tools.js.map +1 -0
  88. package/dist/staged-upload/store.d.ts +18 -0
  89. package/dist/staged-upload/store.d.ts.map +1 -1
  90. package/dist/staged-upload/store.js +73 -0
  91. package/dist/staged-upload/store.js.map +1 -1
  92. package/dist/staged-upload/types.d.ts +2 -0
  93. package/dist/staged-upload/types.d.ts.map +1 -1
  94. package/docs/mcp/hosted-guide.md +8 -0
  95. package/package.json +1 -1
  96. package/skills/manifest.json +1 -1
  97. package/skills/setup/SKILL.md +23 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @se-studio/contentful-cms Changelog
2
2
 
3
+ ## 3.15.4
4
+
5
+ ### Patch Changes
6
+
7
+ - Advertise OAuth scopes and Client ID Metadata Documents, and add typed MCP tools so ChatGPT and other remote clients can read and save drafts without a shell. Failed hosted commands stay failures, dash-leading field values are not parsed as flags, Client ID metadata fetches stay on public hosts and within 64KiB, an unregistered redirect is not followed, playbook names stay inside the editor pack, and text appends check the stored offset.
8
+
3
9
  ## 3.15.3
4
10
 
5
11
  ### Patch Changes
package/HOSTED.md CHANGED
@@ -60,6 +60,26 @@ See [hosted-guide.md](./docs/mcp/hosted-guide.md) for troubleshooting.
60
60
 
61
61
  ---
62
62
 
63
+ ## Other AI clients
64
+
65
+ The MCP URL (`https://<host>/api/mcp`) is the same for every client. Sign in with Contentful when the client asks.
66
+
67
+ | Client | How to connect |
68
+ |--------|----------------|
69
+ | ChatGPT | Settings → Apps & Connectors → create a custom MCP server → paste the URL → OAuth. Draft writes need Business, Enterprise, or Edu. Recreate the connector after a cms-edit upgrade so the tool list reloads. |
70
+ | Cursor / VS Code | Remote HTTP MCP server, URL ending in `/api/mcp`, then OAuth. |
71
+ | Gemini CLI | `mcpServers.<name>.url` set to the MCP URL. |
72
+
73
+ Typed tools (`search`, `fetch`, `set_field`, `append_text`, `save_draft`) are for clients that do not read MCP resources and cannot run a shell. `cms_edit` is unchanged. Nothing publishes.
74
+
75
+ **Existing hosts,** when bumping this package, re-export `OPTIONS` from `api/mcp` and the OAuth well-known routes, and add:
76
+
77
+ `src/app/.well-known/oauth-protected-resource/[...path]/route.ts` → `oauth-protected-resource-path`
78
+
79
+ New scaffolds already include those files. `cms-edit host scaffold` does not overwrite a route that is already there.
80
+
81
+ ---
82
+
63
83
  ## Step 3 — Try it
64
84
 
65
85
  **Getting started:** Ask Claude to read the **cms-edit guide** (`cms-edit://guide` resource) or use the **`cms_edit_verify`** prompt to check version and connectivity.
@@ -1 +1 @@
1
- {"version":3,"file":"host-scaffold.d.ts","sourceRoot":"","sources":["../../src/commands/host-scaffold.ts"],"names":[],"mappings":"AAAA,uFAAuF;AAIvF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,wBAAgB,0BAA0B,IAAI,MAAM,CAEnD;AAwFD,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA0BlE"}
1
+ {"version":3,"file":"host-scaffold.d.ts","sourceRoot":"","sources":["../../src/commands/host-scaffold.ts"],"names":[],"mappings":"AAAA,uFAAuF;AAIvF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,wBAAgB,0BAA0B,IAAI,MAAM,CAEnD;AA0FD,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA0BlE"}
@@ -48,16 +48,18 @@ export const config = {
48
48
  `,
49
49
  'src/app/oauth/register/route.ts': `export { POST } from '@se-studio/contentful-cms/hosted/next/routes/oauth-register';
50
50
  `,
51
- 'src/app/api/mcp/route.ts': `export { GET, POST, DELETE } from '@se-studio/contentful-cms/hosted/next/routes/mcp';
51
+ 'src/app/api/mcp/route.ts': `export { GET, POST, DELETE, OPTIONS } from '@se-studio/contentful-cms/hosted/next/routes/mcp';
52
52
  `,
53
53
  'src/app/api/health/route.ts': `export { GET } from '@se-studio/contentful-cms/hosted/next/routes/health';
54
54
  `,
55
55
  'src/app/api/staged-upload/route.ts': stagedUploadScaffoldSource(),
56
56
  'src/app/api/oauth/link-contentful/route.ts': `export { POST } from '@se-studio/contentful-cms/hosted/next/routes/link-contentful';
57
57
  `,
58
- 'src/app/.well-known/oauth-authorization-server/route.ts': `export { GET } from '@se-studio/contentful-cms/hosted/next/routes/oauth-authorization-server';
58
+ 'src/app/.well-known/oauth-authorization-server/route.ts': `export { GET, OPTIONS } from '@se-studio/contentful-cms/hosted/next/routes/oauth-authorization-server';
59
59
  `,
60
- 'src/app/.well-known/oauth-protected-resource/route.ts': `export { GET } from '@se-studio/contentful-cms/hosted/next/routes/oauth-protected-resource';
60
+ 'src/app/.well-known/oauth-protected-resource/route.ts': `export { GET, OPTIONS } from '@se-studio/contentful-cms/hosted/next/routes/oauth-protected-resource';
61
+ `,
62
+ 'src/app/.well-known/oauth-protected-resource/[...path]/route.ts': `export { GET, OPTIONS } from '@se-studio/contentful-cms/hosted/next/routes/oauth-protected-resource-path';
61
63
  `,
62
64
  'scripts/stage-site.mjs': `#!/usr/bin/env node
63
65
  import { existsSync } from 'node:fs';
@@ -1 +1 @@
1
- {"version":3,"file":"host-scaffold.js","sourceRoot":"","sources":["../../src/commands/host-scaffold.ts"],"names":[],"mappings":"AAAA,uFAAuF;AAEvF,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,UAAU,0BAA0B;IACxC,OAAO,2FAA2F,CAAC;AACrG,CAAC;AAED,MAAM,cAAc,GAA2B;IAC7C,cAAc,EAAE;;;;;;;;;;;CAWjB;IACC,oBAAoB,EAAE;;;;;;;CAOvB;IACC,kBAAkB,EAAE;CACrB;IACC,2BAA2B,EAAE;CAC9B;IACC,qCAAqC,EAAE;CACxC;IACC,gDAAgD,EAAE;CACnD;IACC,+BAA+B,EAAE;CAClC;IACC,0CAA0C,EAAE;CAC7C;IACC,0BAA0B,EAAE;CAC7B;IACC,4CAA4C,EAAE;CAC/C;IACC,kCAAkC,EAAE;CACrC;IACC,8BAA8B,EAAE;CACjC;IACC,iCAAiC,EAAE;CACpC;IACC,0BAA0B,EAAE;CAC7B;IACC,6BAA6B,EAAE;CAChC;IACC,oCAAoC,EAAE,0BAA0B,EAAE;IAClE,4CAA4C,EAAE;CAC/C;IACC,yDAAyD,EAAE;CAC5D;IACC,uDAAuD,EAAE;CAC1D;IACC,wBAAwB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6B3B;CACA,CAAC;AAEF,MAAM,UAAU,2BAA2B,CAAC,OAAgB;IAC1D,OAAO;SACJ,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,oEAAoE,CAAC;SACjF,MAAM,CAAC,mBAAmB,EAAE,sCAAsC,CAAC;SACnE,MAAM,CAAC,SAAS,EAAE,mCAAmC,CAAC;SACtD,MAAM,CAAC,CAAC,IAA2C,EAAE,EAAE;QACtD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACvD,MAAM,OAAO,GAAa,EAAE,CAAC;QAE7B,KAAK,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;YACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YAC7C,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACxC,SAAS;YACX,CAAC;YACD,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAClD,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACjC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC7B,CAAC;QAED,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;YAC5D,OAAO;QACT,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,CAAC,MAAM,aAAa,OAAO,EAAE,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"host-scaffold.js","sourceRoot":"","sources":["../../src/commands/host-scaffold.ts"],"names":[],"mappings":"AAAA,uFAAuF;AAEvF,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,UAAU,0BAA0B;IACxC,OAAO,2FAA2F,CAAC;AACrG,CAAC;AAED,MAAM,cAAc,GAA2B;IAC7C,cAAc,EAAE;;;;;;;;;;;CAWjB;IACC,oBAAoB,EAAE;;;;;;;CAOvB;IACC,kBAAkB,EAAE;CACrB;IACC,2BAA2B,EAAE;CAC9B;IACC,qCAAqC,EAAE;CACxC;IACC,gDAAgD,EAAE;CACnD;IACC,+BAA+B,EAAE;CAClC;IACC,0CAA0C,EAAE;CAC7C;IACC,0BAA0B,EAAE;CAC7B;IACC,4CAA4C,EAAE;CAC/C;IACC,kCAAkC,EAAE;CACrC;IACC,8BAA8B,EAAE;CACjC;IACC,iCAAiC,EAAE;CACpC;IACC,0BAA0B,EAAE;CAC7B;IACC,6BAA6B,EAAE;CAChC;IACC,oCAAoC,EAAE,0BAA0B,EAAE;IAClE,4CAA4C,EAAE;CAC/C;IACC,yDAAyD,EAAE;CAC5D;IACC,uDAAuD,EAAE;CAC1D;IACC,iEAAiE,EAAE;CACpE;IACC,wBAAwB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6B3B;CACA,CAAC;AAEF,MAAM,UAAU,2BAA2B,CAAC,OAAgB;IAC1D,OAAO;SACJ,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,oEAAoE,CAAC;SACjF,MAAM,CAAC,mBAAmB,EAAE,sCAAsC,CAAC;SACnE,MAAM,CAAC,SAAS,EAAE,mCAAmC,CAAC;SACtD,MAAM,CAAC,CAAC,IAA2C,EAAE,EAAE;QACtD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACvD,MAAM,OAAO,GAAa,EAAE,CAAC;QAE7B,KAAK,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;YACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YAC7C,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACxC,SAAS;YACX,CAAC;YACD,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAClD,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACjC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC7B,CAAC;QAED,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;YAC5D,OAAO;QACT,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,CAAC,MAAM,aAAa,OAAO,EAAE,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -1,5 +1,5 @@
1
1
  /** SDK `application` value. Becomes `app cms-edit/<version>` in X-Contentful-User-Agent. */
2
- export declare const CMA_APPLICATION = "cms-edit/3.15.3";
2
+ export declare const CMA_APPLICATION = "cms-edit/3.15.4";
3
3
  export declare function cmaClientOptions(accessToken: string): {
4
4
  accessToken: string;
5
5
  application: string;
@@ -1 +1 @@
1
- {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../src/editor-pack/load.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,eAAO,MAAM,4BAA4B,yBAAyB,CAAC;AAEnE,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAqCD,wBAAgB,qBAAqB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAc1E;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAUlF;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAwB9E;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,kBAAkB,GAAG,IAAI,CAkB3B"}
1
+ {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../src/editor-pack/load.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,eAAO,MAAM,4BAA4B,yBAAyB,CAAC;AAEnE,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAqCD,wBAAgB,qBAAqB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAc1E;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAUlF;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAwB9E;AAeD,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,kBAAkB,GAAG,IAAI,CAkB3B"}
@@ -79,12 +79,24 @@ export function listEditorPackResources(packPath) {
79
79
  }))
80
80
  .sort((a, b) => a.name.localeCompare(b.name));
81
81
  }
82
+ function pathInsidePack(packPath, candidate) {
83
+ if (candidate.includes('\0')) {
84
+ return null;
85
+ }
86
+ const root = path.resolve(packPath);
87
+ const fullPath = path.resolve(root, candidate);
88
+ const relative = path.relative(root, fullPath);
89
+ if (relative.startsWith('..') || path.isAbsolute(relative)) {
90
+ return null;
91
+ }
92
+ return fullPath;
93
+ }
82
94
  export function getEditorPackResource(packPath, resourceName) {
83
95
  const normalized = resourceName.replace(/^\/+/, '');
84
96
  const candidates = [`${normalized}.md`, `${normalized}.json`, normalized];
85
97
  for (const candidate of candidates) {
86
- const fullPath = path.join(packPath, candidate);
87
- if (fs.existsSync(fullPath) && fs.statSync(fullPath).isFile()) {
98
+ const fullPath = pathInsidePack(packPath, candidate);
99
+ if (fullPath && fs.existsSync(fullPath) && fs.statSync(fullPath).isFile()) {
88
100
  const name = candidate.replace(/\.(md|json)$/, '');
89
101
  return {
90
102
  uri: `${CUSTOMER_RESOURCE_URI_PREFIX}${name}`,
@@ -1 +1 @@
1
- {"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/editor-pack/load.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/editor-pack/load.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export declare const HOSTED_GUIDE_TEMPLATE = "# cms-edit MCP guide\n\nUse this guide when editing Contentful draft content through a hosted MCP connector (Claude Desktop Integrations + OAuth, or Grok Build).\n\n{{SITE_INTRO}}\n\n## Safety rules\n\ncms-edit **cannot and will not**:\n\n- Publish or unpublish entries\n- Archive or delete published entries\n\nAll `save` operations create **drafts only**. A human must review and publish in Contentful.\n\n**Assets:** Always **search and reuse** first (`index sync`, then `asset search`). Raster/video go through **`cms_edit_media`** (Drive, or intake then prepare \u2192 import). Video, and an image master over 4MB, is a presigned PUT (`intake: direct`) then prepare with `httpsUrls`. An image at or under 4MB uses a function POST then `stagedUploadIds`. Never `asset upload` jpeg/png/webp/gif/mp4, and never convert those files with local ffmpeg. SVG/PDF/Lottie: staged upload then `asset upload --staged`. **`--base64` is not supported on hosted MCP.**\n\n## MCP tools\n\n| Tool | Purpose |\n|------|---------|\n| `cms_edit` | Run any cms-edit command via an `args` array |\n| `cms_edit_request_staged_upload` | Presigned URL. `kind=asset` (default): binaries. `kind=text`: HtmlComponent fields then `set --staged`. `kind=json`: `create from-json --staged`. |\n| `cms_edit_version` | Check the installed cms-edit version (no session required) |\n| `cms_edit_help` | Guide topics (`overview`, `workflow`, `commands`, `troubleshooting`, `hosted`) **or** playbooks (`create-from-json`, `fields-html-component`, `fields-component`, \u2026) |\n\n## Customer editor pack (read first)\n\nWhen a site editor pack is deployed, these MCP resources provide **site-specific** context. Read them before creating or editing content:\n\n| Resource | Purpose |\n|----------|---------|\n| `cms-edit://customer/index` | List of all customer resources |\n| `cms-edit://customer/tasks-index` | Intent \u2192 task playbook map (filtered for this site) |\n| `cms-edit://customer/capabilities` | Machine-readable list of what this site supports |\n| `cms-edit://customer/checklist` | First-session onboarding steps |\n| `cms-edit://customer/overview` | Site name, space, staging URL, handoff rules |\n| `cms-edit://customer/routing` | Article/tag URL rules for this site |\n| `cms-edit://customer/production-site` | Production URL and how to fetch page markdown (do not guess `.md` URLs) |\n| `cms-edit://customer/components-index` | Component types and when to use each |\n| `cms-edit://customer/collections-index` | Collection types |\n| `cms-edit://customer/brand` | Brand voice and terminology (if configured) |\n| `cms-edit://customer/articles` | Article/publication playbook (if configured) |\n| `cms-edit://customer/defaults` | Featured image rules and article types (if configured) |\n| `cms-edit://customer/site-facts` | Optional canonical business facts (if configured) |\n| `cms-edit://customer/task-*` | Capability playbooks (e.g. `task-media-reuse-and-upload`) |\n\n**Workflow:** read `tasks-index` \u2192 `capabilities` \u2192 `checklist` \u2192 `overview` \u2192 `routing` \u2192 `production-site` \u2192 pick a `task-*` playbook for your goal \u2192 `components-index` \u2192 then use `cms_edit` commands.\n\n## MCP prompts\n\n| Prompt | Purpose |\n|--------|---------|\n| `cms_edit_verify` | Check version and connectivity |\n| `cms_edit_explore` | List site content and open a page |\n| `cms_edit_edit_page` | Edit a page through diff \u2192 save |\n| `cms_edit_edit_article` | Edit an article through diff \u2192 save |\n| `cms_edit_index_sync` | Build/refresh local index (assets, media, templates, taxonomy) |\n| `cms_edit_create_page` | Create a page with template selection |\n| `cms_edit_create_article` | Create an article (requires article type; featured image rules) |\n| `cms_edit_create_from_doc` | Create a page from a freeform document (infer \u2192 confirm \u2192 dry-run) |\n| `cms_edit_create_article_from_doc` | Create an article from a freeform document |\n| `cms_edit_taxonomy` | Import taxonomy entries (`create \u2026 --if-not-exists`) |\n| `cms_edit_bulk_seo` | Update SEO meta descriptions (read `task-seo-descriptions`) |\n| `cms_edit_bulk_find_replace` | Bulk find-replace in rich text across entries |\n| `cms_edit_bulk_article_tags` | Update tags on one or more articles |\n| `cms_edit_import_authors` | Create person/author entries from a list or sheet |\n| `cms_edit_media` | Find existing assets or upload new ones (reuse-first) |\n\nRead the full guide anytime via the `cms-edit://guide` resource or `cms_edit_help`.\n\n## End-to-end QA prompt\n\nFor release QA after cms-edit or editor-pack upgrades, use a **copy-paste Claude Desktop test script** (phases: connector \u2192 customer resources \u2192 discovery \u2192 session \u2192 schema \u2192 media \u2192 dry-run writes \u2192 negatives). See [e2e-test-prompt.md](./e2e-test-prompt.md) to author one per customer site. Example: Brightline `docs/cms-edit/MCP-E2E-TEST.md`.\n\n## Core workflow\n\nStandard editing flow: **open \u2192 snapshot \u2192 read \u2192 set/rtf \u2192 diff \u2192 save**\n\nEach step is a separate `cms_edit` call. Sessions persist in Redis between calls (hosted) or on disk (local). MCP auto-uses session `_mcp`.\n\n### 1. Open a page\n\n```\n[\"open\", \"--page-slug\", \"/\"]\n[\"open\", \"--page-slug\", \"/pricing\"]\n[\"open\", \"--id\", \"<entry-id>\"]\n[\"open\", \"--include-chrome\", \"--page-slug\", \"/pricing\"]\n```\n\nDefault `open` / `peek` fetch the page or article tree and the template entry, but **not** template menu/footer/navigation. Edit nav with `[\"nav\", \"open\", \"--nav-id\", \"<id>\"]` or `--nav-name` (not `--id`). Use `--include-chrome` only when you need those trees. Template `menu` is site-wide; `page.menu` overrides one page. Nested nav items are often shared \u2014 ask global vs page-specific before `set`.\n\n**Homepage (all SE Studio sites):** Contentful stores the marketing homepage slug as `index`. The live site URL is `/`. In cms-edit, `--page-slug /` and `--page-slug /index` are equivalent (both resolve to `index`). Read `cms-edit://customer/routing` for site-specific exceptions (e.g. Pedestal uses `home`).\n\n### 2. Snapshot \u2014 see the content tree\n\n```\n[\"snapshot\"]\n```\n\nOutput shows `@c0`, `@c1`, \u2026 refs for each component. Use these refs in `read`, `set`, and `rtf`.\n\n### 3. Read fields\n\n```\n[\"read\", \"@c1\"]\n[\"read\", \"@c1\", \"heading\"]\n```\n\n### 4. Edit fields\n\n```\n[\"set\", \"@c1\", \"heading\", \"New heading text\"]\n[\"rtf\", \"@c1\", \"body\", \"--content\", \"# Title\\n\\nParagraph text.\"]\n```\n\nFor rich text, prefer `--content` with inline markdown. Use `--base64` when special characters cause issues.\n\n### 5. Review and save\n\n```\n[\"diff\"]\n[\"save\"]\n```\n\nAlways run `diff` before `save`. To abandon changes: `[\"discard\"]`.\n\n## When to use Contentful UI\n\n| Task | Where |\n|------|-------|\n| Edit copy, add sections, create pages/articles | **Agent + cms-edit** (drafts) |\n| Upload new images and files | **Agent + cms-edit** \u2014 search/reuse first; raster/video via `cms_edit_media` import |\n| Publish approved drafts | **Contentful UI** |\n| Edit copy directly in Contentful | **Avoid** \u2014 use cms-edit instead |\n\ncms-edit saves **drafts only**. A colleague must **publish in Contentful** for changes to go live.\n\n## Asset upload (hosted MCP)\n\nHosted connectors have **no server filesystem** and **reject `asset upload --base64`**. Raster/video: intake then the **media pipeline**. SVG/PDF/Lottie: staged then `asset upload --staged`.\n\n| Source | When | Example |\n|--------|------|---------|\n| **Direct + pipeline** | video, or an image over 4MB | Presigned PUT, then `cms_edit_media` prepare `httpsUrls` \u2192 import (required for video) |\n| **Staged + pipeline** | image at or under 4MB | Function POST, then prepare `stagedUploadIds` \u2192 import |\n| **`--url`** | Pipeline-ready **images** only, or SVG/PDF | `[\"asset\", \"upload\", \"--url\", \"https://\u2026.blob.vercel-storage.com/ready.jpg\"]` |\n| **Staged consume** | SVG/PDF/Lottie | `asset upload --staged` |\n\n**After upload:** note the returned asset `id`, attach to the entry (`asset set @root media <id>` for person portraits), then `diff` \u2192 `save`. Upload alone does not update entries.\n\n**PNG** when transparency matters.\n\nFull workflow: `cms-edit://customer/task-media-reuse-and-upload`.\n\n### Common pitfalls (agents)\n\n| Issue | Do this |\n|-------|---------|\n| Singular Media on a component (`visual`) | `set @cN visual <mediaId> --link` \u2014 **not** `add \u2026 --target visual` |\n| Shared Drive folder has extra files | Import with `sourceNames` or `onlyWithOverrides` after catalog |\n| Prepare says no media / empty folder | Share folder **Viewer** with `media-pipeline-reader@se-media-pipeline.iam.gserviceaccount.com`, then re-prepare once |\n| MCP tool times out ~180s | `read` / `diff` / re-`catalog` before retrying the same write \u2014 server may already have saved |\n| `preview urls` has no Live Preview URL | Not a failed save. For **draft-only** pages use **siteLivePreview** (`/preview?id=`). Staging `showsDrafts` is false unless `DRAFT_ONLY`. |\n| Reuse-first import matches old fileNames | dry-run first; set `overrides[].fileName` for unique names when duplication is required |\n\n### Staged upload\n\nKeeps binary **and large text/JSON** out of MCP tool args. The agent uploads via `curl`, then passes only a short `uploadId`.\n\n1. `cms_edit_request_staged_upload` with `fileName`, `mimeType`, optional `kind` (`asset` \\| `text` \\| `json`), optional `byteLength`, optional `title`. If the wrapper schema has no `kind`, use `cms_edit` `[\"staged-upload\", \"request\", \"--kind\", \"json\", \"--file-name\", \"...\", \"--mime\", \"application/json\"]` (or `--kind text` for HtmlComponent fields).\n2. Run the returned `curlCommand` in a shell (function route: POST multipart to `uploadUrl`; direct intake: PUT `--data-binary`)\n3. Follow `consumeArgs`:\n - **asset, intake direct** (video, or an image over 4MB): media prepare with the public intake URL\n - **asset, intake function:** media prepare for jpeg/png/webp/gif at or under 4MB; **asset upload --staged** for SVG/PDF/Lottie\n - **text:** `set @ref field --staged <id>` (insert ref and field id)\n - **json:** `create from-json --staged <id>` (add `--dry-run --strict` first). Dry-run does not consume the slot.\n4. For pipeline jobs: wait \u2192 catalog \u2192 **import** (required for video). Then link and save\n\nHosted **inline** `--json` / `--content` / `--*-base64` is capped at **8192 bytes**. Function POST (JSON, text, SVG, PDF, Lottie, image \u2264 4MB): **4 MB**. Video and an image master over 4MB: **100MB** presigned PUT (`BLOB_READ_WRITE_TOKEN` on the host), then the media pipeline. Rate limit: **1000 upload URLs per user per hour**. TTL: **60 minutes**.\n\n## Featured images (articles)\n\nRead `cms-edit://customer/defaults` when present. Otherwise:\n\n1. **Custom** \u2014 set `featuredImage` or `featuredImageAssetFilename` on the article when the editor provides a specific image\n2. **Article type** \u2014 if omitted, cms-edit inherits the linked **articleType** `featuredImage`\n3. **Site default** \u2014 from `editor.defaults` in the site config (also in `defaults.json` in the editor pack)\n\nRun `[\"index\", \"sync\"]` before resolving assets by filename.\n\n## JSON payloads (filesystem vs no filesystem)\n\nHosted MCP cannot see your disk. **Do not** put 10\u201350k strings in `cms_edit` args.\n\n- **Over 8k:** write the file, `kind=json` or `kind=text`, curl, `--staged`\n- **Tiny JSON only:** `--json` on the tool call\n- Never `--file` or stdin for content\n\n## Create content\n\n### Create a page\n\n```\n[\"schema\", \"component\"]\n[\"help\", \"create-from-json\"]\n[\"create\", \"from-json\", \"--json\", \"{...}\", \"--dry-run\", \"--strict\"]\n[\"create\", \"from-json\", \"--json\", \"{...}\"]\n```\n\nUse `\"components\"` (not `\"content\"`) and nested `\"type\"` (not `\"componentType\"`). Peek a live entry or `schema <ct>` before authoring field ids.\n\nEmpty `components` fails validation. Incremental `add`/`set` is for tiny patches only.\n\n### Create an article\n\nEvery article requires an **articleType**:\n\n```\n[\"index\", \"sync\"]\n[\"list\", \"--type\", \"articleType\"]\n[\"create\", \"article\", \"--slug\", \"resources/blog/my-post\", \"--title\", \"My Post\", \"--article-type-slug\", \"resources/blog\"]\n```\n\nOr `create from-json` with `\"type\": \"article\"` and `articleTypeSlug` / `articleTypeId`.\n\nUse MCP prompt `cms_edit_create_article` for guided creation.\n\n## Common sequences\n\n### List all pages\n\n```\n[\"list\", \"--type\", \"page\"]\n```\n\n### Refresh local index (assets, media, templates, taxonomy)\n\nRun before asset filename search, media-by-filename list, or fast template/taxonomy lookup:\n\n```\n[\"index\", \"sync\"]\n[\"index\", \"status\"]\n[\"list\", \"--type\", \"template\"]\n```\n\nAsset search and media-by-filename list **require** the index. Template/taxonomy list prefers the index when built.\n\n### Explore the homepage\n\n```\n[\"open\", \"--page-slug\", \"/\"]\n[\"snapshot\"]\n[\"read\", \"@c1\"]\n```\n\n### Edit copy on a page\n\n```\n[\"open\", \"--page-slug\", \"{{EXAMPLE_SLUG}}\"]\n[\"snapshot\"]\n[\"read\", \"@c1\", \"heading\"]\n[\"set\", \"@c1\", \"heading\", \"Updated heading\"]\n[\"diff\"]\n[\"save\"]\n```\n\n## Field discovery\n\n```\n[\"schema\", \"component\"]\n[\"list\", \"--type\", \"page\"]\n[\"search\", \"pricing\"]\n```\n\n## Grok Build setup\n\nGrok connects to the same hosted MCP URL as Claude. Add to `~/.grok/config.toml`:\n\n```toml\n[mcp_servers.cms-edit-brightline]\nurl = \"https://brightline.content.se.studio/api/mcp\"\nenabled = true\n```\n\nReplace the server name and host with your site's deployment. The URL **must** end with `/api/mcp` (not the site root).\n\n**Connect:**\n\n1. In Grok, run `/mcps` and select your cms-edit server\n2. Press **`i`** to initiate OAuth (not just enable the toggle)\n3. Sign in with Contentful when the browser opens\n4. Verify with `grok mcp doctor <server-name>` or call `cms_edit_version`\n\nOAuth is two steps: Grok obtains an MCP token, then you sign in with Contentful to link your account. If the browser flashes and closes immediately, reconnect after upgrading cms-edit (loopback redirect handling).\n\n## Hosted connector rules\n\n{{HOSTED_RULES}}\n\n## Session tips\n\n- After `open`, subsequent MCP commands share session `_mcp` automatically (stored in Redis on hosted).\n- Use `--session <name>` only when juggling multiple pages \u2014 pass it **before** the subcommand on every call: `[\"--session\", \"my-work\", \"open\", \"--page-slug\", \"/\"]`.\n- Snapshot JSON includes `sessionName` and `sessionKey` for debugging.\n- If you see \"No active session\", check `/api/health` (Redis must be ok), then run `open` again. Set `LOG_CMS_SESSION=1` on Vercel and search runtime logs for `[cms-edit:session]` (`redis save ok` / `redis load hit` / `requireSession miss`).\n\n### peek vs open vs read\n\n| Goal | MCP args |\n|------|----------|\n| Edit workflow (session) | `[\"open\", \"--page-slug\", \"/\"]` then `[\"read\", \"@c0\"]` |\n| Preview tree + fields, no session | `[\"peek\", \"--page-slug\", \"/pricing\"]` or `[\"peek\", \"--id\", \"<entry-id>\"]` (JSON includes `rootFields`) |\n| Read fields by entry ID, no session | `[\"read\", \"<entry-id>\", \"--id\"]` or `[\"read\", \"<entry-id>\", \"--id\", \"heading\"]` |\n| Debug session persistence | `[\"diagnose\"]` \u2014 reports store, userId, active session key |\n\n- **`peek` is one-shot** \u2014 prints tree and **root field values** (`rootFields` in JSON). No session is created; do not chain `read @ref` afterward.\n- **`open` / `nav open` persist** the session. `preview urls /slug` follows that slug even if leftover `_mcp` is another page (JSON may include `sessionRootIgnored`).\n- **Use flat lookup flags** for `open` and `peek` \u2014 same as CLI (`--page-slug`, `--id`, etc.). See `help lookup`. `nav open` uses `--nav-id` or `--nav-name` only.\n- **`read @root`** only works after `open` (uses the active session). The hint in peek output is for terminal users who already ran `open`.\n- **Do not invent flags** \u2014 there is no `--read`, `--then`, or chained peek+read syntax. One command per `cms_edit` call.\n\n## Troubleshooting\n\n| Problem | What to do |\n|---------|------------|\n| **401 / connection failed** | Reconnect: Claude \u2192 Settings \u2192 Integrations, or Grok `/mcps` \u2192 press `i`. Complete Contentful sign-in. If Grok says \u201CFailed to get tools after auth\u201D or `auth required`, check Vercel `[cms-edit:oauth] auth_failure`. `invalid_refresh_token` is a rotated/missing MCP refresh UUID (fixed in **3.6.1+** by not rotating). `missing_contentful_token` / `invalid_contentful_token` means the CMA cache is gone \u2014 **3.5.3+** returns `invalid_token` so Grok re-runs Contentful sign-in. If it still loops, delete that server\u2019s entry from `~/.grok/mcp_credentials.json` and press `i` again. Set `LOG_CMS_OAUTH=1` for connect success traces. |\n| **No cms_edit tool** | Confirm the integration is connected under Settings \u2192 Integrations |\n| **No active session** | Do not pass `--space` on hosted. Check `/api/health` \u2014 `redis` must be ok. MCP uses `_mcp` session automatically. Manual session: `[\"--session\", \"name\", \"open\", \"--page-slug\", \"/\"]`. Fallback: `[\"read\", \"<entry-id>\", \"--id\"]` |\n| **Wrong space** | Your Contentful account must have access to this deployment's space |\n| **Check version** | Call `cms_edit_version` or `curl /api/health` and read `cmsEdit` |\n| **staged GET failed 405** | Pipeline cannot download staged files. Host must export GET `/api/staged-upload` (`@se-studio/contentful-cms` with staged GET). Bump + redeploy the host. Do not retry prepare or use the Contentful UI. |\n| **staged GET failed 404** | GET is mounted; the slot is missing, expired, or not POSTed yet. Re-stage (POST) and prepare once. Not a host bump. |\n| **pipeline_unconfigured** | `/api/health` `checks.mediaPipeline.ok` is false. Ops set `MEDIA_PIPELINE_*` on the host. Do not ask the user for a pipeline key. |\n\n## Articles\n\n**Recent articles** (by publication `date`, not last-updated):\n\n```json\n[\"list\", \"--type\", \"article\", \"--sort\", \"date\", \"-n\", \"10\"]\n```\n\nAlternative: `[\"search\", \"<keyword>\", \"--type\", \"article\"]` (also sorts by date).\n\n**Draft articles** \u2014 `peek` and `open` load drafts via CMA (not published-only). To discover drafts:\n\n```json\n[\"list\", \"--type\", \"article\", \"--sort\", \"date\"]\n[\"search\", \"<title>\", \"--type\", \"article\"]\n[\"list\", \"--type\", \"article\", \"--slug\", \"<slug>\"]\n```\n\nThen open: `[\"peek\", \"--article-slug\", \"<slug>\"]` or `[\"open\", \"--id\", \"<entry-id>\"]`. Use `--article-slug`, not `--page-slug`.\n\n**Published-only** is opt-in: `list --published` and `resolve --published` use the Delivery API index and omit never-published drafts.\n\nAfter upgrading cms-edit, run `[\"index\", \"sync\"]` once so the local index includes article `date` values (schema v4).\n\n**Index freshness on hosted MCP:** The catalog index is shared via Redis (gzipped SQLite blob). `index status` on a cold instance may show **not built** until `list`, `open`, or another index command runs \u2014 that is normal. Committed writes (`save`, `create page`, `asset upload`, \u2026) mark the index dirty; the next discovery command refreshes it. In-session `set` edits do not trigger a sync.\n\n## Command reference (cms_edit args)\n\n**Discovery:** `list --type <type>`, `search <query>`, `schema <contentType>`, `index sync`, `index status`\n\n**Reading:** `open --page-slug <slug>`, `open --id <id>`, `peek --page-slug <slug>`, `peek --id <id>`, `snapshot`, `read <ref>`, `read <ref> <field>`, `read <id> --id [field]`\n\n**Diagnostics:** `diagnose` \u2014 session store, userId, active session (after open/read issues)\n\n**Editing:** `set <ref> <field> <value>`, `rtf <ref> <field> --content \"<md>\"`, `diff`, `save`, `discard`\n\n**Creating:** `create from-json --json \u2026 --dry-run --strict`, `export from-json`, `apply from-json --json \u2026`, `create page` / `create article` for empty shells, `add` for tiny inserts\n\n**Other:** `health`, `version`, `guide [topic]`\n";
1
+ export declare const HOSTED_GUIDE_TEMPLATE = "# cms-edit MCP guide\n\nUse this guide when editing Contentful draft content through a hosted MCP connector (Claude Desktop Integrations + OAuth, or Grok Build).\n\n{{SITE_INTRO}}\n\n## Safety rules\n\ncms-edit **cannot and will not**:\n\n- Publish or unpublish entries\n- Archive or delete published entries\n\nAll `save` operations create **drafts only**. A human must review and publish in Contentful.\n\n**Assets:** Always **search and reuse** first (`index sync`, then `asset search`). Raster/video go through **`cms_edit_media`** (Drive, or intake then prepare \u2192 import). Video, and an image master over 4MB, is a presigned PUT (`intake: direct`) then prepare with `httpsUrls`. An image at or under 4MB uses a function POST then `stagedUploadIds`. Never `asset upload` jpeg/png/webp/gif/mp4, and never convert those files with local ffmpeg. SVG/PDF/Lottie: staged upload then `asset upload --staged`. **`--base64` is not supported on hosted MCP.**\n\n## MCP tools\n\n| Tool | Purpose |\n|------|---------|\n| `cms_edit` | Run any cms-edit command via an `args` array |\n| `cms_edit_request_staged_upload` | Presigned URL. `kind=asset` (default): binaries. `kind=text`: HtmlComponent fields then `set --staged`. `kind=json`: `create from-json --staged`. |\n| `cms_edit_version` | Check the installed cms-edit version (no session required) |\n| `cms_edit_help` | Guide topics (`overview`, `workflow`, `commands`, `troubleshooting`, `hosted`) **or** playbooks (`create-from-json`, `fields-html-component`, `fields-component`, \u2026) |\n\n## Customer editor pack (read first)\n\nWhen a site editor pack is deployed, these MCP resources provide **site-specific** context. Read them before creating or editing content:\n\n| Resource | Purpose |\n|----------|---------|\n| `cms-edit://customer/index` | List of all customer resources |\n| `cms-edit://customer/tasks-index` | Intent \u2192 task playbook map (filtered for this site) |\n| `cms-edit://customer/capabilities` | Machine-readable list of what this site supports |\n| `cms-edit://customer/checklist` | First-session onboarding steps |\n| `cms-edit://customer/overview` | Site name, space, staging URL, handoff rules |\n| `cms-edit://customer/routing` | Article/tag URL rules for this site |\n| `cms-edit://customer/production-site` | Production URL and how to fetch page markdown (do not guess `.md` URLs) |\n| `cms-edit://customer/components-index` | Component types and when to use each |\n| `cms-edit://customer/collections-index` | Collection types |\n| `cms-edit://customer/brand` | Brand voice and terminology (if configured) |\n| `cms-edit://customer/articles` | Article/publication playbook (if configured) |\n| `cms-edit://customer/defaults` | Featured image rules and article types (if configured) |\n| `cms-edit://customer/site-facts` | Optional canonical business facts (if configured) |\n| `cms-edit://customer/task-*` | Capability playbooks (e.g. `task-media-reuse-and-upload`) |\n\n**Workflow:** read `tasks-index` \u2192 `capabilities` \u2192 `checklist` \u2192 `overview` \u2192 `routing` \u2192 `production-site` \u2192 pick a `task-*` playbook for your goal \u2192 `components-index` \u2192 then use `cms_edit` commands.\n\n## MCP prompts\n\n| Prompt | Purpose |\n|--------|---------|\n| `cms_edit_verify` | Check version and connectivity |\n| `cms_edit_explore` | List site content and open a page |\n| `cms_edit_edit_page` | Edit a page through diff \u2192 save |\n| `cms_edit_edit_article` | Edit an article through diff \u2192 save |\n| `cms_edit_index_sync` | Build/refresh local index (assets, media, templates, taxonomy) |\n| `cms_edit_create_page` | Create a page with template selection |\n| `cms_edit_create_article` | Create an article (requires article type; featured image rules) |\n| `cms_edit_create_from_doc` | Create a page from a freeform document (infer \u2192 confirm \u2192 dry-run) |\n| `cms_edit_create_article_from_doc` | Create an article from a freeform document |\n| `cms_edit_taxonomy` | Import taxonomy entries (`create \u2026 --if-not-exists`) |\n| `cms_edit_bulk_seo` | Update SEO meta descriptions (read `task-seo-descriptions`) |\n| `cms_edit_bulk_find_replace` | Bulk find-replace in rich text across entries |\n| `cms_edit_bulk_article_tags` | Update tags on one or more articles |\n| `cms_edit_import_authors` | Create person/author entries from a list or sheet |\n| `cms_edit_media` | Find existing assets or upload new ones (reuse-first) |\n\nRead the full guide anytime via the `cms-edit://guide` resource or `cms_edit_help`.\n\n## End-to-end QA prompt\n\nFor release QA after cms-edit or editor-pack upgrades, use a **copy-paste Claude Desktop test script** (phases: connector \u2192 customer resources \u2192 discovery \u2192 session \u2192 schema \u2192 media \u2192 dry-run writes \u2192 negatives). See [e2e-test-prompt.md](./e2e-test-prompt.md) to author one per customer site. Example: Brightline `docs/cms-edit/MCP-E2E-TEST.md`.\n\n## Core workflow\n\nStandard editing flow: **open \u2192 snapshot \u2192 read \u2192 set/rtf \u2192 diff \u2192 save**\n\nEach step is a separate `cms_edit` call. Sessions persist in Redis between calls (hosted) or on disk (local). MCP auto-uses session `_mcp`.\n\n### 1. Open a page\n\n```\n[\"open\", \"--page-slug\", \"/\"]\n[\"open\", \"--page-slug\", \"/pricing\"]\n[\"open\", \"--id\", \"<entry-id>\"]\n[\"open\", \"--include-chrome\", \"--page-slug\", \"/pricing\"]\n```\n\nDefault `open` / `peek` fetch the page or article tree and the template entry, but **not** template menu/footer/navigation. Edit nav with `[\"nav\", \"open\", \"--nav-id\", \"<id>\"]` or `--nav-name` (not `--id`). Use `--include-chrome` only when you need those trees. Template `menu` is site-wide; `page.menu` overrides one page. Nested nav items are often shared \u2014 ask global vs page-specific before `set`.\n\n**Homepage (all SE Studio sites):** Contentful stores the marketing homepage slug as `index`. The live site URL is `/`. In cms-edit, `--page-slug /` and `--page-slug /index` are equivalent (both resolve to `index`). Read `cms-edit://customer/routing` for site-specific exceptions (e.g. Pedestal uses `home`).\n\n### 2. Snapshot \u2014 see the content tree\n\n```\n[\"snapshot\"]\n```\n\nOutput shows `@c0`, `@c1`, \u2026 refs for each component. Use these refs in `read`, `set`, and `rtf`.\n\n### 3. Read fields\n\n```\n[\"read\", \"@c1\"]\n[\"read\", \"@c1\", \"heading\"]\n```\n\n### 4. Edit fields\n\n```\n[\"set\", \"@c1\", \"heading\", \"New heading text\"]\n[\"rtf\", \"@c1\", \"body\", \"--content\", \"# Title\\n\\nParagraph text.\"]\n```\n\nFor rich text, prefer `--content` with inline markdown. Use `--base64` when special characters cause issues.\n\n### 5. Review and save\n\n```\n[\"diff\"]\n[\"save\"]\n```\n\nAlways run `diff` before `save`. To abandon changes: `[\"discard\"]`.\n\n## When to use Contentful UI\n\n| Task | Where |\n|------|-------|\n| Edit copy, add sections, create pages/articles | **Agent + cms-edit** (drafts) |\n| Upload new images and files | **Agent + cms-edit** \u2014 search/reuse first; raster/video via `cms_edit_media` import |\n| Publish approved drafts | **Contentful UI** |\n| Edit copy directly in Contentful | **Avoid** \u2014 use cms-edit instead |\n\ncms-edit saves **drafts only**. A colleague must **publish in Contentful** for changes to go live.\n\n## Asset upload (hosted MCP)\n\nHosted connectors have **no server filesystem** and **reject `asset upload --base64`**. Raster/video: intake then the **media pipeline**. SVG/PDF/Lottie: staged then `asset upload --staged`.\n\n| Source | When | Example |\n|--------|------|---------|\n| **Direct + pipeline** | video, or an image over 4MB | Presigned PUT, then `cms_edit_media` prepare `httpsUrls` \u2192 import (required for video) |\n| **Staged + pipeline** | image at or under 4MB | Function POST, then prepare `stagedUploadIds` \u2192 import |\n| **`--url`** | Pipeline-ready **images** only, or SVG/PDF | `[\"asset\", \"upload\", \"--url\", \"https://\u2026.blob.vercel-storage.com/ready.jpg\"]` |\n| **Staged consume** | SVG/PDF/Lottie | `asset upload --staged` |\n\n**After upload:** note the returned asset `id`, attach to the entry (`asset set @root media <id>` for person portraits), then `diff` \u2192 `save`. Upload alone does not update entries.\n\n**PNG** when transparency matters.\n\nFull workflow: `cms-edit://customer/task-media-reuse-and-upload`.\n\n### Common pitfalls (agents)\n\n| Issue | Do this |\n|-------|---------|\n| Singular Media on a component (`visual`) | `set @cN visual <mediaId> --link` \u2014 **not** `add \u2026 --target visual` |\n| Shared Drive folder has extra files | Import with `sourceNames` or `onlyWithOverrides` after catalog |\n| Prepare says no media / empty folder | Share folder **Viewer** with `media-pipeline-reader@se-media-pipeline.iam.gserviceaccount.com`, then re-prepare once |\n| MCP tool times out ~180s | `read` / `diff` / re-`catalog` before retrying the same write \u2014 server may already have saved |\n| `preview urls` has no Live Preview URL | Not a failed save. For **draft-only** pages use **siteLivePreview** (`/preview?id=`). Staging `showsDrafts` is false unless `DRAFT_ONLY`. |\n| Reuse-first import matches old fileNames | dry-run first; set `overrides[].fileName` for unique names when duplication is required |\n\n### Staged upload\n\nKeeps binary **and large text/JSON** out of MCP tool args. The agent uploads via `curl`, then passes only a short `uploadId`.\n\n1. `cms_edit_request_staged_upload` with `fileName`, `mimeType`, optional `kind` (`asset` \\| `text` \\| `json`), optional `byteLength`, optional `title`. If the wrapper schema has no `kind`, use `cms_edit` `[\"staged-upload\", \"request\", \"--kind\", \"json\", \"--file-name\", \"...\", \"--mime\", \"application/json\"]` (or `--kind text` for HtmlComponent fields).\n2. Run the returned `curlCommand` in a shell (function route: POST multipart to `uploadUrl`; direct intake: PUT `--data-binary`)\n3. Follow `consumeArgs`:\n - **asset, intake direct** (video, or an image over 4MB): media prepare with the public intake URL\n - **asset, intake function:** media prepare for jpeg/png/webp/gif at or under 4MB; **asset upload --staged** for SVG/PDF/Lottie\n - **text:** `set @ref field --staged <id>` (insert ref and field id)\n - **json:** `create from-json --staged <id>` (add `--dry-run --strict` first). Dry-run does not consume the slot.\n4. For pipeline jobs: wait \u2192 catalog \u2192 **import** (required for video). Then link and save\n\nHosted **inline** `--json` / `--content` / `--*-base64` is capped at **8192 bytes**. Function POST (JSON, text, SVG, PDF, Lottie, image \u2264 4MB): **4 MB**. Video and an image master over 4MB: **100MB** presigned PUT (`BLOB_READ_WRITE_TOKEN` on the host), then the media pipeline. Rate limit: **1000 upload URLs per user per hour**. TTL: **60 minutes**.\n\n## Featured images (articles)\n\nRead `cms-edit://customer/defaults` when present. Otherwise:\n\n1. **Custom** \u2014 set `featuredImage` or `featuredImageAssetFilename` on the article when the editor provides a specific image\n2. **Article type** \u2014 if omitted, cms-edit inherits the linked **articleType** `featuredImage`\n3. **Site default** \u2014 from `editor.defaults` in the site config (also in `defaults.json` in the editor pack)\n\nRun `[\"index\", \"sync\"]` before resolving assets by filename.\n\n## JSON payloads (filesystem vs no filesystem)\n\nHosted MCP cannot see your disk. **Do not** put 10\u201350k strings in `cms_edit` args.\n\n- **Over 8k:** write the file, `kind=json` or `kind=text`, curl, `--staged`\n- **Tiny JSON only:** `--json` on the tool call\n- Never `--file` or stdin for content\n\n## Create content\n\n### Create a page\n\n```\n[\"schema\", \"component\"]\n[\"help\", \"create-from-json\"]\n[\"create\", \"from-json\", \"--json\", \"{...}\", \"--dry-run\", \"--strict\"]\n[\"create\", \"from-json\", \"--json\", \"{...}\"]\n```\n\nUse `\"components\"` (not `\"content\"`) and nested `\"type\"` (not `\"componentType\"`). Peek a live entry or `schema <ct>` before authoring field ids.\n\nEmpty `components` fails validation. Incremental `add`/`set` is for tiny patches only.\n\n### Create an article\n\nEvery article requires an **articleType**:\n\n```\n[\"index\", \"sync\"]\n[\"list\", \"--type\", \"articleType\"]\n[\"create\", \"article\", \"--slug\", \"resources/blog/my-post\", \"--title\", \"My Post\", \"--article-type-slug\", \"resources/blog\"]\n```\n\nOr `create from-json` with `\"type\": \"article\"` and `articleTypeSlug` / `articleTypeId`.\n\nUse MCP prompt `cms_edit_create_article` for guided creation.\n\n## Common sequences\n\n### List all pages\n\n```\n[\"list\", \"--type\", \"page\"]\n```\n\n### Refresh local index (assets, media, templates, taxonomy)\n\nRun before asset filename search, media-by-filename list, or fast template/taxonomy lookup:\n\n```\n[\"index\", \"sync\"]\n[\"index\", \"status\"]\n[\"list\", \"--type\", \"template\"]\n```\n\nAsset search and media-by-filename list **require** the index. Template/taxonomy list prefers the index when built.\n\n### Explore the homepage\n\n```\n[\"open\", \"--page-slug\", \"/\"]\n[\"snapshot\"]\n[\"read\", \"@c1\"]\n```\n\n### Edit copy on a page\n\n```\n[\"open\", \"--page-slug\", \"{{EXAMPLE_SLUG}}\"]\n[\"snapshot\"]\n[\"read\", \"@c1\", \"heading\"]\n[\"set\", \"@c1\", \"heading\", \"Updated heading\"]\n[\"diff\"]\n[\"save\"]\n```\n\n## Field discovery\n\n```\n[\"schema\", \"component\"]\n[\"list\", \"--type\", \"page\"]\n[\"search\", \"pricing\"]\n```\n\n## Grok Build setup\n\nGrok connects to the same hosted MCP URL as Claude. Add to `~/.grok/config.toml`:\n\n```toml\n[mcp_servers.cms-edit-brightline]\nurl = \"https://brightline.content.se.studio/api/mcp\"\nenabled = true\n```\n\nReplace the server name and host with your site's deployment. The URL **must** end with `/api/mcp` (not the site root).\n\n**Connect:**\n\n1. In Grok, run `/mcps` and select your cms-edit server\n2. Press **`i`** to initiate OAuth (not just enable the toggle)\n3. Sign in with Contentful when the browser opens\n4. Verify with `grok mcp doctor <server-name>` or call `cms_edit_version`\n\nOAuth is two steps: Grok obtains an MCP token, then you sign in with Contentful to link your account. If the browser flashes and closes immediately, reconnect after upgrading cms-edit (loopback redirect handling).\n\n## Other clients\n\nPaste the same `/api/mcp` URL. ChatGPT: Settings \u2192 Apps & Connectors \u2192 custom MCP server \u2192 OAuth \u2192 Contentful. Draft saves need a Business, Enterprise, or Edu workspace. Recreate the connector after a tool change.\n\nCursor and VS Code: remote HTTP MCP, then OAuth. Gemini CLI: `url` under `mcpServers`.\n\nIf the client has no shell, use `search`, `fetch`, `get_editor_guide`, `set_field`, `diff_draft`, `save_draft`, and `append_text` (chunks of at most 8192 bytes). `save_draft` writes drafts only.\n\n## Hosted connector rules\n\n{{HOSTED_RULES}}\n\n## Session tips\n\n- After `open`, subsequent MCP commands share session `_mcp` automatically (stored in Redis on hosted).\n- Use `--session <name>` only when juggling multiple pages \u2014 pass it **before** the subcommand on every call: `[\"--session\", \"my-work\", \"open\", \"--page-slug\", \"/\"]`.\n- Snapshot JSON includes `sessionName` and `sessionKey` for debugging.\n- If you see \"No active session\", check `/api/health` (Redis must be ok), then run `open` again. Set `LOG_CMS_SESSION=1` on Vercel and search runtime logs for `[cms-edit:session]` (`redis save ok` / `redis load hit` / `requireSession miss`).\n\n### peek vs open vs read\n\n| Goal | MCP args |\n|------|----------|\n| Edit workflow (session) | `[\"open\", \"--page-slug\", \"/\"]` then `[\"read\", \"@c0\"]` |\n| Preview tree + fields, no session | `[\"peek\", \"--page-slug\", \"/pricing\"]` or `[\"peek\", \"--id\", \"<entry-id>\"]` (JSON includes `rootFields`) |\n| Read fields by entry ID, no session | `[\"read\", \"<entry-id>\", \"--id\"]` or `[\"read\", \"<entry-id>\", \"--id\", \"heading\"]` |\n| Debug session persistence | `[\"diagnose\"]` \u2014 reports store, userId, active session key |\n\n- **`peek` is one-shot** \u2014 prints tree and **root field values** (`rootFields` in JSON). No session is created; do not chain `read @ref` afterward.\n- **`open` / `nav open` persist** the session. `preview urls /slug` follows that slug even if leftover `_mcp` is another page (JSON may include `sessionRootIgnored`).\n- **Use flat lookup flags** for `open` and `peek` \u2014 same as CLI (`--page-slug`, `--id`, etc.). See `help lookup`. `nav open` uses `--nav-id` or `--nav-name` only.\n- **`read @root`** only works after `open` (uses the active session). The hint in peek output is for terminal users who already ran `open`.\n- **Do not invent flags** \u2014 there is no `--read`, `--then`, or chained peek+read syntax. One command per `cms_edit` call.\n\n## Troubleshooting\n\n| Problem | What to do |\n|---------|------------|\n| **401 / connection failed** | Reconnect: Claude \u2192 Settings \u2192 Integrations, or Grok `/mcps` \u2192 press `i`. Complete Contentful sign-in. If Grok says \u201CFailed to get tools after auth\u201D or `auth required`, check Vercel `[cms-edit:oauth] auth_failure`. `invalid_refresh_token` is a rotated/missing MCP refresh UUID (fixed in **3.6.1+** by not rotating). `missing_contentful_token` / `invalid_contentful_token` means the CMA cache is gone \u2014 **3.5.3+** returns `invalid_token` so Grok re-runs Contentful sign-in. If it still loops, delete that server\u2019s entry from `~/.grok/mcp_credentials.json` and press `i` again. Set `LOG_CMS_OAUTH=1` for connect success traces. |\n| **No cms_edit tool** | Confirm the integration is connected under Settings \u2192 Integrations |\n| **No active session** | Do not pass `--space` on hosted. Check `/api/health` \u2014 `redis` must be ok. MCP uses `_mcp` session automatically. Manual session: `[\"--session\", \"name\", \"open\", \"--page-slug\", \"/\"]`. Fallback: `[\"read\", \"<entry-id>\", \"--id\"]` |\n| **Wrong space** | Your Contentful account must have access to this deployment's space |\n| **Check version** | Call `cms_edit_version` or `curl /api/health` and read `cmsEdit` |\n| **staged GET failed 405** | Pipeline cannot download staged files. Host must export GET `/api/staged-upload` (`@se-studio/contentful-cms` with staged GET). Bump + redeploy the host. Do not retry prepare or use the Contentful UI. |\n| **staged GET failed 404** | GET is mounted; the slot is missing, expired, or not POSTed yet. Re-stage (POST) and prepare once. Not a host bump. |\n| **pipeline_unconfigured** | `/api/health` `checks.mediaPipeline.ok` is false. Ops set `MEDIA_PIPELINE_*` on the host. Do not ask the user for a pipeline key. |\n\n## Articles\n\n**Recent articles** (by publication `date`, not last-updated):\n\n```json\n[\"list\", \"--type\", \"article\", \"--sort\", \"date\", \"-n\", \"10\"]\n```\n\nAlternative: `[\"search\", \"<keyword>\", \"--type\", \"article\"]` (also sorts by date).\n\n**Draft articles** \u2014 `peek` and `open` load drafts via CMA (not published-only). To discover drafts:\n\n```json\n[\"list\", \"--type\", \"article\", \"--sort\", \"date\"]\n[\"search\", \"<title>\", \"--type\", \"article\"]\n[\"list\", \"--type\", \"article\", \"--slug\", \"<slug>\"]\n```\n\nThen open: `[\"peek\", \"--article-slug\", \"<slug>\"]` or `[\"open\", \"--id\", \"<entry-id>\"]`. Use `--article-slug`, not `--page-slug`.\n\n**Published-only** is opt-in: `list --published` and `resolve --published` use the Delivery API index and omit never-published drafts.\n\nAfter upgrading cms-edit, run `[\"index\", \"sync\"]` once so the local index includes article `date` values (schema v4).\n\n**Index freshness on hosted MCP:** The catalog index is shared via Redis (gzipped SQLite blob). `index status` on a cold instance may show **not built** until `list`, `open`, or another index command runs \u2014 that is normal. Committed writes (`save`, `create page`, `asset upload`, \u2026) mark the index dirty; the next discovery command refreshes it. In-session `set` edits do not trigger a sync.\n\n## Command reference (cms_edit args)\n\n**Discovery:** `list --type <type>`, `search <query>`, `schema <contentType>`, `index sync`, `index status`\n\n**Reading:** `open --page-slug <slug>`, `open --id <id>`, `peek --page-slug <slug>`, `peek --id <id>`, `snapshot`, `read <ref>`, `read <ref> <field>`, `read <id> --id [field]`\n\n**Diagnostics:** `diagnose` \u2014 session store, userId, active session (after open/read issues)\n\n**Editing:** `set <ref> <field> <value>`, `rtf <ref> <field> --content \"<md>\"`, `diff`, `save`, `discard`\n\n**Creating:** `create from-json --json \u2026 --dry-run --strict`, `export from-json`, `apply from-json --json \u2026`, `create page` / `create article` for empty shells, `add` for tiny inserts\n\n**Other:** `health`, `version`, `guide [topic]`\n";
2
2
  //# sourceMappingURL=hosted-guide.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hosted-guide.d.ts","sourceRoot":"","sources":["../../src/generated/hosted-guide.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,qBAAqB,4/nBAA6qnB,CAAC"}
1
+ {"version":3,"file":"hosted-guide.d.ts","sourceRoot":"","sources":["../../src/generated/hosted-guide.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,qBAAqB,6hpBAA0roB,CAAC"}
@@ -1,3 +1,3 @@
1
1
  // Generated by scripts/generate-embedded-assets.mjs — do not edit manually.
2
- export const HOSTED_GUIDE_TEMPLATE = "# cms-edit MCP guide\n\nUse this guide when editing Contentful draft content through a hosted MCP connector (Claude Desktop Integrations + OAuth, or Grok Build).\n\n{{SITE_INTRO}}\n\n## Safety rules\n\ncms-edit **cannot and will not**:\n\n- Publish or unpublish entries\n- Archive or delete published entries\n\nAll `save` operations create **drafts only**. A human must review and publish in Contentful.\n\n**Assets:** Always **search and reuse** first (`index sync`, then `asset search`). Raster/video go through **`cms_edit_media`** (Drive, or intake then prepare → import). Video, and an image master over 4MB, is a presigned PUT (`intake: direct`) then prepare with `httpsUrls`. An image at or under 4MB uses a function POST then `stagedUploadIds`. Never `asset upload` jpeg/png/webp/gif/mp4, and never convert those files with local ffmpeg. SVG/PDF/Lottie: staged upload then `asset upload --staged`. **`--base64` is not supported on hosted MCP.**\n\n## MCP tools\n\n| Tool | Purpose |\n|------|---------|\n| `cms_edit` | Run any cms-edit command via an `args` array |\n| `cms_edit_request_staged_upload` | Presigned URL. `kind=asset` (default): binaries. `kind=text`: HtmlComponent fields then `set --staged`. `kind=json`: `create from-json --staged`. |\n| `cms_edit_version` | Check the installed cms-edit version (no session required) |\n| `cms_edit_help` | Guide topics (`overview`, `workflow`, `commands`, `troubleshooting`, `hosted`) **or** playbooks (`create-from-json`, `fields-html-component`, `fields-component`, …) |\n\n## Customer editor pack (read first)\n\nWhen a site editor pack is deployed, these MCP resources provide **site-specific** context. Read them before creating or editing content:\n\n| Resource | Purpose |\n|----------|---------|\n| `cms-edit://customer/index` | List of all customer resources |\n| `cms-edit://customer/tasks-index` | Intent → task playbook map (filtered for this site) |\n| `cms-edit://customer/capabilities` | Machine-readable list of what this site supports |\n| `cms-edit://customer/checklist` | First-session onboarding steps |\n| `cms-edit://customer/overview` | Site name, space, staging URL, handoff rules |\n| `cms-edit://customer/routing` | Article/tag URL rules for this site |\n| `cms-edit://customer/production-site` | Production URL and how to fetch page markdown (do not guess `.md` URLs) |\n| `cms-edit://customer/components-index` | Component types and when to use each |\n| `cms-edit://customer/collections-index` | Collection types |\n| `cms-edit://customer/brand` | Brand voice and terminology (if configured) |\n| `cms-edit://customer/articles` | Article/publication playbook (if configured) |\n| `cms-edit://customer/defaults` | Featured image rules and article types (if configured) |\n| `cms-edit://customer/site-facts` | Optional canonical business facts (if configured) |\n| `cms-edit://customer/task-*` | Capability playbooks (e.g. `task-media-reuse-and-upload`) |\n\n**Workflow:** read `tasks-index` → `capabilities` → `checklist` → `overview` → `routing` → `production-site` → pick a `task-*` playbook for your goal → `components-index` → then use `cms_edit` commands.\n\n## MCP prompts\n\n| Prompt | Purpose |\n|--------|---------|\n| `cms_edit_verify` | Check version and connectivity |\n| `cms_edit_explore` | List site content and open a page |\n| `cms_edit_edit_page` | Edit a page through diff → save |\n| `cms_edit_edit_article` | Edit an article through diff → save |\n| `cms_edit_index_sync` | Build/refresh local index (assets, media, templates, taxonomy) |\n| `cms_edit_create_page` | Create a page with template selection |\n| `cms_edit_create_article` | Create an article (requires article type; featured image rules) |\n| `cms_edit_create_from_doc` | Create a page from a freeform document (infer → confirm → dry-run) |\n| `cms_edit_create_article_from_doc` | Create an article from a freeform document |\n| `cms_edit_taxonomy` | Import taxonomy entries (`create … --if-not-exists`) |\n| `cms_edit_bulk_seo` | Update SEO meta descriptions (read `task-seo-descriptions`) |\n| `cms_edit_bulk_find_replace` | Bulk find-replace in rich text across entries |\n| `cms_edit_bulk_article_tags` | Update tags on one or more articles |\n| `cms_edit_import_authors` | Create person/author entries from a list or sheet |\n| `cms_edit_media` | Find existing assets or upload new ones (reuse-first) |\n\nRead the full guide anytime via the `cms-edit://guide` resource or `cms_edit_help`.\n\n## End-to-end QA prompt\n\nFor release QA after cms-edit or editor-pack upgrades, use a **copy-paste Claude Desktop test script** (phases: connector → customer resources → discovery → session → schema → media → dry-run writes → negatives). See [e2e-test-prompt.md](./e2e-test-prompt.md) to author one per customer site. Example: Brightline `docs/cms-edit/MCP-E2E-TEST.md`.\n\n## Core workflow\n\nStandard editing flow: **open → snapshot → read → set/rtf → diff → save**\n\nEach step is a separate `cms_edit` call. Sessions persist in Redis between calls (hosted) or on disk (local). MCP auto-uses session `_mcp`.\n\n### 1. Open a page\n\n```\n[\"open\", \"--page-slug\", \"/\"]\n[\"open\", \"--page-slug\", \"/pricing\"]\n[\"open\", \"--id\", \"<entry-id>\"]\n[\"open\", \"--include-chrome\", \"--page-slug\", \"/pricing\"]\n```\n\nDefault `open` / `peek` fetch the page or article tree and the template entry, but **not** template menu/footer/navigation. Edit nav with `[\"nav\", \"open\", \"--nav-id\", \"<id>\"]` or `--nav-name` (not `--id`). Use `--include-chrome` only when you need those trees. Template `menu` is site-wide; `page.menu` overrides one page. Nested nav items are often shared — ask global vs page-specific before `set`.\n\n**Homepage (all SE Studio sites):** Contentful stores the marketing homepage slug as `index`. The live site URL is `/`. In cms-edit, `--page-slug /` and `--page-slug /index` are equivalent (both resolve to `index`). Read `cms-edit://customer/routing` for site-specific exceptions (e.g. Pedestal uses `home`).\n\n### 2. Snapshot — see the content tree\n\n```\n[\"snapshot\"]\n```\n\nOutput shows `@c0`, `@c1`, … refs for each component. Use these refs in `read`, `set`, and `rtf`.\n\n### 3. Read fields\n\n```\n[\"read\", \"@c1\"]\n[\"read\", \"@c1\", \"heading\"]\n```\n\n### 4. Edit fields\n\n```\n[\"set\", \"@c1\", \"heading\", \"New heading text\"]\n[\"rtf\", \"@c1\", \"body\", \"--content\", \"# Title\\n\\nParagraph text.\"]\n```\n\nFor rich text, prefer `--content` with inline markdown. Use `--base64` when special characters cause issues.\n\n### 5. Review and save\n\n```\n[\"diff\"]\n[\"save\"]\n```\n\nAlways run `diff` before `save`. To abandon changes: `[\"discard\"]`.\n\n## When to use Contentful UI\n\n| Task | Where |\n|------|-------|\n| Edit copy, add sections, create pages/articles | **Agent + cms-edit** (drafts) |\n| Upload new images and files | **Agent + cms-edit** — search/reuse first; raster/video via `cms_edit_media` import |\n| Publish approved drafts | **Contentful UI** |\n| Edit copy directly in Contentful | **Avoid** — use cms-edit instead |\n\ncms-edit saves **drafts only**. A colleague must **publish in Contentful** for changes to go live.\n\n## Asset upload (hosted MCP)\n\nHosted connectors have **no server filesystem** and **reject `asset upload --base64`**. Raster/video: intake then the **media pipeline**. SVG/PDF/Lottie: staged then `asset upload --staged`.\n\n| Source | When | Example |\n|--------|------|---------|\n| **Direct + pipeline** | video, or an image over 4MB | Presigned PUT, then `cms_edit_media` prepare `httpsUrls` → import (required for video) |\n| **Staged + pipeline** | image at or under 4MB | Function POST, then prepare `stagedUploadIds` → import |\n| **`--url`** | Pipeline-ready **images** only, or SVG/PDF | `[\"asset\", \"upload\", \"--url\", \"https://….blob.vercel-storage.com/ready.jpg\"]` |\n| **Staged consume** | SVG/PDF/Lottie | `asset upload --staged` |\n\n**After upload:** note the returned asset `id`, attach to the entry (`asset set @root media <id>` for person portraits), then `diff` → `save`. Upload alone does not update entries.\n\n**PNG** when transparency matters.\n\nFull workflow: `cms-edit://customer/task-media-reuse-and-upload`.\n\n### Common pitfalls (agents)\n\n| Issue | Do this |\n|-------|---------|\n| Singular Media on a component (`visual`) | `set @cN visual <mediaId> --link` — **not** `add … --target visual` |\n| Shared Drive folder has extra files | Import with `sourceNames` or `onlyWithOverrides` after catalog |\n| Prepare says no media / empty folder | Share folder **Viewer** with `media-pipeline-reader@se-media-pipeline.iam.gserviceaccount.com`, then re-prepare once |\n| MCP tool times out ~180s | `read` / `diff` / re-`catalog` before retrying the same write — server may already have saved |\n| `preview urls` has no Live Preview URL | Not a failed save. For **draft-only** pages use **siteLivePreview** (`/preview?id=`). Staging `showsDrafts` is false unless `DRAFT_ONLY`. |\n| Reuse-first import matches old fileNames | dry-run first; set `overrides[].fileName` for unique names when duplication is required |\n\n### Staged upload\n\nKeeps binary **and large text/JSON** out of MCP tool args. The agent uploads via `curl`, then passes only a short `uploadId`.\n\n1. `cms_edit_request_staged_upload` with `fileName`, `mimeType`, optional `kind` (`asset` \\| `text` \\| `json`), optional `byteLength`, optional `title`. If the wrapper schema has no `kind`, use `cms_edit` `[\"staged-upload\", \"request\", \"--kind\", \"json\", \"--file-name\", \"...\", \"--mime\", \"application/json\"]` (or `--kind text` for HtmlComponent fields).\n2. Run the returned `curlCommand` in a shell (function route: POST multipart to `uploadUrl`; direct intake: PUT `--data-binary`)\n3. Follow `consumeArgs`:\n - **asset, intake direct** (video, or an image over 4MB): media prepare with the public intake URL\n - **asset, intake function:** media prepare for jpeg/png/webp/gif at or under 4MB; **asset upload --staged** for SVG/PDF/Lottie\n - **text:** `set @ref field --staged <id>` (insert ref and field id)\n - **json:** `create from-json --staged <id>` (add `--dry-run --strict` first). Dry-run does not consume the slot.\n4. For pipeline jobs: wait → catalog → **import** (required for video). Then link and save\n\nHosted **inline** `--json` / `--content` / `--*-base64` is capped at **8192 bytes**. Function POST (JSON, text, SVG, PDF, Lottie, image ≤ 4MB): **4 MB**. Video and an image master over 4MB: **100MB** presigned PUT (`BLOB_READ_WRITE_TOKEN` on the host), then the media pipeline. Rate limit: **1000 upload URLs per user per hour**. TTL: **60 minutes**.\n\n## Featured images (articles)\n\nRead `cms-edit://customer/defaults` when present. Otherwise:\n\n1. **Custom** — set `featuredImage` or `featuredImageAssetFilename` on the article when the editor provides a specific image\n2. **Article type** — if omitted, cms-edit inherits the linked **articleType** `featuredImage`\n3. **Site default** — from `editor.defaults` in the site config (also in `defaults.json` in the editor pack)\n\nRun `[\"index\", \"sync\"]` before resolving assets by filename.\n\n## JSON payloads (filesystem vs no filesystem)\n\nHosted MCP cannot see your disk. **Do not** put 10–50k strings in `cms_edit` args.\n\n- **Over 8k:** write the file, `kind=json` or `kind=text`, curl, `--staged`\n- **Tiny JSON only:** `--json` on the tool call\n- Never `--file` or stdin for content\n\n## Create content\n\n### Create a page\n\n```\n[\"schema\", \"component\"]\n[\"help\", \"create-from-json\"]\n[\"create\", \"from-json\", \"--json\", \"{...}\", \"--dry-run\", \"--strict\"]\n[\"create\", \"from-json\", \"--json\", \"{...}\"]\n```\n\nUse `\"components\"` (not `\"content\"`) and nested `\"type\"` (not `\"componentType\"`). Peek a live entry or `schema <ct>` before authoring field ids.\n\nEmpty `components` fails validation. Incremental `add`/`set` is for tiny patches only.\n\n### Create an article\n\nEvery article requires an **articleType**:\n\n```\n[\"index\", \"sync\"]\n[\"list\", \"--type\", \"articleType\"]\n[\"create\", \"article\", \"--slug\", \"resources/blog/my-post\", \"--title\", \"My Post\", \"--article-type-slug\", \"resources/blog\"]\n```\n\nOr `create from-json` with `\"type\": \"article\"` and `articleTypeSlug` / `articleTypeId`.\n\nUse MCP prompt `cms_edit_create_article` for guided creation.\n\n## Common sequences\n\n### List all pages\n\n```\n[\"list\", \"--type\", \"page\"]\n```\n\n### Refresh local index (assets, media, templates, taxonomy)\n\nRun before asset filename search, media-by-filename list, or fast template/taxonomy lookup:\n\n```\n[\"index\", \"sync\"]\n[\"index\", \"status\"]\n[\"list\", \"--type\", \"template\"]\n```\n\nAsset search and media-by-filename list **require** the index. Template/taxonomy list prefers the index when built.\n\n### Explore the homepage\n\n```\n[\"open\", \"--page-slug\", \"/\"]\n[\"snapshot\"]\n[\"read\", \"@c1\"]\n```\n\n### Edit copy on a page\n\n```\n[\"open\", \"--page-slug\", \"{{EXAMPLE_SLUG}}\"]\n[\"snapshot\"]\n[\"read\", \"@c1\", \"heading\"]\n[\"set\", \"@c1\", \"heading\", \"Updated heading\"]\n[\"diff\"]\n[\"save\"]\n```\n\n## Field discovery\n\n```\n[\"schema\", \"component\"]\n[\"list\", \"--type\", \"page\"]\n[\"search\", \"pricing\"]\n```\n\n## Grok Build setup\n\nGrok connects to the same hosted MCP URL as Claude. Add to `~/.grok/config.toml`:\n\n```toml\n[mcp_servers.cms-edit-brightline]\nurl = \"https://brightline.content.se.studio/api/mcp\"\nenabled = true\n```\n\nReplace the server name and host with your site's deployment. The URL **must** end with `/api/mcp` (not the site root).\n\n**Connect:**\n\n1. In Grok, run `/mcps` and select your cms-edit server\n2. Press **`i`** to initiate OAuth (not just enable the toggle)\n3. Sign in with Contentful when the browser opens\n4. Verify with `grok mcp doctor <server-name>` or call `cms_edit_version`\n\nOAuth is two steps: Grok obtains an MCP token, then you sign in with Contentful to link your account. If the browser flashes and closes immediately, reconnect after upgrading cms-edit (loopback redirect handling).\n\n## Hosted connector rules\n\n{{HOSTED_RULES}}\n\n## Session tips\n\n- After `open`, subsequent MCP commands share session `_mcp` automatically (stored in Redis on hosted).\n- Use `--session <name>` only when juggling multiple pages — pass it **before** the subcommand on every call: `[\"--session\", \"my-work\", \"open\", \"--page-slug\", \"/\"]`.\n- Snapshot JSON includes `sessionName` and `sessionKey` for debugging.\n- If you see \"No active session\", check `/api/health` (Redis must be ok), then run `open` again. Set `LOG_CMS_SESSION=1` on Vercel and search runtime logs for `[cms-edit:session]` (`redis save ok` / `redis load hit` / `requireSession miss`).\n\n### peek vs open vs read\n\n| Goal | MCP args |\n|------|----------|\n| Edit workflow (session) | `[\"open\", \"--page-slug\", \"/\"]` then `[\"read\", \"@c0\"]` |\n| Preview tree + fields, no session | `[\"peek\", \"--page-slug\", \"/pricing\"]` or `[\"peek\", \"--id\", \"<entry-id>\"]` (JSON includes `rootFields`) |\n| Read fields by entry ID, no session | `[\"read\", \"<entry-id>\", \"--id\"]` or `[\"read\", \"<entry-id>\", \"--id\", \"heading\"]` |\n| Debug session persistence | `[\"diagnose\"]` — reports store, userId, active session key |\n\n- **`peek` is one-shot** — prints tree and **root field values** (`rootFields` in JSON). No session is created; do not chain `read @ref` afterward.\n- **`open` / `nav open` persist** the session. `preview urls /slug` follows that slug even if leftover `_mcp` is another page (JSON may include `sessionRootIgnored`).\n- **Use flat lookup flags** for `open` and `peek` — same as CLI (`--page-slug`, `--id`, etc.). See `help lookup`. `nav open` uses `--nav-id` or `--nav-name` only.\n- **`read @root`** only works after `open` (uses the active session). The hint in peek output is for terminal users who already ran `open`.\n- **Do not invent flags** — there is no `--read`, `--then`, or chained peek+read syntax. One command per `cms_edit` call.\n\n## Troubleshooting\n\n| Problem | What to do |\n|---------|------------|\n| **401 / connection failed** | Reconnect: Claude → Settings → Integrations, or Grok `/mcps` → press `i`. Complete Contentful sign-in. If Grok says “Failed to get tools after auth” or `auth required`, check Vercel `[cms-edit:oauth] auth_failure`. `invalid_refresh_token` is a rotated/missing MCP refresh UUID (fixed in **3.6.1+** by not rotating). `missing_contentful_token` / `invalid_contentful_token` means the CMA cache is gone — **3.5.3+** returns `invalid_token` so Grok re-runs Contentful sign-in. If it still loops, delete that server’s entry from `~/.grok/mcp_credentials.json` and press `i` again. Set `LOG_CMS_OAUTH=1` for connect success traces. |\n| **No cms_edit tool** | Confirm the integration is connected under Settings → Integrations |\n| **No active session** | Do not pass `--space` on hosted. Check `/api/health` — `redis` must be ok. MCP uses `_mcp` session automatically. Manual session: `[\"--session\", \"name\", \"open\", \"--page-slug\", \"/\"]`. Fallback: `[\"read\", \"<entry-id>\", \"--id\"]` |\n| **Wrong space** | Your Contentful account must have access to this deployment's space |\n| **Check version** | Call `cms_edit_version` or `curl /api/health` and read `cmsEdit` |\n| **staged GET failed 405** | Pipeline cannot download staged files. Host must export GET `/api/staged-upload` (`@se-studio/contentful-cms` with staged GET). Bump + redeploy the host. Do not retry prepare or use the Contentful UI. |\n| **staged GET failed 404** | GET is mounted; the slot is missing, expired, or not POSTed yet. Re-stage (POST) and prepare once. Not a host bump. |\n| **pipeline_unconfigured** | `/api/health` `checks.mediaPipeline.ok` is false. Ops set `MEDIA_PIPELINE_*` on the host. Do not ask the user for a pipeline key. |\n\n## Articles\n\n**Recent articles** (by publication `date`, not last-updated):\n\n```json\n[\"list\", \"--type\", \"article\", \"--sort\", \"date\", \"-n\", \"10\"]\n```\n\nAlternative: `[\"search\", \"<keyword>\", \"--type\", \"article\"]` (also sorts by date).\n\n**Draft articles** — `peek` and `open` load drafts via CMA (not published-only). To discover drafts:\n\n```json\n[\"list\", \"--type\", \"article\", \"--sort\", \"date\"]\n[\"search\", \"<title>\", \"--type\", \"article\"]\n[\"list\", \"--type\", \"article\", \"--slug\", \"<slug>\"]\n```\n\nThen open: `[\"peek\", \"--article-slug\", \"<slug>\"]` or `[\"open\", \"--id\", \"<entry-id>\"]`. Use `--article-slug`, not `--page-slug`.\n\n**Published-only** is opt-in: `list --published` and `resolve --published` use the Delivery API index and omit never-published drafts.\n\nAfter upgrading cms-edit, run `[\"index\", \"sync\"]` once so the local index includes article `date` values (schema v4).\n\n**Index freshness on hosted MCP:** The catalog index is shared via Redis (gzipped SQLite blob). `index status` on a cold instance may show **not built** until `list`, `open`, or another index command runs — that is normal. Committed writes (`save`, `create page`, `asset upload`, …) mark the index dirty; the next discovery command refreshes it. In-session `set` edits do not trigger a sync.\n\n## Command reference (cms_edit args)\n\n**Discovery:** `list --type <type>`, `search <query>`, `schema <contentType>`, `index sync`, `index status`\n\n**Reading:** `open --page-slug <slug>`, `open --id <id>`, `peek --page-slug <slug>`, `peek --id <id>`, `snapshot`, `read <ref>`, `read <ref> <field>`, `read <id> --id [field]`\n\n**Diagnostics:** `diagnose` — session store, userId, active session (after open/read issues)\n\n**Editing:** `set <ref> <field> <value>`, `rtf <ref> <field> --content \"<md>\"`, `diff`, `save`, `discard`\n\n**Creating:** `create from-json --json … --dry-run --strict`, `export from-json`, `apply from-json --json …`, `create page` / `create article` for empty shells, `add` for tiny inserts\n\n**Other:** `health`, `version`, `guide [topic]`\n";
2
+ export const HOSTED_GUIDE_TEMPLATE = "# cms-edit MCP guide\n\nUse this guide when editing Contentful draft content through a hosted MCP connector (Claude Desktop Integrations + OAuth, or Grok Build).\n\n{{SITE_INTRO}}\n\n## Safety rules\n\ncms-edit **cannot and will not**:\n\n- Publish or unpublish entries\n- Archive or delete published entries\n\nAll `save` operations create **drafts only**. A human must review and publish in Contentful.\n\n**Assets:** Always **search and reuse** first (`index sync`, then `asset search`). Raster/video go through **`cms_edit_media`** (Drive, or intake then prepare → import). Video, and an image master over 4MB, is a presigned PUT (`intake: direct`) then prepare with `httpsUrls`. An image at or under 4MB uses a function POST then `stagedUploadIds`. Never `asset upload` jpeg/png/webp/gif/mp4, and never convert those files with local ffmpeg. SVG/PDF/Lottie: staged upload then `asset upload --staged`. **`--base64` is not supported on hosted MCP.**\n\n## MCP tools\n\n| Tool | Purpose |\n|------|---------|\n| `cms_edit` | Run any cms-edit command via an `args` array |\n| `cms_edit_request_staged_upload` | Presigned URL. `kind=asset` (default): binaries. `kind=text`: HtmlComponent fields then `set --staged`. `kind=json`: `create from-json --staged`. |\n| `cms_edit_version` | Check the installed cms-edit version (no session required) |\n| `cms_edit_help` | Guide topics (`overview`, `workflow`, `commands`, `troubleshooting`, `hosted`) **or** playbooks (`create-from-json`, `fields-html-component`, `fields-component`, …) |\n\n## Customer editor pack (read first)\n\nWhen a site editor pack is deployed, these MCP resources provide **site-specific** context. Read them before creating or editing content:\n\n| Resource | Purpose |\n|----------|---------|\n| `cms-edit://customer/index` | List of all customer resources |\n| `cms-edit://customer/tasks-index` | Intent → task playbook map (filtered for this site) |\n| `cms-edit://customer/capabilities` | Machine-readable list of what this site supports |\n| `cms-edit://customer/checklist` | First-session onboarding steps |\n| `cms-edit://customer/overview` | Site name, space, staging URL, handoff rules |\n| `cms-edit://customer/routing` | Article/tag URL rules for this site |\n| `cms-edit://customer/production-site` | Production URL and how to fetch page markdown (do not guess `.md` URLs) |\n| `cms-edit://customer/components-index` | Component types and when to use each |\n| `cms-edit://customer/collections-index` | Collection types |\n| `cms-edit://customer/brand` | Brand voice and terminology (if configured) |\n| `cms-edit://customer/articles` | Article/publication playbook (if configured) |\n| `cms-edit://customer/defaults` | Featured image rules and article types (if configured) |\n| `cms-edit://customer/site-facts` | Optional canonical business facts (if configured) |\n| `cms-edit://customer/task-*` | Capability playbooks (e.g. `task-media-reuse-and-upload`) |\n\n**Workflow:** read `tasks-index` → `capabilities` → `checklist` → `overview` → `routing` → `production-site` → pick a `task-*` playbook for your goal → `components-index` → then use `cms_edit` commands.\n\n## MCP prompts\n\n| Prompt | Purpose |\n|--------|---------|\n| `cms_edit_verify` | Check version and connectivity |\n| `cms_edit_explore` | List site content and open a page |\n| `cms_edit_edit_page` | Edit a page through diff → save |\n| `cms_edit_edit_article` | Edit an article through diff → save |\n| `cms_edit_index_sync` | Build/refresh local index (assets, media, templates, taxonomy) |\n| `cms_edit_create_page` | Create a page with template selection |\n| `cms_edit_create_article` | Create an article (requires article type; featured image rules) |\n| `cms_edit_create_from_doc` | Create a page from a freeform document (infer → confirm → dry-run) |\n| `cms_edit_create_article_from_doc` | Create an article from a freeform document |\n| `cms_edit_taxonomy` | Import taxonomy entries (`create … --if-not-exists`) |\n| `cms_edit_bulk_seo` | Update SEO meta descriptions (read `task-seo-descriptions`) |\n| `cms_edit_bulk_find_replace` | Bulk find-replace in rich text across entries |\n| `cms_edit_bulk_article_tags` | Update tags on one or more articles |\n| `cms_edit_import_authors` | Create person/author entries from a list or sheet |\n| `cms_edit_media` | Find existing assets or upload new ones (reuse-first) |\n\nRead the full guide anytime via the `cms-edit://guide` resource or `cms_edit_help`.\n\n## End-to-end QA prompt\n\nFor release QA after cms-edit or editor-pack upgrades, use a **copy-paste Claude Desktop test script** (phases: connector → customer resources → discovery → session → schema → media → dry-run writes → negatives). See [e2e-test-prompt.md](./e2e-test-prompt.md) to author one per customer site. Example: Brightline `docs/cms-edit/MCP-E2E-TEST.md`.\n\n## Core workflow\n\nStandard editing flow: **open → snapshot → read → set/rtf → diff → save**\n\nEach step is a separate `cms_edit` call. Sessions persist in Redis between calls (hosted) or on disk (local). MCP auto-uses session `_mcp`.\n\n### 1. Open a page\n\n```\n[\"open\", \"--page-slug\", \"/\"]\n[\"open\", \"--page-slug\", \"/pricing\"]\n[\"open\", \"--id\", \"<entry-id>\"]\n[\"open\", \"--include-chrome\", \"--page-slug\", \"/pricing\"]\n```\n\nDefault `open` / `peek` fetch the page or article tree and the template entry, but **not** template menu/footer/navigation. Edit nav with `[\"nav\", \"open\", \"--nav-id\", \"<id>\"]` or `--nav-name` (not `--id`). Use `--include-chrome` only when you need those trees. Template `menu` is site-wide; `page.menu` overrides one page. Nested nav items are often shared — ask global vs page-specific before `set`.\n\n**Homepage (all SE Studio sites):** Contentful stores the marketing homepage slug as `index`. The live site URL is `/`. In cms-edit, `--page-slug /` and `--page-slug /index` are equivalent (both resolve to `index`). Read `cms-edit://customer/routing` for site-specific exceptions (e.g. Pedestal uses `home`).\n\n### 2. Snapshot — see the content tree\n\n```\n[\"snapshot\"]\n```\n\nOutput shows `@c0`, `@c1`, … refs for each component. Use these refs in `read`, `set`, and `rtf`.\n\n### 3. Read fields\n\n```\n[\"read\", \"@c1\"]\n[\"read\", \"@c1\", \"heading\"]\n```\n\n### 4. Edit fields\n\n```\n[\"set\", \"@c1\", \"heading\", \"New heading text\"]\n[\"rtf\", \"@c1\", \"body\", \"--content\", \"# Title\\n\\nParagraph text.\"]\n```\n\nFor rich text, prefer `--content` with inline markdown. Use `--base64` when special characters cause issues.\n\n### 5. Review and save\n\n```\n[\"diff\"]\n[\"save\"]\n```\n\nAlways run `diff` before `save`. To abandon changes: `[\"discard\"]`.\n\n## When to use Contentful UI\n\n| Task | Where |\n|------|-------|\n| Edit copy, add sections, create pages/articles | **Agent + cms-edit** (drafts) |\n| Upload new images and files | **Agent + cms-edit** — search/reuse first; raster/video via `cms_edit_media` import |\n| Publish approved drafts | **Contentful UI** |\n| Edit copy directly in Contentful | **Avoid** — use cms-edit instead |\n\ncms-edit saves **drafts only**. A colleague must **publish in Contentful** for changes to go live.\n\n## Asset upload (hosted MCP)\n\nHosted connectors have **no server filesystem** and **reject `asset upload --base64`**. Raster/video: intake then the **media pipeline**. SVG/PDF/Lottie: staged then `asset upload --staged`.\n\n| Source | When | Example |\n|--------|------|---------|\n| **Direct + pipeline** | video, or an image over 4MB | Presigned PUT, then `cms_edit_media` prepare `httpsUrls` → import (required for video) |\n| **Staged + pipeline** | image at or under 4MB | Function POST, then prepare `stagedUploadIds` → import |\n| **`--url`** | Pipeline-ready **images** only, or SVG/PDF | `[\"asset\", \"upload\", \"--url\", \"https://….blob.vercel-storage.com/ready.jpg\"]` |\n| **Staged consume** | SVG/PDF/Lottie | `asset upload --staged` |\n\n**After upload:** note the returned asset `id`, attach to the entry (`asset set @root media <id>` for person portraits), then `diff` → `save`. Upload alone does not update entries.\n\n**PNG** when transparency matters.\n\nFull workflow: `cms-edit://customer/task-media-reuse-and-upload`.\n\n### Common pitfalls (agents)\n\n| Issue | Do this |\n|-------|---------|\n| Singular Media on a component (`visual`) | `set @cN visual <mediaId> --link` — **not** `add … --target visual` |\n| Shared Drive folder has extra files | Import with `sourceNames` or `onlyWithOverrides` after catalog |\n| Prepare says no media / empty folder | Share folder **Viewer** with `media-pipeline-reader@se-media-pipeline.iam.gserviceaccount.com`, then re-prepare once |\n| MCP tool times out ~180s | `read` / `diff` / re-`catalog` before retrying the same write — server may already have saved |\n| `preview urls` has no Live Preview URL | Not a failed save. For **draft-only** pages use **siteLivePreview** (`/preview?id=`). Staging `showsDrafts` is false unless `DRAFT_ONLY`. |\n| Reuse-first import matches old fileNames | dry-run first; set `overrides[].fileName` for unique names when duplication is required |\n\n### Staged upload\n\nKeeps binary **and large text/JSON** out of MCP tool args. The agent uploads via `curl`, then passes only a short `uploadId`.\n\n1. `cms_edit_request_staged_upload` with `fileName`, `mimeType`, optional `kind` (`asset` \\| `text` \\| `json`), optional `byteLength`, optional `title`. If the wrapper schema has no `kind`, use `cms_edit` `[\"staged-upload\", \"request\", \"--kind\", \"json\", \"--file-name\", \"...\", \"--mime\", \"application/json\"]` (or `--kind text` for HtmlComponent fields).\n2. Run the returned `curlCommand` in a shell (function route: POST multipart to `uploadUrl`; direct intake: PUT `--data-binary`)\n3. Follow `consumeArgs`:\n - **asset, intake direct** (video, or an image over 4MB): media prepare with the public intake URL\n - **asset, intake function:** media prepare for jpeg/png/webp/gif at or under 4MB; **asset upload --staged** for SVG/PDF/Lottie\n - **text:** `set @ref field --staged <id>` (insert ref and field id)\n - **json:** `create from-json --staged <id>` (add `--dry-run --strict` first). Dry-run does not consume the slot.\n4. For pipeline jobs: wait → catalog → **import** (required for video). Then link and save\n\nHosted **inline** `--json` / `--content` / `--*-base64` is capped at **8192 bytes**. Function POST (JSON, text, SVG, PDF, Lottie, image ≤ 4MB): **4 MB**. Video and an image master over 4MB: **100MB** presigned PUT (`BLOB_READ_WRITE_TOKEN` on the host), then the media pipeline. Rate limit: **1000 upload URLs per user per hour**. TTL: **60 minutes**.\n\n## Featured images (articles)\n\nRead `cms-edit://customer/defaults` when present. Otherwise:\n\n1. **Custom** — set `featuredImage` or `featuredImageAssetFilename` on the article when the editor provides a specific image\n2. **Article type** — if omitted, cms-edit inherits the linked **articleType** `featuredImage`\n3. **Site default** — from `editor.defaults` in the site config (also in `defaults.json` in the editor pack)\n\nRun `[\"index\", \"sync\"]` before resolving assets by filename.\n\n## JSON payloads (filesystem vs no filesystem)\n\nHosted MCP cannot see your disk. **Do not** put 10–50k strings in `cms_edit` args.\n\n- **Over 8k:** write the file, `kind=json` or `kind=text`, curl, `--staged`\n- **Tiny JSON only:** `--json` on the tool call\n- Never `--file` or stdin for content\n\n## Create content\n\n### Create a page\n\n```\n[\"schema\", \"component\"]\n[\"help\", \"create-from-json\"]\n[\"create\", \"from-json\", \"--json\", \"{...}\", \"--dry-run\", \"--strict\"]\n[\"create\", \"from-json\", \"--json\", \"{...}\"]\n```\n\nUse `\"components\"` (not `\"content\"`) and nested `\"type\"` (not `\"componentType\"`). Peek a live entry or `schema <ct>` before authoring field ids.\n\nEmpty `components` fails validation. Incremental `add`/`set` is for tiny patches only.\n\n### Create an article\n\nEvery article requires an **articleType**:\n\n```\n[\"index\", \"sync\"]\n[\"list\", \"--type\", \"articleType\"]\n[\"create\", \"article\", \"--slug\", \"resources/blog/my-post\", \"--title\", \"My Post\", \"--article-type-slug\", \"resources/blog\"]\n```\n\nOr `create from-json` with `\"type\": \"article\"` and `articleTypeSlug` / `articleTypeId`.\n\nUse MCP prompt `cms_edit_create_article` for guided creation.\n\n## Common sequences\n\n### List all pages\n\n```\n[\"list\", \"--type\", \"page\"]\n```\n\n### Refresh local index (assets, media, templates, taxonomy)\n\nRun before asset filename search, media-by-filename list, or fast template/taxonomy lookup:\n\n```\n[\"index\", \"sync\"]\n[\"index\", \"status\"]\n[\"list\", \"--type\", \"template\"]\n```\n\nAsset search and media-by-filename list **require** the index. Template/taxonomy list prefers the index when built.\n\n### Explore the homepage\n\n```\n[\"open\", \"--page-slug\", \"/\"]\n[\"snapshot\"]\n[\"read\", \"@c1\"]\n```\n\n### Edit copy on a page\n\n```\n[\"open\", \"--page-slug\", \"{{EXAMPLE_SLUG}}\"]\n[\"snapshot\"]\n[\"read\", \"@c1\", \"heading\"]\n[\"set\", \"@c1\", \"heading\", \"Updated heading\"]\n[\"diff\"]\n[\"save\"]\n```\n\n## Field discovery\n\n```\n[\"schema\", \"component\"]\n[\"list\", \"--type\", \"page\"]\n[\"search\", \"pricing\"]\n```\n\n## Grok Build setup\n\nGrok connects to the same hosted MCP URL as Claude. Add to `~/.grok/config.toml`:\n\n```toml\n[mcp_servers.cms-edit-brightline]\nurl = \"https://brightline.content.se.studio/api/mcp\"\nenabled = true\n```\n\nReplace the server name and host with your site's deployment. The URL **must** end with `/api/mcp` (not the site root).\n\n**Connect:**\n\n1. In Grok, run `/mcps` and select your cms-edit server\n2. Press **`i`** to initiate OAuth (not just enable the toggle)\n3. Sign in with Contentful when the browser opens\n4. Verify with `grok mcp doctor <server-name>` or call `cms_edit_version`\n\nOAuth is two steps: Grok obtains an MCP token, then you sign in with Contentful to link your account. If the browser flashes and closes immediately, reconnect after upgrading cms-edit (loopback redirect handling).\n\n## Other clients\n\nPaste the same `/api/mcp` URL. ChatGPT: Settings → Apps & Connectors → custom MCP server → OAuth → Contentful. Draft saves need a Business, Enterprise, or Edu workspace. Recreate the connector after a tool change.\n\nCursor and VS Code: remote HTTP MCP, then OAuth. Gemini CLI: `url` under `mcpServers`.\n\nIf the client has no shell, use `search`, `fetch`, `get_editor_guide`, `set_field`, `diff_draft`, `save_draft`, and `append_text` (chunks of at most 8192 bytes). `save_draft` writes drafts only.\n\n## Hosted connector rules\n\n{{HOSTED_RULES}}\n\n## Session tips\n\n- After `open`, subsequent MCP commands share session `_mcp` automatically (stored in Redis on hosted).\n- Use `--session <name>` only when juggling multiple pages — pass it **before** the subcommand on every call: `[\"--session\", \"my-work\", \"open\", \"--page-slug\", \"/\"]`.\n- Snapshot JSON includes `sessionName` and `sessionKey` for debugging.\n- If you see \"No active session\", check `/api/health` (Redis must be ok), then run `open` again. Set `LOG_CMS_SESSION=1` on Vercel and search runtime logs for `[cms-edit:session]` (`redis save ok` / `redis load hit` / `requireSession miss`).\n\n### peek vs open vs read\n\n| Goal | MCP args |\n|------|----------|\n| Edit workflow (session) | `[\"open\", \"--page-slug\", \"/\"]` then `[\"read\", \"@c0\"]` |\n| Preview tree + fields, no session | `[\"peek\", \"--page-slug\", \"/pricing\"]` or `[\"peek\", \"--id\", \"<entry-id>\"]` (JSON includes `rootFields`) |\n| Read fields by entry ID, no session | `[\"read\", \"<entry-id>\", \"--id\"]` or `[\"read\", \"<entry-id>\", \"--id\", \"heading\"]` |\n| Debug session persistence | `[\"diagnose\"]` — reports store, userId, active session key |\n\n- **`peek` is one-shot** — prints tree and **root field values** (`rootFields` in JSON). No session is created; do not chain `read @ref` afterward.\n- **`open` / `nav open` persist** the session. `preview urls /slug` follows that slug even if leftover `_mcp` is another page (JSON may include `sessionRootIgnored`).\n- **Use flat lookup flags** for `open` and `peek` — same as CLI (`--page-slug`, `--id`, etc.). See `help lookup`. `nav open` uses `--nav-id` or `--nav-name` only.\n- **`read @root`** only works after `open` (uses the active session). The hint in peek output is for terminal users who already ran `open`.\n- **Do not invent flags** — there is no `--read`, `--then`, or chained peek+read syntax. One command per `cms_edit` call.\n\n## Troubleshooting\n\n| Problem | What to do |\n|---------|------------|\n| **401 / connection failed** | Reconnect: Claude → Settings → Integrations, or Grok `/mcps` → press `i`. Complete Contentful sign-in. If Grok says “Failed to get tools after auth” or `auth required`, check Vercel `[cms-edit:oauth] auth_failure`. `invalid_refresh_token` is a rotated/missing MCP refresh UUID (fixed in **3.6.1+** by not rotating). `missing_contentful_token` / `invalid_contentful_token` means the CMA cache is gone — **3.5.3+** returns `invalid_token` so Grok re-runs Contentful sign-in. If it still loops, delete that server’s entry from `~/.grok/mcp_credentials.json` and press `i` again. Set `LOG_CMS_OAUTH=1` for connect success traces. |\n| **No cms_edit tool** | Confirm the integration is connected under Settings → Integrations |\n| **No active session** | Do not pass `--space` on hosted. Check `/api/health` — `redis` must be ok. MCP uses `_mcp` session automatically. Manual session: `[\"--session\", \"name\", \"open\", \"--page-slug\", \"/\"]`. Fallback: `[\"read\", \"<entry-id>\", \"--id\"]` |\n| **Wrong space** | Your Contentful account must have access to this deployment's space |\n| **Check version** | Call `cms_edit_version` or `curl /api/health` and read `cmsEdit` |\n| **staged GET failed 405** | Pipeline cannot download staged files. Host must export GET `/api/staged-upload` (`@se-studio/contentful-cms` with staged GET). Bump + redeploy the host. Do not retry prepare or use the Contentful UI. |\n| **staged GET failed 404** | GET is mounted; the slot is missing, expired, or not POSTed yet. Re-stage (POST) and prepare once. Not a host bump. |\n| **pipeline_unconfigured** | `/api/health` `checks.mediaPipeline.ok` is false. Ops set `MEDIA_PIPELINE_*` on the host. Do not ask the user for a pipeline key. |\n\n## Articles\n\n**Recent articles** (by publication `date`, not last-updated):\n\n```json\n[\"list\", \"--type\", \"article\", \"--sort\", \"date\", \"-n\", \"10\"]\n```\n\nAlternative: `[\"search\", \"<keyword>\", \"--type\", \"article\"]` (also sorts by date).\n\n**Draft articles** — `peek` and `open` load drafts via CMA (not published-only). To discover drafts:\n\n```json\n[\"list\", \"--type\", \"article\", \"--sort\", \"date\"]\n[\"search\", \"<title>\", \"--type\", \"article\"]\n[\"list\", \"--type\", \"article\", \"--slug\", \"<slug>\"]\n```\n\nThen open: `[\"peek\", \"--article-slug\", \"<slug>\"]` or `[\"open\", \"--id\", \"<entry-id>\"]`. Use `--article-slug`, not `--page-slug`.\n\n**Published-only** is opt-in: `list --published` and `resolve --published` use the Delivery API index and omit never-published drafts.\n\nAfter upgrading cms-edit, run `[\"index\", \"sync\"]` once so the local index includes article `date` values (schema v4).\n\n**Index freshness on hosted MCP:** The catalog index is shared via Redis (gzipped SQLite blob). `index status` on a cold instance may show **not built** until `list`, `open`, or another index command runs — that is normal. Committed writes (`save`, `create page`, `asset upload`, …) mark the index dirty; the next discovery command refreshes it. In-session `set` edits do not trigger a sync.\n\n## Command reference (cms_edit args)\n\n**Discovery:** `list --type <type>`, `search <query>`, `schema <contentType>`, `index sync`, `index status`\n\n**Reading:** `open --page-slug <slug>`, `open --id <id>`, `peek --page-slug <slug>`, `peek --id <id>`, `snapshot`, `read <ref>`, `read <ref> <field>`, `read <id> --id [field]`\n\n**Diagnostics:** `diagnose` — session store, userId, active session (after open/read issues)\n\n**Editing:** `set <ref> <field> <value>`, `rtf <ref> <field> --content \"<md>\"`, `diff`, `save`, `discard`\n\n**Creating:** `create from-json --json … --dry-run --strict`, `export from-json`, `apply from-json --json …`, `create page` / `create article` for empty shells, `add` for tiny inserts\n\n**Other:** `health`, `version`, `guide [topic]`\n";
3
3
  //# sourceMappingURL=hosted-guide.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hosted-guide.js","sourceRoot":"","sources":["../../src/generated/hosted-guide.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,MAAM,CAAC,MAAM,qBAAqB,GAAG,0qnBAA0qnB,CAAC"}
1
+ {"version":3,"file":"hosted-guide.js","sourceRoot":"","sources":["../../src/generated/hosted-guide.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,MAAM,CAAC,MAAM,qBAAqB,GAAG,uroBAAuroB,CAAC"}
@@ -1,3 +1,3 @@
1
1
  export declare const CMS_EDIT_PACKAGE_NAME = "@se-studio/contentful-cms";
2
- export declare const CMS_EDIT_VERSION = "3.15.3";
2
+ export declare const CMS_EDIT_VERSION = "3.15.4";
3
3
  //# sourceMappingURL=version.d.ts.map
@@ -1,4 +1,4 @@
1
1
  // Generated by scripts/generate-embedded-assets.mjs — do not edit manually.
2
2
  export const CMS_EDIT_PACKAGE_NAME = "@se-studio/contentful-cms";
3
- export const CMS_EDIT_VERSION = "3.15.3";
3
+ export const CMS_EDIT_VERSION = "3.15.4";
4
4
  //# sourceMappingURL=version.js.map
@@ -19,7 +19,7 @@ export { runWithContentfulRequestStats } from '../telemetry/index.js';
19
19
  export { CMS_EDIT_PACKAGE_NAME, CMS_EDIT_VERSION, type CmsEditVersionInfo, getVersionInfo, } from '../version.js';
20
20
  export { isMcpUnauthorizedError, type McpAuthFailureReason, McpUnauthorizedError, resolveContentfulTokenFromRequest, unauthorizedMcpResponse, } from './oauth/auth.js';
21
21
  export { completeAuthorizationCodeGrant, issueAuthorizationRedirect, } from './oauth/complete.js';
22
- export { getContentfulAuthorizeUrl, getContentfulOAuthClientId, getContentfulOAuthRedirectUri, getMcpResourceUrl, getProtectedResourceMetadataUrl, getPublicOrigin, } from './oauth/config.js';
22
+ export { getContentfulAuthorizeUrl, getContentfulOAuthClientId, getContentfulOAuthRedirectUri, getMcpResourceUrl, getProtectedResourceMetadataUrl, getPublicOrigin, isMcpProtectedResourcePath, } from './oauth/config.js';
23
23
  export { handleLinkContentfulPost, handleOAuthAuthorizationServerMetadataGet, handleOAuthAuthorizeGet, handleOAuthHealthCheck, handleOAuthProtectedResourceMetadataGet, handleOAuthRegisterPost, handleOAuthTokenPost, type OAuthHandlerContext, } from './oauth/handlers.js';
24
24
  export { signMcpAccessToken, verifyMcpAccessToken } from './oauth/jwt.js';
25
25
  export { authorizationCodeGrantFailureReason, isOauthLoggingVerbose, isTransientContentfulFailure, isUnusableContentfulCacheReason, oauthLogAuthFailure, oauthLogMcpHandlerError, oauthLogVerbose, patValidationFailureReason, } from './oauth/log.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hosted/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hosted/index.ts"],"names":[],"mappings":"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"}
@@ -18,7 +18,7 @@ export { runWithContentfulRequestStats } from '../telemetry/index.js';
18
18
  export { CMS_EDIT_PACKAGE_NAME, CMS_EDIT_VERSION, getVersionInfo, } from '../version.js';
19
19
  export { isMcpUnauthorizedError, McpUnauthorizedError, resolveContentfulTokenFromRequest, unauthorizedMcpResponse, } from './oauth/auth.js';
20
20
  export { completeAuthorizationCodeGrant, issueAuthorizationRedirect, } from './oauth/complete.js';
21
- export { getContentfulAuthorizeUrl, getContentfulOAuthClientId, getContentfulOAuthRedirectUri, getMcpResourceUrl, getProtectedResourceMetadataUrl, getPublicOrigin, } from './oauth/config.js';
21
+ export { getContentfulAuthorizeUrl, getContentfulOAuthClientId, getContentfulOAuthRedirectUri, getMcpResourceUrl, getProtectedResourceMetadataUrl, getPublicOrigin, isMcpProtectedResourcePath, } from './oauth/config.js';
22
22
  export { handleLinkContentfulPost, handleOAuthAuthorizationServerMetadataGet, handleOAuthAuthorizeGet, handleOAuthHealthCheck, handleOAuthProtectedResourceMetadataGet, handleOAuthRegisterPost, handleOAuthTokenPost, } from './oauth/handlers.js';
23
23
  export { signMcpAccessToken, verifyMcpAccessToken } from './oauth/jwt.js';
24
24
  export { authorizationCodeGrantFailureReason, isOauthLoggingVerbose, isTransientContentfulFailure, isUnusableContentfulCacheReason, oauthLogAuthFailure, oauthLogMcpHandlerError, oauthLogVerbose, patValidationFailureReason, } from './oauth/log.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hosted/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EAEtB,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAElB,2BAA2B,EAE3B,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EACL,4BAA4B,EAC5B,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAsB,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EAAgC,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAC9F,OAAO,EAEL,eAAe,EACf,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,qBAAqB,EACrB,8BAA8B,GAC/B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAGL,cAAc,EACd,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAC7F,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EACL,eAAe,GAGhB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAC7F,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAEhB,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,sBAAsB,EAEtB,oBAAoB,EACpB,iCAAiC,EACjC,uBAAuB,GACxB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,8BAA8B,EAC9B,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,yBAAyB,EACzB,0BAA0B,EAC1B,6BAA6B,EAC7B,iBAAiB,EACjB,+BAA+B,EAC/B,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,wBAAwB,EACxB,yCAAyC,EACzC,uBAAuB,EACvB,sBAAsB,EACtB,uCAAuC,EACvC,uBAAuB,EACvB,oBAAoB,GAErB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EACL,mCAAmC,EACnC,qBAAqB,EACrB,4BAA4B,EAC5B,+BAA+B,EAC/B,mBAAmB,EACnB,uBAAuB,EACvB,eAAe,EACf,0BAA0B,GAC3B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,8BAA8B,EAC9B,uBAAuB,EACvB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,GAEvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAGL,kBAAkB,EAClB,gBAAgB,EAIhB,0BAA0B,EAE1B,eAAe,GAChB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hosted/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EAEtB,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAElB,2BAA2B,EAE3B,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EACL,4BAA4B,EAC5B,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAsB,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EAAgC,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAC9F,OAAO,EAEL,eAAe,EACf,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,qBAAqB,EACrB,8BAA8B,GAC/B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAGL,cAAc,EACd,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAC7F,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EACL,eAAe,GAGhB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAC7F,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAEhB,cAAc,GACf,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,sBAAsB,EAEtB,oBAAoB,EACpB,iCAAiC,EACjC,uBAAuB,GACxB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,8BAA8B,EAC9B,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,yBAAyB,EACzB,0BAA0B,EAC1B,6BAA6B,EAC7B,iBAAiB,EACjB,+BAA+B,EAC/B,eAAe,EACf,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,wBAAwB,EACxB,yCAAyC,EACzC,uBAAuB,EACvB,sBAAsB,EACtB,uCAAuC,EACvC,uBAAuB,EACvB,oBAAoB,GAErB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EACL,mCAAmC,EACnC,qBAAqB,EACrB,4BAA4B,EAC5B,+BAA+B,EAC/B,mBAAmB,EACnB,uBAAuB,EACvB,eAAe,EACf,0BAA0B,GAC3B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,8BAA8B,EAC9B,uBAAuB,EACvB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,GAEvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAGL,kBAAkB,EAClB,gBAAgB,EAIhB,0BAA0B,EAE1B,eAAe,GAChB,MAAM,kBAAkB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"CmsEditPage.d.ts","sourceRoot":"","sources":["../../../../src/hosted/next/pages/CmsEditPage.tsx"],"names":[],"mappings":"AAeA,wBAA8B,qBAAqB,yCAqLlD"}
1
+ {"version":3,"file":"CmsEditPage.d.ts","sourceRoot":"","sources":["../../../../src/hosted/next/pages/CmsEditPage.tsx"],"names":[],"mappings":"AAeA,wBAA8B,qBAAqB,yCAoNlD"}
@@ -19,6 +19,6 @@ export default async function CmsEditOnboardingPage() {
19
19
  const connectorName = `cms-edit (${displayName})`;
20
20
  const installUrl = buildClaudeConnectorInstallUrl(mcpUrl, connectorName);
21
21
  const canUseInstallLink = isPublicHttpsMcpUrl(mcpUrl);
22
- return (_jsxs(HostedPageShell, { displayName: displayName, version: version, children: [_jsxs("h1", { style: h1Style, children: ["cms-edit for ", displayName] }), _jsx("p", { children: "Edit Contentful draft content from Claude. Sign in with your Contentful account \u2014 no tokens or command line required." }), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Quick connect (recommended)" }), canUseInstallLink ? (_jsxs(_Fragment, { children: [_jsx("p", { children: "Click the button below. It opens Claude with the connector name and URL prefilled \u2014 you just confirm and sign in with Contentful." }), _jsx("p", { children: _jsx("a", { href: installUrl, style: buttonStyle, children: "Connect to Claude" }) }), _jsxs("p", { style: mutedStyle, children: ["Works in Claude Desktop and claude.ai (same account). Shortcut:", ' ', _jsx("a", { href: "/connect", style: linkStyle, children: "/connect" })] })] })) : (_jsx("p", { children: "The one-click link requires a public HTTPS URL. For local dev, add the connector manually below or use Claude Code." }))] }), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Manual setup" }), _jsxs("ol", { children: [_jsxs("li", { children: ["Install", ' ', _jsx("a", { href: "https://claude.ai/download", style: linkStyle, children: "Claude Desktop" }), ' ', "if needed"] }), _jsxs("li", { children: ["Open ", _jsx("strong", { children: "Customize \u2192 Connectors" }), " (or Settings \u2192 Integrations in some versions)"] }), _jsxs("li", { children: ["Click ", _jsx("strong", { children: "Add custom connector" })] }), _jsxs("li", { children: ["Paste this URL, then ", _jsx("strong", { children: "Connect" }), " and sign in with Contentful:"] })] }), _jsx("code", { style: codeStyle, children: mcpUrl })] }), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Site playbooks" }), _jsxs("p", { children: ["Site-specific rules for ", displayName, " (articles, routing, components, and more). Claude Integrations cannot read ", _jsx("code", { children: "cms-edit://customer/*" }), " MCP resources \u2014 use the", ' ', _jsx("strong", { children: "cms_edit_customer" }), " tool or the URLs below."] }), _jsxs("ul", { children: [_jsxs("li", { children: [_jsx("strong", { children: "Start:" }), ' ', _jsx("a", { href: "/cms-edit/playbooks/tasks-index", style: linkStyle, children: "tasks-index" }), ' ', "\u2014 intent \u2192 task playbooks"] }), _jsxs("li", { children: [_jsx("a", { href: "/cms-edit/playbooks/capabilities", style: linkStyle, children: "capabilities" }), ' ', "\u00B7", ' ', _jsx("a", { href: "/cms-edit/playbooks/checklist", style: linkStyle, children: "checklist" })] }), _jsxs("li", { children: [_jsx("a", { href: "/cms-edit/playbooks", style: linkStyle, children: "Browse all playbooks" }), ' ', "\u00B7", ' ', _jsx("a", { href: "/api/customer", style: linkStyle, children: "JSON index" })] }), _jsxs("li", { children: ["Examples:", ' ', _jsx("a", { href: "/api/customer/overview", style: linkStyle, children: "overview" }), ",", ' ', _jsx("a", { href: "/api/customer/routing", style: linkStyle, children: "routing" }), ",", ' ', _jsx("a", { href: "/api/customer/articles", style: linkStyle, children: "articles" })] })] }), _jsx("blockquote", { style: calloutStyle, children: "In Claude: read tasks-index first, then the matching task-* playbook. Use cms_edit_customer with resource \"tasks-index\" or cms_edit [\"customer\", \"tasks-index\"]." })] }), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Verify" }), _jsx("p", { children: "Start a new conversation and ask:" }), _jsx("blockquote", { style: calloutStyle, children: "Read the cms-edit guide, then tasks-index, and verify the connection." })] }), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Common tasks" }), _jsx("p", { children: "Examples you can paste into Claude (or use the matching MCP prompts):" }), _jsxs("ul", { children: [_jsxs("li", { children: [_jsx("strong", { children: "Edit a page:" }), " \u201CUpdate the hero heading on /about-us\u201D"] }), _jsxs("li", { children: [_jsx("strong", { children: "Create an article:" }), " \u201CCreate a new blog article titled \u2026\u201D (Claude will ask for the article type)"] }), _jsxs("li", { children: [_jsx("strong", { children: "Go live:" }), " After Claude saves a draft, open Contentful and publish \u2014 cms-edit does not publish for you"] })] }), _jsx("p", { style: mutedStyle, children: "Use Contentful only to publish and upload images. Do all copy editing in Claude." })] }), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Troubleshooting" }), _jsxs("ul", { children: [_jsxs("li", { children: [_jsx("strong", { children: "Connection stopped working?" }), " Open Customize \u2192 Connectors and click", ' ', _jsx("strong", { children: "Connect" }), " again."] }), _jsxs("li", { children: [_jsx("strong", { children: "Wrong space?" }), " Your Contentful account must have access to this site's space."] }), _jsxs("li", { children: ["Health check: ", _jsx("code", { children: "/api/health" })] })] })] })] }));
22
+ return (_jsxs(HostedPageShell, { displayName: displayName, version: version, children: [_jsxs("h1", { style: h1Style, children: ["cms-edit for ", displayName] }), _jsx("p", { children: "Edit Contentful draft content from Claude. Sign in with your Contentful account \u2014 no tokens or command line required." }), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Quick connect (recommended)" }), canUseInstallLink ? (_jsxs(_Fragment, { children: [_jsx("p", { children: "Click the button below. It opens Claude with the connector name and URL prefilled \u2014 you just confirm and sign in with Contentful." }), _jsx("p", { children: _jsx("a", { href: installUrl, style: buttonStyle, children: "Connect to Claude" }) }), _jsxs("p", { style: mutedStyle, children: ["Works in Claude Desktop and claude.ai (same account). Shortcut:", ' ', _jsx("a", { href: "/connect", style: linkStyle, children: "/connect" })] })] })) : (_jsx("p", { children: "The one-click link requires a public HTTPS URL. For local dev, add the connector manually below or use Claude Code." }))] }), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Manual setup" }), _jsxs("ol", { children: [_jsxs("li", { children: ["Install", ' ', _jsx("a", { href: "https://claude.ai/download", style: linkStyle, children: "Claude Desktop" }), ' ', "if needed"] }), _jsxs("li", { children: ["Open ", _jsx("strong", { children: "Customize \u2192 Connectors" }), " (or Settings \u2192 Integrations in some versions)"] }), _jsxs("li", { children: ["Click ", _jsx("strong", { children: "Add custom connector" })] }), _jsxs("li", { children: ["Paste this URL, then ", _jsx("strong", { children: "Connect" }), " and sign in with Contentful:"] })] }), _jsx("code", { style: codeStyle, children: mcpUrl })] }), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "ChatGPT, Cursor, and other clients" }), _jsx("p", { children: "The same MCP URL works in any client that can call a remote MCP server and sign in with OAuth. Paste it, choose OAuth, then sign in with Contentful." }), _jsxs("ul", { children: [_jsxs("li", { children: [_jsx("strong", { children: "ChatGPT:" }), " Settings \u2192 Apps & Connectors \u2192 create a custom MCP server. Draft saves need a Business, Enterprise, or Edu workspace. After a cms-edit upgrade, remove the connector and add it again so ChatGPT reloads the tool list."] }), _jsxs("li", { children: [_jsx("strong", { children: "Cursor / VS Code:" }), " add the URL as a remote HTTP MCP server and complete the Contentful sign-in."] }), _jsxs("li", { children: [_jsx("strong", { children: "Grok:" }), " put the URL in ", _jsx("code", { children: "~/.grok/config.toml" }), ", then", ' ', _jsx("code", { children: "/mcps" }), " and press ", _jsx("code", { children: "i" }), "."] }), _jsxs("li", { children: [_jsx("strong", { children: "Gemini CLI:" }), " set ", _jsx("code", { children: "mcpServers" }), " ", _jsx("code", { children: "url" }), " to this MCP URL."] })] }), _jsx("p", { style: mutedStyle, children: "Clients without a shell can use search, fetch, set_field, and append_text. Nothing here publishes. A person still publishes in Contentful." })] }), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Site playbooks" }), _jsxs("p", { children: ["Site-specific rules for ", displayName, " (articles, routing, components, and more). Claude Integrations cannot read ", _jsx("code", { children: "cms-edit://customer/*" }), " MCP resources \u2014 use the", ' ', _jsx("strong", { children: "cms_edit_customer" }), " tool or the URLs below."] }), _jsxs("ul", { children: [_jsxs("li", { children: [_jsx("strong", { children: "Start:" }), ' ', _jsx("a", { href: "/cms-edit/playbooks/tasks-index", style: linkStyle, children: "tasks-index" }), ' ', "\u2014 intent \u2192 task playbooks"] }), _jsxs("li", { children: [_jsx("a", { href: "/cms-edit/playbooks/capabilities", style: linkStyle, children: "capabilities" }), ' ', "\u00B7", ' ', _jsx("a", { href: "/cms-edit/playbooks/checklist", style: linkStyle, children: "checklist" })] }), _jsxs("li", { children: [_jsx("a", { href: "/cms-edit/playbooks", style: linkStyle, children: "Browse all playbooks" }), ' ', "\u00B7", ' ', _jsx("a", { href: "/api/customer", style: linkStyle, children: "JSON index" })] }), _jsxs("li", { children: ["Examples:", ' ', _jsx("a", { href: "/api/customer/overview", style: linkStyle, children: "overview" }), ",", ' ', _jsx("a", { href: "/api/customer/routing", style: linkStyle, children: "routing" }), ",", ' ', _jsx("a", { href: "/api/customer/articles", style: linkStyle, children: "articles" })] })] }), _jsx("blockquote", { style: calloutStyle, children: "In Claude: read tasks-index first, then the matching task-* playbook. Use cms_edit_customer with resource \"tasks-index\" or cms_edit [\"customer\", \"tasks-index\"]." })] }), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Verify" }), _jsx("p", { children: "Start a new conversation and ask:" }), _jsx("blockquote", { style: calloutStyle, children: "Read the cms-edit guide, then tasks-index, and verify the connection." })] }), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Common tasks" }), _jsx("p", { children: "Examples you can paste into Claude (or use the matching MCP prompts):" }), _jsxs("ul", { children: [_jsxs("li", { children: [_jsx("strong", { children: "Edit a page:" }), " \u201CUpdate the hero heading on /about-us\u201D"] }), _jsxs("li", { children: [_jsx("strong", { children: "Create an article:" }), " \u201CCreate a new blog article titled \u2026\u201D (Claude will ask for the article type)"] }), _jsxs("li", { children: [_jsx("strong", { children: "Go live:" }), " After Claude saves a draft, open Contentful and publish \u2014 cms-edit does not publish for you"] })] }), _jsx("p", { style: mutedStyle, children: "Use Contentful only to publish and upload images. Do all copy editing in Claude." })] }), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Troubleshooting" }), _jsxs("ul", { children: [_jsxs("li", { children: [_jsx("strong", { children: "Connection stopped working?" }), " Open Customize \u2192 Connectors and click", ' ', _jsx("strong", { children: "Connect" }), " again."] }), _jsxs("li", { children: [_jsx("strong", { children: "Wrong space?" }), " Your Contentful account must have access to this site's space."] }), _jsxs("li", { children: ["Health check: ", _jsx("code", { children: "/api/health" })] })] })] })] }));
23
23
  }
24
24
  //# sourceMappingURL=CmsEditPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CmsEditPage.js","sourceRoot":"","sources":["../../../../src/hosted/next/pages/CmsEditPage.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CmsEditPage.js","sourceRoot":"","sources":["../../../../src/hosted/next/pages/CmsEditPage.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"HomePage.d.ts","sourceRoot":"","sources":["../../../../src/hosted/next/pages/HomePage.tsx"],"names":[],"mappings":"AAeA,wBAA8B,QAAQ,yCA2HrC"}
1
+ {"version":3,"file":"HomePage.d.ts","sourceRoot":"","sources":["../../../../src/hosted/next/pages/HomePage.tsx"],"names":[],"mappings":"AAeA,wBAA8B,QAAQ,yCAwIrC"}
@@ -32,6 +32,6 @@ export default async function HomePage() {
32
32
  },
33
33
  },
34
34
  }, null, 2);
35
- return (_jsxs(HostedPageShell, { displayName: displayName, version: version, children: [_jsxs("h1", { style: h1Style, children: ["cms-edit for ", displayName] }), _jsx("p", { children: "Hosted MCP server for editing Contentful draft content. Sign in with your Contentful account via OAuth \u2014 no personal access token required." }), canUseInstallLink && (_jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Connect to Claude" }), _jsx("p", { children: "One-click setup \u2014 opens Claude with the connector prefilled. Confirm, then sign in with Contentful." }), _jsx("p", { children: _jsx("a", { href: installUrl, style: buttonStyle, children: "Connect to Claude" }) }), _jsxs("p", { style: mutedStyle, children: ["Or use", ' ', _jsx("a", { href: "/connect", style: linkStyle, children: "/connect" }), ' ', "\u00B7 Editor guide:", ' ', _jsx("a", { href: "/cms-edit", style: linkStyle, children: "/cms-edit" }), ' ', "\u00B7 Task playbooks:", ' ', _jsx("a", { href: "/cms-edit/playbooks/tasks-index", style: linkStyle, children: "tasks-index" })] })] })), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Deployment" }), _jsxs("ul", { children: [_jsxs("li", { children: [_jsx("strong", { children: "Project:" }), " ", projectKey] }), _jsxs("li", { children: [_jsx("strong", { children: "Space ID:" }), " ", spaceId] }), _jsxs("li", { children: [_jsx("strong", { children: "cms-edit version:" }), " ", version] }), _jsxs("li", { children: [_jsx("strong", { children: "MCP URL:" }), " ", _jsx("code", { children: mcpUrl })] }), _jsxs("li", { children: [_jsx("strong", { children: "Health:" }), ' ', _jsx("a", { href: "/api/health", style: linkStyle, children: "/api/health" })] })] })] }), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Claude Desktop (manual)" }), _jsxs("p", { children: [_jsx("strong", { children: "Customize \u2192 Connectors \u2192 Add custom connector" }), " \u2014 paste the MCP URL, then Connect and sign in with Contentful."] })] }), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Claude Code" }), _jsx("p", { children: "Add the server from your terminal (local scope \u2014 this project only):" }), _jsx("code", { style: codeStyle, children: claudeCodeCommand }), _jsxs("p", { children: ["Then run ", _jsx("code", { children: "/mcp" }), " in Claude Code and complete OAuth + Contentful sign-in."] }), _jsx("code", { style: codeStyle, children: mcpJson })] }), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Verify" }), _jsx("blockquote", { style: calloutStyle, children: "Read the cms-edit guide and tasks-index, then verify the connection." })] })] }));
35
+ return (_jsxs(HostedPageShell, { displayName: displayName, version: version, children: [_jsxs("h1", { style: h1Style, children: ["cms-edit for ", displayName] }), _jsx("p", { children: "Hosted MCP server for editing Contentful draft content. Sign in with your Contentful account via OAuth \u2014 no personal access token required." }), canUseInstallLink && (_jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Connect to Claude" }), _jsx("p", { children: "One-click setup \u2014 opens Claude with the connector prefilled. Confirm, then sign in with Contentful." }), _jsx("p", { children: _jsx("a", { href: installUrl, style: buttonStyle, children: "Connect to Claude" }) }), _jsxs("p", { style: mutedStyle, children: ["Or use", ' ', _jsx("a", { href: "/connect", style: linkStyle, children: "/connect" }), ' ', "\u00B7 Editor guide:", ' ', _jsx("a", { href: "/cms-edit", style: linkStyle, children: "/cms-edit" }), ' ', "\u00B7 Task playbooks:", ' ', _jsx("a", { href: "/cms-edit/playbooks/tasks-index", style: linkStyle, children: "tasks-index" })] })] })), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Deployment" }), _jsxs("ul", { children: [_jsxs("li", { children: [_jsx("strong", { children: "Project:" }), " ", projectKey] }), _jsxs("li", { children: [_jsx("strong", { children: "Space ID:" }), " ", spaceId] }), _jsxs("li", { children: [_jsx("strong", { children: "cms-edit version:" }), " ", version] }), _jsxs("li", { children: [_jsx("strong", { children: "MCP URL:" }), " ", _jsx("code", { children: mcpUrl })] }), _jsxs("li", { children: [_jsx("strong", { children: "Health:" }), ' ', _jsx("a", { href: "/api/health", style: linkStyle, children: "/api/health" })] })] })] }), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Claude Desktop (manual)" }), _jsxs("p", { children: [_jsx("strong", { children: "Customize \u2192 Connectors \u2192 Add custom connector" }), " \u2014 paste the MCP URL, then Connect and sign in with Contentful."] })] }), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Claude Code" }), _jsx("p", { children: "Add the server from your terminal (local scope \u2014 this project only):" }), _jsx("code", { style: codeStyle, children: claudeCodeCommand }), _jsxs("p", { children: ["Then run ", _jsx("code", { children: "/mcp" }), " in Claude Code and complete OAuth + Contentful sign-in."] }), _jsx("code", { style: codeStyle, children: mcpJson })] }), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Other MCP clients" }), _jsxs("p", { children: ["ChatGPT, Cursor, VS Code, Grok, and Gemini CLI use this same URL with OAuth. Editor steps are on", ' ', _jsx("a", { href: "/cms-edit", style: linkStyle, children: "/cms-edit" }), ". ChatGPT draft writes need a Business, Enterprise, or Edu workspace, and the connector must be recreated after a tool change."] })] }), _jsxs("section", { style: sectionStyle, children: [_jsx("h2", { style: h2Style, children: "Verify" }), _jsx("blockquote", { style: calloutStyle, children: "Read the cms-edit guide and tasks-index, then verify the connection." })] })] }));
36
36
  }
37
37
  //# sourceMappingURL=HomePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"HomePage.js","sourceRoot":"","sources":["../../../../src/hosted/next/pages/HomePage.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"HomePage.js","sourceRoot":"","sources":["../../../../src/hosted/next/pages/HomePage.tsx"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  export declare function GET(request: Request): Promise<Response>;
2
2
  export declare function POST(request: Request): Promise<Response>;
3
3
  export declare function DELETE(request: Request): Promise<Response>;
4
+ export declare function OPTIONS(): Promise<Response>;
4
5
  //# sourceMappingURL=mcp.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../../../src/hosted/next/routes/mcp.ts"],"names":[],"mappings":"AA2CA,wBAAsB,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAE7D;AAED,wBAAsB,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAE9D;AAED,wBAAsB,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAEhE"}
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../../../src/hosted/next/routes/mcp.ts"],"names":[],"mappings":"AA4CA,wBAAsB,GAAG,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAE7D;AAED,wBAAsB,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAE9D;AAED,wBAAsB,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAEhE;AAED,wBAAsB,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,CAEjD"}