markedin.dev

markedin.mi

The file format for agentic systems and the humans who work with them.

Structured YAML frontmatter. Markdown body that renders from it. One file — the agent reads the data, the human reads the document. No separate data file. No sync problem.

Two files for the same information

An agent working with files needs structured data it can reliably read and write — JSON or YAML, with known keys at known paths. A human reading that same file needs prose: headings, context, the information arranged to make sense.

That creates a tradeoff: Markdown is readable but unreliable for agents; JSON/YAML are reliable but hard for humans. The goal is one file that serves both.

Markedin (.mi) solves this: frontmatter as structured data, the body as its template. Agents write to the data; the output renders automatically.

One file. One source of truth — human- and agent-friendly by default.

Source and output from one file

The frontmatter is full YAML — scalars, objects, arrays, nested. The body is markdown with {{ }} expressions that resolve against it. Run the renderer and get clean markdown. Query the frontmatter directly and get structured JSON. Same file, either path.

Source — task.mi
task.mi yaml + markdown
---
task: Implement rate limiting
status: in_progress
owner:
  name: Dana
  team: Platform
priority: high
notes:
  - Token bucket algorithm
  - 100 req/min per API key
blocked: false
---

# {{task}}

**Status:** {{status}} · **Owner:** {{owner.name}} ({{owner.team}})

First note: {{notes[0]}}

## Notes

{{#each notes}}
- {{this}}
{{/each}}

{{#if blocked}}
⚠️ This task is currently blocked.
{{else}}
✅ No blockers.
{{/if}}
Rendered output
stdout markdown
# Implement rate limiting

**Status:** in_progress · **Owner:** Dana (Platform)

First note: Token bucket algorithm

## Notes

- Token bucket algorithm
- 100 req/min per API key

✅ No blockers.
Readable without rendering. A raw .mi file is still legible — {{task}} in place of the resolved value is a minor interruption, not a broken document. Commit them to a repo and they read fine in any file viewer.

Six expressions

The full template surface. Everything resolves against the frontmatter of the same file.

Expression Resolves to
{{key}} Scalar value. Arrays render comma-separated inline.
{{key.nested}} Dot-path into an object.
{{array[0]}} Array index. Bracket and dot notation both work.
{{#each items}} … {{/each}} Iterate an array. Object fields available directly. {{@index}}, {{@first}}, {{@last}} available inside the block.
{{#if key}} … {{else}} … {{/if}} Conditional block. Falsy: false, 0, empty string, null, [], {}.
{{> key}} Inline a frontmatter string value as raw text — for reusable prose fragments.

One binary, multiple outputs

usage sh
mi <file.mi> Render to markdown on stdout (default).
mi <file.mi> --html Render to a full HTML document.
mi <file.mi> --html-frag HTML fragment — body content only, no wrapper.
mi <file.mi> --json Print frontmatter as JSON.
mi <file.mi> --yaml Print frontmatter as YAML.
mi <file.mi> --embed Include frontmatter in the output.
mi check <file.mi> Validate that frontmatter parses cleanly.
For agents. --json is the read path — structured JSON out, no prose parsing. Write updated values back into the YAML block. The rendered markdown follows.