Skip to main content

HiraraReader

Self-hosted Office-document reader for AI agents — docx, pptx, xlsx → text. No API keys.

Part of the Hirara tool hub. Pure-Python — python-docx, python-pptx, and openpyxl. URL fetches route through the hub's shared SSRF guard, hirara-core.

License Python MCP


One tool, three formats

office_read takes a Word, PowerPoint, or Excel file and returns clean markdown (plus the plain text). The format is auto-detected from the file contents — they are all ZIP containers, told apart by what's inside — so the agent never has to pick; it just says "read this file."

Format What comes out
.docx Headings (#), bullet lists (-), and tables preserved as markdown
.pptx Per-slide text under ## Slide N, plus speaker notes
.xlsx One markdown table per sheet, under ## Sheet: <name>

It pairs with the hub's other readers: hirarapdf for PDFs and hiraraocr for images and scans. This one owns the Office formats.

Legacy binary formats (.doc / .xls / .ppt) are recognized and rejected with a clear message — save as the modern OOXML format instead.


Quick start

pip install -e ../hirara-core        # shared SSRF guard (repo-local)
pip install -e ".[service,mcp]"

As an HTTP service:

uvicorn hirarareader.service:app --host 127.0.0.1 --port 8500

Read a document (base64, path, or URL) → markdown + text:

curl -X POST localhost:8500/office_read -H 'content-type: application/json' \
  -d '{"file_path":"/path/to/report.docx"}'

Or upload it directly:

curl -X POST localhost:8500/office_read/upload -F file=@deck.pptx

As an MCP server over stdio (Claude Desktop / Cursor / agent runtimes):

python -m hirarareader.mcp_server

With Docker (loopback-bound, nothing to download at boot):

docker compose up -d --build

API

Endpoint Purpose
POST /office_read Read one document. file_path / file_url / file_base64, filename
POST /office_read/upload Same, multipart file upload
GET /schemas Tool definition, ready for an LLM tools array
GET /health Liveness + supported formats

Response carries kind (docx/pptx/xlsx), markdown, text, meta (paragraph/slide/sheet counts), truncated, source, and error. Errors come back in the body, not as HTTP status codes: the caller is an agent loop, and "unrecognized document" is a result to reason about.


Security

  • file_url is off by default. When enabled (CRDR_ALLOW_URL_FETCH=true), the fetch goes through hirara-core's safe_download — resolve-then-pin, every redirect hop re-validated, streamed under a byte cap — never a bare httpx.get.
  • Local file access is gated. file_path lets a caller name any file on the host; fine for a local/MCP server, off in the Docker image. Set CRDR_ALLOW_LOCAL_PATH=true only for a trusted, local deployment.
  • Everything is size-capped — input by CRDR_MAX_BYTES, output by CRDR_MAX_CHARS (flags truncated), spreadsheet rows by CRDR_MAX_ROWS.

Configuration

All via environment variable.

Variable Default Notes
CRDR_MAX_BYTES 26214400 Cap on an input file (25 MB)
CRDR_MAX_CHARS 500000 Cap on output text/markdown; flags truncated
CRDR_MAX_ROWS 2000 Per-sheet row cap for spreadsheets
CRDR_ALLOW_URL_FETCH false Enable file_url (through the SSRF guard)
CRDR_ALLOW_LOCAL_PATH true (lib) / false (image) file_path reads

Testing

pip install -e ".[dev]"
pytest -q

The suite builds tiny real .docx/.pptx/.xlsx files in memory and reads them back — so it exercises the actual libraries end-to-end, no fixtures checked in. Verified on a live server: all three formats read to the expected markdown.


License

Apache License 2.0 — see LICENSE and NOTICE.

Copyright 2026 Lucas D Marshall (Kaung Myat San).

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hirarareader-0.1.0.tar.gz (19.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hirarareader-0.1.0-py3-none-any.whl (18.9 kB view details)

Uploaded Python 3

File details

Details for the file hirarareader-0.1.0.tar.gz.

File metadata

  • Download URL: hirarareader-0.1.0.tar.gz
  • Upload date:
  • Size: 19.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for hirarareader-0.1.0.tar.gz
Algorithm Hash digest
SHA256 afa4e7d58bfba1ceaf530f572150fb9bad77e0eaca90d10f1feead93f978cfbe
MD5 1957f565c2502b92c513d9ad435b076f
BLAKE2b-256 10c8bcadcad82f58532344c5fee47531aec52bac8a5236e80806f90c4aff0259

See more details on using hashes here.

Provenance

The following attestation bundles were made for hirarareader-0.1.0.tar.gz:

Publisher: pypi-publish.yml on lucasdmarshall/Hirara

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hirarareader-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: hirarareader-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 18.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for hirarareader-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e20c6a9effebc385472ef12ad65cf23f800670821655f9f16a25b1c1ac276dcf
MD5 1c1f1180cafaaf1bcaddc1e878846a90
BLAKE2b-256 9d012cb6d707d99034378db3e45a948b229d5dbe90c47694078e86bc479b9782

See more details on using hashes here.

Provenance

The following attestation bundles were made for hirarareader-0.1.0-py3-none-any.whl:

Publisher: pypi-publish.yml on lucasdmarshall/Hirara

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page