Metadata-Version: 2.4
Name: justfill-mcp
Version: 0.4.0
Summary: JustFill MCP server — let AI agents detect, review and fill PDF form fields via justfill.app
Project-URL: Homepage, https://justfill.app
License-Expression: MIT
License-File: LICENSE
Keywords: ai-agents,claude,form-filling,forms,mcp,model-context-protocol,pdf
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Office/Business
Requires-Python: >=3.10
Requires-Dist: httpx>=0.24.0
Requires-Dist: mcp>=1.2.0
Requires-Dist: pillow>=10.0.0
Requires-Dist: pypdf>=4.0.0
Description-Content-Type: text/markdown

# JustFill MCP Server

Let AI agents (Claude, ChatGPT, n8n — any MCP client) detect, review and fill
PDF form fields through [justfill.app](https://justfill.app).

## Why agents can trust it

| Source | Confidence | What it means |
|---|---|---|
| **Saved template** | 1.0 | This exact PDF was filled before; geometry is human/agent-verified. No ML runs at all. |
| **AcroForm** | 1.0 | The PDF has embedded form fields — read from the file, filled natively. |
| **ML detection** | 0.0–0.95 | An honest draft. Review it visually (`render_preview`), fix it, then `save_template` to lock it in. |

ML confidence is *calibrated*: the detector's raw scores are not
probabilities (its server-side filter accepts boxes from raw ~0.02 and
auto-accepts at raw 0.15), so they are mapped onto 0–1 to mean what you'd
expect — ≥0.75 "detector is sure", 0.4–0.75 "probably right, glance at the
preview", <0.4 "borderline accept, verify". The raw detector score is kept
on each field as `raw_score`.

The correction loop (`render_preview` → `add/update/remove_field`) exists
precisely because ML detection has false positives and negatives. A false
positive costs nothing (leave it unfilled or remove it); a false negative is
visible on the preview and fixable with one `add_field` call. Once reviewed,
`save_template` makes every future fill of that form deterministic.

## Setup

```bash
uv tool install ./mcp-server        # or: pip install ./mcp-server
```

Authorize once (opens the browser, one click while logged in to justfill.app):

```bash
justfill-mcp login
```

Then the config needs no credentials at all:

```json
{
  "mcpServers": {
    "justfill": { "command": "justfill-mcp" }
  }
}
```

Alternatives, in the order the server checks them:

1. `JUSTFILL_API_KEY` env — create a key at justfill.app → Account → API Keys
   and put `"env": {"JUSTFILL_API_KEY": "jf_live_…"}` in the config.
2. The key saved by `justfill-mcp login` (`~/.config/justfill/credentials.json`).
3. `JUSTFILL_EMAIL` + `JUSTFILL_PASSWORD` — legacy fallback; an API key is
   better (no password in config files, revocable per client, never expires
   mid-session).

## Tools

- `open_pdf(path, min_confidence=0.0, max_pages=10, force_detect=False)` —
  template → AcroForm → ML resolution order. Accepts scanned images too
  (jpg/png/tiff → converted to PDF, deterministically, so templates still
  match). `force_detect=True` ignores a saved template and re-runs ML.
- `render_preview(page_index)` — page image with labeled field boxes (blue = deterministic, green/orange/red = ML confidence)
- `render_filled_preview(values, page_index)` — the same page with your values
  drawn in place (checkboxes get an X). Costs no fills — check before you fill.
- `list_fields(page_index?)`
- `add_field(x, y, w, h, name, page_index, field_type, align?, vertical_align?)` — coords in % of page, top-left origin
- `update_field(field_id, …)` / `remove_field(field_id)`
- `update_fields([{field_id, …}, …])` / `remove_fields([ids])` — batch versions
- `prune_fields(field_type?, confidence_below?, width_below?, height_below?, page_index?, exclude_ids?)` —
  bulk-delete detection noise in one call (criteria AND-ed, removed ids returned)
- `fill_pdf(values, output_path, flatten=True)` — `values` = `{field_id: text}`;
  responds with `warnings` for values that will be shrunk/truncated to fit
- `save_template(name)` — persist the reviewed layout for deterministic repeat fills
- `list_templates()`

Text alignment: `align` = `left|center|right`, `vertical_align` =
`top|middle|bottom` — set per field (e.g. `right` for RTL forms, `center` for
boxed digits). Persisted in templates.

## Example agent flow

```
open_pdf("~/forms/w-9.pdf")            → acroform, 27 fields, confidence 1.0
fill_pdf({"f1": "Jane Doe", …}, "~/out/w-9-filled.pdf")
```

```
open_pdf("~/forms/scan.jpg")           → converted to PDF; ml, 34 fields
render_preview(0)                      → agent sees noise + one missed line
prune_fields(field_type="cell", width_below=3)   → 16 removed in one call
add_field(x=18, y=62.5, w=40, h=3, name="Phone")
render_filled_preview({…})             → values sit right, no overflow
fill_pdf({…}, "~/out/filled.pdf")
save_template("Client intake form")    → next time: deterministic
```

## Notes

- Auth is a regular justfill.app account; tokens auto-refresh on expiry.
- Detection is free; downloads consume the account's fill allowance/credits
  (same rules as the web app).
- One PDF open at a time per server session (by design — keeps ids stable).
