The tabnas API

Everything tabnas.dev serves to a program, described by an OpenAPI 3.1 document at /openapi.json (or /openapi.yaml). Every operation is a GET, none of them needs a key, and none of them is rate limited.

What this is not: tabnas does not parse your documents over HTTP. The engine runs in your own process — that is the point of it — and this site publishes the catalogue around it: which versions the documentation describes, what the packages are, every error code the engine can raise, and how to connect an agent over MCP. The one endpoint that executes anything is the hosted MCP server below, and running it locally is still the recommendation.

Endpoints

EndpointOperationWhat it returns
GET /llms.txt getLlmsIndex The llms.txt site index Start here
GET /llms-full.txt getLlmsFull Every documentation page in one file Start here
GET /openapi.json getOpenApiJson This document, as JSON Start here
GET /openapi.yaml getOpenApiYaml This document, as YAML Start here
GET /versions.json getVersions The package versions this documentation describes Catalogues
GET /packages.json getPackages The package catalogue Catalogues
GET /errors.json getErrorRegistry Every error code the engine and its plugins raise Catalogues
GET /errors/{code}.json getErrorCode One error code Catalogues
GET /.well-known/mcp getMcpManifest How to connect an agent over MCP MCP
GET /{page}.md getPageMarkdown Any documentation page, as markdown Content

Each operation carries a unique operationId, typed parameters and a response schema in /openapi.json, so a tool that turns an OpenAPI document into callable functions can do so without further description.

Any page, as markdown

Every page on this site is content-negotiated. Ask for markdown and the same URL answers with markdown instead of HTML — no navigation, no styling, no scripts — and the response carries Vary: Accept so a cache keeps the two apart (acceptmarkdown.com).

curl -H "Accept: text/markdown" https://tabnas.dev/docs/quickstart

The same bytes are at the path plus .md, for callers that would rather not set a header — https://tabnas.dev/docs/quickstart.md, and https://tabnas.dev/index.md for the home page. Each twin opens with a small YAML frontmatter block carrying the page's title, description and canonical URL.

If you want the whole documentation set in one request instead, that is /llms-full.txt; the index of what is here is /llms.txt.

When something is wrong

A path that does not exist returns a real 404 — never a 200 with an application shell. What is in the body depends on what you asked for: application/json, any path under /api/, and any path ending .json or .yaml get an error object; a browser gets the 404 page; anything else gets markdown carrying the same links.

{
  "error": {
    "status": 404,
    "code": "not_found",
    "message": "Not Found",
    "hint": "Nothing is published at /api/v1/parse. This site is documentation for the tabnas parsing engine; start from /llms.txt for the machine-readable index, or /openapi.json for the endpoints that return JSON.",
    "documentation": "https://tabnas.dev/api",
    "openapi": "https://tabnas.dev/openapi.json",
    "resources": {
      "llms.txt": "https://tabnas.dev/llms.txt"
    }
  }
}

code is stable and safe to branch on: it is one of not_found, method_not_allowed (the site is read-only, so anything other than GET, HEAD or OPTIONS gets one) and not_acceptable (you asked for a representation that does not exist for that URL). hint is written to tell you what to do next, and resources lists the site's entry points so one failed request is enough to recover.

Errors from the engine are a different thing entirely: a parse failure carries a diagnostic whose code is the contract across both runtimes. All 46 of them are at /errors.json, one at a time at /errors/<code>.json, and with prose at /errors.

The MCP endpoint

7 tools that actually run the engine — parse, validate a grammar, explain a failure, run fixtures, read the plugin catalogue, compare two grammar versions — are served over the Model Context Protocol from a separate service at https://mcp.tabnas.dev, deployed from the tabnas/mcp repository. Start from /.well-known/mcp on this domain, which names both transports; /mcp has each tool's contract.

EndpointOperationWhat it does
GET https://mcp.tabnas.dev/health getMcpHealth Hosted MCP endpoint liveness
POST https://mcp.tabnas.dev/mcp callMcpTool Call the hosted MCP server

Local stdio stays the recommended path: npx --yes @tabnas/mcp mcp is the same code, unbounded and private. The hosted endpoint is bounded by a body cap and a per-IP rate limit, both reported by its own /.well-known/mcp.