Is Stipple — Document Verification & Extraction MCP server safe?
Yes, with the usual care.
Safe to use. Minor gaps such as a missing repository or slower maintenance.
What to know before installing
- highWrite-action tools reachable without authentication
Public scan report
scanner v0.1.9 · 2026-09-20 · same rubric, same numbers if you re-run it
1 high1 low
- –Code scanremote-only server, no package to scann/a
- Live reliabilityremote reachable in 2618ms17/20
- Tool poisoning16 tool descriptions checked13/15
- Auth qualityopen endpoint exposes 2 write-action tools with no auth3/15
- Maintenancelast push 22 days ago15/15
- Maintainer identitynamespace and repository owner differ; GitHub account older than a year; website matches verified namespace7/10
Findings (2)
- highWrite-action tools reachable without authentication
auth.open-write - lowUnusually long tool description (over 2,000 characters)
poison.long-descriptiontool extract_fields: …Extract structured FIELDS from a document (PDF or image) with a vision model. USE THIS WHEN you need specific values OUT of a document — a payslip's gross/net, an invoice's total/ABN, a form's checkboxes, a table's cells — rather than a yes/no about the document. (For "is this genuine?" use verify_document; "what kind of document is this?" is `options={"classify": true}` right here.) Say WHAT to pull, four ways: - `fields`: an ad-hoc list — names like ["gross_pay","abn"], or objects {"name":..., "type":"text|amount|date|boolean", "description":...}. THE general case: ask for exactly the fields your task needs. Use type "boolean" for a checkbox/tickbox. `"question"` works instead of `"description"` if you would rather just ask: {"name":"customer_name", "question":"What is the customer name?"}. - `template`: a named preset — "payslip", "tax_invoice", "bank_statement", "receipt". - NEITHER: AUTO — the document is classified and that type's fields are used. - auto on an unrecognised type: schema-free — every labelled field is returned. Provide the document ONE way: `url` (a public http(s) link — fetched server-side, the cheapest call) OR `bytes_b64` (inline base64, plus `filename` for PDF-vs-image routing). `country` is an optional hint; `max_pages` caps how many pages are read (default a few; hard ceiling 10). `options` turns on extra capabilities. Every one defaults OFF, and asking for one that this server does not support is an ERROR naming it — never a silent no-op, so you can always tell "asked wrongly" from "nothing found". Available today: - `{"grounding": true}` — every value gains `bbox` (the rectangle it was read from, in PDF points, origin top-left) and `text_layer_match`. Use it to CITE a value back to the page. Born-digital PDFs only for now; a scan returns `bbox: null` and `grounding: "none"`. - `{"flag_below": 0.7}` — adds `needs_review`, the fields under that confidence, weakest first. Use it to route the doubtful ones to a human instead of checking everything. - `{"tables": true}` — adds `tables`: whole tables with their rows. On a PDF these are read from the document's own rules and coordinates (exact cells, merged-cell colspans, no model call and NO CREDIT for the table pass); on a scan the model reads the rows and the table says `source: "vlm"` with no cell geometry. `{"tables": {"formats": ["json","markdown","html"], "borderless": true, "cells": true}}` to tune it. - `{"classify": true}` — adds `classification`: the full verdict (type, country, confidence, evidence), not just the routing. Free in auto mode. - `{"redact": true}` — adds `pii` (a MASKED inventory) and `redacted_text`, so you can extract and check for personal data in ONE call. A field you NAMED is still returned in full; the inventory never is. Two things to know before turning it on: `redacted_text` is the document's WHOLE text body with detected PII replaced — for a PDF that means every page, not just the ones `max_pages` covers — and redaction is best-effort coverage, so anything it failed to detect stays in that text verbatim. It also costs an extra page-equivalent per page, because it is a second model pass. - `{"layout": true}` — adds `layout.blocks`: every text block with its role (heading/body), font, size, column and reading order. Born-digital PDFs only; free. - `{"links": true}` — adds `links`: the PDF's own link annotations with uri, anchor text and bbox. Free. A URL merely PRINTED on the page is not an annotation. - `{"figures": true}` — adds `figures`: where the embedded images sit (bbox and pixel size), never the bytes. Free. - `{"chunks": true}` — adds `chunks`: retrieval-ready pieces that carry provenance a text splitter cannot give you — `heading_path` (where in the document), `bbox` and page range (citable back to the page), tables never sliced. Six strategies via `{"chunks": {"strategy": "section|page|chars|recursive|element|hierarchical", "max_chars": 1500, "min_chars": 200, "overlap": 100, "include_headings": true}}`. `hierarchical` adds parent context chunks for small-to-big retrieval. Born-digital PDFs only; free. - `{"split": true}` — adds `documents`: the page ranges of the distinct documents in one file (a bundle of 3 stapled PDFs -> 3 entries with types). One classifier call per page, so it costs +1 page-equivalent per page read. `render_scale` (one of 1.0, 1.5, 2.0, 3.0, 4.0; default 2.0) raises rasterisation for small or dense print. Call `GET /v1/extract/capabilities` for the full machine-readable list. COST: 1 credit per page read, minimum 1 — with `fields` or a `template` given, a one-page receipt costs 1 and a ten-page statement costs 10; AUTO mode adds 1 for the routing classification. Options that add model reads add page-equivalents (`redact` +pages, `split` +pages replacing the auto/classify +1, `tables` +pages only on a scan); deterministic work is free, and an encrypted PDF is charged the one-page floor only. Pages charged is min(`max_pages`, the document's real length), resolved before the call runs, so you can predict the price. Set `max_pages` to cap your spend on a long document. CAPABILITY-ONLY: `options.classify` and/or `options.redact` with no `fields`, no `template` and no other option skips field extraction entirely — classify-only costs 1 credit and redact-only 1 per page, exactly what the retired classify_document and redact_pii tools charged. Returns `{mode, document_type, fields{name:{value,confidence,page}}, not_found, pages_read, page_limit, page_count}`. `page_count` is the document's real length, so you can see when `max_pages` truncated it. EXTRACTION, not verification — values are what the document SHOWS, not proof it is genuine. A field that isn't clearly present comes back in `not_found` (it abstains rather than guessing). `text_layer_match` is `exact` / `normalised` when the printed value was located on the page, `multiple` when the same string appears more than once (no box — we will not guess which), and `absent` when it is not there. It reports whether the string was FOUND, not that the value is correct. The document is never stored. …
Overall 73/100. Components that don't apply are left out of the denominator. Any critical finding is an F.RubricAppeal a findingJSON
Other servers that do what Stipple — Document Verification & Extraction does
- CitraLocal-first PDF evidence for agents: structure, tables, OCR, and citations. SDK · CLI · MCP.not reviewedEstablishedA
Stipple — Document Verification & Extraction reviews, tools and install