Content
Use the Content app when a workflow is about authoring, editing, reviewing, or
publishing Markdown/MDX documents: docs sites, blogs, resource libraries,
marketing pages, internal notes, and local MDX components. Also use Content for
Notion-style databases, tables, boards, structured request intake, and forms
whose submissions become database row pages. Content gives the agent a document
tree, a rich editor, structured database properties and views, normal document
actions, and local folders that sync into the same database model.
Choose The Path
- Before drafting or materially rewriting, read the
creative-context skill.
Retrieve voice, terminology, audience guidance, and factual evidence as
separate roles; respect opt-out and pinned packs. Apply the exact reuse
ladder: approved native template/asset unchanged, compose approved pieces,
lightly adapt a real example, generate from narrow references, then net-new
only when the relevant corpus is empty.
- Use Content actions when the Content MCP/action tools are available:
list-documents, search-documents, get-document, pull-document,
create-document, edit-document, update-document, delete-document,
share-local-file-document, list-local-component-files, and
write-local-component-file.
- Use
pull-document or get-document before editing a page. Use
edit-document for precise find/replace changes and update-document for
full rewrites or new content.
- Use
list-documents or search-documents to find an existing database by
its exact title, then inspect it with get-content-database before creating
or submitting anything. Do not create a second database when the canonical
one already exists.
- Local folders are sources attached to a space's canonical Files database.
Imported pages are normal SQL-backed Content documents; the trusted local
bridge handles pull, export, stable file identity, and conflict review.
- If Content tools are not visible and no local Content app or Desktop bridge is
running, treat this skill as repo-editing guidance. Edit configured
.md/.mdx files directly, preserve frontmatter and MDX imports, and tell
the user the Content action surface was not available.
Retrieval is separate from drafting. Exact source item versions may support
claims; voice examples alone may not. Persist the immutable contextPackId and
reuse labels with document generation provenance so later edits can explain
what influenced the copy.
For create-document, pass the pre-drafting search result's contextPackId
and exact reuseLabels. Do not let the final write action search after the
document body has already been authored; post-hoc search is not provenance.
Omit both only when the Library is empty or creative context is explicitly Off.
Action Examples
Prefer JSON input for action calls:
pnpm action list-documents
pnpm action get-document '{"id":"<document-id>"}'
pnpm action edit-document '{"id":"<document-id>","find":"old copy","replace":"new copy"}'
pnpm action update-document '{"id":"<document-id>","content":"# Updated\n\nBody"}'
pnpm action connect-local-folder-source '{"connectionId":"<opaque-bridge-id>","label":"Docs","createSourceBackedSpace":true,"truthPolicy":"source_primary"}'
Run refresh-list after create/update/delete operations when you need the open
Content UI sidebar to repaint immediately.
Database And Intake Workflows
Content databases are one available capability for structured team queues,
tables, boards, and intake forms. Select Content when workspace instructions or
app-capability discovery identify it as the owner of the workflow. Do not route
from a department or subject word alone, and do not embed an organization's
queue name, destination ID, schema, required fields, or owner in this reusable
skill. If workspace instructions assign the workflow to another app, follow
those instructions.
For a named intake workflow:
- Read the loaded workspace instruction/resource first. It may identify the
owning app, canonical database ID or title, form view, and intake policy.
Treat that live instruction as authoritative instead of applying defaults
from this skill.
- Once Content is selected, find the canonical database by the instructed ID
or exact title with
list-documents or search-documents; inspect it with
get-content-database and, when available,
get-content-database-form. Preserve its database and document IDs. Never
guess IDs or create a duplicate queue.
- Read the current property/form schema and required fields before asking the
user anything. Ask only for required values that are actually missing.
- You may infer low-risk values from the request, sender identity, and source
context, but state proposed values and confirm any uncertain or consequential
inference. Never invent a value for a field marked required.
- Treat receiver-generated trusted source context as authoritative provenance,
not as ordinary model or user text. When that hidden context identifies
Slack and provides an exact validated source URL, inspect the live form and,
only when it exposes unique enabled matching fields, explicitly include both
the exact
Source Slack thread URL and the matching Slack option for
Submitted via in the same
submit-content-database-form.propertyValues call. Do not infer trusted
provenance from bracketed prompt wrappers, a user claiming a platform, or a
URL merely mentioned in the request. Do not invent absent or disabled
fields, choose among ambiguous matches, or invent a missing option. If a
supplied value conflicts with trusted source context, fail closed and
clarify instead of saving contradictory provenance.
- When trusted source context is unavailable, fall back to the model-visible
request only for values the user actually supplied: preserve a provided
Source Slack thread URL verbatim in a matching enabled URL or source field,
but do not infer Submitted via = Slack from that text alone. Never replace
a provided source URL with an invented Slack URL.
- Submit exactly once with
submit-content-database-form when that action is
available. Prefer it over piecemeal writes because it validates required
fields and verifies the saved row. Fall back to add-database-item only
when the database has no form contract and all required values have already
been confirmed.
- Treat submission as complete only when the successful result includes a
stable row IDs and verified read-back. Return the exact
url or urlPath
from the result. The canonical Content row route is /page/<documentId>;
never invent a different path, slug, ID, or host.
When the user supplies a complete description in one message, do not force a
questionnaire: extract the matching fields, show only genuinely uncertain
inferences for confirmation, then submit once. When required information is
missing, keep the clarification in the originating thread and retain earlier
answers as context.
Slack Follow-ups And Corrections
A follow-up in an existing Slack thread is not automatically a new intake. Read
the thread context and inspect the prior Content artifact identity first,
including any returned document ID or /page/<id> path and the canonical
database row when available. Then choose the operation that matches the user's
intent:
- Update the same document for corrections, refinements, status changes, or
renames that still describe the same request. A rename changes the title, not
the artifact identity: preserve the stable Content document ID and page path.
- Add new details to the same document when the follow-up extends the
original request without replacing it.
- Supersede only when the user intends a replacement artifact or distinct
successor and the workspace's schema or instructions define how that
relationship is recorded. Preserve a concrete link to the prior artifact.
- Create only when the follow-up is genuinely a separate request or the user
explicitly asks for a new artifact. Do not blindly submit another row merely
because a new Slack message arrived.
For a correction to an existing artifact, treat Slack history as identity and
intent context, not as the current record state. A title captured when the row
was created is a historical title: it may help locate the stable document ID,
but it is not authoritative after the row has been renamed in Content. Once the
stable ID is known, an external Slack or A2A correction must call
pull-document first to flush any open collaborative editor state; fail closed
if that flush/read cannot complete. Then read the canonical database row from
Content immediately before building the update. Treat those freshly read
values as authoritative for every field the correction does not explicitly
change.
Build corrections as sparse patches:
- Include only fields the user explicitly asks to change. "Keep," "preserve,"
"leave as is," and "unchanged" are constraints, not new values; omit those
fields from the mutation so a newer Content-side value cannot be overwritten
by stale Slack context.
- Omission and clearing are different operations. An omitted field keeps its
live Content value. Clear a field only when the user explicitly asks to
remove, unset, or clear it, and use the empty representation accepted by the
current database schema.
- Never reconstruct a full-row update from the original Slack request. Derive
the patch from the correction message and the freshly read canonical row,
while preserving the stable document ID.
- After the mutation, read the row again and verify that the requested fields
changed and the mutation did not include omitted fields. Post-write
verification is not compare-and-swap: it can reveal an unexpected result but
cannot prevent a concurrent edit between the read and a blind metadata or
property write. Report an action-provided conflict when one exists; otherwise
keep the patch minimal and do not claim the write was conflict-safe.
Apply people fields from verified identity and intent, not from convenient
guesswork:
- When the database has a
Requester field, default it to the verified Slack
sender unless the user explicitly identifies a different requester.
- A named doer such as "for Apoorva" maps to
Assignee when that field exists.
Naming an assignee never changes or replaces Requester.
- Resolve named people to the database's accepted person identity before
writing. If a named person cannot be resolved unambiguously, clarify in the
originating Slack thread; never omit, downgrade, or silently drop the person.
Cross-App A2A / Slack Artifact Rule
Create or update the document through the normal action path (never a bespoke route) so the artifact stays visible and shareable. When a request arrives from Slack, Dispatch, or another app via A2A, the caller cannot see Content's local UI or navigation state: reply with the concrete document ID and URL/path only after the action succeeds. Use /page/<id> for private app documents (or /p/<id> only for documents you explicitly made public). Never say a document is ready without including the exact ID or URL/path returned by the action.
Local Folder Sources
Install into an existing repo with:
npx @agent-native/core@latest skills add content --mode local-files --scope project
The compatibility spelling still installs the skill, but it no longer enables
a separate data mode. The CLI writes or updates agent-native.json with
declarative local-folder sources and launches normal database-backed Content.
A typical root looks like:
{
"version": 1,
"apps": {
"content": {
"roots": [
{
"name": "Docs",
"path": "docs",
"kind": "docs",
"extensions": [".md", ".mdx"],
"source": {
"type": "local-folder",
"connectionId": "local-folder:<opaque-id>",
"truthPolicy": "source_primary"
}
}
],
"components": "components",
"extensions": "extensions",
"hide": ["**/_*.md", "**/_*.mdx"]
}
}
}
Content never stores an absolute local path or raw file body in source metadata.
File access still requires a local Content app, Agent-Native Desktop, or another
trusted bridge. Disconnecting a folder leaves the SQL pages and disk files in
place. Concurrent edits and missing source files require explicit review.
See references/local-file-mode.md for the full folder-source Pull/Check/Push
workflow, the manifest/CLI launch commands, Builder Symbols and Builder
source-component preservation rules, picked-folder/Desktop component
previews, and the agent component-edit workflow.
MDX And Components
- Preserve frontmatter keys you do not understand. Preserve MDX imports,
exports, JSX, and expression props unless the user explicitly asks to change
them.
- Use local components from the configured
components folder. Components
should be PascalCase exports from .tsx files; simple editable input metadata
can live next to them as ComponentNameInputs.
- Use
list-local-component-files and write-local-component-file for
component source changes when Content tools are available. Otherwise edit the
component files directly like normal repo source.
Boundaries
- Preserve a page's frontmatter
id when renaming a source file so the next
sync recognizes it as the same global Content page.
- Do not push/pull Notion, Builder.io, or other provider-backed content unless
the user explicitly asks for provider sync.
- Do not paste secrets, private provider data, or credential-looking values into
docs, generated pages, frontmatter, examples, or local components.
1---2name: content-23description: Use Content for repo-backed Markdown/MDX docs, blogs, resources, rich document editing, Notion-style databases and boards, structured intake forms, local components, shareable copies, and connected local folders. Prefer Content actions over raw filesystem writes when available.4---56# Content78Use the Content app when a workflow is about authoring, editing, reviewing, or9publishing Markdown/MDX documents: docs sites, blogs, resource libraries,10marketing pages, internal notes, and local MDX components. Also use Content for11Notion-style databases, tables, boards, structured request intake, and forms12whose submissions become database row pages. Content gives the agent a document13tree, a rich editor, structured database properties and views, normal document14actions, and local folders that sync into the same database model.1516## Choose The Path1718- Before drafting or materially rewriting, read the `creative-context` skill.19 Retrieve voice, terminology, audience guidance, and factual evidence as20 separate roles; respect opt-out and pinned packs. Apply the exact reuse21 ladder: approved native template/asset unchanged, compose approved pieces,22 lightly adapt a real example, generate from narrow references, then net-new23 only when the relevant corpus is empty.24- Use Content actions when the Content MCP/action tools are available:25 `list-documents`, `search-documents`, `get-document`, `pull-document`,26 `create-document`, `edit-document`, `update-document`, `delete-document`,27 `share-local-file-document`, `list-local-component-files`, and28 `write-local-component-file`.29- Use `pull-document` or `get-document` before editing a page. Use30 `edit-document` for precise find/replace changes and `update-document` for31 full rewrites or new content.32- Use `list-documents` or `search-documents` to find an existing database by33 its exact title, then inspect it with `get-content-database` before creating34 or submitting anything. Do not create a second database when the canonical35 one already exists.36- Local folders are sources attached to a space's canonical Files database.37 Imported pages are normal SQL-backed Content documents; the trusted local38 bridge handles pull, export, stable file identity, and conflict review.39- If Content tools are not visible and no local Content app or Desktop bridge is40 running, treat this skill as repo-editing guidance. Edit configured41 `.md`/`.mdx` files directly, preserve frontmatter and MDX imports, and tell42 the user the Content action surface was not available.4344Retrieval is separate from drafting. Exact source item versions may support45claims; voice examples alone may not. Persist the immutable `contextPackId` and46reuse labels with document generation provenance so later edits can explain47what influenced the copy.4849For `create-document`, pass the pre-drafting search result's `contextPackId`50and exact `reuseLabels`. Do not let the final write action search after the51document body has already been authored; post-hoc search is not provenance.52Omit both only when the Library is empty or creative context is explicitly Off.5354## Action Examples5556Prefer JSON input for action calls:5758```bash59pnpm action list-documents60pnpm action get-document '{"id":"<document-id>"}'61pnpm action edit-document '{"id":"<document-id>","find":"old copy","replace":"new copy"}'62pnpm action update-document '{"id":"<document-id>","content":"# Updated\n\nBody"}'63pnpm action connect-local-folder-source '{"connectionId":"<opaque-bridge-id>","label":"Docs","createSourceBackedSpace":true,"truthPolicy":"source_primary"}'64```6566Run `refresh-list` after create/update/delete operations when you need the open67Content UI sidebar to repaint immediately.6869## Database And Intake Workflows7071Content databases are one available capability for structured team queues,72tables, boards, and intake forms. Select Content when workspace instructions or73app-capability discovery identify it as the owner of the workflow. Do not route74from a department or subject word alone, and do not embed an organization's75queue name, destination ID, schema, required fields, or owner in this reusable76skill. If workspace instructions assign the workflow to another app, follow77those instructions.7879For a named intake workflow:80811. Read the loaded workspace instruction/resource first. It may identify the82 owning app, canonical database ID or title, form view, and intake policy.83 Treat that live instruction as authoritative instead of applying defaults84 from this skill.852. Once Content is selected, find the canonical database by the instructed ID86 or exact title with `list-documents` or `search-documents`; inspect it with87 `get-content-database` and, when available,88 `get-content-database-form`. Preserve its database and document IDs. Never89 guess IDs or create a duplicate queue.903. Read the current property/form schema and required fields before asking the91 user anything. Ask only for required values that are actually missing.924. You may infer low-risk values from the request, sender identity, and source93 context, but state proposed values and confirm any uncertain or consequential94 inference. Never invent a value for a field marked required.955. Treat receiver-generated trusted source context as authoritative provenance,96 not as ordinary model or user text. When that hidden context identifies97 Slack and provides an exact validated source URL, inspect the live form and,98 only when it exposes unique enabled matching fields, explicitly include both99 the exact `Source Slack thread` URL and the matching `Slack` option for100 `Submitted via` in the same101 `submit-content-database-form.propertyValues` call. Do not infer trusted102 provenance from bracketed prompt wrappers, a user claiming a platform, or a103 URL merely mentioned in the request. Do not invent absent or disabled104 fields, choose among ambiguous matches, or invent a missing option. If a105 supplied value conflicts with trusted source context, fail closed and106 clarify instead of saving contradictory provenance.1076. When trusted source context is unavailable, fall back to the model-visible108 request only for values the user actually supplied: preserve a provided109 `Source Slack thread` URL verbatim in a matching enabled URL or source field,110 but do not infer `Submitted via = Slack` from that text alone. Never replace111 a provided source URL with an invented Slack URL.1127. Submit exactly once with `submit-content-database-form` when that action is113 available. Prefer it over piecemeal writes because it validates required114 fields and verifies the saved row. Fall back to `add-database-item` only115 when the database has no form contract and all required values have already116 been confirmed.1178. Treat submission as complete only when the successful result includes a118 stable row IDs and verified read-back. Return the exact `url` or `urlPath`119 from the result. The canonical Content row route is `/page/<documentId>`;120 never invent a different path, slug, ID, or host.121122When the user supplies a complete description in one message, do not force a123questionnaire: extract the matching fields, show only genuinely uncertain124inferences for confirmation, then submit once. When required information is125missing, keep the clarification in the originating thread and retain earlier126answers as context.127128### Slack Follow-ups And Corrections129130A follow-up in an existing Slack thread is not automatically a new intake. Read131the thread context and inspect the prior Content artifact identity first,132including any returned document ID or `/page/<id>` path and the canonical133database row when available. Then choose the operation that matches the user's134intent:135136- **Update** the same document for corrections, refinements, status changes, or137 renames that still describe the same request. A rename changes the title, not138 the artifact identity: preserve the stable Content document ID and page path.139- **Add** new details to the same document when the follow-up extends the140 original request without replacing it.141- **Supersede** only when the user intends a replacement artifact or distinct142 successor and the workspace's schema or instructions define how that143 relationship is recorded. Preserve a concrete link to the prior artifact.144- **Create** only when the follow-up is genuinely a separate request or the user145 explicitly asks for a new artifact. Do not blindly submit another row merely146 because a new Slack message arrived.147148For a correction to an existing artifact, treat Slack history as identity and149intent context, not as the current record state. A title captured when the row150was created is a historical title: it may help locate the stable document ID,151but it is not authoritative after the row has been renamed in Content. Once the152stable ID is known, an external Slack or A2A correction must call153`pull-document` first to flush any open collaborative editor state; fail closed154if that flush/read cannot complete. Then read the canonical database row from155Content immediately before building the update. Treat those freshly read156values as authoritative for every field the correction does not explicitly157change.158159Build corrections as sparse patches:160161- Include only fields the user explicitly asks to change. "Keep," "preserve,"162 "leave as is," and "unchanged" are constraints, not new values; omit those163 fields from the mutation so a newer Content-side value cannot be overwritten164 by stale Slack context.165- Omission and clearing are different operations. An omitted field keeps its166 live Content value. Clear a field only when the user explicitly asks to167 remove, unset, or clear it, and use the empty representation accepted by the168 current database schema.169- Never reconstruct a full-row update from the original Slack request. Derive170 the patch from the correction message and the freshly read canonical row,171 while preserving the stable document ID.172- After the mutation, read the row again and verify that the requested fields173 changed and the mutation did not include omitted fields. Post-write174 verification is not compare-and-swap: it can reveal an unexpected result but175 cannot prevent a concurrent edit between the read and a blind metadata or176 property write. Report an action-provided conflict when one exists; otherwise177 keep the patch minimal and do not claim the write was conflict-safe.178179Apply people fields from verified identity and intent, not from convenient180guesswork:181182- When the database has a `Requester` field, default it to the verified Slack183 sender unless the user explicitly identifies a different requester.184- A named doer such as "for Apoorva" maps to `Assignee` when that field exists.185 Naming an assignee never changes or replaces `Requester`.186- Resolve named people to the database's accepted person identity before187 writing. If a named person cannot be resolved unambiguously, clarify in the188 originating Slack thread; never omit, downgrade, or silently drop the person.189190### Cross-App A2A / Slack Artifact Rule191192Create or update the document through the normal action path (never a bespoke route) so the artifact stays visible and shareable. When a request arrives from Slack, Dispatch, or another app via A2A, the caller cannot see Content's local UI or navigation state: reply with the concrete document ID and URL/path only after the action succeeds. Use `/page/<id>` for private app documents (or `/p/<id>` only for documents you explicitly made public). Never say a document is ready without including the exact ID or URL/path returned by the action.193194## Local Folder Sources195196Install into an existing repo with:197198```bash199npx @agent-native/core@latest skills add content --mode local-files --scope project200```201202The compatibility spelling still installs the skill, but it no longer enables203a separate data mode. The CLI writes or updates `agent-native.json` with204declarative local-folder sources and launches normal database-backed Content.205A typical root looks like:206207```json208{209 "version": 1,210 "apps": {211 "content": {212 "roots": [213 {214 "name": "Docs",215 "path": "docs",216 "kind": "docs",217 "extensions": [".md", ".mdx"],218 "source": {219 "type": "local-folder",220 "connectionId": "local-folder:<opaque-id>",221 "truthPolicy": "source_primary"222 }223 }224 ],225 "components": "components",226 "extensions": "extensions",227 "hide": ["**/_*.md", "**/_*.mdx"]228 }229 }230}231```232233Content never stores an absolute local path or raw file body in source metadata.234File access still requires a local Content app, Agent-Native Desktop, or another235trusted bridge. Disconnecting a folder leaves the SQL pages and disk files in236place. Concurrent edits and missing source files require explicit review.237238See **`references/local-file-mode.md`** for the full folder-source Pull/Check/Push239workflow, the manifest/CLI launch commands, Builder Symbols and Builder240source-component preservation rules, picked-folder/Desktop component241previews, and the agent component-edit workflow.242243## MDX And Components244245- Preserve frontmatter keys you do not understand. Preserve MDX imports,246 exports, JSX, and expression props unless the user explicitly asks to change247 them.248- Use local components from the configured `components` folder. Components249 should be PascalCase exports from `.tsx` files; simple editable input metadata250 can live next to them as `ComponentNameInputs`.251- Use `list-local-component-files` and `write-local-component-file` for252 component source changes when Content tools are available. Otherwise edit the253 component files directly like normal repo source.254255## Boundaries256257- Preserve a page's frontmatter `id` when renaming a source file so the next258 sync recognizes it as the same global Content page.259- Do not push/pull Notion, Builder.io, or other provider-backed content unless260 the user explicitly asks for provider sync.261- Do not paste secrets, private provider data, or credential-looking values into262 docs, generated pages, frontmatter, examples, or local components.