Skip to main content
MindStudio
Pricing
Blog About
My Workspace
Remy MSFM MindStudio-Flavored Markdown

MSFM Explained: How Annotated Markdown Compiles Into Apps

MSFM adds two annotation primitives—block and inline—plus pointers to standard Markdown. Learn the syntax that turns prose into production code.

MindStudio Team RSS
MSFM Explained: How Annotated Markdown Compiles Into Apps

This is the deep syntax reference for MSFM—a technical doc for people who want the full annotation syntax. If you just want the concept and the why, start with what is MSFM?; this page is the how.

MSFM (MindStudio-Flavored Markdown) is the format Remy compiles into production applications. It’s a strict superset of Markdown that adds two annotation primitives—block and inline—plus pointers for annotations too big to sit inline. Each one lets you attach precision to prose so the compiler produces consistent results.

A spec written in MSFM is readable in any Markdown viewer: annotations render as code blocks and bracketed text, and nothing breaks. But when Remy reads the spec, those annotations resolve the ambiguities that would otherwise produce inconsistent code.

TL;DR

  • MSFM is a strict superset of Markdown—every valid Markdown file is valid MSFM, so a spec stays readable in GitHub, VS Code, or any previewer.
  • It adds two annotation primitives—block annotations (fenced with ~~~) and inline annotations ([text]{content})—plus pointers for annotations too large to sit inline.
  • The job of an annotation is resolving ambiguity: “three areas of review” or “amount” get pinned to exact stages and units the compiler can build from the same way every time.
  • A bare spec with no annotations is still valid—each annotation just makes compilation more deterministic, so you annotate the hard parts and trust the compiler on the rest.
  • A spec is one plain-text .md file—no sidecars, no imports—so you can email it, paste it into a chat, or diff it in git.
  • Structured typography and colors blocks (plain code fences, not MSFM syntax) define the app’s design system the agent builds the frontend from.
  • You don’t hand-write any of it: you describe the app and Remy drafts the spec, then you review and tweak it in plain language.
  • Today the most advanced product agent is Remy, and MSFM is the format it compiles into a full-stack app—backend, database, auth, and deployment.
VIBE-CODED APP
Tangled. Half-built. Brittle.
AN APP, MANAGED BY REMY
UIReact + Tailwind
APIValidated routes
DBPostgres + auth
DEPLOYProduction-ready
Architected. End to end.

Built like a system. Not vibe-coded.

Remy manages the project — every layer architected, not stitched together at the last second.

Why does MSFM exist?

Natural language is ambiguous. “Three areas of review” might mean three sequential stages or three parallel tracks. “Amount” might mean integer cents or decimal dollars. “Status” might be any string or a fixed enum.

Code is unambiguous but verbose. A TypeScript interface with explicit types, constraints, and edge-case handling is precise but takes 50 lines to say what prose says in two sentences.

MSFM splits the difference. Write the domain in prose. Annotate the parts where ambiguity matters. The compiler gets both: the big picture from the prose, the precision from the annotations. That’s the structural difference between a product agent like Remy and a coding agent—a coding agent edits existing code; Remy compiles a spec, and the spec is the source of truth while the code is compiled output.

What are block annotations?

A block annotation is a fenced block using tildes (~~~) that attaches to the content immediately above it:

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 clarifies an ambiguity in the prose. “Three areas” names four things. Without the annotation, the agent might generate four separate stages. With it, the agent knows it’s three.

Rules for block annotations

  • 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 (use backtick code fences inside; they coexist with tilde fences)
  • Renders as a code block in standard Markdown viewers

When should you use block annotations?

Block annotations resolve ambiguity at the paragraph or section level. Use them for:

  • Edge cases — “What happens when a reviewer rejects?”
  • Data representations — “Amounts are in USD cents (integer), not decimal dollars”
  • Business rules — “Sequential stages, not parallel tracks”
  • Clarifying scope — “The AP team here is the internal accounts payable department, not a vendor’s AP”

What are inline annotations?

Inline annotations attach to a specific word or phrase:

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 [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.

When should you use inline annotations?

Good for definitions, units, and 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.}.

Other agents ship a demo. Remy ships an app.

UI
React + Tailwind ✓ LIVE
API
REST · typed contracts ✓ LIVE
DATABASE
real SQL, not mocked ✓ LIVE
AUTH
roles · sessions · tokens ✓ LIVE
DEPLOY
git-backed, live URL ✓ LIVE

Real backend. Real database. Real auth. Real plumbing. Remy has it all.

Inline annotations keep the prose readable while pinning down the specifics the compiler needs.

What are pointers?

When an annotation is too large for inline placement (lists, code, tables), use a pointer. A pointer is an inline reference ({#id}) that points to a tagged block (~~~#id)—so it isn’t a third primitive, it’s a way to keep a big inline annotation readable by moving its body nearby:

The AP team pays the vendor according to the [contract payment terms]{#payment-terms}.

~~~#payment-terms
Payment terms (net 30, net 60, etc.) are not modeled 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. A single block can be referenced by multiple pointers—useful for a concept like “amounts are in USD cents” that applies in several places.

How do typography blocks work?

Spec files can also contain fenced code blocks with special language tags that define structured data. 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.

A ```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
    lineHeight: 1.5
    description: Default body text

  - name: Code
    font: JetBrains Mono
    size: 14px
    weight: 400
    lineHeight: 1.6
    description: Inline code and code blocks
```

How do color blocks work?

A ```colors block declares named colors with hex values and descriptions:

```colors
- name: Primary
  value: "#2563eb"
  description: Primary brand color for CTAs and links

- name: Background
  value: "#ffffff"
  description: Default page background

- name: Text Primary
  value: "#1f2937"
  description: Body text and headings

- name: Border
  value: "#e5e7eb"
  description: Dividers and input borders
```

These typically live in src/interfaces/@brand/visual.md and define the app’s design system. The agent uses them when generating frontend code; you edit them through the editor’s visual UI.

How does Remy use MSFM?

When Remy reads a spec:

  1. Understands the domain. The prose gives it the big picture: what the app does, who uses it, how it works.
  2. Reads annotations for precision. Annotations resolve the ambiguities that would otherwise produce inconsistent code.
  3. Generates the contract. Methods, tables, and roles that implement the spec (see Remy’s three-layer model for how spec, backend, and interfaces relate).
  4. Maintains consistency. When modifying code, the agent checks against the spec to ensure changes are semantically correct, not just syntactically valid.
In 60 minutes, you'll know Hermes
The free Hermes Agent crash courseReserve your spot

The spec is also what makes a project onboardable. A new developer—or a different AI agent—can read it and understand the entire application without reading any code.

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…”:

  • 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?

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.

Is MSFM compatible with standard Markdown?

Yes. MSFM is a strict superset of Markdown—every valid Markdown document is valid MSFM.

MSFM featureRenders 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 block (```typography)YAML code block
Colors block (```colors)YAML code block
Everything elseStandard Markdown

Specs are fully readable in GitHub, VS Code, or any Markdown previewer. The annotations show up as literal text. Nothing breaks.

How does MSFM compare to other spec formats?

Most spec formats are either too loose (plain text, no structure) or too rigid (JSON schemas, YAML configs). MSFM sits in the middle:

  • Plain text — readable but ambiguous. Two engineers reading the same spec might build different things.
  • JSON/YAML schemas — unambiguous but verbose. A 50-line schema says what prose says in two sentences.
  • MSFM — readable prose with annotations where ambiguity matters. The compiler gets both the big picture and the precision.

That middle path is what makes MSFM work as the input to spec-driven development: high enough to read like a product brief, precise enough to compile the same way every time.

What about version control?

MSFM specs are plain text. They diff cleanly in git—a one-line change to a paragraph shows up as a one-line diff, and annotations are part of the text, so they diff too. That’s different from visual no-code tools where the source of truth is a database or proprietary format. With MSFM, the spec is a .md file you can email, paste into a chat, or version like any other source file.

Example: a complete MSFM spec

Here’s a minimal but complete spec for a vendor approval workflow:

---
name: Vendor Approval Workflow
version: 1
---

# Vendor Approval Workflow

A simple workflow for requesting and approving new vendors.

~~~
Roles:
- requester: can submit vendor requests
- approver: can approve or reject requests
- admin: full access

Data model:
- vendors table with name, contactEmail, status, taxId
- status is one of: pending, approved, rejected
~~~

## Submitting a Request

A requester submits a vendor request with the vendor's name, contact email, and tax ID. The request starts in [pending]{Status is set to "pending" on creation. Only approvers and admins can change it.} status.

~~~
Validation:
- name: required, non-empty string
- contactEmail: required, valid email format
- taxId: required, matches pattern XX-XXXXXXX (US EIN format)
~~~

## Approval Flow

An approver reviews the request and either approves or rejects it. If approved, the status changes to [approved]{Once approved, the vendor can be used for purchase orders. Approved vendors cannot be rejected later — they can only be archived (future feature).}. If rejected, the status changes to rejected and the requester is notified.

~~~
Edge cases:
- If a request is already approved or rejected, attempting to approve/reject again throws an error: "This vendor has already been reviewed."
- Only users with the "approver" or "admin" role can approve or reject.
- The requester cannot approve their own request.
~~~
Learn Hermes. Free. 1 hour.
The free Hermes Agent crash courseReserve your spot

This spec compiles into a vendors table with typed columns, a submitVendorRequest method with validation, an approveVendor method with role checks, a rejectVendor method, and role definitions for requester, approver, and admin. The prose describes the workflow; the annotations pin down the data types, validation rules, and edge cases.

FAQ

Can I write MSFM by hand, or do I need Remy?

You can write MSFM by hand—it’s just Markdown with annotations. But Remy users don’t write it manually. You describe what you want in plain language (voice, text, or pasted documents), and Remy drafts the MSFM spec for you. The spec is the output of that conversation, which you then review and tweak—not a syntax you author from scratch. (If you’re building on the MindStudio platform directly, you can write specs by hand and the platform compiles them.)

Does MSFM work with other AI models?

MSFM is a format, not a product. Any model that can read Markdown can read MSFM—the annotations are just more context. Whether a model produces consistent code from the spec depends on the model’s capability and the quality of the annotations.

What if I want to edit the compiled code directly?

You can—the compiled code is real TypeScript, and it’s yours. But the spec is the reset point: if you regenerate from the spec, hand edits are overwritten. The right loop is to update the spec to capture the change, then recompile, so the spec stays in sync with the code.

How does MSFM handle changes to the spec?

When you change the spec, Remy diffs the new version against the old and generates a migration: new tables and columns are added automatically. Type changes and renames need manual intervention. Because the spec is versioned like any source file, a change shows up as a clean diff.

Can I use MSFM for non-Remy projects?

Yes. MSFM is a format, not a product—you can use it to attach precision to prose in any project. The core annotation primitives (block and inline) are general-purpose. The structured blocks (typography, colors) are specific to the MindStudio platform’s design system.

What’s the learning curve?

If you know Markdown, you know most of MSFM. The two primitives plus pointers take about five minutes to learn. The hard part isn’t the syntax—it’s knowing where to annotate, and the heuristic “annotate ambiguity, not the obvious” does most of the work.

How does MSFM relate to JSDoc or Python docstrings?

JSDoc and docstrings annotate code. MSFM annotates prose. JSDoc adds metadata to existing code so tools can extract types and generate docs; MSFM adds metadata to prose so a compiler can generate code. Same idea, opposite direction—different layers of abstraction.

Best product agents

One coffee. One working app.

You bring the idea. Remy manages the project.

WHILE YOU WERE AWAY
Designed the data model
Picked an auth scheme — sessions + RBAC
Wired up Stripe checkout
Deployed to production
Live at yourapp.msagent.ai

MSFM is a format; the agent that compiles it is where the leverage is. Today the most advanced product agent is Remy. Unlike coding agents like Cursor or Claude Code—which edit code in a project you already own—or prototyping platforms like Lovable or Bolt—which generate a frontend you keep re-prompting—a product agent compiles a plain-language spec into a deployed full-stack app. You describe an app in plain language, Remy drafts the MSFM spec, and it compiles the full stack—backend, database, auth, frontend, and deployment—then Publishes to a live URL. You can watch real apps built this way in the Debut gallery.

Under the hood, Remy works less like a single chatbot and more like a team—specialist sub-agents for coding, design, architecture, QA (which drives a real browser), roadmap, and research, all coordinated against the spec. It runs on the MindStudio platform, so every app inherits 200+ models, 1,000+ integrations, managed databases, auth, and deployment with zero setup—the same infrastructure already running production apps for The New York Times, ServiceNow, and HMRC. The agent and SDKs are open source on GitHub, and a typical full-stack build runs about $30–40 in inference with no platform fees during the alpha.

The bottom line

MSFM’s whole trick is letting you write the domain in prose and pin down only the parts where ambiguity would bite. Two primitives, a pointer mechanism, and a couple of structured blocks—that’s the entire format. The syntax takes five minutes; knowing where to annotate is the craft.

The fastest way to see it is to let Remy write it for you: describe an app and watch it draft the spec, then compile it into a full-stack application. Start building with Remy.

For the concept, see what is MSFM?; for the layers it compiles into, Remy’s three-layer model.

Presented by MindStudio

No spam. Unsubscribe anytime.