@neopress/mcp 1.6.0 → 1.6.1
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.
- package/dist/bin.cjs +16 -15
- package/dist/http-bin.cjs +16 -15
- package/dist/index.d.ts +9 -2
- package/dist/index.js +16 -15
- package/package.json +1 -1
package/dist/bin.cjs
CHANGED
|
@@ -20421,9 +20421,8 @@ Use these rules before generating pages, collection schemas, entries, forms, or
|
|
|
20421
20421
|
|
|
20422
20422
|
## Operating boundary
|
|
20423
20423
|
|
|
20424
|
-
-
|
|
20425
|
-
-
|
|
20426
|
-
- MCP is available as local stdio and remote Streamable HTTP over the first-party SDK/API.
|
|
20424
|
+
- Connect the remote MCP server and sign in with your Neopress account through OAuth.
|
|
20425
|
+
- MCP is available on Launch and above. Your site role controls which actions you can perform.
|
|
20427
20426
|
- MCP is a Neopress contract adapter, not a reference crawler or managed page generator.
|
|
20428
20427
|
- The host coding agent should perform \`r.jina.ai\` markdown fetches, browser screenshots, DOM/CSS/SVG/background-image extraction, reference analysis, and TSX authoring with its own tools and tokens.
|
|
20429
20428
|
- Use MCP to read/write Neopress resources, upload or register assets, compile, publish, and verify. Do not expect MCP to spend Neopress server-side LLM tokens for reference analysis or page generation.
|
|
@@ -20437,9 +20436,9 @@ Use these rules before generating pages, collection schemas, entries, forms, or
|
|
|
20437
20436
|
|
|
20438
20437
|
## Cache
|
|
20439
20438
|
|
|
20440
|
-
- Site publish invalidates site/layout/collection reader cache tags in the
|
|
20439
|
+
- Site publish invalidates site/layout/collection reader cache tags in the environment connected to MCP.
|
|
20441
20440
|
- Entry publish/unpublish invalidates entry reader cache when production visibility changes.
|
|
20442
|
-
- A localhost publish does not invalidate production reader cache. For production validation, publish through the production
|
|
20441
|
+
- A localhost publish does not invalidate production reader cache. For production validation, publish through the production MCP server and verify the live URL.
|
|
20443
20442
|
|
|
20444
20443
|
## Analytics and autopilot
|
|
20445
20444
|
|
|
@@ -20452,7 +20451,7 @@ Use these rules before generating pages, collection schemas, entries, forms, or
|
|
|
20452
20451
|
|
|
20453
20452
|
- Layout owns header, footer, global CSS, and 404. Page TSX starts at page content.
|
|
20454
20453
|
- Generated page TSX is sandboxed. Do not import Supabase, create API clients, read env vars, use filesystem/process APIs, or assume arbitrary npm packages.
|
|
20455
|
-
- Use allowed runtime packages only: React/Next basics, react-dom (createPortal), shadcn UI imports, lucide-react, @base-ui/react/drawer, @base-ui/react/dialog, @base-ui/react/accordion, @base-ui/react/switch, @base-ui/react/tabs, @base-ui/react/select, @neopress/youtube, @neopress/map, clsx, class-variance-authority, tailwind-merge, motion/react (never \`framer-motion\` — old package name, not on the allowlist), motion-plus/react (Motion+ premium components: Ticker, Carousel, Cursor, AnimateNumber, AnimateText, Typewriter, ScrambleText, Curtains), @paper-design/shaders-react, gsap (including \`gsap/ScrollTrigger\`, driven via \`@gsap/react\`'s \`useGSAP\`), react-hook-form, zod, @hookform/resolvers, @hookform/resolvers/zod, @neopress/content, @neopress/routing, @neopress/i18n, and @neopress/forms.
|
|
20454
|
+
- Use allowed runtime packages only: React/Next basics, react-dom (createPortal), shadcn UI imports, lucide-react, @base-ui/react/drawer, @base-ui/react/dialog, @base-ui/react/accordion, @base-ui/react/switch, @base-ui/react/tabs, @base-ui/react/select, @neopress/youtube, @neopress/map, clsx, class-variance-authority, tailwind-merge, motion/react (never \`framer-motion\` — old package name, not on the allowlist), motion-plus/react (Motion+ premium components: Ticker, Carousel, Cursor, AnimateNumber, AnimateText, Typewriter, ScrambleText, Curtains), @paper-design/shaders-react, gsap (including \`gsap/ScrollTrigger\`, driven via \`@gsap/react\`'s \`useGSAP\`), react-hook-form, zod, @hookform/resolvers, @hookform/resolvers/zod, @neopress/content, @neopress/routing, @neopress/i18n, @neopress/responsive (MobileOnly with deferred desktop/mobile callbacks), and @neopress/forms.
|
|
20456
20455
|
- For dates, render an existing \`displayDate\` field directly when available. For raw timestamps, use \`Intl.DateTimeFormat\` or \`Date#toLocaleDateString\` with an explicit locale and \`timeZone\` so server rendering and hydration agree; use the site's required zone, or \`UTC\` when none is specified.
|
|
20457
20456
|
- @base-ui/react/select is an accessible listbox/dropdown (replaces a native \`<select>\`, whose popup is unstyled OS chrome). Compose its parts directly in page TSX; a \`<Select.Item value>\` is a string or the documented \`null\` sentinel (unlike Radix, an empty string is not banned); the \`Select.Popup\` portals to \`document.body\`, so give it an explicit z-index and an opaque background; match the trigger width with \`min-w-[var(--anchor-width)]\` (from \`Select.Positioner\`), cap the list with \`max-h-[var(--available-height)]\`, and set \`alignItemWithTrigger={false}\` for standard below-trigger placement. @base-ui/react/drawer is the gesture mobile sheet; @base-ui/react/dialog the non-gesture modal — both portal to \`document.body\`, need an opaque Popup background + z-index, and take \`modal\` for focus-trap.
|
|
20458
20457
|
- react-dom is for \`createPortal\` — portal full-viewport overlays (mobile drawer, modal) to \`document.body\` so a \`backdrop-filter\`/\`transform\` ancestor can't trap their \`position: fixed\` inside its box. ALWAYS render the portal behind an open-state guard (\`{open && createPortal(…, document.body)}\`): an unguarded \`document\` reference throws during SSR.
|
|
@@ -20474,7 +20473,9 @@ Use these rules before generating pages, collection schemas, entries, forms, or
|
|
|
20474
20473
|
- \`queryConfig\` is stored in page \`draftMeta.queryConfig\`.
|
|
20475
20474
|
- Query labels become React props. Entry query results are flattened, so use \`post.body\` instead of \`post.data.body\`.
|
|
20476
20475
|
- A query may include \`collectionWindow\` on an \`entries\` query for a dynamic detail route. Its label receives \`{ before, after, items }\`; each is a flattened-entry array around the current entry, and \`items\` combines both directions. Windows use \`published_at DESC, id DESC\`, allow 0–20 entries per direction, and may only declare that exact order. Use the exact configured label, never a guessed prop name. Optional \`matchFields\` compare raw anchor-snapshot fields only when the source field has a value.
|
|
20477
|
-
- Initial CMS data arrives through those injected query props. \`entryClient\`, when injected in reader/preview for a site handle, is only a client-side auxiliary for load-more/filter/get/create interactions after the initial render; do not use it for initial render or server data loading.
|
|
20476
|
+
- Initial CMS data arrives through those injected query props. \`entryClient\`, when injected in reader/preview for a site handle, is only a client-side auxiliary for load-more/filter/get/create interactions after the initial render; do not use it for initial render or server data loading. Its entries come back flattened like injected props, ordered \`published_at DESC, id DESC\`.
|
|
20477
|
+
- Server-side binding is the default because injected props are server-rendered and crawlable; \`entryClient\` is for after-hydration needs only (large-collection load-more, a read that depends on visitor input such as search text or a chosen filter, or an explicit client-side request).
|
|
20478
|
+
- Load-more pagination: give the list query a \`limit\` (first page injected server-side), then append \`entryClient.more(propLabel, { offset: shown.length, filters? })\` — the server re-runs that page's stored binding query from the offset, so the page restates nothing; \`filters\` is equality on scalar schema fields (\`{ category: "TECH" }\`), applied to the same published data. \`entryClient.list({ collectionId, offset, limit, filters? })\` is only for reads whose query depends on visitor input or that are too large to inject; a light, fixed set revealed on click is a bound query instead. Judge "light" by what the query injects into the page, not by how much the UI shows: a query without a \`limit\` ships every entry with every field. Without a \`limit\` a list query injects every entry, so paginate by slicing the prop instead.
|
|
20478
20479
|
- Use numeric \`collection_id\` filters. Runtime controls site, status, locale, deleted state, and published snapshots.
|
|
20479
20480
|
|
|
20480
20481
|
## Collections and entries
|
|
@@ -20488,7 +20489,7 @@ Use these rules before generating pages, collection schemas, entries, forms, or
|
|
|
20488
20489
|
|
|
20489
20490
|
- Reference fields require a schema field with \`type: "references"\` and target \`collection_id\`.
|
|
20490
20491
|
- Links live in \`entry_references\`, not only in raw entry \`data\`.
|
|
20491
|
-
- \`includeReferences\` fetches arrays keyed by the includeReferences alias or field key, and parent entry \`id\` must be selected. With an alias, the alias prop remains an array of referenced entries. Without an alias, if the field key matches a raw numeric reference field in \`entry.data\`, flattening unwraps that array to one
|
|
20492
|
+
- \`includeReferences\` fetches arrays keyed by the includeReferences alias or field key, and parent entry \`id\` must be selected. With an alias, the alias prop remains an array of referenced entries. Without an alias, if the field key matches a raw numeric reference field in \`entry.data\`, flattening unwraps that array to one object or null; references linked only through \`entry_references\` stay arrays. Every referenced entry is flattened like the parent (\`ref.<fieldId>\`; \`ref.data\` kept for backward compatibility), one level deep.
|
|
20492
20493
|
- After changing references, publish the source entry again.
|
|
20493
20494
|
|
|
20494
20495
|
## Forms
|
|
@@ -20501,7 +20502,7 @@ Use these rules before generating pages, collection schemas, entries, forms, or
|
|
|
20501
20502
|
## Unsupported visitor features
|
|
20502
20503
|
|
|
20503
20504
|
Generated Neopress pages do not support visitor login/accounts, member areas, carts, checkout, payments, subscriptions, or order management.`;
|
|
20504
|
-
const SERVER_INSTRUCTIONS = `Use Neopress MCP tools to manage a selected Neopress site through
|
|
20505
|
+
const SERVER_INSTRUCTIONS = `Use Neopress MCP tools to manage a selected Neopress site through an authenticated MCP connection.
|
|
20505
20506
|
|
|
20506
20507
|
Before generating TSX or schema-backed pages, call neopress_get_runtime_contract or read neopress://runtime-contract.
|
|
20507
20508
|
Use numeric IDs returned by tools. Publish entries separately from site publish. Use read-only analytics tools before autopilot recommendations. Verify production URLs after production publish.
|
|
@@ -20924,7 +20925,7 @@ const toolDefinitions = [
|
|
|
20924
20925
|
{
|
|
20925
20926
|
name: "neopress_site_select",
|
|
20926
20927
|
title: "Select Active Site",
|
|
20927
|
-
description: "Verify access to a site and store it as the active site for future MCP
|
|
20928
|
+
description: "Verify access to a site and store it as the active site for future MCP operations.",
|
|
20928
20929
|
inputSchema: { siteId: number().int().positive() },
|
|
20929
20930
|
handler: async (input, context, extra) => {
|
|
20930
20931
|
const selectedSiteId = asNumber(input, "siteId");
|
|
@@ -21588,7 +21589,7 @@ const toolDefinitions = [
|
|
|
21588
21589
|
{
|
|
21589
21590
|
name: "neopress_analytics_event_create",
|
|
21590
21591
|
title: "Create Analytics Event",
|
|
21591
|
-
description: "Create a saved analytics event definition. Discover
|
|
21592
|
+
description: "Create a saved analytics event definition over raw analytics signals. Discover page and form IDs with neopress_analytics_targets_list. Click targets use an observed href:<absolute-url> or selector:<fingerprint> key; outbound counts external-link clicks site-wide. Built-in events start collecting without editing or republishing page TSX. Optional id is a client UUID: reuse the same id and payload after an uncertain response.",
|
|
21592
21593
|
inputSchema: {
|
|
21593
21594
|
...siteIdShape,
|
|
21594
21595
|
id: string().uuid().optional(),
|
|
@@ -21599,8 +21600,8 @@ const toolDefinitions = [
|
|
|
21599
21600
|
"click",
|
|
21600
21601
|
"form",
|
|
21601
21602
|
"scroll",
|
|
21602
|
-
"
|
|
21603
|
-
"
|
|
21603
|
+
"dwell",
|
|
21604
|
+
"outbound"
|
|
21604
21605
|
]),
|
|
21605
21606
|
eventName: string().optional(),
|
|
21606
21607
|
path: string().optional(),
|
|
@@ -21637,8 +21638,8 @@ const toolDefinitions = [
|
|
|
21637
21638
|
"click",
|
|
21638
21639
|
"form",
|
|
21639
21640
|
"scroll",
|
|
21640
|
-
"
|
|
21641
|
-
"
|
|
21641
|
+
"dwell",
|
|
21642
|
+
"outbound"
|
|
21642
21643
|
]).optional(),
|
|
21643
21644
|
eventName: string().optional(),
|
|
21644
21645
|
path: string().optional(),
|
package/dist/http-bin.cjs
CHANGED
|
@@ -21804,9 +21804,8 @@ Use these rules before generating pages, collection schemas, entries, forms, or
|
|
|
21804
21804
|
|
|
21805
21805
|
## Operating boundary
|
|
21806
21806
|
|
|
21807
|
-
-
|
|
21808
|
-
-
|
|
21809
|
-
- MCP is available as local stdio and remote Streamable HTTP over the first-party SDK/API.
|
|
21807
|
+
- Connect the remote MCP server and sign in with your Neopress account through OAuth.
|
|
21808
|
+
- MCP is available on Launch and above. Your site role controls which actions you can perform.
|
|
21810
21809
|
- MCP is a Neopress contract adapter, not a reference crawler or managed page generator.
|
|
21811
21810
|
- The host coding agent should perform \`r.jina.ai\` markdown fetches, browser screenshots, DOM/CSS/SVG/background-image extraction, reference analysis, and TSX authoring with its own tools and tokens.
|
|
21812
21811
|
- Use MCP to read/write Neopress resources, upload or register assets, compile, publish, and verify. Do not expect MCP to spend Neopress server-side LLM tokens for reference analysis or page generation.
|
|
@@ -21820,9 +21819,9 @@ Use these rules before generating pages, collection schemas, entries, forms, or
|
|
|
21820
21819
|
|
|
21821
21820
|
## Cache
|
|
21822
21821
|
|
|
21823
|
-
- Site publish invalidates site/layout/collection reader cache tags in the
|
|
21822
|
+
- Site publish invalidates site/layout/collection reader cache tags in the environment connected to MCP.
|
|
21824
21823
|
- Entry publish/unpublish invalidates entry reader cache when production visibility changes.
|
|
21825
|
-
- A localhost publish does not invalidate production reader cache. For production validation, publish through the production
|
|
21824
|
+
- A localhost publish does not invalidate production reader cache. For production validation, publish through the production MCP server and verify the live URL.
|
|
21826
21825
|
|
|
21827
21826
|
## Analytics and autopilot
|
|
21828
21827
|
|
|
@@ -21835,7 +21834,7 @@ Use these rules before generating pages, collection schemas, entries, forms, or
|
|
|
21835
21834
|
|
|
21836
21835
|
- Layout owns header, footer, global CSS, and 404. Page TSX starts at page content.
|
|
21837
21836
|
- Generated page TSX is sandboxed. Do not import Supabase, create API clients, read env vars, use filesystem/process APIs, or assume arbitrary npm packages.
|
|
21838
|
-
- Use allowed runtime packages only: React/Next basics, react-dom (createPortal), shadcn UI imports, lucide-react, @base-ui/react/drawer, @base-ui/react/dialog, @base-ui/react/accordion, @base-ui/react/switch, @base-ui/react/tabs, @base-ui/react/select, @neopress/youtube, @neopress/map, clsx, class-variance-authority, tailwind-merge, motion/react (never \`framer-motion\` — old package name, not on the allowlist), motion-plus/react (Motion+ premium components: Ticker, Carousel, Cursor, AnimateNumber, AnimateText, Typewriter, ScrambleText, Curtains), @paper-design/shaders-react, gsap (including \`gsap/ScrollTrigger\`, driven via \`@gsap/react\`'s \`useGSAP\`), react-hook-form, zod, @hookform/resolvers, @hookform/resolvers/zod, @neopress/content, @neopress/routing, @neopress/i18n, and @neopress/forms.
|
|
21837
|
+
- Use allowed runtime packages only: React/Next basics, react-dom (createPortal), shadcn UI imports, lucide-react, @base-ui/react/drawer, @base-ui/react/dialog, @base-ui/react/accordion, @base-ui/react/switch, @base-ui/react/tabs, @base-ui/react/select, @neopress/youtube, @neopress/map, clsx, class-variance-authority, tailwind-merge, motion/react (never \`framer-motion\` — old package name, not on the allowlist), motion-plus/react (Motion+ premium components: Ticker, Carousel, Cursor, AnimateNumber, AnimateText, Typewriter, ScrambleText, Curtains), @paper-design/shaders-react, gsap (including \`gsap/ScrollTrigger\`, driven via \`@gsap/react\`'s \`useGSAP\`), react-hook-form, zod, @hookform/resolvers, @hookform/resolvers/zod, @neopress/content, @neopress/routing, @neopress/i18n, @neopress/responsive (MobileOnly with deferred desktop/mobile callbacks), and @neopress/forms.
|
|
21839
21838
|
- For dates, render an existing \`displayDate\` field directly when available. For raw timestamps, use \`Intl.DateTimeFormat\` or \`Date#toLocaleDateString\` with an explicit locale and \`timeZone\` so server rendering and hydration agree; use the site's required zone, or \`UTC\` when none is specified.
|
|
21840
21839
|
- @base-ui/react/select is an accessible listbox/dropdown (replaces a native \`<select>\`, whose popup is unstyled OS chrome). Compose its parts directly in page TSX; a \`<Select.Item value>\` is a string or the documented \`null\` sentinel (unlike Radix, an empty string is not banned); the \`Select.Popup\` portals to \`document.body\`, so give it an explicit z-index and an opaque background; match the trigger width with \`min-w-[var(--anchor-width)]\` (from \`Select.Positioner\`), cap the list with \`max-h-[var(--available-height)]\`, and set \`alignItemWithTrigger={false}\` for standard below-trigger placement. @base-ui/react/drawer is the gesture mobile sheet; @base-ui/react/dialog the non-gesture modal — both portal to \`document.body\`, need an opaque Popup background + z-index, and take \`modal\` for focus-trap.
|
|
21841
21840
|
- react-dom is for \`createPortal\` — portal full-viewport overlays (mobile drawer, modal) to \`document.body\` so a \`backdrop-filter\`/\`transform\` ancestor can't trap their \`position: fixed\` inside its box. ALWAYS render the portal behind an open-state guard (\`{open && createPortal(…, document.body)}\`): an unguarded \`document\` reference throws during SSR.
|
|
@@ -21857,7 +21856,9 @@ Use these rules before generating pages, collection schemas, entries, forms, or
|
|
|
21857
21856
|
- \`queryConfig\` is stored in page \`draftMeta.queryConfig\`.
|
|
21858
21857
|
- Query labels become React props. Entry query results are flattened, so use \`post.body\` instead of \`post.data.body\`.
|
|
21859
21858
|
- A query may include \`collectionWindow\` on an \`entries\` query for a dynamic detail route. Its label receives \`{ before, after, items }\`; each is a flattened-entry array around the current entry, and \`items\` combines both directions. Windows use \`published_at DESC, id DESC\`, allow 0–20 entries per direction, and may only declare that exact order. Use the exact configured label, never a guessed prop name. Optional \`matchFields\` compare raw anchor-snapshot fields only when the source field has a value.
|
|
21860
|
-
- Initial CMS data arrives through those injected query props. \`entryClient\`, when injected in reader/preview for a site handle, is only a client-side auxiliary for load-more/filter/get/create interactions after the initial render; do not use it for initial render or server data loading.
|
|
21859
|
+
- Initial CMS data arrives through those injected query props. \`entryClient\`, when injected in reader/preview for a site handle, is only a client-side auxiliary for load-more/filter/get/create interactions after the initial render; do not use it for initial render or server data loading. Its entries come back flattened like injected props, ordered \`published_at DESC, id DESC\`.
|
|
21860
|
+
- Server-side binding is the default because injected props are server-rendered and crawlable; \`entryClient\` is for after-hydration needs only (large-collection load-more, a read that depends on visitor input such as search text or a chosen filter, or an explicit client-side request).
|
|
21861
|
+
- Load-more pagination: give the list query a \`limit\` (first page injected server-side), then append \`entryClient.more(propLabel, { offset: shown.length, filters? })\` — the server re-runs that page's stored binding query from the offset, so the page restates nothing; \`filters\` is equality on scalar schema fields (\`{ category: "TECH" }\`), applied to the same published data. \`entryClient.list({ collectionId, offset, limit, filters? })\` is only for reads whose query depends on visitor input or that are too large to inject; a light, fixed set revealed on click is a bound query instead. Judge "light" by what the query injects into the page, not by how much the UI shows: a query without a \`limit\` ships every entry with every field. Without a \`limit\` a list query injects every entry, so paginate by slicing the prop instead.
|
|
21861
21862
|
- Use numeric \`collection_id\` filters. Runtime controls site, status, locale, deleted state, and published snapshots.
|
|
21862
21863
|
|
|
21863
21864
|
## Collections and entries
|
|
@@ -21871,7 +21872,7 @@ Use these rules before generating pages, collection schemas, entries, forms, or
|
|
|
21871
21872
|
|
|
21872
21873
|
- Reference fields require a schema field with \`type: "references"\` and target \`collection_id\`.
|
|
21873
21874
|
- Links live in \`entry_references\`, not only in raw entry \`data\`.
|
|
21874
|
-
- \`includeReferences\` fetches arrays keyed by the includeReferences alias or field key, and parent entry \`id\` must be selected. With an alias, the alias prop remains an array of referenced entries. Without an alias, if the field key matches a raw numeric reference field in \`entry.data\`, flattening unwraps that array to one
|
|
21875
|
+
- \`includeReferences\` fetches arrays keyed by the includeReferences alias or field key, and parent entry \`id\` must be selected. With an alias, the alias prop remains an array of referenced entries. Without an alias, if the field key matches a raw numeric reference field in \`entry.data\`, flattening unwraps that array to one object or null; references linked only through \`entry_references\` stay arrays. Every referenced entry is flattened like the parent (\`ref.<fieldId>\`; \`ref.data\` kept for backward compatibility), one level deep.
|
|
21875
21876
|
- After changing references, publish the source entry again.
|
|
21876
21877
|
|
|
21877
21878
|
## Forms
|
|
@@ -21884,7 +21885,7 @@ Use these rules before generating pages, collection schemas, entries, forms, or
|
|
|
21884
21885
|
## Unsupported visitor features
|
|
21885
21886
|
|
|
21886
21887
|
Generated Neopress pages do not support visitor login/accounts, member areas, carts, checkout, payments, subscriptions, or order management.`;
|
|
21887
|
-
const SERVER_INSTRUCTIONS = `Use Neopress MCP tools to manage a selected Neopress site through
|
|
21888
|
+
const SERVER_INSTRUCTIONS = `Use Neopress MCP tools to manage a selected Neopress site through an authenticated MCP connection.
|
|
21888
21889
|
|
|
21889
21890
|
Before generating TSX or schema-backed pages, call neopress_get_runtime_contract or read neopress://runtime-contract.
|
|
21890
21891
|
Use numeric IDs returned by tools. Publish entries separately from site publish. Use read-only analytics tools before autopilot recommendations. Verify production URLs after production publish.
|
|
@@ -22307,7 +22308,7 @@ const toolDefinitions = [
|
|
|
22307
22308
|
{
|
|
22308
22309
|
name: "neopress_site_select",
|
|
22309
22310
|
title: "Select Active Site",
|
|
22310
|
-
description: "Verify access to a site and store it as the active site for future MCP
|
|
22311
|
+
description: "Verify access to a site and store it as the active site for future MCP operations.",
|
|
22311
22312
|
inputSchema: { siteId: number().int().positive() },
|
|
22312
22313
|
handler: async (input, context, extra) => {
|
|
22313
22314
|
const selectedSiteId = asNumber(input, "siteId");
|
|
@@ -22971,7 +22972,7 @@ const toolDefinitions = [
|
|
|
22971
22972
|
{
|
|
22972
22973
|
name: "neopress_analytics_event_create",
|
|
22973
22974
|
title: "Create Analytics Event",
|
|
22974
|
-
description: "Create a saved analytics event definition. Discover
|
|
22975
|
+
description: "Create a saved analytics event definition over raw analytics signals. Discover page and form IDs with neopress_analytics_targets_list. Click targets use an observed href:<absolute-url> or selector:<fingerprint> key; outbound counts external-link clicks site-wide. Built-in events start collecting without editing or republishing page TSX. Optional id is a client UUID: reuse the same id and payload after an uncertain response.",
|
|
22975
22976
|
inputSchema: {
|
|
22976
22977
|
...siteIdShape,
|
|
22977
22978
|
id: string().uuid().optional(),
|
|
@@ -22982,8 +22983,8 @@ const toolDefinitions = [
|
|
|
22982
22983
|
"click",
|
|
22983
22984
|
"form",
|
|
22984
22985
|
"scroll",
|
|
22985
|
-
"
|
|
22986
|
-
"
|
|
22986
|
+
"dwell",
|
|
22987
|
+
"outbound"
|
|
22987
22988
|
]),
|
|
22988
22989
|
eventName: string().optional(),
|
|
22989
22990
|
path: string().optional(),
|
|
@@ -23020,8 +23021,8 @@ const toolDefinitions = [
|
|
|
23020
23021
|
"click",
|
|
23021
23022
|
"form",
|
|
23022
23023
|
"scroll",
|
|
23023
|
-
"
|
|
23024
|
-
"
|
|
23024
|
+
"dwell",
|
|
23025
|
+
"outbound"
|
|
23025
23026
|
]).optional(),
|
|
23026
23027
|
eventName: string().optional(),
|
|
23027
23028
|
path: string().optional(),
|
package/dist/index.d.ts
CHANGED
|
@@ -198,11 +198,13 @@ interface SiteLayout {
|
|
|
198
198
|
draftTsx: string | null;
|
|
199
199
|
draftGlobalCss: string | null;
|
|
200
200
|
draftNotFoundTsx: string | null;
|
|
201
|
+
draftI18n: unknown;
|
|
201
202
|
prodTsx: string | null;
|
|
202
203
|
prodJs: string | null;
|
|
203
204
|
prodGlobalCss: string | null;
|
|
204
205
|
prodNotFoundTsx: string | null;
|
|
205
206
|
prodNotFoundJs: string | null;
|
|
207
|
+
prodI18n: unknown;
|
|
206
208
|
}
|
|
207
209
|
interface Headshot {
|
|
208
210
|
id: number;
|
|
@@ -289,7 +291,9 @@ interface SearchConsoleQueryResult {
|
|
|
289
291
|
};
|
|
290
292
|
error?: string;
|
|
291
293
|
}
|
|
292
|
-
type AnalyticsEventType = "custom" | "page" | "click" | "form" | "scroll" | "visibility" | "dwell";
|
|
294
|
+
type AnalyticsEventType = "custom" | "page" | "click" | "form" | "scroll" | "visibility" | "dwell" | "outbound";
|
|
295
|
+
/** `visibility` remains readable for historical definitions but cannot be created. */
|
|
296
|
+
type AnalyticsEventCreateType = Exclude<AnalyticsEventType, "visibility">;
|
|
293
297
|
type FunnelFilterField = "event.path" | "event.url" | "event.referrer" | "event.referrer_source" | "event.property" | "session.referrer" | "session.referrer_source" | "session.traffic_category" | "session.utm_source" | "session.utm_medium" | "session.utm_campaign" | "session.utm_content" | "session.utm_term";
|
|
294
298
|
type FunnelFilterOperator = "eq" | "neq" | "contains" | "not_contains" | "starts_with" | "ends_with" | "exists" | "not_exists" | "gt" | "gte" | "lt" | "lte";
|
|
295
299
|
type AnalyticsFunnelFilterCondition = {
|
|
@@ -315,6 +319,7 @@ interface AnalyticsEventDefinition {
|
|
|
315
319
|
name: string;
|
|
316
320
|
chart_visible: boolean;
|
|
317
321
|
is_pinned: boolean;
|
|
322
|
+
sort_order?: number | null;
|
|
318
323
|
event_type: AnalyticsEventType;
|
|
319
324
|
event_name: string;
|
|
320
325
|
path: string;
|
|
@@ -330,7 +335,7 @@ interface AnalyticsEventDefinitionInput {
|
|
|
330
335
|
/** Optional client UUID; reuse it with the same payload after an uncertain create response. */
|
|
331
336
|
id?: string;
|
|
332
337
|
name: string;
|
|
333
|
-
eventType:
|
|
338
|
+
eventType: AnalyticsEventCreateType;
|
|
334
339
|
eventName?: string;
|
|
335
340
|
path?: string;
|
|
336
341
|
selector?: string;
|
|
@@ -647,6 +652,8 @@ declare class SiteEndpoint {
|
|
|
647
652
|
draftTsx?: string;
|
|
648
653
|
draftNotFoundTsx?: string;
|
|
649
654
|
draftGlobalCss?: string;
|
|
655
|
+
/** Replaces draft translations; null clears them, omission preserves them. */
|
|
656
|
+
draftI18n?: unknown;
|
|
650
657
|
}): Promise<SiteLayout>;
|
|
651
658
|
delete(): Promise<{
|
|
652
659
|
siteId: number;
|
package/dist/index.js
CHANGED
|
@@ -923,9 +923,8 @@ Use these rules before generating pages, collection schemas, entries, forms, or
|
|
|
923
923
|
|
|
924
924
|
## Operating boundary
|
|
925
925
|
|
|
926
|
-
-
|
|
927
|
-
-
|
|
928
|
-
- MCP is available as local stdio and remote Streamable HTTP over the first-party SDK/API.
|
|
926
|
+
- Connect the remote MCP server and sign in with your Neopress account through OAuth.
|
|
927
|
+
- MCP is available on Launch and above. Your site role controls which actions you can perform.
|
|
929
928
|
- MCP is a Neopress contract adapter, not a reference crawler or managed page generator.
|
|
930
929
|
- The host coding agent should perform \`r.jina.ai\` markdown fetches, browser screenshots, DOM/CSS/SVG/background-image extraction, reference analysis, and TSX authoring with its own tools and tokens.
|
|
931
930
|
- Use MCP to read/write Neopress resources, upload or register assets, compile, publish, and verify. Do not expect MCP to spend Neopress server-side LLM tokens for reference analysis or page generation.
|
|
@@ -939,9 +938,9 @@ Use these rules before generating pages, collection schemas, entries, forms, or
|
|
|
939
938
|
|
|
940
939
|
## Cache
|
|
941
940
|
|
|
942
|
-
- Site publish invalidates site/layout/collection reader cache tags in the
|
|
941
|
+
- Site publish invalidates site/layout/collection reader cache tags in the environment connected to MCP.
|
|
943
942
|
- Entry publish/unpublish invalidates entry reader cache when production visibility changes.
|
|
944
|
-
- A localhost publish does not invalidate production reader cache. For production validation, publish through the production
|
|
943
|
+
- A localhost publish does not invalidate production reader cache. For production validation, publish through the production MCP server and verify the live URL.
|
|
945
944
|
|
|
946
945
|
## Analytics and autopilot
|
|
947
946
|
|
|
@@ -954,7 +953,7 @@ Use these rules before generating pages, collection schemas, entries, forms, or
|
|
|
954
953
|
|
|
955
954
|
- Layout owns header, footer, global CSS, and 404. Page TSX starts at page content.
|
|
956
955
|
- Generated page TSX is sandboxed. Do not import Supabase, create API clients, read env vars, use filesystem/process APIs, or assume arbitrary npm packages.
|
|
957
|
-
- Use allowed runtime packages only: React/Next basics, react-dom (createPortal), shadcn UI imports, lucide-react, @base-ui/react/drawer, @base-ui/react/dialog, @base-ui/react/accordion, @base-ui/react/switch, @base-ui/react/tabs, @base-ui/react/select, @neopress/youtube, @neopress/map, clsx, class-variance-authority, tailwind-merge, motion/react (never \`framer-motion\` — old package name, not on the allowlist), motion-plus/react (Motion+ premium components: Ticker, Carousel, Cursor, AnimateNumber, AnimateText, Typewriter, ScrambleText, Curtains), @paper-design/shaders-react, gsap (including \`gsap/ScrollTrigger\`, driven via \`@gsap/react\`'s \`useGSAP\`), react-hook-form, zod, @hookform/resolvers, @hookform/resolvers/zod, @neopress/content, @neopress/routing, @neopress/i18n, and @neopress/forms.
|
|
956
|
+
- Use allowed runtime packages only: React/Next basics, react-dom (createPortal), shadcn UI imports, lucide-react, @base-ui/react/drawer, @base-ui/react/dialog, @base-ui/react/accordion, @base-ui/react/switch, @base-ui/react/tabs, @base-ui/react/select, @neopress/youtube, @neopress/map, clsx, class-variance-authority, tailwind-merge, motion/react (never \`framer-motion\` — old package name, not on the allowlist), motion-plus/react (Motion+ premium components: Ticker, Carousel, Cursor, AnimateNumber, AnimateText, Typewriter, ScrambleText, Curtains), @paper-design/shaders-react, gsap (including \`gsap/ScrollTrigger\`, driven via \`@gsap/react\`'s \`useGSAP\`), react-hook-form, zod, @hookform/resolvers, @hookform/resolvers/zod, @neopress/content, @neopress/routing, @neopress/i18n, @neopress/responsive (MobileOnly with deferred desktop/mobile callbacks), and @neopress/forms.
|
|
958
957
|
- For dates, render an existing \`displayDate\` field directly when available. For raw timestamps, use \`Intl.DateTimeFormat\` or \`Date#toLocaleDateString\` with an explicit locale and \`timeZone\` so server rendering and hydration agree; use the site's required zone, or \`UTC\` when none is specified.
|
|
959
958
|
- @base-ui/react/select is an accessible listbox/dropdown (replaces a native \`<select>\`, whose popup is unstyled OS chrome). Compose its parts directly in page TSX; a \`<Select.Item value>\` is a string or the documented \`null\` sentinel (unlike Radix, an empty string is not banned); the \`Select.Popup\` portals to \`document.body\`, so give it an explicit z-index and an opaque background; match the trigger width with \`min-w-[var(--anchor-width)]\` (from \`Select.Positioner\`), cap the list with \`max-h-[var(--available-height)]\`, and set \`alignItemWithTrigger={false}\` for standard below-trigger placement. @base-ui/react/drawer is the gesture mobile sheet; @base-ui/react/dialog the non-gesture modal — both portal to \`document.body\`, need an opaque Popup background + z-index, and take \`modal\` for focus-trap.
|
|
960
959
|
- react-dom is for \`createPortal\` — portal full-viewport overlays (mobile drawer, modal) to \`document.body\` so a \`backdrop-filter\`/\`transform\` ancestor can't trap their \`position: fixed\` inside its box. ALWAYS render the portal behind an open-state guard (\`{open && createPortal(…, document.body)}\`): an unguarded \`document\` reference throws during SSR.
|
|
@@ -976,7 +975,9 @@ Use these rules before generating pages, collection schemas, entries, forms, or
|
|
|
976
975
|
- \`queryConfig\` is stored in page \`draftMeta.queryConfig\`.
|
|
977
976
|
- Query labels become React props. Entry query results are flattened, so use \`post.body\` instead of \`post.data.body\`.
|
|
978
977
|
- A query may include \`collectionWindow\` on an \`entries\` query for a dynamic detail route. Its label receives \`{ before, after, items }\`; each is a flattened-entry array around the current entry, and \`items\` combines both directions. Windows use \`published_at DESC, id DESC\`, allow 0–20 entries per direction, and may only declare that exact order. Use the exact configured label, never a guessed prop name. Optional \`matchFields\` compare raw anchor-snapshot fields only when the source field has a value.
|
|
979
|
-
- Initial CMS data arrives through those injected query props. \`entryClient\`, when injected in reader/preview for a site handle, is only a client-side auxiliary for load-more/filter/get/create interactions after the initial render; do not use it for initial render or server data loading.
|
|
978
|
+
- Initial CMS data arrives through those injected query props. \`entryClient\`, when injected in reader/preview for a site handle, is only a client-side auxiliary for load-more/filter/get/create interactions after the initial render; do not use it for initial render or server data loading. Its entries come back flattened like injected props, ordered \`published_at DESC, id DESC\`.
|
|
979
|
+
- Server-side binding is the default because injected props are server-rendered and crawlable; \`entryClient\` is for after-hydration needs only (large-collection load-more, a read that depends on visitor input such as search text or a chosen filter, or an explicit client-side request).
|
|
980
|
+
- Load-more pagination: give the list query a \`limit\` (first page injected server-side), then append \`entryClient.more(propLabel, { offset: shown.length, filters? })\` — the server re-runs that page's stored binding query from the offset, so the page restates nothing; \`filters\` is equality on scalar schema fields (\`{ category: "TECH" }\`), applied to the same published data. \`entryClient.list({ collectionId, offset, limit, filters? })\` is only for reads whose query depends on visitor input or that are too large to inject; a light, fixed set revealed on click is a bound query instead. Judge "light" by what the query injects into the page, not by how much the UI shows: a query without a \`limit\` ships every entry with every field. Without a \`limit\` a list query injects every entry, so paginate by slicing the prop instead.
|
|
980
981
|
- Use numeric \`collection_id\` filters. Runtime controls site, status, locale, deleted state, and published snapshots.
|
|
981
982
|
|
|
982
983
|
## Collections and entries
|
|
@@ -990,7 +991,7 @@ Use these rules before generating pages, collection schemas, entries, forms, or
|
|
|
990
991
|
|
|
991
992
|
- Reference fields require a schema field with \`type: "references"\` and target \`collection_id\`.
|
|
992
993
|
- Links live in \`entry_references\`, not only in raw entry \`data\`.
|
|
993
|
-
- \`includeReferences\` fetches arrays keyed by the includeReferences alias or field key, and parent entry \`id\` must be selected. With an alias, the alias prop remains an array of referenced entries. Without an alias, if the field key matches a raw numeric reference field in \`entry.data\`, flattening unwraps that array to one
|
|
994
|
+
- \`includeReferences\` fetches arrays keyed by the includeReferences alias or field key, and parent entry \`id\` must be selected. With an alias, the alias prop remains an array of referenced entries. Without an alias, if the field key matches a raw numeric reference field in \`entry.data\`, flattening unwraps that array to one object or null; references linked only through \`entry_references\` stay arrays. Every referenced entry is flattened like the parent (\`ref.<fieldId>\`; \`ref.data\` kept for backward compatibility), one level deep.
|
|
994
995
|
- After changing references, publish the source entry again.
|
|
995
996
|
|
|
996
997
|
## Forms
|
|
@@ -1003,7 +1004,7 @@ Use these rules before generating pages, collection schemas, entries, forms, or
|
|
|
1003
1004
|
## Unsupported visitor features
|
|
1004
1005
|
|
|
1005
1006
|
Generated Neopress pages do not support visitor login/accounts, member areas, carts, checkout, payments, subscriptions, or order management.`;
|
|
1006
|
-
const SERVER_INSTRUCTIONS = `Use Neopress MCP tools to manage a selected Neopress site through
|
|
1007
|
+
const SERVER_INSTRUCTIONS = `Use Neopress MCP tools to manage a selected Neopress site through an authenticated MCP connection.
|
|
1007
1008
|
|
|
1008
1009
|
Before generating TSX or schema-backed pages, call neopress_get_runtime_contract or read neopress://runtime-contract.
|
|
1009
1010
|
Use numeric IDs returned by tools. Publish entries separately from site publish. Use read-only analytics tools before autopilot recommendations. Verify production URLs after production publish.
|
|
@@ -1426,7 +1427,7 @@ const toolDefinitions = [
|
|
|
1426
1427
|
{
|
|
1427
1428
|
name: "neopress_site_select",
|
|
1428
1429
|
title: "Select Active Site",
|
|
1429
|
-
description: "Verify access to a site and store it as the active site for future MCP
|
|
1430
|
+
description: "Verify access to a site and store it as the active site for future MCP operations.",
|
|
1430
1431
|
inputSchema: { siteId: z.number().int().positive() },
|
|
1431
1432
|
handler: async (input, context, extra) => {
|
|
1432
1433
|
const selectedSiteId = asNumber(input, "siteId");
|
|
@@ -2090,7 +2091,7 @@ const toolDefinitions = [
|
|
|
2090
2091
|
{
|
|
2091
2092
|
name: "neopress_analytics_event_create",
|
|
2092
2093
|
title: "Create Analytics Event",
|
|
2093
|
-
description: "Create a saved analytics event definition. Discover
|
|
2094
|
+
description: "Create a saved analytics event definition over raw analytics signals. Discover page and form IDs with neopress_analytics_targets_list. Click targets use an observed href:<absolute-url> or selector:<fingerprint> key; outbound counts external-link clicks site-wide. Built-in events start collecting without editing or republishing page TSX. Optional id is a client UUID: reuse the same id and payload after an uncertain response.",
|
|
2094
2095
|
inputSchema: {
|
|
2095
2096
|
...siteIdShape,
|
|
2096
2097
|
id: z.string().uuid().optional(),
|
|
@@ -2101,8 +2102,8 @@ const toolDefinitions = [
|
|
|
2101
2102
|
"click",
|
|
2102
2103
|
"form",
|
|
2103
2104
|
"scroll",
|
|
2104
|
-
"
|
|
2105
|
-
"
|
|
2105
|
+
"dwell",
|
|
2106
|
+
"outbound"
|
|
2106
2107
|
]),
|
|
2107
2108
|
eventName: z.string().optional(),
|
|
2108
2109
|
path: z.string().optional(),
|
|
@@ -2139,8 +2140,8 @@ const toolDefinitions = [
|
|
|
2139
2140
|
"click",
|
|
2140
2141
|
"form",
|
|
2141
2142
|
"scroll",
|
|
2142
|
-
"
|
|
2143
|
-
"
|
|
2143
|
+
"dwell",
|
|
2144
|
+
"outbound"
|
|
2144
2145
|
]).optional(),
|
|
2145
2146
|
eventName: z.string().optional(),
|
|
2146
2147
|
path: z.string().optional(),
|