/api/yaml/format
MCP tool yaml_format Parses input as YAML 1.2 (core schema) and reports every finding with its rule, severity, line, column and offset. Rules follow yamllint's default set and names: syntax, key-duplicates, anchors, braces, brackets, colons, commas, comments, comments-indentation, document-start, empty-lines, empty-values, hyphens, indentation, line-length, new-line-at-end-of-file, new-lines, octal-values, quoted-strings, trailing-spaces, truthy, byte-order-mark. Errors (syntax, key-duplicates, an alias without an anchor) make the document invalid; everything else is a warning or info. An invalid document is still a 200 response, with valid: false, the findings, and formatted and value set to null. When the YAML is valid, formatted is the document re-written with the chosen indentation, one space after colons and hyphens, no padding inside {}/[], at most one blank line in a row, LF line breaks and a final newline. Comments, anchors, tags, key order, block scalars and the text of numbers are kept; quotes are removed only where the plain form means the same string in YAML 1.2 and 1.1 ("yes", "0755", "null" stay quoted). The formatted text is re-parsed and compared with the input before it is returned, so it always has the same value. value is the data as JSON: the first document's value, or an array of all documents when there are several (merge keys applied, at most 1,000 alias expansions).
Browser version (runs locally): YAML Format & Validate.
Try it
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
input required | string (≤ 15000 chars) | — | The YAML text, as a string field or a raw text/plain POST body. |
indent | 2 | 4 | 2 | Spaces per indentation level, for the indentation rule and the formatted output. |
indent_sequences | consistent | indented | flush | consistent | How a sequence under a mapping key is indented: indented (key: then - item), flush (- item at the key’s column), or consistent (either, as long as the whole file does the same; the first one decides). yamllint’s indent-sequences. |
max_line_length | integer (0–1000) | 120 | Longest allowed line, in characters, for the line-length rule; 0 turns the rule off. The default is 120 (yamllint’s is 80, which most Kubernetes and CI files exceed). |
document_start | ignore | require | forbid | ignore | require: every document starts with ---. forbid: the first document has no ---. ignore: either. Applies to the findings and the formatted output. |
quote_style | any | single | double | any | single or double: quoted values should use that quote character (quoted-strings rule), and the formatter converts them. any: no check, and the formatter removes quotes that are not needed. |
Also accepted on every endpoint: format (json | text).
Parameters may come from the query string, a JSON object body, an urlencoded or multipart form,
or (for input) a text/plain body.
Global parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
format | json | text | json | json returns the documented object. text returns only the primary value as text/plain (see "Text output"). |
Response 200 application/json
| Field | Type | Description |
|---|---|---|
valid | boolean | True when there are no error findings: the YAML parses, has no duplicate keys and every alias has an anchor. |
summary | object | |
summary.valid | boolean | True when there are no error findings. |
summary.errors | integer | Number of errors. |
summary.warnings | integer | Number of warnings. |
summary.infos | integer | Number of informational findings. |
diagnostics | array of object | Findings in document order. |
diagnostics[].rule | string | Rule ID, e.g. syntax, duplicate-keys, trailing-spaces. |
diagnostics[].severity | "error" | "warning" | "info" | error makes the document invalid; warning and info are style. |
diagnostics[].message | string | What is wrong and how to fix it. |
diagnostics[].line | integer | 1-based line where the problem starts. |
diagnostics[].column | integer | 1-based column (Unicode code points). |
diagnostics[].offset | integer | 0-based UTF-16 offset into the input. |
diagnostics[].endLine optional | integer | 1-based end line, when the problem spans a range. |
diagnostics[].endColumn optional | integer | 1-based end column. |
diagnostics[].endOffset optional | integer | 0-based end offset. |
documents | integer | Number of YAML documents in the input (0 for an empty or comment-only input). |
formatted | string | null | The formatted YAML, ending with a newline (empty for an empty input); null when the YAML is invalid. |
value | any | The data as JSON: the first document’s value, or an array of every document’s value when there are several; null when invalid. Integers beyond 2^53 − 1 lose precision; .inf and .nan become null. |
Text output (format=text, text/plain): The formatted YAML; when the YAML is invalid, one finding per line (line:column severity rule message).
Errors
Errors are JSON: {"error": "<message>", "code": "<code>", "param": "<name>"?}.
| Status | Code | When |
|---|---|---|
400 | invalid_parameter | input is longer than 15,000 characters (use the page for larger files), or an option is not a listed value. |
400 | missing_parameter | A required parameter is absent. |
400 | unknown_parameter | A parameter name is not in the table above (typos are rejected, not ignored). |
413 | payload_too_large | The request body exceeds 1 MiB. |
405 | method_not_allowed | A method other than GET, POST or OPTIONS. |
Behaviour
- Idempotent: the same arguments always return the same result.
-
Requires a client ID and secret (authentication). Each call is
recorded as one metadata row against your client ID; inputs and outputs are never stored or
logged. Responses carry
cache-control: no-store. - CORS: any origin may call this endpoint from a browser, using your credentials.
Examples
Responses below were produced by running each request through this code at build time. Long strings are shortened.
yamllint-style findings
curl -X POST 'https://util.caruana.me/api/yaml/format' \
-H 'content-type: application/json' \
-d '{"input":"server :\n host: example.com\n port: 8080\n enabled: yes\n mode: 0755\nlist: [ a,b ]\nempty:\n#no space\nname: x \n"}'
Response 200
{
"valid": true,
"summary": {
"valid": true,
"errors": 0,
"warnings": 10,
"infos": 1
},
"diagnostics": [
{
"rule": "colons",
"severity": "warning",
"message": "Too many spaces before colon (1; expected 0).",
"line": 1,
"column": 7,
"offset": 6,
"endLine": 1,
"endColumn": 8,
"endOffset": 7
},
{
"rule": "indentation",
"severity": "warning",
"message": "Wrong indentation: expected 2 spaces but found 4.",
"line": 2,
"column": 1,
"offset": 9,
"endLine": 2,
"endColumn": 5,
"endOffset": 13
},
{
"rule": "colons",
"severity": "warning",
"message": "Too many spaces after colon (2; expected 1).",
"line": 3,
"column": 11,
"offset": 41,
"endLine": 3,
"endColumn": 12,
"endOffset": 42
},
{
"rule": "truthy",
"severity": "warning",
"message": "yes is the string \"yes\" in YAML 1.2 but a boolean in YAML 1.1. Write true or false for a boolean, or quote it for a string.",
"line": 4,
"column": 14,
"offset": 60,
"endLine": 4,
"endColumn": 17,
"endOffset": 63
},
{
"rule": "octal-values",
"severity": "warning",
"message": "0755 is the decimal 755 in YAML 1.2 but octal (493) in YAML 1.1. Write 0o755 for octal, 755 for decimal, or quote it for a string.",
"line": 5,
"column": 11,
"offset": 74,
"endLine": 5,
"endColumn": 15,
"endOffset": 78
},
{
"rule": "brackets",
"severity": "warning",
"message": "Too many spaces inside brackets (1; expected 0).",
"line": 6,
"column": 8,
"offset": 86,
"endLine": 6,
"endColumn": 9,
"endOffset": 87
},
{
"rule": "commas",
"severity": "warning",
"message": "Too few spaces after comma (0; expected 1).",
"line": 6,
"column": 11,
"offset": 89
},
{
"rule": "brackets",
"severity": "warning",
"message": "Too many spaces inside brackets (1; expected 0).",
"line": 6,
"column": 12,
"offset": 90,
"endLine": 6,
"endColumn": 13,
"endOffset": 91
},
{
"rule": "empty-values",
"severity": "info",
"message": "Empty value for key \"empty\": it is null. Write null or ~ to make that explicit, or give it a value.",
"line": 7,
"column": 6,
"offset": 98,
"endLine": 7,
"endColumn": 7,
"endOffset": 99
},
{
"rule": "comments",
"severity": "warning",
"message": "Missing space after \"#\" at the start of the comment.",
"line": 8,
"column": 2,
"offset": 101
},
{
"rule": "trailing-spaces",
"severity": "warning",
"message": "Trailing whitespace.",
"line": 9,
"column": 8,
"offset": 117,
"endLine": 9,
"endColumn": 11,
"endOffset": 120
}
],
"documents": 1,
"formatted": "server:\n host: example.com\n port: 8080\n enabled: yes\n mode: 0755\nlist: [a, b]\nempty: #no space\n\nname: x\n",
"value": {
"server": {
"host": "example.com",
"port": 8080,
"enabled": "yes",
"mode": 755
},
"list": [
"a",
"b"
],
"empty": null,
"name": "x"
}
}
Same call as an MCP tools/call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "yaml_format",
"arguments": {
"input": "server :\n host: example.com\n port: 8080\n enabled: yes\n mode: 0755\nlist: [ a,b ]\nempty:\n#no space\nname: x \n"
}
}
}Format with comments kept, 4-space indent
curl -X POST 'https://util.caruana.me/api/yaml/format' \
-H 'content-type: application/json' \
-d '{"input":"# Service settings\nservice:\n name: \"web\" # quotes are not needed here\n replicas: 3\n ports:\n - 80\n - 443\n country: \"no\" # stays quoted: YAML 1.1 reads no as false\n","indent":4,"indent_sequences":"indented"}'
Response 200
{
"valid": true,
"summary": {
"valid": true,
"errors": 0,
"warnings": 3,
"infos": 0
},
"diagnostics": [
{
"rule": "indentation",
"severity": "warning",
"message": "Wrong indentation: expected 4 spaces but found 2.",
"line": 3,
"column": 1,
"offset": 28,
"endLine": 3,
"endColumn": 3,
"endOffset": 30
},
{
"rule": "indentation",
"severity": "warning",
"message": "Wrong indentation: expected 6 spaces but found 2.",
"line": 6,
"column": 1,
"offset": 96,
"endLine": 6,
"endColumn": 3,
"endOffset": 98
},
{
"rule": "comments",
"severity": "warning",
"message": "Too few spaces before an inline comment (1; expected at least 2).",
"line": 8,
"column": 16,
"offset": 126,
"endLine": 8,
"endColumn": 17,
"endOffset": 127
}
],
"documents": 1,
"formatted": "# Service settings\nservice:\n name: web # quotes are not needed here\n replicas: 3\n ports:\n - 80\n … (68 more characters)",
"value": {
"service": {
"name": "web",
"replicas": 3,
"ports": [
80,
443
],
"country": "no"
}
}
}
Same call as an MCP tools/call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "yaml_format",
"arguments": {
"input": "# Service settings\nservice:\n name: \"web\" # quotes are not needed here\n replicas: 3\n ports:\n - 80\n - 443\n country: \"no\" # stays quoted: YAML 1.1 reads no as false\n",
"indent": 4,
"indent_sequences": "indented"
}
}
}Invalid YAML: duplicate key and a syntax error
curl -X POST 'https://util.caruana.me/api/yaml/format' \
-H 'content-type: application/json' \
-d '{"input":"name: a\nname: b\nlist: [1, 2\nnext: 3\n"}'
Response 200
{
"valid": false,
"summary": {
"valid": false,
"errors": 2,
"warnings": 0,
"infos": 0
},
"diagnostics": [
{
"rule": "key-duplicates",
"severity": "error",
"message": "Duplicate key \"n\": keys in a mapping must be unique.",
"line": 2,
"column": 1,
"offset": 8,
"endLine": 2,
"endColumn": 2,
"endOffset": 9
},
{
"rule": "syntax",
"severity": "error",
"message": "Flow sequence in block collection must be sufficiently indented and end with a ].",
"line": 4,
"column": 1,
"offset": 28,
"endLine": 4,
"endColumn": 2,
"endOffset": 29
}
],
"documents": 1,
"formatted": null,
"value": null
}
Same call as an MCP tools/call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "yaml_format",
"arguments": {
"input": "name: a\nname: b\nlist: [1, 2\nnext: 3\n"
}
}
}Strict house style: --- required, double quotes
curl -X POST 'https://util.caruana.me/api/yaml/format' \
-H 'content-type: application/json' \
-d '{"input":"a: '\''single'\''\n---\nb: 1\n","document_start":"require","quote_style":"double"}'
Response 200
{
"valid": true,
"summary": {
"valid": true,
"errors": 0,
"warnings": 2,
"infos": 0
},
"diagnostics": [
{
"rule": "document-start",
"severity": "warning",
"message": "Missing document start \"---\".",
"line": 1,
"column": 1,
"offset": 0
},
{
"rule": "quoted-strings",
"severity": "warning",
"message": "String uses single quotes; use double quotes.",
"line": 1,
"column": 4,
"offset": 3,
"endLine": 1,
"endColumn": 12,
"endOffset": 11
}
],
"documents": 2,
"formatted": "---\na: \"single\"\n---\nb: 1\n",
"value": [
{
"a": "single"
},
{
"b": 1
}
]
}
Same call as an MCP tools/call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "yaml_format",
"arguments": {
"input": "a: 'single'\n---\nb: 1\n",
"document_start": "require",
"quote_style": "double"
}
}
}