The MOML 2.0 rules.

A compact reference for the language contract.

1. Everything is a string.timeout = 45 returns the string "45".
2. Bare unless quoting is required.name = Mike and name = "Mike" mean the same scalar.
3. Backslash is literal outside quotes.path = C:\Users\Karim survives exactly.
4. # comments only at line start.hotkey = #h and color = #085041 are data.
5. Blocks have one structural mode.Dictionary-like entries may mix pairs and named child blocks. Bare list items may not be mixed with them.
6. Commas make inline lists; * is structural only in blocks.colors = red, green is a list. In providers = groq, *openrouter, the * is ordinary text.
7. Empty values and one-item list preservation.key = is an empty string. A one-item inline list is written with one trailing explicit "" so its list shape survives a parser-only round trip.
File identity.Every document begins with # MOML 2.0 and MOML 2.0 files use .m2.
Important: * has two meanings depending on context.Inside a { } block, a leading * marks the active item or named entry. Inside an inline comma list, * has no structural meaning and remains part of the string.

Dictionary-like blocks

provider {
    c1 = openrouter

    details {
        d1 = Hello
        d2 = World
    }

    details1 = Hello, World
}

key = value, inline list values, and named child blocks are all named entries, so they can coexist.

List-like blocks

providers {
    openrouter
    anthropic
   *openai
}

A bare-item block is a list. Do not mix bare items with key = value or named blocks inside the same container.

Rule 7: why the one-item list sentinel exists

This rule is a deliberate round-trip preservation choice, not type inference. MOML stores strings and structure only, so models = llama4 has no way to tell the parser whether the application intended a scalar string or a one-item list.

Scalar:             models = llama4
One-item list:      models = llama4, ""

The trailing explicit empty string is a structural sentinel used only to preserve list shape when the writer serializes a one-item inline list. MOML preserves it exactly; a schema-aware Gatekeeper may remove one trailing structural empty before returning that setting to the application.

Why MOML chooses this compromiseWithout the sentinel, a one-item list would collapse to a scalar on read-back. Avoiding it would require brackets, type markers, schema-aware parsing, or another special syntax. MOML deliberately accepts this small visible convention in one narrow case to keep the rest of the language typeless, minimal, and round-trip stable. Normal scalars and lists with two or more items are unaffected.

Nested blocks

provider {
    details {
        details2 {
            x1 = New
            x2 = Old
        }
    }
}

Nesting depth is not the restriction; structural consistency inside each individual block is.

Quoted strings

Inside quotes MOML defines exactly four escapes: \\, \", \n, and \t. Outside quotes, backslash is ordinary data.

Mental modelA block is either dictionary-like or list-like. Named blocks are simply named dictionary entries whose values are nested containers.