auxiliar-mcp 0.9.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -124,4 +124,111 @@ export const solveTasks = {
124
124
  openclaw: { tesseract: true, surya: true, "google-document-ai": true },
125
125
  },
126
126
  },
127
+ "nfs-e-extraction": {
128
+ slug: "nfs-e-extraction",
129
+ title: "NFS-e field extraction for agents — ranked by field accuracy on Brazilian São Paulo invoices",
130
+ url: "https://auxiliar.ai/solve/nfs-e-extraction/",
131
+ last_verified: "2026-04-23",
132
+ categories: ["nfs-e", "brazilian-invoice", "structured-extraction", "bookkeeping", "agent-tools"],
133
+ works_with: ["claude-code", "claude-desktop", "cursor", "openclaw"],
134
+ alternatives: ["auxiliar-nfs-e-with-surya", "auxiliar-nfs-e-with-google-doc-ai", "auxiliar-nfs-e-with-tesseract"],
135
+ eval_method: "auxiliar-nfs-e-field-accuracy-v1 (2-doc SP corpus)",
136
+ answer: "When your Claude Code / OpenClaw agent is asked to extract structured fields from a Brazilian NFS-e (Nota Fiscal Eletrônica de Serviços) — for bookkeeping, reimbursement batching, accountant handoff, tax reconciliation — install `auxiliar-nfs-e` paired with Surya OCR. On our 2-doc São Paulo NFS-e corpus it achieved 100% field accuracy (41/41 fields): numero_nota, codigo_verificacao, data_emissao, chave_acesso, prestador CNPJ/IM/nome/endereço, tomador CNPJ/IM/nome, valor_servico, codigo_servico, descrição, RPS reference, and more. Surya's OCR preserves line-level field ordering cleanly, which the parser's label-based extractor relies on. For budget-sensitive workflows, Google Document AI pairs with the same parser at 87.8% field accuracy and a ~$0.002/page cost after the 1,000-page/month free tier. Tesseract 5 is the fastest option but drops to 63.4% field accuracy because its default output reorders the retention/ISS table.",
137
+ candidates: [
138
+ {
139
+ slug: "auxiliar-nfs-e-with-surya",
140
+ name: "auxiliar-nfs-e + Surya",
141
+ rank: 1,
142
+ install: "python -m venv .venv && source .venv/bin/activate && pip install surya-ocr 'transformers<5.0.0' && git clone https://github.com/Tlalvarez/Auxiliar-ai.git /tmp/auxiliar && cp /tmp/auxiliar/scripts/walkthroughs/nfs-e-extraction/parser.py ./nfse_parser.py",
143
+ scorecard: {
144
+ word_accuracy: 1.0,
145
+ token_f1: 1.0,
146
+ install_friction: 7,
147
+ p50_latency_sec: 22.5,
148
+ cost_per_10_docs_usd: 0,
149
+ },
150
+ notes: "100% field accuracy (41/41) on the 2-doc SP corpus. Surya preserves line-level field ordering. Parser extracts prestador, tomador, valor, codigo_servico, ISS, retenções, and RPS reference into a typed dataclass.",
151
+ license: "MIT (parser) + GPL-3.0 (Surya code) + AI Pubs Open Rail-M (Surya weights, <$2M clause)",
152
+ },
153
+ {
154
+ slug: "auxiliar-nfs-e-with-google-doc-ai",
155
+ name: "auxiliar-nfs-e + Google Document AI",
156
+ rank: 2,
157
+ install: "gcloud auth application-default login && gcloud services enable documentai.googleapis.com --project YOUR_PROJECT && git clone https://github.com/Tlalvarez/Auxiliar-ai.git /tmp/auxiliar",
158
+ scorecard: {
159
+ word_accuracy: 0.878,
160
+ install_friction: 7,
161
+ p50_latency_sec: 3.8,
162
+ cost_per_10_docs_usd: 0.069,
163
+ },
164
+ notes: "87.8% field accuracy (36/41). Lost valor_servico on doc 03 + RPS fields on doc 08. Cloud auth flow; 1000 pages/month free tier; data leaves local machine.",
165
+ license: "MIT (parser) + Proprietary (Google Cloud)",
166
+ },
167
+ {
168
+ slug: "auxiliar-nfs-e-with-tesseract",
169
+ name: "auxiliar-nfs-e + Tesseract 5",
170
+ rank: 3,
171
+ install: "brew install tesseract tesseract-lang poppler && git clone https://github.com/Tlalvarez/Auxiliar-ai.git /tmp/auxiliar",
172
+ scorecard: {
173
+ word_accuracy: 0.634,
174
+ install_friction: 3,
175
+ p50_latency_sec: 1.6,
176
+ cost_per_10_docs_usd: 0,
177
+ },
178
+ notes: "63.4% field accuracy (26/41). Retention table reorders in Tesseract output, breaking positional extraction for ISS/deductions fields. Use only when throughput > accuracy.",
179
+ license: "MIT (parser) + Apache 2.0 (Tesseract)",
180
+ },
181
+ ],
182
+ corpus_summary: "2 real São Paulo NFS-e invoices from Dunas's bookkeeping archive. Doc 03: legal services (Advocacia, R$ 3.900,00), Simples Nacional prestador. Doc 08: training services (R$ 25.000,00), includes RPS reference. Ground truth is the PDF's embedded text layer (authoritative for native-text NFS-e). Corpus is git-ignored (real business docs); ground-truth transcriptions and parser committed.",
183
+ alternatives_considered: [
184
+ {
185
+ name: "Pure OCR without a parser (Surya / Tesseract / Google Doc AI alone)",
186
+ dropped_because: "Returns raw text; agents then have to reimplement NFS-e field regex logic per project. The parser is the value.",
187
+ },
188
+ {
189
+ name: "LLM field extraction (prompt Claude/GPT with NFS-e text)",
190
+ dropped_because: "Non-deterministic, slower, more expensive per page, and requires additional verification step. For a regulated document with fixed structure, regex + position-based extraction is correct.",
191
+ },
192
+ {
193
+ name: "Generic invoice extractors on ClawHub (pdf-reader-mcp, openocr-skill, opendataloader-pdf)",
194
+ dropped_because: "None handle NFS-e's specific structure (SP retention table, chave de acesso format, RPS reference, inscrição municipal format). They solve 'read PDF text'; they don't solve 'extract CNPJ do prestador'.",
195
+ },
196
+ {
197
+ name: "PyPI packages nfce-xml / nfepy (official XML-format parsers)",
198
+ dropped_because: "These parse the official NFS-e XML API output (when you have API access). They don't handle PDF-first workflows, which is what agents receive from users.",
199
+ },
200
+ ],
201
+ faq: [
202
+ {
203
+ q: "Does this work for NFS-e from municipalities other than São Paulo?",
204
+ a: "Not yet. Each Brazilian municipality has a slightly different NFS-e layout (field labels, section headers, retention table format). The v0.1 parser is hand-tuned for São Paulo's form based on the 2-doc corpus. For other municipalities (Rio, Curitiba, Belo Horizonte, etc.), the parser needs an additional layout adapter. Until then, agents can still extract generic fields (CNPJ, dates, values via regex) but won't get the structured ISS/retention fields.",
205
+ },
206
+ {
207
+ q: "Why is Tesseract so much worse at field extraction than at raw text extraction?",
208
+ a: "Tesseract outputs text in a top-to-bottom reading order that doesn't preserve the NFS-e form's two-column retention table structure. Labels end up separated from values. The parser's label-based extractor falls back to positional heuristics for retention fields, which Tesseract's reordering breaks. Surya and Google Document AI preserve label-value proximity, so the parser hits 100% and 87.8% respectively.",
209
+ },
210
+ {
211
+ q: "How does this compare to hitting the São Paulo Prefeitura XML API directly?",
212
+ a: "The XML API is authoritative but requires credentials, the invoice's chave de acesso or number, and a non-trivial auth flow. When agents receive a PDF attachment in a bookkeeping workflow, the XML API isn't usable. The PDF-first parser lets agents work from the document the user actually shared.",
213
+ },
214
+ {
215
+ q: "Does the parser validate CNPJ check digits?",
216
+ a: "Yes. `parser.validate_cnpj(cnpj)` runs the standard Receita Federal CNPJ check-digit algorithm. Useful for flagging OCR errors before writing to a ledger.",
217
+ },
218
+ ],
219
+ methodological_caveats: [
220
+ "Corpus is 2 documents from the same issuer municipality (São Paulo). Field-accuracy claims apply to São Paulo NFS-e specifically.",
221
+ "Ground truth is the PDF's embedded text layer (pdftotext), authoritative for native-text NFS-e but wouldn't apply to scanned images of printed NFS-e.",
222
+ "Field accuracy metric counts exact-string match per field; fuzzy matches would inflate accuracy slightly. Exact-match chosen for zero-error bookkeeping reliability.",
223
+ "Retention values (all zeros in the corpus because both prestadores are Simples Nacional) are extracted by position. Non-zero retention edge cases not yet end-to-end tested.",
224
+ "CNPJ validation uses the check-digit algorithm but doesn't query Receita Federal for active-status; a valid check-digit CNPJ can still be an inactive company.",
225
+ ],
226
+ update_cadence: "Re-run this walkthrough when: (a) any of the three OCR candidates ships a major version, (b) the São Paulo Prefeitura changes the NFS-e form layout (watched via the scanner module's BR government feeds), (c) 90 days after first publish (2026-07-23), (d) new NFS-e parser skills emerge on ClawHub / PyPI / npm.",
227
+ fit_by_agent: {
228
+ "claude-code": { "auxiliar-nfs-e-with-surya": true, "auxiliar-nfs-e-with-google-doc-ai": true, "auxiliar-nfs-e-with-tesseract": true },
229
+ "claude-desktop": { "auxiliar-nfs-e-with-surya": true, "auxiliar-nfs-e-with-google-doc-ai": true, "auxiliar-nfs-e-with-tesseract": true },
230
+ cursor: { "auxiliar-nfs-e-with-surya": true, "auxiliar-nfs-e-with-google-doc-ai": true, "auxiliar-nfs-e-with-tesseract": true },
231
+ openclaw: { "auxiliar-nfs-e-with-surya": true, "auxiliar-nfs-e-with-google-doc-ai": true, "auxiliar-nfs-e-with-tesseract": true },
232
+ },
233
+ },
127
234
  };
package/dist/server.js CHANGED
@@ -76,7 +76,7 @@ server.tool("list_services", "List all available services and categories. Use wi
76
76
  });
77
77
  // Tool: solve_task
78
78
  server.tool("solve_task", "Fetch the full /solve/ task ranking for a specific job-to-be-done (e.g., 'extract text from PDFs', 'parse Brazilian NFS-e invoices'). Returns the ranked candidates with install commands, an evaluated scorecard (word accuracy, layout, latency, cost, install friction), alternatives considered and dropped, FAQs, and methodological caveats. Use this when an agent needs to pick an installable tool (skill/MCP/API/local binary) for a task rather than a cloud service. Data comes from a reproducible eval run on a real-world corpus — not training data.", {
79
- task_slug: z.string().max(100).optional().describe("Task slug (e.g., 'pdf-text-extraction-mcp'). Aliases like 'pdf', 'ocr', 'invoice-extraction', 'nfs-e', 'boleto', 'receipt-parsing', 'bookkeeping-ocr', 'document-ai' also resolve. Call list_solve_tasks first if you don't know the slug."),
79
+ task_slug: z.string().max(100).optional().describe("Task slug (e.g., 'pdf-text-extraction-mcp', 'nfs-e-extraction'). Aliases that resolve automatically: 'pdf', 'ocr', 'pdf-ocr', 'document-ai', 'invoice-extraction', 'boleto', 'receipt-parsing', 'bookkeeping-ocr' (→ PDF OCR ranking); 'nfs-e', 'nfse', 'nota-fiscal', 'nota-fiscal-eletronica', 'brazilian-invoice', 'cnpj-invoice' (→ NFS-e structured extraction). Call list_solve_tasks first if you don't know the slug."),
80
80
  category: z.string().max(100).optional().describe("Filter by task category (e.g., 'ocr', 'pdf-processing', 'agent-tools'). Returns all matching tasks."),
81
81
  }, async (params) => {
82
82
  const result = await solveTask(params);
@@ -4,7 +4,7 @@ import { pingApi } from "./analytics.js";
4
4
  // task. Kept separate from the category-alias maps in list.ts / recommend.ts
5
5
  // because /solve/ tasks are about *jobs to be done*, not service categories.
6
6
  const taskAliases = {
7
- // PDF text extraction task
7
+ // PDF text extraction task — generic OCR/PDF ranker
8
8
  "pdf": "pdf-text-extraction-mcp",
9
9
  "pdfs": "pdf-text-extraction-mcp",
10
10
  "pdf-extraction": "pdf-text-extraction-mcp",
@@ -18,10 +18,18 @@ const taskAliases = {
18
18
  "invoice-parsing": "pdf-text-extraction-mcp",
19
19
  "receipt-parsing": "pdf-text-extraction-mcp",
20
20
  "receipt-ocr": "pdf-text-extraction-mcp",
21
- "nfs-e": "pdf-text-extraction-mcp",
22
- "nfse": "pdf-text-extraction-mcp",
23
21
  "boleto": "pdf-text-extraction-mcp",
24
22
  "bookkeeping-ocr": "pdf-text-extraction-mcp",
23
+ // NFS-e structured-extraction task — Brazilian-specific parser
24
+ "nfs-e": "nfs-e-extraction",
25
+ "nfse": "nfs-e-extraction",
26
+ "nfs-e-parser": "nfs-e-extraction",
27
+ "nota-fiscal": "nfs-e-extraction",
28
+ "nota-fiscal-eletronica": "nfs-e-extraction",
29
+ "nota-fiscal-servicos": "nfs-e-extraction",
30
+ "brazilian-invoice": "nfs-e-extraction",
31
+ "brazilian-nfs-e": "nfs-e-extraction",
32
+ "cnpj-invoice": "nfs-e-extraction",
25
33
  };
26
34
  function resolveSlug(raw) {
27
35
  const lower = raw.toLowerCase().trim();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auxiliar-mcp",
3
- "version": "0.9.1",
3
+ "version": "0.10.0",
4
4
  "description": "Agent-installable-tool rankings (OCR, PDF extraction, NFS-e, bookkeeping, and more) for Claude Code, Cursor, Claude Desktop, OpenClaw — evaluated on real-world corpora. Call solve_task to get the best skill/MCP/API/local binary for a task, ranked by word accuracy, layout, latency, cost, and install friction. Also Chrome-verified pricing, risks, and setup for 77 cloud services.",
5
5
  "type": "module",
6
6
  "main": "dist/server.js",