{
  "openapi": "3.1.1",
  "info": {
    "title": "Wikinest Markdown to HTML API",
    "version": "1.0.0",
    "summary": "Turn wiki Markdown with panels, status lozenges and a table of contents into safe HTML.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://wikinestmarkdowntohtml.usefulweb.app"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Turn wiki Markdown with panels, status lozenges and a table of contents into safe HTML.",
        "description": "Converts a Wikinest page written in Markdown into sanitised HTML: headings with anchors, tables, task lists, highlighted code, info/success/warning/error panels, expand sections, status lozenges, dates, mentions, [[page links]] and the table-of-contents and child-pages macros. It reports the outline, links that point nowhere and unsafe addresses it dropped.\n\nMethodology:\n- Blocks are read line by line: ATX headings, paragraphs, fenced code, block quotes, bullet/numbered/task lists (nested by indentation), GFM tables with alignment, rules, and the Wikinest blocks — :::info/success/warning/error panels (note = info, tip = success), :::expand sections and the {{toc}}, {{children}} and {{embed URL}} macros on a line of their own.\n- Inline: code spans, **bold**, *italic*, ~~strike~~, links, images, autolinks and bare https addresses, [[Page]] / [[Page|label]] / [[KEY:Page]] links, @[Name] mentions, {status:colour|text} lozenges and {date:YYYY-MM-DD}.\n- Sanitised by construction: every piece of text is escaped, raw HTML in the Markdown is shown as text, links keep only http(s), mailto and #anchors, images only https and attachments; nothing else reaches the output. External links open in a new tab with noopener.\n- Heading anchors are slugs of the heading text (duplicates get -2, -3); the outline nests headings by level and numbers them 1, 1.1, 1.2 …\n- Code blocks are highlighted by a small one-pass tokenizer (comments, strings, numbers, keywords, literals, tags) for JavaScript/TypeScript, Python, shell, SQL, CSS, JSON, YAML, Go, Rust, Java/Kotlin/C#, C/C++, PHP and HTML/XML.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "wikinest_markdown_to_html",
        "x-owner-app": "wikinest",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WikinestMarkdownToHtmlInput"
              },
              "examples": {
                "example1": {
                  "summary": "Runbook with panels, a table, code and task lists",
                  "value": {
                    "markdown": "# Runbook: api\n\n{status:green|Active} · Owner: @[Grace Hopper] · Last reviewed {date:2026-11-24}\n\n{{toc}}\n\n## Alerts\n| Alert | Meaning | First step |\n| --- | --- | --- |\n| High error rate | More than 2 % of requests fail | Check the latest deploy |\n\n## Diagnosis\n1. Check the [[Dashboards]] page\n2. Read the logs:\n\n```sh\njournalctl -u api --since \"15 min ago\"\n```\n\n:::warning Before you restart\nTell the on-call channel first. See [[Escalation]].\n:::\n\n## Recovery\n- [x] Restart the service\n- [ ] Write the incident note\n\n:::expand Older notes\nMoved from the old wiki.\n:::\n",
                    "pageTitles": "Dashboards\nOn-call rota",
                    "tocLevels": 2
                  }
                },
                "example2": {
                  "summary": "Team handbook home page as a standalone document",
                  "value": {
                    "markdown": "Welcome to the handbook of the **Orbit team**. Start with [[Onboarding: new teammate]], then browse the sections below.\n\n{{toc 2}}\n\n## Sections\n{{children}}\n\n## Status\n| Area | Owner | Status |\n| --- | --- | --- |\n| Rituals | @[Ada] | {status:green|Up to date} |\n| Decisions | @[Grace] | {status:yellow|Needs review} |\n| How-tos | @[Linus] | {status:blue|Growing} |\n\n:::info How to edit\nPress **E** or choose **Edit**, change the Markdown on the left and watch the preview on the right. Publish creates a new version you can compare and restore later.\n:::\n",
                    "pageTitles": "Team handbook\nRituals\nPlanning 2026-11-24\nRetrospective 2026-11-24\nDecisions\nADR 1: Markdown for all documentation\nHow-tos\nHow to request access\nOnboarding: new teammate",
                    "children": "Rituals\nDecisions\nHow-tos\nOnboarding: new teammate",
                    "standalone": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WikinestMarkdownToHtmlResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "WikinestMarkdownToHtmlInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "markdown": {
            "title": "Page in Markdown",
            "description": "Wikinest Markdown: CommonMark and GitHub tables/task lists plus [[Page]] links, :::info panels, {status:green|Done}, {date:2026-11-24}, {{toc}} and {{children}}.",
            "type": "string",
            "maxLength": 400000,
            "default": ""
          },
          "pageTitles": {
            "title": "Existing page titles (optional, one per line)",
            "description": "[[Links]] to these titles become links to \u003cslug\u003e.html; others are marked as missing pages.",
            "type": "string",
            "maxLength": 20000,
            "default": ""
          },
          "children": {
            "title": "Child pages for {{children}} (optional, one per line)",
            "type": "string",
            "maxLength": 20000,
            "default": ""
          },
          "tocLevels": {
            "title": "Headings in the outline down to level",
            "type": "integer",
            "minimum": 1,
            "maximum": 6,
            "default": 3
          },
          "standalone": {
            "title": "Whole HTML document with a stylesheet (light and dark)",
            "type": "boolean",
            "default": false
          }
        },
        "required": []
      },
      "WikinestMarkdownToHtmlResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object"
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}