AILANG Parse

io.github.sunholo-dataPublished by GitHub account sunholo-datav0.14.1Updated Nov 5, 2026

Parse, convert and create Office and PDF documents. OAuth at /mcp/connect/, API key at /mcp/.

The publisher's own server: Parse

VerifiedStreamable HTTPWeb executableProductivity & WorkflowFiles & Storage

Overview

AI-generated overview

Parses Office, PDF and image documents into structured blocks, Markdown or HTML, and converts or creates documents in nine formats.

What you can do
  • Parse documents into structured blocks, Markdown, HTML, A2UI or a short summary
  • Convert documents between formats and generate new ones from Markdown
  • Edit Office documents by applying JSON edit deltas
  • Upload files through a picker card or one-time upload links
  • Estimate parsing cost and latency, and list supported formats and sample documents
  • Check account plan, usage, keys and request-history settings, and send anonymous feedback
When to use it
Useful when an assistant needs to read DOCX, PPTX, XLSX, PDF or image files and get clean structured or Markdown output, or when it should produce a report, slide deck or spreadsheet from Markdown. Worth adding for document-heavy workflows rather than general chat.
Requirements
Either the hosted endpoint or a local npm/PyPI package run with npx or uvx. The hosted agent surface takes an optional API key (DOCPARSE_API_KEY or an Authorization bearer header); without one, sign-in goes through a device-flow tool, and browser clients use the OAuth connect path. The local CLI needs poppler for PDFs and optional extra backends for scanned files.
Before you install
Uploaded files are sent to the hosted service and kept for reuse for about 30 minutes before deletion; request history retention depends on the account setting. The API key is a secret. AI backends for PDFs and images are opt-in and may incur paid model usage. Editing and conversion write new documents, and feedback submissions are queued for human review.

Installation

In SourceWeft

  1. Open AILANG Parse in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/io.github.sunholo-data%2Fparse/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config.

{
  "mcpServers": {
    "ailang-parse": {
      "type": "http",
      "url": "https://docparse.ailang.sunholo.com/mcp/connect/"
    }
  }
}

README

AILANG Parse

[AILANG Registry] [PyPI] [npm] [Go] [MCP Registry] [CI]

Universal document parsing and generation in AILANG. Extracts structured content from DOCX, PPTX, XLSX, PDF, and image files into JSON and markdown — and writes documents back out in 9 formats. To author a document, write Markdown and convert it; see Writing documents in Markdown.

Office formats (DOCX, PPTX, XLSX) use deterministic XML parsing — no AI, no cloud, instant results. PDFs default to the deterministic pdftotext backend (poppler) — also no AI, no cloud — with poppler (headings, lists, tables and header/footer from the same tools, no installs), docling and liteparse as local alternatives escalating automatically to local docling OCR for scanned/image-only PDFs. Pluggable AI (Gemini, Claude, local Ollama) is available via --pdf-backend ai but is never chosen automatically. Images delegate to whatever AI model you plug in. AILANG Parse is AI-agnostic: swap --pdf-backend/--ai to change the backend, zero code changes.

Install

Two routes; both put a docparse command on your PATH, and both write output next to the file you parse (--output-dir DIR or DOCPARSE_OUTPUT_DIR to change that).

Already have AILANG? (0.42.0+ of this package, AILANG v0.40.0 dev or later)

bash
ailang install sunholo/ailang_parsedocparse report.docx

The package's [bin] table gives you a shim in ~/.ailang/bin that runs straight out of the registry cache: parse one file, or --convert it. It is deliberately the thin path — describe/summarize, batch mode, PDF backends and --install-backends are not on it (see below). ailang bin list / ailang bin uninstall docparse manage it.

Otherwise, or for the full CLI:

bash
curl -fsSL https://www.sunholo.com/ailang-parse/install.sh | sh

Fetches the published package (~400 KB), installs the AILANG runtime if you do not have it, and links the full docparse wrapper (plus docparse-audit and docparse-render) into ~/.local/bin. --version, --prefix and --uninstall are supported; re-running is a no-op. If you install both, ailang install tells you which one docparse resolves to.

That covers every deterministic format. PDF needs two more things, and they are easy to miss:

bash
brew install poppler        # pdftotext, the default PDF backend                            # (apt install poppler-utils on Debian/Ubuntu)docparse --install-backends # docling + liteparse, for scans and layout

--install-backends matters even if you never pass --pdf-backend: when pdftotext finds no text layer the parser escalates to docling on its own, so without it a scanned PDF fails on the default backend. AI backends authenticate with Google ADC (gcloud auth application-default login), not an API key.

Contributors: install from a clone instead
bash
git clone https://github.com/sunholo-data/ailang-parse.gitln -s "$(pwd)/ailang-parse/bin/docparse" /usr/local/bin/docparse

The wrapper finds the project root by walking up for docparse/main.ail, so it works from a clone, an installed prefix, or a symlink chain. Note that the CLI wrapper and the PDF adapter live under assets/ — the only path the AILANG publisher bundles verbatim — with symlinks at their historical locations.

SDKs

Use AILANG Parse from your language of choice:

bash
pip install ailang-parse          # Pythonnpm install @ailang/parse         # JavaScript/TypeScriptgo get github.com/sunholo-data/ailang-parse-go  # Go

Quick Start

bash
# Office documents (deterministic, no AI needed)docparse report.docxdocparse slides.pptxdocparse spreadsheet.xlsx
# PDF (deterministic pdftotext by default — no AI); images (AI auto-enabled)docparse document.pdfdocparse photo.png
# Optionsdocparse report.docx describe        # AI image descriptionsdocparse report.docx summarize       # AI document summarydocparse contract.pdf                # PDF: deterministic pdftotext (default)docparse scan.pdf                    # Scanned PDF: escalates to local docling OCRdocparse scan.pdf --pdf-backend ai --ai gemini-3.5-flash-lite  # External AI (paid), opt-in only
# Format conversiondocparse report.docx --convert output.htmldocparse data.csv --convert report.docxdocparse notes.md --convert slides.pptxdocparse notes.md --convert offer.docx --reference-doc letterhead.docx
# AI document generationailang run --entry main --caps IO,FS,Env,AI --ai gemini-3.5-flash-lite \  docparse/main.ail --generate report.docx --prompt "Q1 sales report with tables"

Output

Every run produces, in the directory you ran from (--output-dir DIR or DOCPARSE_OUTPUT_DIR to change it):

  • <filename>.json — Structured JSON with typed blocks
  • <filename>.md — LLM-ready markdown

What AILANG Parse Extracts

FeatureDOCXPPTXXLSXBest Competitor
Tables with merged cellsYesYesYesRaw OOXML only
Track changes (redlining)Yes——Pandoc (3/3)
Comments (interleaved)Yes——Raw OOXML (2/2)
Headers/footersYes——Kreuzberg (2/3)
Text boxes / VML shapesYesYes—Raw OOXML (1/2)
Equations (§22.1)Yes——None
Field codes (§17.16)Yes——Kreuzberg, OOXML
Speaker notes—Yes—None
Multi-sheet extraction——YesKreuzberg

OfficeDocBench v2 (87 files, 11 formats, 8 metrics): AILANG Parse PR #116 candidate 98.1% composite with 100.0% coverage. Ten adapters compared, including the hosted Extend (Parse 2.0, 53.3% coverage-adjusted) and LlamaParse (standard mode) APIs. Source-verified structural assertions now measure cell positions, comment targets, list depth, formatting, formulas, colours, and slide/notes relationships. Methodology and results.

Supported Formats

Parsing (16 formats): DOCX, PPTX, XLSX, ODT, ODP, ODS, HTML, Markdown, CSV, EPUB, EML, MBOX, TEX, RTF, PDF, images (JPG/PNG)

Generation (9 formats): DOCX, PPTX, XLSX, ODT, ODP, ODS, HTML, Markdown, QMD (Quarto)

Writing documents in Markdown

Markdown is the input an LLM can write, so it is the practical way to generate a document: write markdown, convert to any of the nine output formats.

bash
docparse report.md --convert report.docx

What survives the trip: YAML front matter (title/author/date → document properties), bold/italic/code/strike as real character formatting, links as real hyperlinks, images (local paths are read and embedded), fenced code blocks, blockquotes, nested lists, thematic breaks, and tables with alignment and column spans.

Headers, footers, comments and tracked changes have no Markdown syntax; those are preserved when converting from a document that already contains them.

Local document verification (v0.41.2+)

docparse-audit and docparse-render are AILANG companions to the CLI. AILANG Parse v0.41.2 requires AILANG 0.35.0 or newer. They run locally and require no hosted account. The installer links them when present in the installed release; in a checkout use ./bin/docparse-audit and ./bin/docparse-render.

bash
docparse-audit report.docx --strictdocparse-render report.docx --output-dir qa/reportdocparse-render before.docx --compare after.docx --output-dir qa/comparison

The read-only DOCX audit emits JSON inventories and findings for table grids and headers, heading gaps, image descriptions, links, comments and fields. Exit codes are 0 for a completed audit, 1 for findings with --strict, and 2 for unreadable input. It is a bounded structural check; it does not certify accessibility or resolve arbitrary style inheritance.

Rendering supports .docx, .odt, .pptx, .xlsx and .pdf. Install LibreOffice and Poppler for Office input; PDF needs only Poppler. No new Python dependency is needed. Select tools with --soffice / --pdftoppm (or DOCPARSE_SOFFICE / DOCPARSE_PDFTOPPM). --dpi defaults to 144 and --timeout to 120 seconds per process. The output directory must be new. Each document gets a PDF and numbered PNG pages; the manifest records source hashes, tool paths and page directories. Comparison identifies changed/added/removed pages using uncompressed raster hashes. Inspect the two PNG sets side by side; no diff overlays are generated. visual_review: pending means page images still need inspection.

The implementation is in docparse/services/document_render.ail and docparse/services/docx_audit.ail; regression verification is AILANG too:

bash
ailang run --entry main --caps IO,FS,Env,Process \  --process-allowlist "true,false,mktemp,mkdir,$(command -v soffice),$(command -v pdftoppm)" \  --process-timeout 120s scripts/verify_document_quality.ail -- \  /tmp/docparse-quality-new "$(command -v soffice)" "$(command -v pdftoppm)"

Styling a generated DOCX from a template

--reference-doc is the Quarto/Pandoc reference-doc feature: an existing .docx supplies the look, the Markdown supplies the content.

bash
docparse annex.md --convert annex.docx --reference-doc letterhead.docx

Generated tables use the selected section's usable width, with bounded content weights for columns and repeating semantic headers. Merged-cell widths sum the columns they cover.

The template's styles.xml, numbering.xml, theme, embedded fonts, headers, footers and page setup are applied to the new content. Everything the merge does not regenerate is carried through byte-for-byte, so the letterhead, logo and licensed fonts come out exactly as they went in.

What comes from where:

Templatepage size, margins, headers, footers, page numbering, fonts, theme, colours
Your documentthe body content, and docProps/core.xml (title/author)
Mergedstyles.xml (ours fill only the styleIds the template lacks), numbering.xml (our list definitions take ids above the template's), [Content_Types].xml, both .rels

Two consequences worth knowing:

  • The template's headers and footers win. A source document's own headers are dropped rather than mixed with the letterhead. The page furniture all lives in the template's body <w:sectPr>, which is lifted whole.
  • The template's comments are dropped along with its body, and so are commentsExtended.xml and people.xml. Comments in the source document still come through.

Two flags refine a multi-section template:

  • --reference-section N picks which of the template's sections supplies the page setup, headers and footers — 1 is the first section, Word's numbering. The default is the last section (the body-level one, what the flag-less behaviour has always lifted). A multi-section template's wanted furniture is often an earlier section's — the master agreement's CONFIDENTIAL footer, not the Annex's missing one.
  • --table-style NAME binds generated tables to a table style the template defines (matched on styleId, then style name). Without it, the style named Table is used if the template has one, else the first table style that is not the implicit Normal Table. Under a bound style the generator stops emitting its own hardcoded borders — the style carries them.

An unreadable or non-DOCX reference is an error and writes nothing — a silent fallback to the built-in styling would produce a plausible file missing exactly the letterhead it was asked for. DOCX output only.

Architecture

docparse/├── types/document.ail           # Block ADT (11 variants)├── services/│   ├── format_router.ail        # Format detection (36 inline tests)│   ├── zip_extract.ail          # ZIP layer (9 inline tests)│   ├── docx_parser.ail          # DOCX XML → Blocks (6 inline tests)│   ├── pptx_parser.ail          # PPTX slides → Blocks│   ├── xlsx_parser.ail          # XLSX worksheets → Blocks│   ├── direct_ai_parser.ail     # PDF/image → Blocks (AI)│   ├── layout_ai.ail            # AI self-healing (optional)│   ├── output_formatter.ail     # JSON + markdown output│   └── docparse_browser.ail     # WASM browser adapter└── main.ail                     # CLI entry point

91 contracts, 50+ inline tests. Of the 91, Z3 proves 14 outright; the rest are checked at runtime under --prove/--verify-contracts in CI, and skip statically because parser code is recursive and higher-order, which is outside Z3's decidable fragment.

AI Configuration

AILANG Parse uses AILANG's AI effect — any model AILANG supports works:

bash
docparse scan.pdf --ai gemini-3.5-flash-lite          # Google (default; fast)docparse scan.pdf --ai granite-docling           # Local Ollama (free)docparse scan.pdf --ai claude-haiku-4-5          # Anthropic

AI usage is bounded by capability budgets (AI @limit=200 on main), so costs are predictable.

Dev Commands

bash
docparse --check       # Type-check all modulesdocparse --test        # Run inline testsdocparse --prove       # Static Z3 contract verification

Benchmarks

bash
uv run benchmarks/run_benchmarks.py --suite office     # Structural (no API, instant)uv run benchmarks/run_benchmarks.py --suite pdf         # PDF extraction (needs AI)uv run benchmarks/run_benchmarks.py --competitors       # Compare to Docling etc.

See benchmarks/ for details.

License

Apache 2.0

Source: README.md at commit b48b321

Tools

10

createUpload

Create upload link

Get one-time upload links for files in your sandbox or workspace, when you can run shell commands with network access (Claude Code, Codex, a code sandbox). One token PER FILE: a token uploads exactly one file. For several files set count (1..20) to get that many descriptors in one call. Each descriptor has a curl line: run it where the file is (replace <path>); it prints a receipt with a fileRef. Then call mcpParse, mcpConvert or editDocument with that fileRef. Tokens work once, for 10 minutes. If curl fails with a network error, or the user wants to pick a file, call uploadDocument instead, or ask for an https:// link. Never parse the file yourself.

ParameterscountfilenamemimeType

editDocument

Edit document

Edit a document: parse it, apply a JSON array of edit deltas, and return the modified blocks (same shape as mcpParse with outputFormat "blocks"). deltas "" or "[]" returns the document unchanged. Office formats only: docx, pptx, xlsx, odt, odp, ods. Give the document ONE way: fileRef: a file the user uploaded (mcp-file://docparse/file_...). file: in ChatGPT, the file the user attached (ChatGPT fills it in). content + filename: the file base64-encoded, contentEncoding="base64", e.g. filename "contract.docx". filepath: an https:// URL of a publicly reachable document, or a sample id from mcpFormats such as "sample_docx_formatting". To get a file back, pass the edited blocks' Markdown to mcpConvert. Which way to send a file: a file in your sandbox or workspace: call createUpload (one token PER FILE; set count for several) and run its curl line, then pass the fileRef here. curl fails with a network error, or the user wants to pick a file: call uploadDocument (the user chooses it in the AILANG Parse card). The card parses the file; it does not convert or edit it. a public https:// link; short text as content. In ChatGPT, file. Never parse the file yourself (your own script, or your own reading of it) and present that as this tool's result: if the file cannot be sent, tell the user.

ParametersfiledeltascontentfileReffilenamefilepathcontentEncoding

mcpAccount

Account, quota and usage

Your AILANG Parse account: plan, monthly usage and limits, your keys, and whether request history is kept. Actions: "status" (default) → plan, usage this month and remaining allowance "keys" → your keys with per-key usage ("usage" is an alias) "history" → whether request history (parsed output kept for replay) is on for your account "history_on" / "history_off" → change it for the account and all its keys

Parametersaction

mcpConvert

Convert document

Create a document in another format: docx, pptx, xlsx, odt, odp, ods, html, md or qmd. To write a new document, write Markdown and send it as content with filename "notes.md" (headings become slides in pptx). To convert an existing document, give it ONE way: fileRef: a file the user uploaded (mcp-file://docparse/file_...). file: in ChatGPT, the file the user attached (ChatGPT fills it in). content + filename: the document itself; binary files base64-encoded with contentEncoding="base64", text as plain text. input: an https:// URL of a publicly reachable document, or a sample id from mcpFormats. Which way to send a file: a file in your sandbox or workspace: call createUpload (one token PER FILE; set count for several) and run its curl line, then pass the fileRef here. curl fails with a network error, or the user wants to pick a file: call uploadDocument (the user chooses it in the AILANG Parse card). The card parses the file; it does not convert or edit it. a public https:// link; short text as content. In ChatGPT, file. Never parse the file yourself (your own script, or your own reading of it) and present that as this tool's result: if the file cannot be sent, tell the user. The result carries download_url, a link to the generated file valid for one hour: give it to the user. It also carries the file as base64 in content (encoding "base64"; text formats come back as utf8). Leave outputPath empty: the server cannot write to your filesystem.

ParametersfileinputcontentfileReffilenameoutputPathoutputFormatrequiredcontentEncoding

mcpEstimate

Estimate cost and latency

Estimate cost and latency for parsing a document. Accepts a file path or sample_id. No auth required.

ParametersfilepathrequiredoutputFormatrequired

mcpFormats

List formats and capabilities

What AILANG Parse can read and write, how to send it a document, and the sample documents you can try without one. No sign-in needed.

Takes no parameters.

mcpParse

Parse document

Parse a document into structured blocks, Markdown, HTML or A2UI, or a short summary of it. Give the document ONE way: fileRef: an uploaded file (mcp-file://docparse/file_...). The same user can use it again for 30 minutes after the first use (more parts, another format), then it is deleted. file: in ChatGPT, the file the user attached (ChatGPT fills it in). filepath: an https:// URL of a publicly reachable document, or a sample id from mcpFormats such as "sample_docx_formatting". content + filename: short text only (Markdown, HTML, CSV); the filename's extension picks the parser. outputFormat: blocks (default), markdown, html, a2ui, or summary (counts, the first 50 headings, warnings: a few KB). Look with summary first when a document may be large. Large documents come in parts: when the result has page.nextCursor, call mcpParse again with the same fileRef/filepath and cursor=<nextCursor> for the next part; read every part before answering about the whole document. maxChars sets the part size as a string of digits (default "80000", "2000".."120000"). pdfBackend: leave empty for PDFs with a text layer. Set "ai" when the result is PDF_TEXT_LAYER_SPARSE (a scanned PDF): each page is read by an AI model, about 5 seconds a page, and the call counts as an AI request. Pass the same pdfBackend with every cursor call. Which way to send a file: a file in your sandbox or workspace: call createUpload (one token PER FILE; set count for several) and run its curl line, then call this tool with the fileRef the upload prints. curl fails with a network error, or the user wants to pick a file: call uploadDocument; the user chooses it in the AILANG Parse card, which uploads it and gives you its fileRef. a public https:// link: filepath. Short text: content. Never parse the file yourself (your own script, or your own reading of it) and present that as this tool's result: if the file cannot be sent, tell the user.

ParametersfilecursorcontentfileReffilenamefilepathmaxCharsrequestIdpdfBackendoutputFormatcontentEncoding

submit_feedback

Send feedback

Anonymous bug report / feature request / docs gap, queued for human review. Default routing: `public-feedback` inbox (general AILANG). Pass `package="vendor/name"` (e.g. "sunholo/auth") to route to that package's `pkg:vendor/name` inbox where its autonomous agent watches. Categories: bug, feature, docs, limitation. Body limit 10KB, snippet limit 4KB. Optional contact field for follow-up; opaque to the server. Set `auto_dispatch=true` to authorize the package agent to act on your submission immediately (default false — files for human triage; pkg-feedback agent template lands in a separate sprint).

Parametersbodyrequiredtitlerequiredcontactpackagesnippetcategoryrequiredauto_dispatchailang_versionrequired

uploadDocument

Upload a document

Let the user pick a file to parse: shows the AILANG Parse card with a Choose file button. The card uploads the file and tries to summarise it for you; either way you get its fileRef. Then call mcpParse with that fileRef for the content (the same user can reuse it for 30 minutes; a large document comes in parts). Use this when the user wants to pick a file, or when createUpload's curl fails with a network error. For a file already in your sandbox or workspace, use createUpload + curl instead. Never parse the file yourself.

ParametersoutputFormat

uploadViaHost

Receive upload from widget

Receive a file from the AILANG Parse upload widget, relayed by the host as base64. Only the widget calls this; ticket is the upload token it holds.

Parametersbase64requiredticketrequiredfilenamerequired

Version history

3
  1. v0.14.1LatestNov 5, 2026
  2. v0.14.0Nov 3, 2026
  3. v0.13.1Sep 16, 2026

Score

100% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts

Other Parse integrations