Same engine as the web app and the MCP server, from the terminal. No network, no accounts, no telemetry.
Install
npx sirdas factura.pdf # nothing to install but Node 20+
npm i -g sirdas # or keep it around
From source:
git clone https://github.com/Brayan15p/SIRDAS-APP-PDF.git && cd SIRDAS-APP-PDF
npm install && npm run build -w packages/core -w packages/mcp -w packages/cli
node packages/cli/dist/main.js --help # or: npm link -w packages/cli
Commands
# Start here: reads any file end to end (PDF, scan, DOCX, XLSX, PPTX, HTML, EPUB, CSV, EML, PNG/JPG)
sirdas <file>
sirdas leer <file> [--json] [--no-anonymize] [--no-ocr] [--max-tokens 1500] [-o out.md]
sirdas convertir <file.docx|xlsx|pptx|odt|epub|html|csv|eml|rtf> [--json] [-o out.md]
sirdas separar <batch.pdf> [-d dir] [--json] # one PDF per document inside a batch
sirdas formulario <file.pdf> [--json] # filled form fields and checkboxes
sirdas classify <file.pdf> [--json] # factura, contrato, historia_clinica…
sirdas revisar <folder> [--sin-nombres] # run everything over real files, report without content
sirdas pages <file.pdf> delete|extract|rotate [--pages "2, 4-6"] [--angle 90] [-o out.pdf]
sirdas number <file.pdf> [--format "Página {n} de {total}"] [--position bottom-right] [--skip-first 1]
sirdas watermark <file.pdf> --text CONFIDENCIAL [--opacity 0.15]
sirdas protect <file.pdf> [--no-print] [--no-copy] [--no-edit] [-o out.pdf] # asks for the password, or SIRDAS_PASSWORD
sirdas unlock <file.pdf> [-o out.pdf]
sirdas markdown <file.pdf> [--no-anonymize] [--json] [-o out.md] [--force]
sirdas ocr <scan.pdf> [--lang spa+eng] [--lang-path dir] [--no-anonymize]
sirdas ocr --download-models [--lang spa] # once; then it works offline
sirdas anonymize [file.txt] [--json] [--map map.json] # reads stdin when no file
sirdas restore [file.txt] --map map.json # puts the real data back
sirdas chunks <file.pdf> [--max-tokens 2000] [--json] [-d dir]
sirdas tables <file.pdf> [--csv|--markdown|--json] [-d dir] [--delimiter ";"]
sirdas compare <before.pdf> <after.pdf> [--all] [--json] [--ignore-case]
sirdas info <file.pdf> [--json]
sirdas merge <a.pdf> <b.pdf> [...] -o out.pdf [--force]
sirdas split <file.pdf> [--ranges "1-3, 5, 8-end"] [-d dir] [--force]
sirdas compress <file.pdf> [-o out.pdf] [--force] # lossless
# Training data (all local, no model is ever called)
sirdas dataset <a.pdf|b.docx|c.html> [...] [--format text|chat|prompt-completion|alpaca|sharegpt|langchain|llamaindex|embeddings]
[--hf] # train/validation/test.jsonl + Hugging Face README.md
[--max-tokens 2000] [--no-anonymize] [--no-dedupe]
[--strip-boilerplate] [--split] [--seed s]
[--template "..."] [--system "..."]
[-d dir] [--no-meta] [--json]
sirdas dedupe <a.pdf> <b.pdf> [...] [--threshold 0.8] [--json]
sirdas boilerplate <a.pdf> <b.pdf> [...] [--min-words 5] [--json]
sirdas contamination <train.pdf> [...] --against <eval.pdf> [--n 13] [--json]
sirdas rl <a.pdf> [...] [--max-per-table 10] [--lang es|en] [-o f.jsonl]
sirdas rl --reward-fn # the Python reward function
sirdas mcp # start the MCP server over stdio
md is an alias of markdown.
Conventions agents can rely on
- Exit codes:
0success ·1usage error (bad flags, missing input, refusing to overwrite) ·2the file could not be processed (password-protected, damaged, not a PDF). The reason is printed to stderr in one sentence. - stdout is the payload.
markdownprints Markdown; with--jsonit prints one JSON object (markdown,pages,tokens_estimate,anonymized,redacted,has_text,source). Progress and warnings go to stderr. - Anonymization is on by default for
markdown;--no-anonymizekeeps the original data. - Never overwrites an existing file without
--force. anonymize --jsonincludes the placeholder→valuemapping; keep it local.
The anonymize → AI → restore round trip
Nothing is ever deleted. The original PDF is untouched and the mapping — which holds the real values — stays on your machine.
# 1. Anonymize, keeping the mapping
sirdas markdown historia.pdf --json | jq -r .markdown > anonima.md
sirdas anonymize anonima.md --map mapa.json > anonima-final.md
# 2. Send anonima-final.md to any model, then restore its answer locally
cat respuesta-de-la-ia.txt | sirdas restore --map mapa.json
A name always comes back whole: placeholders map to the complete original value, never a fragment.
Examples
# Markdown for an LLM, personal data replaced
sirdas markdown historia.pdf > historia.md
# Structured output for a script
sirdas markdown contrato.pdf --json | jq '.tokens_estimate, .redacted'
# Anonymize a snippet before pasting it anywhere
echo "Paciente: Ana Gómez, C.C. 52.123.456" | sirdas anonymize
# Split the first three pages and the last one
sirdas split informe.pdf --ranges "1-3, 8-end" -d ./partes
# Pull an invoice's line items into a spreadsheet (CSV carries a BOM for Excel)
sirdas tables factura.pdf --delimiter ";" -d ./tablas
# Split a long document into chat-sized pieces
sirdas chunks informe.pdf --max-tokens 2000 -d ./partes
# Merge, then shrink losslessly
sirdas merge a.pdf b.pdf -o todo.pdf && sirdas compress todo.pdf