MSFM Explained: The Markdown Syntax That Compiles Into Apps
MSFM adds block annotations, inline annotations, and pointers to standard Markdown. Learn the syntax that turns prose into production code.
What Is MSFM?
MSFM (MindStudio-Flavored Markdown) is a strict superset of Markdown that adds three annotation primitives: block annotations, inline annotations, and pointers. It’s the format Remy reads when compiling specs into full-stack applications. A spec written in MSFM looks like normal Markdown — headings, paragraphs, lists, tables — with annotations attached to resolve ambiguity. The prose describes what the app does; the annotations carry the precision an AI compiler needs to produce consistent code.
MSFM is designed for one job: turn natural language specifications into deterministic backend contracts. When you describe a vendor approval workflow in plain English, the annotations pin down edge cases (“what happens when a reviewer rejects?”), data representations (“amounts are integer cents, not decimal dollars”), and business rules (“approvals flow sequentially, not in parallel”). The compiler reads both the prose and the annotations to generate TypeScript methods, database schemas, and interface configs.
At a Glance
- Strict superset of Markdown — every valid Markdown file is valid MSFM
- Three primitives — block annotations (
~~~), inline annotations ([text]{content}), pointers ({#id}) - Readable raw — renders correctly in GitHub, VS Code, any Markdown viewer
- Additive precision — a bare spec with no annotations is valid; each annotation makes compilation more deterministic
- One file — no sidecars, no imports, no tooling dependencies
- Structured blocks —
typographyandcolorscode fences for design system declarations
Why Does MSFM Exist?
Built like a system. Not vibe-coded.
Remy manages the project — every layer architected, not stitched together at the last second.
Natural language is ambiguous. “The approval process has three stages” could mean three sequential steps, three parallel reviewers, or three approval tiers. A human reader infers from context; an AI compiler needs explicit guidance. MSFM gives you a way to attach that guidance without abandoning prose.
The alternative is structured formats like JSON or YAML. Those are precise but unreadable at scale. A 2,000-word procurement spec in JSON is a wall of nested objects. The same spec in MSFM is a readable document with annotations where ambiguity exists. You can email it, paste it into a chat, diff it in git, and read it in any text editor. The annotations are just more context, not a separate schema layer.
For more on why the spec layer matters, see Claude Code’s agentic workflow patterns — the same principle applies: structured prompts produce more reliable results than freeform conversation.
How Do Block Annotations Work?
A block annotation is a fenced block using tildes (~~~) that attaches to the content immediately above it. It clarifies, corrects, or extends the preceding paragraph, heading, list, or table.
Syntax
When requesting a new vendor, there are three areas of review:
governance, legal, and accounting, with approvals flowing in that order.
~~~
The spec says "three areas" but lists four names. From the process flowchart, it is three sequential stages:
1. Governance, Risk & Compliance (GRC), one combined stage
2. Legal
3. Accounts Payable (AP)
These are sequential. Each stage must complete before the next is notified. If any stage rejects, the entire request is rejected.
~~~
The annotation resolves an ambiguity in the prose. Without it, the compiler might generate four separate approval stages. With it, the compiler knows it’s three sequential stages with specific rejection semantics.
Rules
- Starts and ends with
~~~on its own line - Attaches to the nearest preceding block element (paragraph, heading, table, list)
- Multiple annotations can follow the same element (read in order)
- Can contain any Markdown content, including backtick code fences (tildes and backticks coexist)
When to Use Block Annotations
Annotate ambiguity, not the obvious. If a statement has only one reasonable interpretation, leave it alone. Block annotations answer “what happens when…” questions:
- What happens when a reviewer rejects?
- What happens when the amount is exactly on the threshold?
- What happens when no user has the required role?
- What happens when this is called twice?
They also pin down data representations:
The purchase order total must not exceed the approved budget.
~~~
Amounts are stored as integer cents (USD). The `totalAmountCents` column is an integer, not a float. A $150.00 purchase order has `totalAmountCents: 15000`.
~~~
How Do Inline Annotations Work?
Inline annotations attach to a specific word or phrase. The [text] is the visible, highlighted span. The {content} is the annotation, hidden by default in a rich editor and visible as literal text in plain Markdown.
Syntax
All invoices can be sent to the [Accounts Payable]{The AP team in
this context refers to the internal accounts payable department, not
a vendor's AP. Only users with the "ap" or "admin" role can process
invoices.} team for processing against the PO.
The annotation clarifies that “Accounts Payable” means the internal team, not a vendor’s department, and specifies the role enforcement.
Everyone else built a construction worker.
We built the contractor.
One file at a time.
UI, API, database, deploy.
When to Use Inline Annotations
Good for definitions, units, and role clarifications:
The PO [amount]{Total across all line items, in USD cents (integer).
Does not include tax, shipping, or fees.} must not exceed the approved
budget for the [cost center]{The organizational budget code that this
purchase is charged to.}.
Inline annotations keep the prose readable while attaching precision exactly where it’s needed. They’re lighter-weight than block annotations and work well for single-concept clarifications.
What Are Pointers and When Should You Use Them?
When an annotation is too large for inline placement (lists, code, tables), use a pointer. The inline reference {#id} points to a block annotation tagged with the same ID.
Syntax
The AP team pays the vendor according to the [contract payment terms]{#payment-terms}.
~~~#payment-terms
We do not model payment terms (net 30, net 60, etc.) on the PO or vendor. The dueDate on the invoice is the sole payment trigger.
A production implementation would:
- Store terms on the vendor record (net_30, net_60, due_on_receipt)
- Auto-calculate dueDate from invoiceDate + terms
- Support early payment discounts (2/10 net 30)
Default behavior when no terms are specified: due on receipt.
~~~
The {#payment-terms} inline reference points to the ~~~#payment-terms block. Keep the block co-located, right after the paragraph containing the pointer.
Multiple Pointers to One Block
A single block annotation can be referenced by multiple pointers. Useful for concepts like “amounts are in USD cents” that apply in several places:
The PO [amount]{#usd-cents} must not exceed the budget.
Each line item has an [amount]{#usd-cents} and a description.
~~~#usd-cents
All monetary amounts are stored as integer cents (USD). A $150.00 value is represented as 15000.
~~~
What Are Typography and Colors Blocks?
MSFM supports two special code fence language tags for design system declarations: typography and colors. These are standard Markdown code fences, not MSFM-specific syntax. The MindStudio editor renders them as rich interactive UI; in a plain Markdown viewer they appear as readable YAML.
Typography Block
Declares fonts with source URLs and named type styles:
```typography
fonts:
- name: Inter
source: https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700
- name: JetBrains Mono
source: https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500
styles:
- name: Heading 1
font: Inter
size: 32px
weight: 700
letterSpacing: -0.02em
lineHeight: 1.2
description: Page titles and primary headings
- name: Body
font: Inter
size: 16px
weight: 400
letterSpacing: 0
lineHeight: 1.5
description: Default paragraph text
- name: Code
font: JetBrains Mono
size: 14px
weight: 400
letterSpacing: 0
lineHeight: 1.4
description: Inline code and code blocks
```
These typically live in src/interfaces/@brand/visual.md and define the app’s typography system. The agent uses them when generating frontend code.
Colors Block
Declares named colors with hex values and descriptions:
```colors
- name: Primary
value: "#3B82F6"
description: Primary brand color, used for CTAs and links
- name: Surface
value: "#FFFFFF"
description: Default background for cards and panels
- name: Text Primary
value: "#1F2937"
description: Default text color for body content
- name: Text Secondary
value: "#6B7280"
description: Muted text for labels and metadata
- name: Border
value: "#E5E7EB"
description: Default border color for dividers and inputs
- name: Error
value: "#EF4444"
description: Error states and destructive actions
```
One coffee. One working app.
You bring the idea. Remy manages the project.
Colors and typography blocks are editable through the editor’s visual UI. The user picks colors from a palette and adjusts font sizes with sliders; the editor writes the YAML back to the spec file.
How Does MSFM Stay Markdown-Compatible?
MSFM is a strict superset of Markdown. Every valid Markdown file is valid MSFM. The annotation primitives render as standard Markdown elements:
| MSFM feature | Renders as in standard Markdown |
|---|---|
Block annotation (~~~...~~~) | Fenced code block |
Inline annotation ([text]{content}) | Literal text with brackets |
Pointer ([text]{#id}) | Literal text |
Tagged block (~~~#id) | Fenced code block with #id visible |
| Typography/colors blocks | Fenced code blocks with language tags |
| Everything else | Standard Markdown |
Specs are fully readable in GitHub, VS Code, or any Markdown previewer. The annotations appear as code blocks and bracketed text. Nothing breaks. This is by design — MSFM files are portable, diffable, and usable in any tool that reads Markdown.
For a deeper look at how annotated prose compiles into working applications, see What Is Claude Mythos? Anthropic’s Most Powerful Model Explained — Anthropic’s frontier model uses similar annotation-driven reasoning to produce deterministic outputs from natural language.
What Are the Authoring Conventions?
Annotate Ambiguity, Not the Obvious
If a statement has only one reasonable interpretation, leave it alone. Annotations resolve genuine ambiguity — places where two engineers might implement different things.
Pin Down Edge Cases
The most valuable annotations answer “what happens when…” questions. What happens when a reviewer rejects? What happens when the amount is exactly on the threshold? What happens when no user has the required role?
Specify Data When It Matters
When “amount” could mean integer cents or decimal dollars, annotate the representation. When “status” could be any string, list the valid values.
Let the Spec Breathe
Not every paragraph needs annotations. A spec with more annotation than prose is over-specified. Annotate the hard parts. Trust the compiler on the straightforward parts.
How Does the Agent Use MSFM?
When Remy reads a spec:
- Understands the domain. The prose gives it the big picture: what the app does, who uses it, how it works.
- Reads annotations for precision. Annotations resolve the ambiguities that would otherwise produce inconsistent code.
- Generates the contract. Methods, tables, and roles in
dist/that implement the spec. - Maintains consistency. When modifying code, the agent checks against the spec to ensure changes are semantically correct, not just syntactically valid.
The spec is also what makes the project onboardable. A new developer (or a different AI agent) can read src/app.md and understand the entire application without reading any code.
For a related example of how AI models use structured context, see What Is Andrej Karpathy’s LLM Wiki? How to Build a Personal Knowledge Base With Claude Code — the same principle applies: structured input produces better reasoning.
What Is Remy?
Remy is a product agent that compiles annotated markdown into a full-stack app — backend, database, frontend, auth, tests, and deployment — in a single step. See goremy.ai.
FAQ
Is MSFM a new language?
No. MSFM is Markdown with three annotation primitives added. Every valid Markdown file is valid MSFM. You can write MSFM in any text editor, render it in any Markdown viewer, and diff it in git like any other Markdown file.
Do I have to write MSFM by hand?
No. Remy users describe what they want in plain language (voice, text, or pasted documents), and the agent generates the MSFM spec on their behalf. The spec is the source of truth, but you don’t write it by hand unless you want to. Developers building directly on the platform can write MSFM specs manually, but most users interact with Remy conversationally.
What happens if I don’t use annotations?
A bare spec with no annotations is valid. The compiler does its best to infer intent from the prose. Each annotation makes compilation more deterministic. If your spec is unambiguous without annotations, you don’t need them. Annotations are additive precision, not a requirement.
Can I use MSFM outside of Remy?
Yes. MSFM is just Markdown with annotations. You can use it for any documentation that benefits from attaching precision to prose. The ~~~ and [text]{content} syntax works in any context where you want to clarify ambiguity without breaking Markdown compatibility.
How does MSFM compare to other spec formats?
MSFM is optimized for readability and AI compilation. JSON and YAML are precise but unreadable at scale. OpenAPI is structured but verbose. MSFM gives you the readability of prose with the precision of annotations exactly where you need them. It’s a strict superset of Markdown, so it works everywhere Markdown works.
What’s the difference between block and inline annotations?
Block annotations attach to the nearest preceding block element (paragraph, heading, list, table) and can contain multiple paragraphs, lists, code, tables. Inline annotations attach to a specific word or phrase and are typically one or two sentences. Use block annotations for edge cases, business rules, and data representations. Use inline annotations for definitions, units, and role clarifications.
Can I nest annotations?
No. Annotations are flat. A block annotation can contain Markdown content (including code fences), but it can’t contain another block annotation. Inline annotations can’t contain other inline annotations. This keeps the syntax simple and the parser unambiguous.
How do I know when to use a pointer vs an inline annotation?
Use a pointer when the annotation is too large for inline placement (lists, code, tables). Use an inline annotation when the clarification is one or two sentences. Pointers keep the prose readable by moving large annotations out of the flow.
Are typography and colors blocks required?
No. They’re optional design system declarations that live in src/interfaces/@brand/visual.md. If your app doesn’t need custom typography or colors, you don’t need these blocks. The agent uses them when generating frontend code, but they’re not required for backend compilation.
How does MSFM handle versioning?
MSFM files are plain text, so they version like any other source file. Diff them in git, track changes over time, roll back to previous versions. The spec is the source of truth, and the compiled code in dist/ is regenerated from the spec on every build.
Start Writing MSFM
Plans first. Then code.
Remy writes the spec, manages the build, and ships the app.
MSFM is Markdown with annotations. If you can write Markdown, you can write MSFM. Start with prose that describes what the app does. Add annotations where ambiguity exists. Pin down edge cases, data representations, and business rules. Let the spec breathe — not every paragraph needs annotations.