auxiliar-mcp 0.7.0 → 0.9.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.
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Event-source feed URLs for the service-event scanner (Phase 1 pilot).
3
+ *
4
+ * One entry per pilot service. Each service lists zero-or-more
5
+ * machine-readable feeds we monitor daily. Source types:
6
+ *
7
+ * - "status": Statuspage.io (or equivalent) incident/history RSS
8
+ * - "changelog": Vendor product changelog RSS/Atom
9
+ * - "security": Vendor security-bulletin RSS/Atom (rare but prized)
10
+ * - "releases": GitHub releases Atom (OSS projects)
11
+ *
12
+ * Phase 1 scope is detector-only — URLs here are data for the Python
13
+ * scanner (`src/auxiliar/scanner/`) to fetch daily. The config is
14
+ * intentionally versioned in-repo (not auto-discovered) so changes are
15
+ * reviewable and a noisy feed can be dropped with a single commit.
16
+ *
17
+ * Verification status: URLs below are the ones we expect each vendor
18
+ * publishes; they MUST be smoke-tested by the detector's first
19
+ * production run and any 404s/parse errors logged. A failing fetch is
20
+ * NOT a false positive — it's a missing positive, tracked separately in
21
+ * the scanner summary.
22
+ *
23
+ * Adding a service: add an entry, redeploy, wait 24h, confirm the
24
+ * source shows up in the next scanner-report.md. Removing is cheap
25
+ * (delete the entry; cursor rows become orphans and can be cleaned up
26
+ * later).
27
+ *
28
+ * This file is written by humans, read by the Python scanner via the
29
+ * build step (`scripts/build-service-api.py` will export it as JSON for
30
+ * Python — Phase 1 scanner reads the JSON snapshot so we don't need a
31
+ * TS runtime in the Lambda).
32
+ */
33
+ export type EventSourceType = "status" | "changelog" | "security" | "releases";
34
+ export interface EventSource {
35
+ type: EventSourceType;
36
+ url: string;
37
+ /** Human-readable note about the feed — why we picked it, caveats. */
38
+ note?: string;
39
+ }
40
+ export interface ServiceEventSources {
41
+ /** Slug matching content/service/<slug>.md and mcp/src/data/risks.ts keys. */
42
+ slug: string;
43
+ /** Human-readable service name. */
44
+ name: string;
45
+ sources: EventSource[];
46
+ }
47
+ export declare const eventSources: ServiceEventSources[];
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Event-source feed URLs for the service-event scanner (Phase 1 pilot).
3
+ *
4
+ * One entry per pilot service. Each service lists zero-or-more
5
+ * machine-readable feeds we monitor daily. Source types:
6
+ *
7
+ * - "status": Statuspage.io (or equivalent) incident/history RSS
8
+ * - "changelog": Vendor product changelog RSS/Atom
9
+ * - "security": Vendor security-bulletin RSS/Atom (rare but prized)
10
+ * - "releases": GitHub releases Atom (OSS projects)
11
+ *
12
+ * Phase 1 scope is detector-only — URLs here are data for the Python
13
+ * scanner (`src/auxiliar/scanner/`) to fetch daily. The config is
14
+ * intentionally versioned in-repo (not auto-discovered) so changes are
15
+ * reviewable and a noisy feed can be dropped with a single commit.
16
+ *
17
+ * Verification status: URLs below are the ones we expect each vendor
18
+ * publishes; they MUST be smoke-tested by the detector's first
19
+ * production run and any 404s/parse errors logged. A failing fetch is
20
+ * NOT a false positive — it's a missing positive, tracked separately in
21
+ * the scanner summary.
22
+ *
23
+ * Adding a service: add an entry, redeploy, wait 24h, confirm the
24
+ * source shows up in the next scanner-report.md. Removing is cheap
25
+ * (delete the entry; cursor rows become orphans and can be cleaned up
26
+ * later).
27
+ *
28
+ * This file is written by humans, read by the Python scanner via the
29
+ * build step (`scripts/build-service-api.py` will export it as JSON for
30
+ * Python — Phase 1 scanner reads the JSON snapshot so we don't need a
31
+ * TS runtime in the Lambda).
32
+ */
33
+ export const eventSources = [
34
+ {
35
+ slug: "vercel",
36
+ name: "Vercel",
37
+ sources: [
38
+ { type: "status", url: "https://www.vercel-status.com/history.rss" },
39
+ { type: "changelog", url: "https://vercel.com/changelog/feed.xml" },
40
+ {
41
+ type: "security",
42
+ url: "https://vercel.com/kb/bulletin",
43
+ note: "Ground-truth fixture source (April 2026 incident). HTML page, not RSS — detector polls with low-frequency hash comparison.",
44
+ },
45
+ ],
46
+ },
47
+ {
48
+ slug: "stripe",
49
+ name: "Stripe",
50
+ sources: [
51
+ { type: "status", url: "https://status.stripe.com/history.rss" },
52
+ { type: "changelog", url: "https://stripe.com/blog/feed.rss" },
53
+ ],
54
+ },
55
+ {
56
+ slug: "supabase",
57
+ name: "Supabase",
58
+ sources: [
59
+ { type: "status", url: "https://status.supabase.com/history.rss" },
60
+ { type: "changelog", url: "https://supabase.com/changelog/feed.xml" },
61
+ ],
62
+ },
63
+ {
64
+ slug: "neon",
65
+ name: "Neon",
66
+ sources: [
67
+ { type: "status", url: "https://neonstatus.com/history.rss" },
68
+ { type: "changelog", url: "https://neon.tech/changelog/feed.xml" },
69
+ ],
70
+ },
71
+ {
72
+ slug: "clerk",
73
+ name: "Clerk",
74
+ sources: [
75
+ { type: "status", url: "https://status.clerk.com/history.rss" },
76
+ { type: "changelog", url: "https://clerk.com/changelog/feed.xml" },
77
+ ],
78
+ },
79
+ {
80
+ slug: "auth0",
81
+ name: "Auth0",
82
+ sources: [
83
+ { type: "status", url: "https://status.auth0.com/history.rss" },
84
+ {
85
+ type: "security",
86
+ url: "https://auth0.com/docs/secure/security-bulletins/rss",
87
+ note: "Auth0 maintains a dedicated security-bulletin feed — historically reliable.",
88
+ },
89
+ ],
90
+ },
91
+ {
92
+ slug: "railway",
93
+ name: "Railway",
94
+ sources: [
95
+ { type: "status", url: "https://status.railway.com/history.rss" },
96
+ { type: "changelog", url: "https://blog.railway.com/feed.xml" },
97
+ ],
98
+ },
99
+ {
100
+ slug: "render",
101
+ name: "Render",
102
+ sources: [
103
+ { type: "status", url: "https://status.render.com/history.rss" },
104
+ { type: "changelog", url: "https://render.com/changelog/rss.xml" },
105
+ ],
106
+ },
107
+ {
108
+ slug: "resend",
109
+ name: "Resend",
110
+ sources: [
111
+ { type: "status", url: "https://resend-status.com/history.rss" },
112
+ { type: "changelog", url: "https://resend.com/changelog/feed.xml" },
113
+ ],
114
+ },
115
+ {
116
+ slug: "authjs",
117
+ name: "Auth.js",
118
+ sources: [
119
+ {
120
+ type: "releases",
121
+ url: "https://github.com/nextauthjs/next-auth/releases.atom",
122
+ note: "OSS project — GitHub releases is the only structured feed. CVEs land here as security-labelled releases.",
123
+ },
124
+ ],
125
+ },
126
+ ];
@@ -532,4 +532,51 @@ export const pricing = {
532
532
  verified_date: "2026-03-28",
533
533
  source: "Chrome-verified from postgresql.org/docs",
534
534
  },
535
+ "surya": {
536
+ provider: "Surya",
537
+ pricing_model: "free",
538
+ tiers: [
539
+ { name: "Self-hosted", price: "$0", includes: "Unlimited pages, fully local CPU/GPU inference, JSON output with text lines and bounding boxes", catches: "GPL-3.0 code license; model weights under AI Pubs Open Rail-M with <$2M funding/revenue clause for free use" },
540
+ ],
541
+ hidden_costs: [
542
+ "Compute: CPU inference averages ~20s/doc on a multi-page scanned PDF; 3-5× faster on MPS (Apple Silicon) or CUDA",
543
+ "~150 MB model weights downloaded on first run",
544
+ "Requires a Python venv and a 'transformers<5.0.0' pin as of 2026-04 (issue #484)",
545
+ "License diligence for distributed/shipped products — internal tooling and SaaS backends typically fine",
546
+ ],
547
+ verified_date: "2026-04-21",
548
+ source: "Verified from github.com/datalab-to/surya and eval on 10-doc corpus (see /solve/pdf-text-extraction-mcp)",
549
+ },
550
+ "tesseract": {
551
+ provider: "Tesseract 5",
552
+ pricing_model: "free",
553
+ tiers: [
554
+ { name: "Self-hosted", price: "$0", includes: "Unlimited pages, Apache 2.0, 100+ languages via .traineddata packs, plain-text output", catches: "PDFs must be pre-rendered with pdftoppm; plain text only (no layout/bounding boxes by default)" },
555
+ ],
556
+ hidden_costs: [
557
+ "Add poppler (pdftoppm) to handle PDF inputs — one extra shell step per doc",
558
+ "Language packs must be installed explicitly: tesseract-lang on brew includes 'por' for Portuguese",
559
+ "Multi-column reading order can diverge from top-to-bottom on dense layouts — downstream may need post-processing",
560
+ ],
561
+ verified_date: "2026-04-21",
562
+ source: "Verified from github.com/tesseract-ocr/tesseract and eval on 10-doc corpus (see /solve/pdf-text-extraction-mcp)",
563
+ },
564
+ "google-document-ai": {
565
+ provider: "Google Document AI",
566
+ pricing_model: "usage-based",
567
+ tiers: [
568
+ { name: "Free tier", price: "$0", includes: "1,000 pages/month per processor (Document OCR)", catches: "Requires a GCP project with billing account linked" },
569
+ { name: "Document OCR", price: "~$1.50 per 1,000 pages", includes: "Generic text + layout extraction", catches: "Sync endpoint caps at 15 pages/request — split or use async batch for larger PDFs" },
570
+ { name: "Form Parser", price: "~$30 per 1,000 pages", includes: "Form fields, tables, key-value pairs", catches: "Higher per-page rate; pick only if you need structured field extraction" },
571
+ { name: "Invoice Parser", price: "~$50 per 1,000 pages (first 1M); ~$30 after", includes: "Invoice-specific schema (line items, totals, vendor)", catches: "Tuned for US invoices; NFS-e and boletos may not map cleanly to the schema" },
572
+ ],
573
+ hidden_costs: [
574
+ "Billing account required — personal Google accounts can't provision processors",
575
+ "Data leaves your local machine — confirm with compliance/counsel before sending confidential financial docs",
576
+ "Third place on word accuracy (69.7%) on a 10-doc mixed corpus against local Surya (76.9%) and Tesseract (75.4%) — paying doesn't automatically mean more accurate extraction",
577
+ "Async batch has separate quotas; large PDF processing may need processor quota increases",
578
+ ],
579
+ verified_date: "2026-04-21",
580
+ source: "Verified from cloud.google.com/document-ai/pricing and eval on 10-doc corpus (see /solve/pdf-text-extraction-mcp)",
581
+ },
535
582
  };
@@ -2233,4 +2233,118 @@ export const recommendations = {
2233
2233
  },
2234
2234
  ],
2235
2235
  },
2236
+ "pdf-extraction": {
2237
+ services: [
2238
+ {
2239
+ slug: "surya",
2240
+ name: "Surya",
2241
+ choose_if: "Best overall word accuracy on mixed PDF corpora (76.9%) with the strongest layout preservation (7.0/10). Runs fully local, handles PDFs natively, free. Top pick for bookkeeping, NFS-e, invoices, and scanned legal docs when accuracy matters more than latency.",
2242
+ avoid_if: "p50 latency is 22s/doc on CPU (14× slower than Tesseract). GPL-3.0 license (+ AI Pubs Open Rail-M on weights, <$2M revenue clause) may complicate end-user-distributed products. Needs Python venv and a transformers<5.0.0 pin.",
2243
+ pricing_model: "free",
2244
+ free_tier: "Unlimited — fully local inference, no API",
2245
+ paid_starts_at: "$0 (self-hosted only)",
2246
+ risks: [
2247
+ "GPL-3.0 code license + AI Pubs Open Rail-M weights license (<$2M funding/revenue clause) — fine for internal tooling and SaaS backends, verify with counsel for distributed products",
2248
+ "Requires transformers<5.0.0 pin as of 2026-04 — bare 'pip install surya-ocr' fails with 'SuryaDecoderConfig' object has no attribute 'pad_token_id' (upstream issue #484)",
2249
+ "~150 MB model weights downloaded on first run",
2250
+ "CPU inference ~20s/doc — expect 3-5× speedup on MPS/CUDA",
2251
+ ],
2252
+ provision_command: "python -m venv .venv && source .venv/bin/activate && pip install surya-ocr 'transformers<5.0.0'",
2253
+ setup_available: false,
2254
+ has_free_tier: true,
2255
+ cheap: true,
2256
+ enterprise: true,
2257
+ eu_regions: true,
2258
+ gdpr_ready: true,
2259
+ open_source: true,
2260
+ provider_cloud: "multi",
2261
+ edge_compatible: false,
2262
+ has_cold_starts: false,
2263
+ has_cli: true,
2264
+ cli_name: "surya_ocr",
2265
+ cli_install: "pip install surya-ocr 'transformers<5.0.0'",
2266
+ has_mcp: false,
2267
+ migration_difficulty: "low",
2268
+ migration_note: "Outputs JSON with text_lines per page. Swap with Tesseract or Document AI by changing the extraction step — downstream code consumes plain text.",
2269
+ key_features: ["local OCR", "native PDF input", "layout-aware extraction", "table detection", "multi-language", "JSON output with bounding boxes", "Brazilian Portuguese supported", "NFS-e", "invoices", "bookkeeping documents", "scanned corporate filings"],
2270
+ best_for_frameworks: ["claude-code", "claude-desktop", "cursor", "openclaw", "python"],
2271
+ default_score: 8,
2272
+ last_reviewed: "2026-04-21",
2273
+ },
2274
+ {
2275
+ slug: "tesseract",
2276
+ name: "Tesseract 5",
2277
+ choose_if: "Fastest local OCR with the cleanest install path — one brew command, 1.6s p50, 75.4% word accuracy (1.5pp behind Surya). Best when throughput matters more than layout fidelity, or when you need a zero-dependency fallback.",
2278
+ avoid_if: "Plain text output only — no layout, no bounding boxes by default. PDFs need a pdftoppm render step first (Tesseract takes images, not PDFs).",
2279
+ pricing_model: "free",
2280
+ free_tier: "Unlimited — fully local, Apache 2.0",
2281
+ paid_starts_at: "$0 (self-hosted only)",
2282
+ risks: [
2283
+ "PDFs need pdftoppm pre-render (one extra step vs. Surya which takes PDFs natively)",
2284
+ "Plain text output — no structured data (form fields, tables, bounding boxes)",
2285
+ "Reading order on multi-column layouts can diverge from top-to-bottom",
2286
+ "Language packs must be installed explicitly (e.g., por for Portuguese)",
2287
+ ],
2288
+ provision_command: "brew install tesseract tesseract-lang poppler",
2289
+ setup_available: false,
2290
+ has_free_tier: true,
2291
+ cheap: true,
2292
+ enterprise: true,
2293
+ eu_regions: true,
2294
+ gdpr_ready: true,
2295
+ open_source: true,
2296
+ provider_cloud: "multi",
2297
+ edge_compatible: false,
2298
+ has_cold_starts: false,
2299
+ has_cli: true,
2300
+ cli_name: "tesseract",
2301
+ cli_install: "brew install tesseract tesseract-lang poppler",
2302
+ has_mcp: false,
2303
+ migration_difficulty: "low",
2304
+ migration_note: "Plain text out. Swapping with Surya/Document AI changes one shell step — downstream text consumers are unchanged.",
2305
+ key_features: ["local OCR", "Apache 2.0", "Portuguese language pack (por.traineddata)", "English, Spanish, 100+ languages", "fast p50", "minimal install", "CLI-first"],
2306
+ best_for_frameworks: ["claude-code", "claude-desktop", "cursor", "openclaw", "bash"],
2307
+ default_score: 7,
2308
+ last_reviewed: "2026-04-21",
2309
+ },
2310
+ {
2311
+ slug: "google-document-ai",
2312
+ name: "Google Document AI",
2313
+ choose_if: "Best results on phone-photographed receipts and mobile-captured documents (94.6% on our corpus's Pix receipt vs. 93.1% for Surya). Structured output (form fields, tables, bounding boxes). 1,000 pages/month free tier, then ~$0.002/page. Pick this when you're already on GCP or need auditable enterprise auth.",
2314
+ avoid_if: "On our 10-doc corpus Document AI placed third overall on word accuracy (69.7%) behind local Surya and Tesseract — paying for a cloud API does not guarantee better extraction on corporate filings or native-text PDFs. Reading order diverges from top-to-bottom. Enterprise-auth install flow.",
2315
+ pricing_model: "usage-based",
2316
+ free_tier: "1,000 pages/month per processor (Document OCR), then billed",
2317
+ paid_starts_at: "~$0.0015/page (Document OCR) to ~$0.05/page (Invoice Parser)",
2318
+ risks: [
2319
+ "Requires a GCP project with billing account linked — not reachable with a personal Google account alone",
2320
+ "Third place overall word accuracy on our 10-doc mixed corpus (0.697 vs. 0.769 for Surya, 0.754 for Tesseract) — the paid option is not automatically the most accurate",
2321
+ "Sync endpoint caps at 15 pages per request — split PDFs or use async batch for larger",
2322
+ "Per-page billing adds up — $0.002 × 10,000 pages = $20, $0.002 × 100,000 = $200",
2323
+ "Data leaves the local machine — confirm with compliance before sending confidential financial docs",
2324
+ ],
2325
+ provision_command: "gcloud services enable documentai.googleapis.com && gcloud auth application-default login",
2326
+ setup_available: false,
2327
+ has_free_tier: true,
2328
+ cheap: false,
2329
+ enterprise: true,
2330
+ eu_regions: true,
2331
+ gdpr_ready: true,
2332
+ open_source: false,
2333
+ provider_cloud: "gcp",
2334
+ edge_compatible: false,
2335
+ has_cold_starts: false,
2336
+ has_cli: true,
2337
+ cli_name: "gcloud",
2338
+ cli_install: "brew install --cask google-cloud-sdk",
2339
+ has_mcp: false,
2340
+ mcp_install: null,
2341
+ migration_difficulty: "medium",
2342
+ migration_note: "JSON response with document.text + layout. Moving off GCP means rewriting the API call + auth; downstream text consumers survive if you abstract the call behind a function.",
2343
+ key_features: ["cloud OCR API", "structured layout output", "bounding boxes", "form fields", "tables", "invoice parser processor", "Portuguese supported", "phone photo receipts", "async batch for large PDFs", "audit logging"],
2344
+ best_for_frameworks: ["claude-code", "claude-desktop", "cursor", "openclaw", "python", "node"],
2345
+ default_score: 6,
2346
+ last_reviewed: "2026-04-21",
2347
+ },
2348
+ ],
2349
+ },
2236
2350
  };
@@ -312,12 +312,55 @@ export const risks = {
312
312
  "vercel": {
313
313
  provider: "Vercel",
314
314
  risks: [
315
+ { severity: "CRITICAL", title: "Active security incident (April 2026)", detail: "Vercel disclosed on 2026-04-19 that a compromise of Context.ai (a third-party AI tool used by a Vercel employee) was escalated to their internal systems via the employee's Google Workspace. A limited subset of customers had credentials compromised; environment variables not marked 'sensitive' on affected accounts may have been accessed. Vercel recommends rotating non-sensitive env vars as a priority, enabling the 'sensitive env vars' feature, reviewing recent deployments, and rotating Deployment Protection tokens. Investigation ongoing; services remain operational. Full advisory: https://vercel.com/kb/bulletin/vercel-april-2026-security-incident" },
315
316
  { severity: "HIGH", title: "Bandwidth overage shock", detail: "Vercel charges starting at $0.15/GB for bandwidth beyond your plan's included usage. The Pro plan includes $20 of usage credit, but a viral post or product launch can still generate surprise charges. " },
316
317
  { severity: "MEDIUM", title: "Hobby tier is non-commercial", detail: "The free Hobby plan explicitly prohibits commercial use. Any revenue-generating app needs the $20/month Pro plan." },
317
318
  { severity: "MEDIUM", title: "Framework lock-in", detail: "Advanced features (ISR, edge middleware, image optimization) are deeply integrated with Next.js. Migrating to another platform means losing these optimizations." },
318
319
  { severity: "LOW", title: "Cold starts on serverless functions", detail: "Serverless functions can have cold starts of 200-500ms. Edge functions are faster but have runtime limitations (no Node.js APIs)." },
319
320
  ],
320
- recent_changes: [],
321
- verified_date: "2026-03-30",
321
+ recent_changes: [
322
+ { date: "2026-04-19", change: "Security incident disclosed — Context.ai supply-chain compromise pivoted into Vercel internal systems via employee Google Workspace. Limited-subset customer credentials affected. See: https://vercel.com/kb/bulletin/vercel-april-2026-security-incident" },
323
+ ],
324
+ verified_date: "2026-04-20",
325
+ },
326
+ "surya": {
327
+ provider: "Surya",
328
+ risks: [
329
+ { severity: "HIGH", title: "Install requires a transformers<5.0.0 pin", detail: "As of 2026-04, 'pip install surya-ocr' alone fails at runtime with 'SuryaDecoderConfig' object has no attribute 'pad_token_id' (upstream issue #484). Pin transformers<5.0.0 in the same install step. Without the pin, bookkeeping runs will fail on the first document." },
330
+ { severity: "MEDIUM", title: "Licensing nuance: GPL-3.0 code + AI Pubs Open Rail-M weights", detail: "Code is GPL-3.0; model weights carry a separate AI Pubs Open Rail-M license with a <$2M funding/revenue clause for free use. Fine for internal tooling, production SaaS backends where outputs stay internal, and bookkeeping pipelines. For products distributed to end users or weights embedded in shipped software, consult counsel." },
331
+ { severity: "MEDIUM", title: "CPU inference is slow (~20s/doc p50)", detail: "A 10-doc bookkeeping batch takes ~3.5 min on CPU. Expect 3-5× speedup on MPS (Apple Silicon) or CUDA. Plan for GPU access or batch processing overnight if you have hundreds of docs/month." },
332
+ { severity: "LOW", title: "Reading order on multi-column layouts", detail: "On dense corporate filings, Surya's reading order can diverge from top-to-bottom, dragging word-error-rate (WER) down. Token F1 (93.4% on our corpus) is the more representative accuracy metric for downstream agent use — the words are captured, the sequencing is imperfect." },
333
+ ],
334
+ recent_changes: [
335
+ { date: "2026-04-21", change: "Eval on 10-document real-world corpus (native PDFs, legal docs, Brazilian corporate registry scans, NFS-e, boleto, phone-photo receipts). Surya placed first on word accuracy (76.9%) and layout (7.0/10). See /solve/pdf-text-extraction-mcp." },
336
+ ],
337
+ verified_date: "2026-04-21",
338
+ },
339
+ "tesseract": {
340
+ provider: "Tesseract 5",
341
+ risks: [
342
+ { severity: "MEDIUM", title: "PDFs require a pre-render step", detail: "Tesseract takes images, not PDFs. You need pdftoppm (from poppler) to render each page first: 'pdftoppm -r 300 doc.pdf page && tesseract page-1.ppm - -l por'. One extra shell step per doc — easy to script, but not zero-config." },
343
+ { severity: "MEDIUM", title: "Plain text output only (no layout)", detail: "Default output is a plain string — no bounding boxes, no form fields, no table structure. If your bookkeeping workflow needs structured invoice fields (line items, totals, vendor), Tesseract alone is not enough; pair it with an LLM for field extraction, or switch to Surya / Document AI." },
344
+ { severity: "LOW", title: "Language pack must be installed explicitly", detail: "brew install tesseract only ships with English. Add 'tesseract-lang' for the full set (includes 'por' for Portuguese). Missing language packs show up as garbage output on non-English docs — easy to miss in CI until a Portuguese invoice lands." },
345
+ { severity: "LOW", title: "Reading order on multi-column", detail: "Like Surya, Tesseract's reading order on dense multi-column layouts can diverge from top-to-bottom. Token F1 (91.4% on our corpus) remains high — the words are captured." },
346
+ ],
347
+ recent_changes: [
348
+ { date: "2026-04-21", change: "Eval on 10-document real-world corpus. Tesseract placed second on word accuracy (75.4%), first on latency (1.6s p50 — 14× faster than Surya), first on install friction (3/10). See /solve/pdf-text-extraction-mcp." },
349
+ ],
350
+ verified_date: "2026-04-21",
351
+ },
352
+ "google-document-ai": {
353
+ provider: "Google Document AI",
354
+ risks: [
355
+ { severity: "HIGH", title: "Paid cloud API is not automatically more accurate than free local tools", detail: "On our 10-doc mixed corpus Document AI placed third on word accuracy (0.697) behind local Surya (0.769) and Tesseract (0.754). Don't assume that paying per page buys you better extraction — for native-text PDFs and Brazilian corporate filings, the local options matched or beat the paid API. Document AI's edge was on phone-photographed receipts (94.6% vs. 93.1% for Surya on a Pix receipt)." },
356
+ { severity: "HIGH", title: "Requires GCP billing account", detail: "Personal Google accounts can't provision processors. You need a GCP project with billing linked (credit card required) even to stay under the 1,000 pages/month free tier. Enterprise-auth install flow: 'gcloud auth application-default login' + processor creation in the console." },
357
+ { severity: "MEDIUM", title: "Data leaves the local machine", detail: "Every PDF is uploaded to Google before extraction. For confidential financial docs (NFS-e with client info, internal invoices, salary receipts), confirm with compliance/counsel before routing through a cloud OCR API. Local tools (Surya, Tesseract) keep documents on the machine." },
358
+ { severity: "MEDIUM", title: "Sync endpoint capped at 15 pages per request", detail: "For larger PDFs you must split the document or switch to async batch. Batch has separate quotas and an extra setup step. Easy to hit on multi-page bank statements." },
359
+ { severity: "LOW", title: "Reading order diverges", detail: "Document AI's reading order on multi-column / watermarked layouts diverges from top-to-bottom. Token F1 (93.4% on our corpus) is strong — use it for downstream agent extraction rather than raw WER." },
360
+ ],
361
+ recent_changes: [
362
+ { date: "2026-04-21", change: "Eval on 10-document real-world corpus. Document AI placed third on word accuracy (69.7%), best on phone-photo receipts specifically. Cost: $0.069 total for 10 docs. See /solve/pdf-text-extraction-mcp." },
363
+ ],
364
+ verified_date: "2026-04-21",
322
365
  },
323
366
  };
@@ -0,0 +1,43 @@
1
+ export interface SolveCandidate {
2
+ slug: string;
3
+ name: string;
4
+ rank: number;
5
+ install: string;
6
+ scorecard: {
7
+ word_accuracy?: number;
8
+ token_f1?: number;
9
+ layout?: number;
10
+ p50_latency_sec?: number;
11
+ install_friction?: number;
12
+ cost_per_10_docs_usd?: number;
13
+ };
14
+ notes: string;
15
+ license?: string;
16
+ }
17
+ export interface SolveAlternativeConsidered {
18
+ name: string;
19
+ dropped_because: string;
20
+ }
21
+ export interface SolveFaq {
22
+ q: string;
23
+ a: string;
24
+ }
25
+ export interface SolveTask {
26
+ slug: string;
27
+ title: string;
28
+ url: string;
29
+ last_verified: string;
30
+ categories: string[];
31
+ works_with: string[];
32
+ alternatives: string[];
33
+ eval_method: string;
34
+ answer: string;
35
+ candidates: SolveCandidate[];
36
+ corpus_summary: string;
37
+ alternatives_considered: SolveAlternativeConsidered[];
38
+ faq: SolveFaq[];
39
+ methodological_caveats: string[];
40
+ update_cadence: string;
41
+ fit_by_agent: Record<string, Record<string, boolean>>;
42
+ }
43
+ export declare const solveTasks: Record<string, SolveTask>;
@@ -0,0 +1,127 @@
1
+ // Structured data for /solve/ task-first tool rankings.
2
+ //
3
+ // Each entry mirrors the published /solve/<slug>/ page on auxiliar.ai.
4
+ // Agents consume this via the solve_task and list_solve_tasks MCP tools so
5
+ // they can get the full eval data (scorecard, install commands, alternatives
6
+ // considered, FAQs, caveats) without depending on a search engine having
7
+ // indexed the page.
8
+ //
9
+ // Keep in sync with content/solve/<slug>.md. Update last_verified when the
10
+ // content/solve/ markdown changes. A build-time generator can automate this
11
+ // later; while only one task is live, hand-maintaining is cheaper than the
12
+ // pipeline.
13
+ export const solveTasks = {
14
+ "pdf-text-extraction-mcp": {
15
+ slug: "pdf-text-extraction-mcp",
16
+ title: "PDF text extraction for Claude Code agents — what to install, ranked by accuracy",
17
+ url: "https://auxiliar.ai/solve/pdf-text-extraction-mcp/",
18
+ last_verified: "2026-04-21",
19
+ categories: ["pdf-processing", "ocr", "agent-tools"],
20
+ works_with: ["claude-code", "claude-desktop", "cursor", "openclaw"],
21
+ alternatives: ["tesseract", "surya", "google-document-ai"],
22
+ eval_method: "auxiliar-ocr-walkthrough-v1",
23
+ answer: "If your Claude Code agent needs to parse PDFs and photo-captured documents reliably, install Surya (`pip install surya-ocr` + pin `transformers<5.0.0`). It led our 10-document real-world corpus on word accuracy (76.9%), layout preservation (7.0/10), and token F1 (93.4%) — while costing zero dollars per page, running entirely local, and handling PDFs natively. For latency-critical workflows where throughput matters more than layout, Tesseract 5 + por.traineddata runs 14× faster (1.6s p50) and installs in one brew command, trading 1.5 percentage points of word accuracy for dramatic speed and the cleanest install path. Google Document AI costs ~$0.002 per page after a 1000-page/month free tier and wins on mobile-captured receipts (94.6% vs 93.1% for Surya on a phone-photo Pix receipt) — but it places third on overall word accuracy on this corpus, diverges from top-to-bottom reading order, and carries an enterprise-auth install flow. For Brazilian corporate filings specifically, local models match or beat the paid vendor API.",
24
+ candidates: [
25
+ {
26
+ slug: "surya",
27
+ name: "Surya",
28
+ rank: 1,
29
+ install: "python -m venv .venv && source .venv/bin/activate && pip install surya-ocr 'transformers<5.0.0'",
30
+ scorecard: {
31
+ word_accuracy: 0.769,
32
+ token_f1: 0.934,
33
+ layout: 7.0,
34
+ p50_latency_sec: 22.1,
35
+ install_friction: 7,
36
+ cost_per_10_docs_usd: 0,
37
+ },
38
+ notes: "Led the corpus on word accuracy and layout preservation. The transformers<5.0.0 pin is required as of 2026-04: 'pip install surya-ocr' alone fails at runtime with 'SuryaDecoderConfig' object has no attribute 'pad_token_id' (issue #484). CPU inference ~22s/doc p50; 3-5× faster on MPS/CUDA.",
39
+ license: "GPL-3.0 (code) + AI Pubs Open Rail-M (weights, <$2M funding/revenue clause)",
40
+ },
41
+ {
42
+ slug: "tesseract",
43
+ name: "Tesseract 5",
44
+ rank: 2,
45
+ install: "brew install tesseract tesseract-lang poppler && pdftoppm -r 300 doc.pdf page && tesseract page-1.ppm - -l por",
46
+ scorecard: {
47
+ word_accuracy: 0.754,
48
+ token_f1: 0.914,
49
+ layout: 5.0,
50
+ p50_latency_sec: 1.6,
51
+ install_friction: 3,
52
+ cost_per_10_docs_usd: 0,
53
+ },
54
+ notes: "14× faster than Surya at p50 latency. Trades 1.5pp of word accuracy for throughput and the cleanest install path. PDFs need pdftoppm pre-render — Tesseract takes images, not PDFs. Plain text output only (no layout/bounding boxes). Language pack 'por' required for Portuguese via tesseract-lang.",
55
+ license: "Apache 2.0",
56
+ },
57
+ {
58
+ slug: "google-document-ai",
59
+ name: "Google Document AI",
60
+ rank: 3,
61
+ install: "gcloud auth application-default login && gcloud services enable documentai.googleapis.com --project YOUR_PROJECT && export DOCUMENT_AI_PROCESSOR_ID=<copied-id>",
62
+ scorecard: {
63
+ word_accuracy: 0.697,
64
+ token_f1: 0.934,
65
+ layout: 5.7,
66
+ p50_latency_sec: 3.8,
67
+ install_friction: 7,
68
+ cost_per_10_docs_usd: 0.069,
69
+ },
70
+ notes: "Third on overall word accuracy on this corpus, but best on phone-photographed receipts specifically (94.6% vs. 93.1% for Surya on a Pix receipt). Structured JSON output (form fields, tables, bounding boxes) is richer than plain text. Requires GCP billing account; 1,000 pages/month free per processor. Sync endpoint caps at 15 pages/request — split or use async batch. Data leaves the local machine.",
71
+ license: "Proprietary (Google Cloud)",
72
+ },
73
+ ],
74
+ corpus_summary: "10 real-world documents spanning OCR stress dimensions: 2 native-text PDFs (clean text layer), 3 digital legal docs (Word-generated PDFs), 2 image-heavy scans (Brazilian corporate-registry certifications with body content in image layer and government watermarks in text layer), 3 structured Brazilian forms (NFSe invoices, boleto), 2 phone-photographed receipts (real lighting and perspective). Ground truth is LLM-drafted, human-finalized transcription. Corpus is git-ignored (contains real business information).",
75
+ alternatives_considered: [
76
+ {
77
+ name: "yescan-ocr-universal (ClawHub skill)",
78
+ dropped_because: "Requires a SCAN_WEBSERVICE_KEY from Quark Scan (Chinese sign-up) and doesn't support PDFs natively (image-only, 5 MB limit). Practical install friction 9/10 for non-Chinese users.",
79
+ },
80
+ {
81
+ name: "Mistral OCR 3 (via everaldo/mcp-mistral-ocr MCP)",
82
+ dropped_because: "Strong on paper (88.9% handwriting, 96.6% table extraction per vendor benchmarks); deferred because no MISTRAL_API_KEY was available. Runner at scripts/ocr-walkthrough/run-mistral-ocr.sh is ready; re-enable when API key is provisioned.",
83
+ },
84
+ {
85
+ name: "pdf-reader-mcp",
86
+ dropped_because: "Looks like an MCP OCR tool but its 2.3.1 docs explicitly list OCR as 'planned, not implemented.' Only does text-layer extraction from native-text PDFs — equivalent to pdftotext. Unsuitable for scanned corpora.",
87
+ },
88
+ ],
89
+ faq: [
90
+ {
91
+ q: "Why is Surya slow compared to Google Document AI?",
92
+ a: "Surya runs locally on PyTorch. First invocation downloads ~150 MB of model weights. Steady-state inference on CPU averages ~20 s/doc on a multi-page scanned PDF. On GPU (MPS on Apple Silicon, CUDA on NVIDIA), expect 3-5× speedup. Google Document AI is a remote server farm.",
93
+ },
94
+ {
95
+ q: "Does 'word accuracy 76.9%' mean Surya gets only 76.9% of words right?",
96
+ a: "No. WER is an order-sensitive metric; it penalizes insertions, deletions, AND reordering. Token F1 (93.4%) is the order-insensitive accuracy — meaning Surya captures 93.4% of the correct words, but in a sequence that differs from ground-truth order in enough places to drag WER down. For downstream agent use, token F1 is usually the relevant metric: did the OCR see the content at all? Surya, Google Document AI, and Tesseract all score 0.91-0.94 on token F1.",
97
+ },
98
+ {
99
+ q: "When should I pay for Document AI over the free local options?",
100
+ a: "Three cases. (1) Your workflow depends on structured output (form fields, tables, bounding boxes) — Document AI's JSON is richer than plain text. (2) You're processing phone photos — Document AI was marginally best on the two phone-photo receipts in our corpus. (3) You're already in GCP and want auditable enterprise auth. Otherwise: local models match or beat Document AI on word accuracy, at $0.",
101
+ },
102
+ {
103
+ q: "Why do all three candidates score 0 on slot 07 (the boleto)?",
104
+ a: "The ground-truth transcription for the boleto is conservative — it excludes visible-decoration text like 'Aponte a câmera do seu celular para este QRCode...' All three OCR engines correctly capture that text, inflating candidate output relative to ground truth. WER explodes on insertions. Token F1 scores for slot 07 (0.575-0.646) are more representative of actual capture quality. If downstream use is agent-driven extraction of boleto fields specifically, all three are usable; if you need exactly ground-truth shape, consider post-processing to filter known-noise phrases.",
105
+ },
106
+ {
107
+ q: "Is Surya's GPL-3.0 license a problem for my startup?",
108
+ a: "Probably not for internal tooling, production services where outputs are consumed internally, or SaaS backends. Note: model weights are under a separate AI Pubs Open Rail-M license, with a <$2M funding/revenue clause for free use. For anything distributed to end users or embedded in shipped software, consult counsel.",
109
+ },
110
+ ],
111
+ methodological_caveats: [
112
+ "Corpus is 10 documents. Statistical confidence intervals are wide; differences under ~5 percentage points in word accuracy should be treated as noise.",
113
+ "Ground truth was LLM-drafted then human-reviewed. Some drafts (especially slot 07 boleto) may be under-conservative on visible-decoration text; WER on those docs is artifactually low.",
114
+ "Layout judge was the same Claude Opus 4.7 model handling the walkthrough (inline, in-conversation). A separate API-isolated judge run with fresh context is the more rigorous approach and is scripted but not yet executed.",
115
+ "Install-friction scores reflect actual install experience in April 2026; versions and paths drift.",
116
+ "Costs: $0.069 total for 10 docs on Document AI; $0 for both local tools. Budget consumed from a $20 walkthrough cap.",
117
+ "Not tested: native multimodal capabilities of Claude, GPT-4o, or Gemini themselves (agents with strong native vision may not need an added OCR tool).",
118
+ ],
119
+ update_cadence: "Re-run this walkthrough when: (a) any candidate ships a major version, (b) new OCR MCPs or ClawHub skills emerge that might outrank the top 3, (c) 90 days after first publish (2026-07-20), (d) Google Document AI pricing changes.",
120
+ fit_by_agent: {
121
+ "claude-code": { tesseract: true, surya: true, "google-document-ai": true },
122
+ "claude-desktop": { tesseract: true, surya: true, "google-document-ai": true },
123
+ cursor: { tesseract: true, surya: true, "google-document-ai": true },
124
+ openclaw: { tesseract: true, surya: true, "google-document-ai": true },
125
+ },
126
+ },
127
+ };
package/dist/server.js CHANGED
@@ -8,13 +8,14 @@ import { checkCompatibility } from "./tools/compatibility.js";
8
8
  import { getPricing } from "./tools/pricing.js";
9
9
  import { getRisks } from "./tools/risks.js";
10
10
  import { listServices } from "./tools/list.js";
11
+ import { solveTask, listSolveTasks } from "./tools/solve.js";
11
12
  const server = new McpServer({
12
13
  name: "auxiliar",
13
- version: "0.7.0",
14
+ version: "0.9.0",
14
15
  });
15
16
  // Tool: recommend_service
16
17
  server.tool("recommend_service", "Get a current, verified recommendation for a cloud service based on your constraints. Returns pricing, risks, provision commands, and alternatives. Data is Chrome-verified from actual service websites (not stale training data).", {
17
- need: z.string().max(100).describe("What kind of service you need (database, email, auth, deploy, payments, search, cms, storage, monitoring, cache, queues, vector, llm, sms, feature-flags, cron — aliases like 'llm-api', 'file-storage', 'vector-db' also work)"),
18
+ need: z.string().max(100).describe("What kind of service you need (database, email, auth, deploy, payments, search, cms, storage, monitoring, cache, queues, vector, llm, sms, feature-flags, cron, pdf-extraction — aliases like 'llm-api', 'file-storage', 'vector-db', 'ocr', 'document-ai', 'invoice-extraction', 'nfs-e' also work)"),
18
19
  framework: z.string().max(100).optional().describe("Your framework (nextjs, express, sveltekit, etc.)"),
19
20
  region: z.string().max(50).optional().describe("Preferred region (us, eu, etc.)"),
20
21
  budget: z.enum(["free", "cheap", "moderate", "enterprise"]).optional().describe("Budget constraint"),
@@ -73,6 +74,23 @@ server.tool("list_services", "List all available services and categories. Use wi
73
74
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
74
75
  };
75
76
  });
77
+ // Tool: solve_task
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."),
80
+ category: z.string().max(100).optional().describe("Filter by task category (e.g., 'ocr', 'pdf-processing', 'agent-tools'). Returns all matching tasks."),
81
+ }, async (params) => {
82
+ const result = await solveTask(params);
83
+ return {
84
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
85
+ };
86
+ });
87
+ // Tool: list_solve_tasks
88
+ server.tool("list_solve_tasks", "List all available /solve/ task rankings with their top picks. Use this to discover what jobs-to-be-done auxiliar.ai has evaluated installable tools for. Complementary to list_services (cloud services catalog): list_solve_tasks surfaces agent-installable tooling (skills, MCPs, APIs, local binaries) evaluated on real-world corpora.", {}, async () => {
89
+ const result = await listSolveTasks();
90
+ return {
91
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
92
+ };
93
+ });
76
94
  async function main() {
77
95
  const transport = new StdioServerTransport();
78
96
  await server.connect(transport);
@@ -48,6 +48,23 @@ const categoryAliases = {
48
48
  "content-management": "cms",
49
49
  "text-messaging": "sms",
50
50
  "text-messages": "sms",
51
+ "pdf": "pdf-extraction",
52
+ "pdfs": "pdf-extraction",
53
+ "pdf-ocr": "pdf-extraction",
54
+ "pdf-parsing": "pdf-extraction",
55
+ "pdf-text-extraction": "pdf-extraction",
56
+ "ocr": "pdf-extraction",
57
+ "document-ai": "pdf-extraction",
58
+ "document-extraction": "pdf-extraction",
59
+ "document-parsing": "pdf-extraction",
60
+ "invoice-extraction": "pdf-extraction",
61
+ "invoice-parsing": "pdf-extraction",
62
+ "receipt-parsing": "pdf-extraction",
63
+ "receipt-ocr": "pdf-extraction",
64
+ "nfs-e": "pdf-extraction",
65
+ "nfse": "pdf-extraction",
66
+ "boleto": "pdf-extraction",
67
+ "bookkeeping-ocr": "pdf-extraction",
51
68
  };
52
69
  export async function listServices(params) {
53
70
  // Ping API for analytics (non-blocking, silent fail)
@@ -30,6 +30,12 @@ interface Recommendation {
30
30
  reason: string;
31
31
  trade_off: string;
32
32
  }>;
33
+ community: {
34
+ total_reports: number;
35
+ success_rate: string;
36
+ avg_integration_time: string | null;
37
+ recommendation_rate: string | null;
38
+ } | null;
33
39
  data_source: string;
34
40
  }
35
41
  export declare function recommendService(params: RecommendParams): Promise<Recommendation>;
@@ -51,13 +51,30 @@ export async function recommendService(params) {
51
51
  "content-management": "cms",
52
52
  "text-messaging": "sms",
53
53
  "text-messages": "sms",
54
+ "pdf": "pdf-extraction",
55
+ "pdfs": "pdf-extraction",
56
+ "pdf-ocr": "pdf-extraction",
57
+ "pdf-parsing": "pdf-extraction",
58
+ "pdf-text-extraction": "pdf-extraction",
59
+ "ocr": "pdf-extraction",
60
+ "document-ai": "pdf-extraction",
61
+ "document-extraction": "pdf-extraction",
62
+ "document-parsing": "pdf-extraction",
63
+ "invoice-extraction": "pdf-extraction",
64
+ "invoice-parsing": "pdf-extraction",
65
+ "receipt-parsing": "pdf-extraction",
66
+ "receipt-ocr": "pdf-extraction",
67
+ "nfs-e": "pdf-extraction",
68
+ "nfse": "pdf-extraction",
69
+ "boleto": "pdf-extraction",
70
+ "bookkeeping-ocr": "pdf-extraction",
54
71
  };
55
72
  const resolvedNeed = categoryAliases[params.need.toLowerCase()] || params.need.toLowerCase();
56
73
  const category = recommendations[resolvedNeed];
57
74
  if (!category) {
58
75
  return {
59
76
  provider: "unknown",
60
- reason: `No recommendations available for category: ${params.need}. Supported: database, email, auth, deploy, payments, search, cms, storage, monitoring, cache, queues, vector, llm, sms, feature-flags, cron`,
77
+ reason: `No recommendations available for category: ${params.need}. Supported: database, email, auth, deploy, payments, search, cms, storage, monitoring, cache, queues, vector, llm, sms, feature-flags, cron, pdf-extraction`,
61
78
  pricing: { model: "unknown", free_tier: "unknown", paid_starts_at: "unknown" },
62
79
  risks: [],
63
80
  warnings: [`No services found for category: ${params.need}. Check auxiliar.ai for supported categories.`],
@@ -72,12 +89,46 @@ export async function recommendService(params) {
72
89
  mcp_install: null,
73
90
  mcp_note: null,
74
91
  alternatives: [],
92
+ community: null,
75
93
  data_source: "auxiliar.ai bundled data",
76
94
  };
77
95
  }
96
+ // Fetch community feedback for all services in this category (non-blocking, best-effort)
97
+ const communityStats = {};
98
+ try {
99
+ const feedbackPromises = category.services.map(async (svc) => {
100
+ try {
101
+ const resp = await fetch(`https://auxiliar.ai/api/feedback?service=${svc.slug}`, { signal: AbortSignal.timeout(3000) });
102
+ const data = await resp.json();
103
+ if (data.stats)
104
+ communityStats[svc.slug] = data.stats;
105
+ }
106
+ catch { }
107
+ });
108
+ await Promise.all(feedbackPromises);
109
+ }
110
+ catch { }
78
111
  // Score each service based on constraints
79
112
  const scored = category.services.map((svc) => {
80
113
  let score = svc.default_score || 5;
114
+ // Community feedback boost/penalty
115
+ // Verified reports have 1.5x weight, anonymous reports have 1.0x weight
116
+ const feedback = communityStats[svc.slug];
117
+ if (feedback) {
118
+ const verifiedReports = feedback.verified_reports || 0;
119
+ const anonymousReports = feedback.total_reports - verifiedReports;
120
+ const weightedReports = anonymousReports * 1.0 + verifiedReports * 1.5;
121
+ const successRate = feedback.total_reports > 0 ? (feedback.outcomes.success / feedback.total_reports) : 0;
122
+ if (weightedReports >= 3 && successRate >= 0.8)
123
+ score += 2;
124
+ if (weightedReports >= 3 && successRate < 0.5)
125
+ score -= 3;
126
+ if (weightedReports >= 5)
127
+ score += 1; // bonus for well-tested services
128
+ // Extra boost for verified credibility
129
+ if (verifiedReports >= 2 && successRate >= 0.8)
130
+ score += 1;
131
+ }
81
132
  // Budget filter
82
133
  if (params.budget === "free" && svc.has_free_tier)
83
134
  score += 3;
@@ -269,6 +320,12 @@ export async function recommendService(params) {
269
320
  reason: a.choose_if,
270
321
  trade_off: a.avoid_if,
271
322
  })),
323
+ community: communityStats[top.slug] ? {
324
+ total_reports: communityStats[top.slug].total_reports,
325
+ success_rate: communityStats[top.slug].success_rate,
326
+ avg_integration_time: communityStats[top.slug].avg_integration_time,
327
+ recommendation_rate: communityStats[top.slug].recommendation_rate,
328
+ } : null,
272
329
  data_source: `auxiliar.ai bundled data, last updated ${top.last_reviewed}`,
273
330
  };
274
331
  }
@@ -0,0 +1,31 @@
1
+ import { type SolveTask } from "../data/solve.js";
2
+ interface SolveTaskParams {
3
+ task_slug?: string;
4
+ category?: string;
5
+ }
6
+ interface SolveTaskResult {
7
+ task?: SolveTask;
8
+ matches?: SolveTask[];
9
+ error?: string;
10
+ available_tasks?: Array<{
11
+ slug: string;
12
+ title: string;
13
+ categories: string[];
14
+ }>;
15
+ }
16
+ export declare function solveTask(params: SolveTaskParams): Promise<SolveTaskResult>;
17
+ interface ListSolveTasksResult {
18
+ tasks: Array<{
19
+ slug: string;
20
+ title: string;
21
+ url: string;
22
+ categories: string[];
23
+ works_with: string[];
24
+ last_verified: string;
25
+ candidate_count: number;
26
+ top_pick: string;
27
+ }>;
28
+ total_tasks: number;
29
+ }
30
+ export declare function listSolveTasks(): Promise<ListSolveTasksResult>;
31
+ export {};
@@ -0,0 +1,85 @@
1
+ import { solveTasks } from "../data/solve.js";
2
+ import { pingApi } from "./analytics.js";
3
+ // Keyword aliases so an agent searching by concept still lands on the right
4
+ // task. Kept separate from the category-alias maps in list.ts / recommend.ts
5
+ // because /solve/ tasks are about *jobs to be done*, not service categories.
6
+ const taskAliases = {
7
+ // PDF text extraction task
8
+ "pdf": "pdf-text-extraction-mcp",
9
+ "pdfs": "pdf-text-extraction-mcp",
10
+ "pdf-extraction": "pdf-text-extraction-mcp",
11
+ "pdf-text": "pdf-text-extraction-mcp",
12
+ "pdf-text-extraction": "pdf-text-extraction-mcp",
13
+ "pdf-ocr": "pdf-text-extraction-mcp",
14
+ "ocr": "pdf-text-extraction-mcp",
15
+ "document-ai": "pdf-text-extraction-mcp",
16
+ "document-extraction": "pdf-text-extraction-mcp",
17
+ "invoice-extraction": "pdf-text-extraction-mcp",
18
+ "invoice-parsing": "pdf-text-extraction-mcp",
19
+ "receipt-parsing": "pdf-text-extraction-mcp",
20
+ "receipt-ocr": "pdf-text-extraction-mcp",
21
+ "nfs-e": "pdf-text-extraction-mcp",
22
+ "nfse": "pdf-text-extraction-mcp",
23
+ "boleto": "pdf-text-extraction-mcp",
24
+ "bookkeeping-ocr": "pdf-text-extraction-mcp",
25
+ };
26
+ function resolveSlug(raw) {
27
+ const lower = raw.toLowerCase().trim();
28
+ return taskAliases[lower] || lower;
29
+ }
30
+ function taskSummary(task) {
31
+ return {
32
+ slug: task.slug,
33
+ title: task.title,
34
+ categories: task.categories,
35
+ };
36
+ }
37
+ export async function solveTask(params) {
38
+ pingApi("solve_task", { task_slug: params.task_slug, category: params.category }).catch(() => { });
39
+ // Slug lookup (with alias resolution)
40
+ if (params.task_slug) {
41
+ const resolved = resolveSlug(params.task_slug);
42
+ const task = solveTasks[resolved];
43
+ if (task) {
44
+ return { task };
45
+ }
46
+ return {
47
+ error: `No /solve/ task found for slug or alias: ${params.task_slug}`,
48
+ available_tasks: Object.values(solveTasks).map(taskSummary),
49
+ };
50
+ }
51
+ // Category filter
52
+ if (params.category) {
53
+ const cat = params.category.toLowerCase().trim();
54
+ const matches = Object.values(solveTasks).filter((t) => t.categories.some((c) => c.toLowerCase() === cat) ||
55
+ t.categories.some((c) => c.toLowerCase().includes(cat)));
56
+ if (matches.length === 0) {
57
+ return {
58
+ error: `No /solve/ tasks found for category: ${params.category}`,
59
+ available_tasks: Object.values(solveTasks).map(taskSummary),
60
+ };
61
+ }
62
+ return { matches };
63
+ }
64
+ return {
65
+ error: "Provide either task_slug or category.",
66
+ available_tasks: Object.values(solveTasks).map(taskSummary),
67
+ };
68
+ }
69
+ export async function listSolveTasks() {
70
+ pingApi("list_solve_tasks", {}).catch(() => { });
71
+ const tasks = Object.values(solveTasks).map((t) => ({
72
+ slug: t.slug,
73
+ title: t.title,
74
+ url: t.url,
75
+ categories: t.categories,
76
+ works_with: t.works_with,
77
+ last_verified: t.last_verified,
78
+ candidate_count: t.candidates.length,
79
+ top_pick: t.candidates.find((c) => c.rank === 1)?.name || t.candidates[0]?.name || "",
80
+ }));
81
+ return {
82
+ tasks,
83
+ total_tasks: tasks.length,
84
+ };
85
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "auxiliar-mcp",
3
- "version": "0.7.0",
4
- "description": "MCP server that keeps your AI agent's infrastructure knowledge current. Chrome-verified pricing, risk flags, compatibility checks, and setup guides for 74 cloud services.",
3
+ "version": "0.9.0",
4
+ "description": "MCP server that keeps your AI agent's infrastructure knowledge current. Chrome-verified pricing, risk flags, compatibility checks, setup guides for 77 cloud services and local agent tools, plus /solve/ task rankings with reproducible evals for agent-installable tooling (skills, MCPs, APIs, local binaries).",
5
5
  "type": "module",
6
6
  "main": "dist/server.js",
7
7
  "bin": {
@@ -20,11 +20,14 @@
20
20
  },
21
21
  "keywords": [
22
22
  "mcp",
23
+ "mcp-server",
23
24
  "model-context-protocol",
24
25
  "ai-agent",
25
26
  "claude-code",
26
27
  "cursor",
28
+ "windsurf",
27
29
  "cloud-services",
30
+ "pricing",
28
31
  "developer-tools",
29
32
  "neon",
30
33
  "resend",