Skip to content

For AI agents

This page orients a coding agent that has been pointed at a Brand Portal codebase. If you are a human, What the portal is and Architecture are a better start.

This site publishes the llms.txt standard:

  • /llms.txt — a structured index of every page, with links and one-line summaries.
  • /llms-full.txt — the entire documentation set concatenated as one Markdown file. Fetch this to load all developer and editor docs into context at once.

Two very different contexts share these docs — identify yours first:

  1. A client site repo (e.g. acme-portal) — content and configuration only; the framework comes from the published @drawnagency/* packages. Most “build or run a site” tasks live here. Start with Building a client site.
  2. The framework monorepo (Drawn-Agency/portal) — the six published packages (plus the private @drawnagency/platform) and the dev, admin, docs, and MCP-connector apps. Start with Monorepo & dev workflow.

Rules that will bite you if you ignore them

Section titled “Rules that will bite you if you ignore them”
  • Use pnpm. The monorepo enforces it with a preinstall only-allow pnpm hook; client repos are pnpm-based too (.npmrc + committed lockfile) but without that hook. Either way npm/yarn break the setup — always use pnpm.
  • The editor import chain must be browser-safe. portal.config.mjs and src/sections.ts are bundled into the hydrated editor island. No node:*, Buffer, server adapters, or unguarded process.env. See Building custom sections and SSR / Netlify gotchas.
  • Publish packages via scripts/publish.sh (which uses pnpm publish), never npm publish. npm publishes workspace:* dependencies literally and silently breaks every consumer install. See Publishing packages.
  • The docs site (apps/docs) must not import @drawnagency/* — not even as types — so it builds independently of package dist. Reference the packages in prose and code fences only, never as a real import.
  • Custom section types register via root src/sections.ts, not the sections config field. See Building custom sections.
  • Never write nav.json (or a nav key) unless you mean to change the page grouping. Sidebar order and grouping live in src/content/nav.json, and a write replaces it wholesale — so {"entries": []} silently deletes every group on the site, with a clean parse and no error. Leaving the file (or the nav key on an MCP save_sections index) alone preserves it. See the nav.json reference.
  • A documentId is not an imageId, and documents are a third sidecar. File metadata for document sections lives in src/content/document-manifest.json, never in image-manifest.json or the index — so a document can’t be referenced until it exists there. Upload it first (MCP upload_document, or the media library’s documents tab), then put the returned id in content.doc.documentId. An id with no manifest entry renders a dead row and is only a validator warning, so nothing stops you shipping it. See the document section reference.
  • A read that reports missing is INCOMPLETE — don’t write from it. MCP content reads return a missing array when an indexed section file isn’t valid JSON: those ids are absent from sections, but their files are still on the branch. Never post back an index that drops them, and never pruneOrphans off such a read — fix the file (re-save that section) first. See Using the MCP connector.
You want to…Page
Stand up a new client siteProvisioning a new site
Create, edit, or populate a site from chat (no checkout)Using the MCP connector
Configure a siteConfiguration · Config reference
Add a custom section typeBuilding custom sections
Understand how rendering worksArchitecture
Run the monorepo locallyMonorepo & dev workflow
Publish a package releasePublishing packages
Wire auth & audiencesAuth & audiences setup
Set environment variablesEnvironment variables · reference