Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.myme.so/llms.txt

Use this file to discover all available pages before exploring further.

Marfa is extensible. Apps register their own types, edges, and extension namespaces. These conventions are how the core set looks, and following them keeps custom work readable alongside it. Some are advisory style; others are server-enforced at registration. Each rule below is marked.

Edges

Name edges so that “source [edge] target” reads as an English sentence. (Style.)
EdgeReads as
parent-ofX is parent of Y
authored-byX was authored by Y
in-threadX is in thread Y
referencesX references Y
attached-toX is attached to Y
derived-fromX is derived from Y
Transitive verbs (references, supersedes) take a direct object and don’t need a preposition. Everything else does. Dropping to bare nouns (parent, thread) loses direction — “X parent Y” is ambiguous — so keep the preposition. Use kebab-case for multi-word names. Dot-namespace custom edges under your app or publisher: app.shops-for, readwise.highlights.

Cardinality

Pick the tightest one that fits. Ask: can the source really have many of these? Can the target? Tighter cardinalities are enforced at edge-creation time and surface data-model mistakes early.

Cascade

Default to orphan. Use cascade only when the target genuinely cannot exist without the source — the only core edge that cascades is parent-of, because a child has no meaning without its parent. For almost everything else, deleting one endpoint should leave the other in place. See Edges for the full core set and their declared constraints.

Types

Use the right namespace. (Server-enforced.) Custom types live under one of:
  • app.<app-name>.<type> — types published by a registered app.
  • user.<type> — personal types in your space.
  • <publisher>.<type> — types published under a publisher handle.
The reserved roots — core, system, app, user, marfa — cannot be claimed as publisher handles. core.* and system.* are platform-only at registration. See Namespaces for the full grammar. Sibling is the default; inherit only when it earns its place. (Style, with server-checked compatible-with.) A custom type is usually its own shape, optionally declaring compatible-with: core.<type>. Inherit only when every ancestor field is semantically required for your type. Children cannot redefine ancestor fields — a bad inheritance choice is hard to recover from. See Types → Sibling vs child. Singular nouns. (Style.) note, not notes. One item, one name. Subtypes earn their place. (Style.) A subtype is justified when its instances share a convergent shape the parent doesn’t carry, consumer apps can query or render it differently, and the differentiating fields aren’t already on the parent. Otherwise prefer a sibling. See Authoring types for the full rubric. See Types for the registration flow and inheritance rules.

Property names

snake_case (Style.) For type fields, edge properties, and extension keys. That matches the core set (due_at, starts_at, display_hints, enum_values). Consistent casing makes filters, display hints, and SDK codegen predictable across custom and core types. Don’t prefix properties with the container they live in. A field on the in-thread edge is position, not edge_position. Context already tells the reader where it lives.

Markdown body

If a type declares a markdown body field, the rendered profile is CommonMark + GFM (Style.) — no wikilinks, no Obsidian-style extensions, no custom syntax. Every client renders this profile, and anything outside it won’t survive the round-trip. This is the reason core.note.body and similar fields stay portable across clients. Custom types with markdown bodies should stick to the same profile.

Extensions

Namespace extensions under your app or publisher: <your-app>.* or <your-handle>.*. (Style.) Put per-app annotations — sync state, reading progress, per-app metadata — in extensions rather than inflating a custom type with fields only one app uses. Sync cursors, agent-local cache state, and other per-machine bookkeeping are not extensions. They live on the agent’s own disk and don’t attach to any item. See Extensions for the namespace grammar and permission model.

Handles

Publishers identify themselves with a handle.
  • Format. (Server-enforced.) Lowercase alphanumeric and hyphens. No leading or trailing hyphens. No consecutive hyphens. Length 3–32 characters.
  • Reserved. (Server-enforced.) The reserved roots core, system, app, user, and marfa cannot be claimed. A list of structural words (admin, api, support, etc.) is reserved against squatting.
See Handles and publishers for the full policy — claim, change, account deletion, redirects.

Scalars

A few cross-cutting conventions for primitive values across the platform:
  • IDs. UUIDv7. Server-generated.
  • Times. ISO 8601 with offset (2026-04-12T14:30:00Z or with explicit +00:00).
  • Tags. Lowercase, kebab-case.
  • Languages. BCP 47 codes (en, en-GB).
  • MIME types. Standard IANA tokens.
  • Type identifiers. Dotted, lowercase, snake_case segments. No forward slashes.