@fenfill/mcp 0.1.0 → 0.2.1

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.
package/README.md CHANGED
@@ -19,6 +19,8 @@ are stamped into the PDF locally and are never sent to fenfill or anywhere else.
19
19
  on your machine. If a box is misplaced, missing or mislabeled, **`edit_template`** fixes it in a
20
20
  local working copy that filling uses at once, and **`save_template`** keeps the fix in a saved
21
21
  template.
22
+ 5. **`reanalyze_template`** re-runs fenfill on some pages of a saved template (a page that was
23
+ never analyzed, or one that came out badly), from the blank PDF already stored with it.
22
24
 
23
25
  ### What is sent where
24
26
 
@@ -30,6 +32,7 @@ are stamped into the PDF locally and are never sent to fenfill or anywhere else.
30
32
  | Saved templates (blank PDF, fields, your logo) | Downloaded from fenfill to fill locally |
31
33
  | Page previews (`preview_page`) | **No**: rendered on your machine |
32
34
  | Layout corrections (`edit_template`) | Only on `save_template`, and then only the layout and the form's own wording |
35
+ | Re-analysis (`reanalyze_template`) | Only the template id, pages, kind and version: nothing is uploaded |
33
36
 
34
37
  `analyze_form` refuses PDFs whose form fields already hold answers, and PDFs this server wrote
35
38
  itself, so a filled-in form isn't uploaded by mistake.
@@ -101,6 +104,7 @@ On native Windows, if the client can't find `npx`, use `"command": "cmd"` with
101
104
  | `preview_page` | Renders one page (PNG) with every field box outlined and tagged, locally. |
102
105
  | `edit_template` | Moves, resizes, relabels, retypes, adds, deletes or regroups fields, locally. |
103
106
  | `save_template` | Saves `edit_template`'s working copy to a saved template. |
107
+ | `reanalyze_template` | Re-analyzes some pages of a saved template, with no upload, and shows the diff. |
104
108
 
105
109
  `analyze_form` options: `pages` (e.g. `"1-3,5"`; long PDFs can be analyzed in chunks, and
106
110
  `fill_form` merges them), `save_as_template` (also keep it as a fenfill template), `access`
@@ -130,16 +134,60 @@ workspace, free native-field (AcroForm) ones included.
130
134
  `preview_page` takes `path` (an analyzed PDF) or `template_id`, a 1-based `page`, optional
131
135
  `values` (to see them stamped; the same shapes as `fill_form`, e.g. `table_rows` =
132
136
  `[{columnId: value}, …]`, `multiselect` = an array of option ids or labels) and `dpi` (default
133
- 110, max 200). It returns a PNG image plus a legend: each box's tag, id, type, label and `box`.
134
- It renders the local working copy (`edit_template`) when there is one, otherwise the saved
137
+ 110, max 200). It returns a PNG image plus a legend: each box's tag, id, type, label and `box`;
138
+ a text/date field's stored `format` and `font_pt` (the size its value starts at; `font_auto`
139
+ when that follows the box height); a choice's options with their own boxes; a table's cells by
140
+ `(row, col)`, its `orientation` and headers (also printed on the image inside, or beside, the
141
+ first cell of each line as `R: …` / `C: …`; a character the bundled fonts lack is shown as `?`
142
+ there, with a warning, and the legend keeps the full text); a `table_rows` table's columns and printed cells
143
+ with their boxes (fill values still go by column id). `warnings` and `placement_warnings` are
144
+ always present (`[]` = checked and clean): placement covers every box shown, so a plain preview
145
+ is a read-only placement audit (see the checks under `edit_template`). `crop`
146
+ (`{x, y, w, h}`, fractions) with `zoom` (default 2, max 8) renders just a region, magnified, and
147
+ lists only what it shows; `legend: "changed"` returns only the rows that changed since your last
148
+ preview of that page (the first time: since fenfill's version), each with only its changed
149
+ options/cells/columns (`members_changed` counts them, so a header edit doesn't list the whole
150
+ grid), plus `removed` ids and `moved_into` (ids that now sit inside a table or group), and
151
+ `legend: "none"` omits the legend. It renders the local working copy (`edit_template`) when there is one, otherwise the saved
135
152
  template or analyzed version; `edited: true` / `false` in the result says which. The page is rendered on your machine by
136
153
  PDFium (WebAssembly, shipped in the package; nothing native is installed), nothing is written to
137
154
  disk, and the image goes only to the calling client.
138
155
 
139
- `edit_template` takes `path` or `template_id` and up to 200 `ops`: `set_box` (absolute
140
- `{id, x, y, w, h}` in one step), `move`, `resize`, `relabel`,
141
- `retype`, `add`, `delete`, `set_format`, `group`, `ungroup`, `set_options`, `set_required`,
142
- `set_description`, `set_placeholder` (table rows and columns can't be added or removed yet).
156
+ `edit_template` takes `path` or `template_id` and up to 200 `ops`:
157
+
158
+ - fields: `set_box` (absolute `{id, x, y, w, h}` in one step), `move`, `resize`, `relabel`,
159
+ `retype`, `add`, `delete`, `set_format` (`date_format` is one of `DD/MM/YYYY`, `MM/DD/YYYY`,
160
+ `YYYY-MM-DD`, `DD.MM.YYYY`, `DD-MM-YYYY`), `set_required`, `set_description`,
161
+ `set_placeholder`, `set_autofill` (a browser autofill token such as `name` or `postal-code`,
162
+ or `null` to clear it);
163
+ - choices and combs: `group` (`kind: "choice" | "comb"`), `ungroup`, `set_options`, and
164
+ `add_option` / `remove_option`, which keep the group's id;
165
+ - tables: `group` with `kind: "table"` (a `cells` grid of field ids, rows × columns with `null`
166
+ for a gap, or `ids` laid out from their boxes; `header_cols`, `header_rows`, `orientation`,
167
+ `format`), `table_insert` / `table_delete` (a row or column; a new line's geometry is
168
+ interpolated from its neighbours unless you pass it), `table_add_cell` (fill an empty slot),
169
+ `table_adopt` (move a loose field into an empty slot), `set_column_type`, `set_orientation`
170
+ and `set_header` / `set_headers` (`{id, axis, texts: [...], start?}`, several in one op). Every cell of one column (or row, for `orientation: "row"`) has one type,
171
+ as in the web editor; `set_format` on a table cell applies to its whole column or row;
172
+ - order: `reorder {page, ids}` moves those top-level entries together, in that order, to where
173
+ the first of them sat, and stamps an explicit `order` on every entry of the page (the web
174
+ editor's layer-panel convention), so a later sub-pixel move no longer reshuffles questions.
175
+
176
+ Any id can be shortened to an unambiguous prefix of 6+ characters (the length of the preview
177
+ tags); an ambiguous prefix is rejected with the candidates. `add`, `move` and `set_box` take an
178
+ optional `snap`: `"underline"` fits the box onto the printed rule under it, `"cell"` into the
179
+ ruled box around it, `"answer"` into that cell's blank part (below a caption printed at its top,
180
+ or after one at its left), read from the page render on your machine; when nothing fits near the
181
+ box, the box is kept and a warning says so. Snap finds printed rules with its own simple line
182
+ finder (one ink threshold per page, not the web editor's wand): a very faint rule on a tinted
183
+ scan can be missed, and an underline box is one line of handwriting tall (as tall as the clear
184
+ space above the rule, within about 11–16 pt). `diff_summary.ops` lists every applied op with
185
+ `snapped: true/false` (when it asked for a snap) and `noop: true` when it changed nothing. After
186
+ each edit, the boxes you touched are checked for three placement problems: a value that would
187
+ print much larger than the page's other fields (an Auto box's text size follows its height), a
188
+ box over printed text (text layer only, so not on scans), and a box that runs a little past the
189
+ ruled cell it sits in (from the page render, so scans too). `set_format` merges into the stored
190
+ format (a date field keeps its date format when you only set `font_size`).
143
191
  Coordinates are fractions of the page (0–1) with a top-left origin, the same as the legend's
144
192
  `box`. Each op is checked against the rules fenfill applies when saving and is rejected with a
145
193
  reason if it breaks them; ops apply in order, all-or-nothing each, except that a box only has to
@@ -160,7 +208,39 @@ memory). A working copy edited in an earlier session can't be checked against th
160
208
  answers: `save_template` then answers `confirm_wording_needed` with the changed ids and
161
209
  properties (never their text); review them and call again with `confirm_wording: true`. An
162
210
  unsaved analysis can be edited for filling but not saved: to keep corrections,
163
- analyze with `save_as_template: true` and edit that template.
211
+ analyze with `save_as_template: true` and edit that template. With nothing to save, it succeeds
212
+ with `saved: false, nothing_to_save: true`. `get_template` says `has_local_edits` (its fields
213
+ are fenfill's saved version; `preview_page` shows the working copy) and gives `field_count`
214
+ (entries listed) and `field_count_total` (the whole form); `save_template`'s `field_count` is
215
+ the whole saved template.
216
+
217
+ ### Re-analyzing pages of a saved template
218
+
219
+ A template saved from only some pages (`analyze_form` with `pages` and `save_as_template`) has
220
+ pages fenfill never looked at: `get_template` lists them as `unanalyzed_pages`, and
221
+ `list_templates` shows `analyzed_pages` next to `page_count`. `reanalyze_template` takes
222
+ `template_id`, `pages` and a `kind`:
223
+
224
+ | `kind` | Use it to |
225
+ | --------------- | --------------------------------------------------------------------------------- |
226
+ | `scratch` | analyze a never-analyzed page, or replace a badly analyzed page's fields entirely |
227
+ | `find` | add blanks the first pass missed, keeping everything already there |
228
+ | `relabel` | re-derive labels, types, groups and sections, keeping the boxes |
229
+ | `label_missing` | fill in only the labels that are missing |
230
+
231
+ `kind` can be left out only when the pages have no fields (it then means `scratch`). Each page
232
+ costs one page scan; `label_missing` is free within the workspace's monthly free-label
233
+ allowance. `estimate: true` prices the run and starts nothing. `relabel` may reset table column
234
+ types and orientation, so check the template with `get_template` afterwards.
235
+
236
+ It uses the PDF already stored with the template, so nothing is uploaded. It refuses while the
237
+ template has unsaved `edit_template` edits (`local_edits_pending`): save them with
238
+ `save_template` first, or pass `discard: true` to drop them when the run finishes. The result
239
+ lists, per changed page, the fields `added`, `removed` and `changed` (label, type, box, or a
240
+ group's cells), then the new fields of those pages; review them with `preview_page` and correct
241
+ them with `edit_template` + `save_template`. Like `analyze_form`, it waits out capacity
242
+ refusals, and if it answers `"running"`, calling it again with the same arguments follows the
243
+ same run at no extra charge.
164
244
 
165
245
  ### Value shapes
166
246
 
@@ -168,7 +248,7 @@ analyze with `save_as_template: true` and edit that template.
168
248
  | ------------------- | --------------------------------------------------------------------------- |
169
249
  | `text`, `multiline` | string, stamped exactly as given |
170
250
  | `comb` | string, one character per cell |
171
- | `date` | `"YYYY-MM-DD"`, printed as `YYYY-MM-DD` |
251
+ | `date` | `"YYYY-MM-DD"`, printed in the field's `date_format` (e.g. `DD/MM/YYYY`) |
172
252
  | `checkbox` | `true` / `false` |
173
253
  | `radio` | option id, option label, or the bare option text (`"No"` for `"Smoke? No"`) |
174
254
  | `multiselect` | array of those |
@@ -192,12 +272,12 @@ fenfill web app for that workspace (for example, your logo if you have set one u
192
272
 
193
273
  ## Configuration
194
274
 
195
- | Variable | Default | Notes |
196
- | ------------------------------ | ------------------------- | ------------------------------------------------------ |
197
- | `FENFILL_API_KEY` | (none) | `ff_live_…` from fenfill → Settings → API keys. |
198
- | `FENFILL_API_URL` | `https://api.fenfill.com` | https only (http allowed for localhost). |
199
- | `FENFILL_CACHE_DIR` | the OS cache folder | Holds schemas and blank forms only, never answers. |
200
- | `FENFILL_ANALYZE_WAIT_SECONDS` | `50` | How long `analyze_form` waits before saying "running". |
275
+ | Variable | Default | Notes |
276
+ | ------------------------------ | ------------------------- | ---------------------------------------------------------------------------- |
277
+ | `FENFILL_API_KEY` | (none) | `ff_live_…` from fenfill → Settings → API keys. |
278
+ | `FENFILL_API_URL` | `https://api.fenfill.com` | https only (http allowed for localhost). |
279
+ | `FENFILL_CACHE_DIR` | the OS cache folder | Holds schemas and blank forms only, never answers. |
280
+ | `FENFILL_ANALYZE_WAIT_SECONDS` | `50` | How long `analyze_form` / `reanalyze_template` wait before saying "running". |
201
281
 
202
282
  `fill_form` works without an API key once a form has been analyzed.
203
283
 
@@ -235,10 +315,13 @@ fenfill web app for that workspace (for example, your logo if you have set one u
235
315
  | `too_many_active_jobs` | Other analyses in the workspace (free native-field ones too) are still running; try again in a minute, or analyze fewer at once. |
236
316
  | `template_conflict` | The template changed in fenfill since your edits began. Your local edits are kept: `edit_template` with `discard: true`, re-apply the ops, save again. |
237
317
  | `invalid_schema` | fenfill (or the local check before it) refused the edited layout; `details` lists each item and reason. Fix them with `edit_template`. |
318
+ | `check_copy_failed` | `preview_page` could not build its outlined copy; `stage` and `id` say where. Fix or remove that field or group with `edit_template`, then preview again. |
238
319
  | `request_too_large` | The edited template is too large to save in one request. |
239
320
  | `answer_in_template` | Edited wording matches an answer from this session, so nothing was sent. Put the form's own wording back with `edit_template`. |
240
321
  | `confirm_wording_needed` | The working copy has wording edited in an earlier session. Review the ids and properties in `changed`, then `save_template` with `confirm_wording: true`. |
241
- | `no_local_edits` | `save_template` has nothing to save for that template (edits to an unsaved analysis can't be saved; see above). |
322
+ | `local_edits_pending` | `reanalyze_template` won't run over unsaved edits: `save_template` them first, or pass `discard: true`. |
323
+ | `kind_required` | The pages already have fields: pass `kind` (`find`, `relabel`, `label_missing`, or `scratch` to replace them). |
324
+ | `job_in_progress` | A job is already running on the template; wait and retry (call `reanalyze_template` again with the same arguments if you started it). |
242
325
  | `upload_outcome_unknown` | An earlier upload was interrupted. To avoid charging twice, the same file isn't re-uploaded for about 10 minutes; check `get_account` meanwhile. |
243
326
 
244
327
  ## API
@@ -1,4 +1,4 @@
1
- @fenfill/mcp 0.1.0 bundles the following third-party software.
1
+ @fenfill/mcp 0.2.1 bundles the following third-party software.
2
2
 
3
3
  @cantoo/pdf-lib@2.11.1 (MIT)
4
4
  ------------------------------------------------------------------------