pdf-form-proof 0.1.0__tar.gz
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.
- pdf_form_proof-0.1.0/.claude-plugin/marketplace.json +12 -0
- pdf_form_proof-0.1.0/.claude-plugin/plugin.json +10 -0
- pdf_form_proof-0.1.0/.gitignore +7 -0
- pdf_form_proof-0.1.0/.mcp.json +8 -0
- pdf_form_proof-0.1.0/.mcpbignore +12 -0
- pdf_form_proof-0.1.0/Dockerfile +9 -0
- pdf_form_proof-0.1.0/GEMINI.md +10 -0
- pdf_form_proof-0.1.0/LICENSE +21 -0
- pdf_form_proof-0.1.0/PKG-INFO +169 -0
- pdf_form_proof-0.1.0/README.md +150 -0
- pdf_form_proof-0.1.0/SKILL.md +44 -0
- pdf_form_proof-0.1.0/gemini-extension.json +13 -0
- pdf_form_proof-0.1.0/manifest.json +68 -0
- pdf_form_proof-0.1.0/pyproject.toml +36 -0
- pdf_form_proof-0.1.0/run_server.py +11 -0
- pdf_form_proof-0.1.0/server.json +23 -0
- pdf_form_proof-0.1.0/skills/pdf-form-proof/SKILL.md +44 -0
- pdf_form_proof-0.1.0/src/pdf_form_proof/__init__.py +3 -0
- pdf_form_proof-0.1.0/src/pdf_form_proof/_acroform.py +242 -0
- pdf_form_proof-0.1.0/src/pdf_form_proof/cli.py +37 -0
- pdf_form_proof-0.1.0/src/pdf_form_proof/fill.py +195 -0
- pdf_form_proof-0.1.0/src/pdf_form_proof/legibility.py +262 -0
- pdf_form_proof-0.1.0/src/pdf_form_proof/server.py +97 -0
- pdf_form_proof-0.1.0/tests/test_smoke.py +31 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pdf-form-proof",
|
|
3
|
+
"owner": { "name": "EssenceAlignment" },
|
|
4
|
+
"plugins": [
|
|
5
|
+
{
|
|
6
|
+
"name": "pdf-form-proof",
|
|
7
|
+
"source": "./",
|
|
8
|
+
"description": "Fill fillable PDF forms, then prove every value is visible on the rendered page.",
|
|
9
|
+
"version": "0.1.0"
|
|
10
|
+
}
|
|
11
|
+
]
|
|
12
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pdf-form-proof",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Fill fillable PDF forms, then prove every value is visible on the rendered page (OCR vs. text layer). Refuses unknown field names; never overwrites; runs locally.",
|
|
5
|
+
"author": { "name": "EssenceAlignment" },
|
|
6
|
+
"homepage": "https://github.com/EssenceAlignment/pdf-form-proof",
|
|
7
|
+
"repository": "https://github.com/EssenceAlignment/pdf-form-proof",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"keywords": ["pdf", "pdf-form", "form-filling", "acroform", "ocr", "verification", "nonprofit", "mcp"]
|
|
10
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
FROM python:3.12-slim
|
|
2
|
+
RUN apt-get update \
|
|
3
|
+
&& apt-get install -y --no-install-recommends poppler-utils tesseract-ocr \
|
|
4
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
5
|
+
WORKDIR /app
|
|
6
|
+
COPY pyproject.toml README.md LICENSE ./
|
|
7
|
+
COPY src ./src
|
|
8
|
+
RUN pip install --no-cache-dir .
|
|
9
|
+
ENTRYPOINT ["pdf-form-proof"]
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# pdf-form-proof
|
|
2
|
+
|
|
3
|
+
Tools: pdf_form_inspect, pdf_form_fill, pdf_form_verify, pdf_sha256.
|
|
4
|
+
|
|
5
|
+
Workflow for any fillable PDF form: inspect to get exact field names and
|
|
6
|
+
checkbox on-states; fill with exact names (unknown names are refused and
|
|
7
|
+
nothing is written); then verify the output so each value is confirmed
|
|
8
|
+
VISIBLE on the rendered page. Report REFUSE verdicts as-is. Never invent a
|
|
9
|
+
field value; ask the user. This tool fills forms and gives no legal, tax, or
|
|
10
|
+
benefits advice. The verify tool needs poppler and tesseract installed.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 EssenceAlignment
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: pdf-form-proof
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Fill fillable PDF forms, then prove every value is visible on the rendered page. MCP server and CLI.
|
|
5
|
+
Project-URL: Homepage, https://github.com/EssenceAlignment/pdf-form-proof
|
|
6
|
+
Project-URL: Issues, https://github.com/EssenceAlignment/pdf-form-proof/issues
|
|
7
|
+
Author: EssenceAlignment
|
|
8
|
+
License: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: acroform,form-filling,mcp,nonprofit,ocr,pdf,pdf-form,verification
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: Office/Business
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Requires-Dist: mcp<2,>=1.10
|
|
16
|
+
Requires-Dist: pillow>=10.0
|
|
17
|
+
Requires-Dist: pypdf>=4.0
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
|
|
20
|
+
# pdf-form-proof
|
|
21
|
+
|
|
22
|
+
Fill a fillable PDF form, then prove every value actually shows on the page.
|
|
23
|
+
|
|
24
|
+
mcp-name: io.github.EssenceAlignment/pdf-form-proof
|
|
25
|
+
|
|
26
|
+
A PDF can hold a value in its data while the page a person sees, prints, or
|
|
27
|
+
uploads shows nothing, or shows it cut off. Most form tools stop at "the field
|
|
28
|
+
was set." This one keeps going: it renders the page, reads it back with OCR
|
|
29
|
+
(optical character recognition, software that reads text from an image), and
|
|
30
|
+
compares that with the text stored in the file. Each value comes back VISIBLE,
|
|
31
|
+
INVISIBLE, RENDER-ONLY, or MISSING.
|
|
32
|
+
|
|
33
|
+
It works as an MCP server (MCP, the Model Context Protocol, is the plug-in
|
|
34
|
+
standard that lets AI apps such as Claude call outside tools), as a Claude
|
|
35
|
+
plugin, as a Gemini CLI extension, and as plain command-line tools.
|
|
36
|
+
|
|
37
|
+
## What it does
|
|
38
|
+
|
|
39
|
+
| Tool | What it does | Changes files? |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| `pdf_form_inspect` | Lists every fillable field: exact name, type, current value, required flag, and the values that check each checkbox or radio button | No |
|
|
42
|
+
| `pdf_form_fill` | Fills fields by exact name and writes a new PDF. Refuses the whole fill if any name is not in the form. Never modifies the source, never overwrites an existing file. Returns the new file's SHA-256 and reads every text value back | Writes one new file |
|
|
43
|
+
| `pdf_form_verify` | Renders a page, OCRs it, and gives each value a verdict. Can be limited to one region of the page so a copy of the value elsewhere cannot make it pass | No |
|
|
44
|
+
| `pdf_sha256` | SHA-256 fingerprint of a file, for a record of exactly what was produced | No |
|
|
45
|
+
|
|
46
|
+
Every tool carries MCP annotations: `readOnlyHint` and `destructiveHint` are set on all four.
|
|
47
|
+
|
|
48
|
+
## Who it is for
|
|
49
|
+
|
|
50
|
+
Anyone who fills the same official PDFs again and again: small nonprofits and
|
|
51
|
+
community organizations (vendor forms such as the IRS W-9, grant and funder
|
|
52
|
+
forms, program intake and consent forms), operations staff, and builders who
|
|
53
|
+
want an AI assistant to fill forms without hiding a partial or invisible fill.
|
|
54
|
+
|
|
55
|
+
## Install
|
|
56
|
+
|
|
57
|
+
You need Python 3.10 or newer and `uv` (https://docs.astral.sh/uv/). The verify
|
|
58
|
+
tool also needs two free programs:
|
|
59
|
+
|
|
60
|
+
- macOS: `brew install poppler tesseract`
|
|
61
|
+
- Debian or Ubuntu: `sudo apt install poppler-utils tesseract-ocr`
|
|
62
|
+
|
|
63
|
+
### Claude Desktop (MCP server)
|
|
64
|
+
|
|
65
|
+
Add this to `claude_desktop_config.json`:
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"mcpServers": {
|
|
70
|
+
"pdf-form-proof": {
|
|
71
|
+
"command": "uvx",
|
|
72
|
+
"args": ["pdf-form-proof"]
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Or install the `.mcpb` file from the latest GitHub release: double-click it, or
|
|
79
|
+
use Settings > Extensions > Advanced settings > Install Extension.
|
|
80
|
+
|
|
81
|
+
### Claude Code (plugin)
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
claude plugin marketplace add EssenceAlignment/pdf-form-proof
|
|
85
|
+
claude plugin install pdf-form-proof@pdf-form-proof
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Gemini CLI (extension)
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
gemini extensions install https://github.com/EssenceAlignment/pdf-form-proof
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Command line
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
uvx --from pdf-form-proof pdf-form-inspect form.pdf
|
|
98
|
+
uvx --from pdf-form-proof pdf-form-fill form.pdf filled.pdf values.json
|
|
99
|
+
uvx --from pdf-form-proof pdf-form-verify filled.pdf --require "Sample Community Food Bank"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`values.json` maps exact field names (from `pdf-form-inspect`) to values:
|
|
103
|
+
|
|
104
|
+
```json
|
|
105
|
+
{
|
|
106
|
+
"topmostSubform[0].Page1[0].f1_01[0]": "Sample Community Food Bank",
|
|
107
|
+
"topmostSubform[0].Page1[0].Boxes3a-b_ReadOrder[0].c1_1[0]": "/1"
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Text fields take a string. A checkbox or radio takes one of its on-state values
|
|
112
|
+
(shown by inspect, for example "/1" or "/Yes"), or an empty string to clear it.
|
|
113
|
+
|
|
114
|
+
Exit codes: 0 success; 1 a finding (verify found a value that is not visible,
|
|
115
|
+
or a fill could not be read back); 2 refused (unknown field names, a missing
|
|
116
|
+
file, an existing output, or a tool such as tesseract failed).
|
|
117
|
+
|
|
118
|
+
## Example
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
$ pdf-form-verify filled.pdf --require "Sample Community Food Bank" --require "Sample Pantry Program"
|
|
122
|
+
PDF FORM PROOF - legibility check verdict: PASS
|
|
123
|
+
file: filled.pdf page 1 at 300 dpi scope: whole page
|
|
124
|
+
VALUE SOURCE TEXT RENDER VERDICT
|
|
125
|
+
Sample Community Food Bank required yes yes VISIBLE
|
|
126
|
+
Sample Pantry Program required yes yes VISIBLE
|
|
127
|
+
limit: legibility only; says nothing about whether values are correct
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Limits (read these)
|
|
131
|
+
|
|
132
|
+
- AcroForm forms only. XFA-only forms (Adobe LiveCycle dynamic forms) are
|
|
133
|
+
detected and refused, not filled.
|
|
134
|
+
- `finalize` removes the XFA packet and the NeedAppearances flag so viewers draw
|
|
135
|
+
the values from their own appearance streams. It does not flatten the form;
|
|
136
|
+
fields stay editable.
|
|
137
|
+
- Verify proves legibility, not correctness. It cannot tell you whether a value
|
|
138
|
+
is the right answer for the form.
|
|
139
|
+
- OCR can misread small, stylized, or handwritten-style fonts. A REFUSE verdict
|
|
140
|
+
means "look at the page," not "the file is broken." A tool failure (missing
|
|
141
|
+
poppler or tesseract, a render error) is reported as a tool failure, never as
|
|
142
|
+
a finding about your document.
|
|
143
|
+
- Signatures are not created. Signature fields are listed by inspect and left alone.
|
|
144
|
+
- This tool fills forms. It does not give legal, tax, benefits, or other
|
|
145
|
+
professional advice, and it does not decide what belongs in any field.
|
|
146
|
+
|
|
147
|
+
## Privacy policy
|
|
148
|
+
|
|
149
|
+
pdf-form-proof runs entirely on your own computer.
|
|
150
|
+
|
|
151
|
+
- Data collection: none. It reads only the PDF files you name and writes only
|
|
152
|
+
the output path you name.
|
|
153
|
+
- Usage and storage: rendered page images are kept in `~/.cache/pdf-form-proof`
|
|
154
|
+
only until the next verify run, which deletes them.
|
|
155
|
+
- Third-party sharing: none. It makes no network calls and sends no telemetry.
|
|
156
|
+
- Retention: nothing is retained beyond the files you create.
|
|
157
|
+
- Contact: open an issue at https://github.com/EssenceAlignment/pdf-form-proof/issues
|
|
158
|
+
|
|
159
|
+
## Origin
|
|
160
|
+
|
|
161
|
+
The fill engine and the visible-on-the-page check were built for a production
|
|
162
|
+
document pipeline after a filled form passed every text-based check and was
|
|
163
|
+
still returned because a value could not be seen on the page. The two rules
|
|
164
|
+
that came out of that: never hide a partial fill, and check the page a person
|
|
165
|
+
sees, not only the data in the file.
|
|
166
|
+
|
|
167
|
+
## License
|
|
168
|
+
|
|
169
|
+
MIT. See `LICENSE`.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# pdf-form-proof
|
|
2
|
+
|
|
3
|
+
Fill a fillable PDF form, then prove every value actually shows on the page.
|
|
4
|
+
|
|
5
|
+
mcp-name: io.github.EssenceAlignment/pdf-form-proof
|
|
6
|
+
|
|
7
|
+
A PDF can hold a value in its data while the page a person sees, prints, or
|
|
8
|
+
uploads shows nothing, or shows it cut off. Most form tools stop at "the field
|
|
9
|
+
was set." This one keeps going: it renders the page, reads it back with OCR
|
|
10
|
+
(optical character recognition, software that reads text from an image), and
|
|
11
|
+
compares that with the text stored in the file. Each value comes back VISIBLE,
|
|
12
|
+
INVISIBLE, RENDER-ONLY, or MISSING.
|
|
13
|
+
|
|
14
|
+
It works as an MCP server (MCP, the Model Context Protocol, is the plug-in
|
|
15
|
+
standard that lets AI apps such as Claude call outside tools), as a Claude
|
|
16
|
+
plugin, as a Gemini CLI extension, and as plain command-line tools.
|
|
17
|
+
|
|
18
|
+
## What it does
|
|
19
|
+
|
|
20
|
+
| Tool | What it does | Changes files? |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| `pdf_form_inspect` | Lists every fillable field: exact name, type, current value, required flag, and the values that check each checkbox or radio button | No |
|
|
23
|
+
| `pdf_form_fill` | Fills fields by exact name and writes a new PDF. Refuses the whole fill if any name is not in the form. Never modifies the source, never overwrites an existing file. Returns the new file's SHA-256 and reads every text value back | Writes one new file |
|
|
24
|
+
| `pdf_form_verify` | Renders a page, OCRs it, and gives each value a verdict. Can be limited to one region of the page so a copy of the value elsewhere cannot make it pass | No |
|
|
25
|
+
| `pdf_sha256` | SHA-256 fingerprint of a file, for a record of exactly what was produced | No |
|
|
26
|
+
|
|
27
|
+
Every tool carries MCP annotations: `readOnlyHint` and `destructiveHint` are set on all four.
|
|
28
|
+
|
|
29
|
+
## Who it is for
|
|
30
|
+
|
|
31
|
+
Anyone who fills the same official PDFs again and again: small nonprofits and
|
|
32
|
+
community organizations (vendor forms such as the IRS W-9, grant and funder
|
|
33
|
+
forms, program intake and consent forms), operations staff, and builders who
|
|
34
|
+
want an AI assistant to fill forms without hiding a partial or invisible fill.
|
|
35
|
+
|
|
36
|
+
## Install
|
|
37
|
+
|
|
38
|
+
You need Python 3.10 or newer and `uv` (https://docs.astral.sh/uv/). The verify
|
|
39
|
+
tool also needs two free programs:
|
|
40
|
+
|
|
41
|
+
- macOS: `brew install poppler tesseract`
|
|
42
|
+
- Debian or Ubuntu: `sudo apt install poppler-utils tesseract-ocr`
|
|
43
|
+
|
|
44
|
+
### Claude Desktop (MCP server)
|
|
45
|
+
|
|
46
|
+
Add this to `claude_desktop_config.json`:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"mcpServers": {
|
|
51
|
+
"pdf-form-proof": {
|
|
52
|
+
"command": "uvx",
|
|
53
|
+
"args": ["pdf-form-proof"]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Or install the `.mcpb` file from the latest GitHub release: double-click it, or
|
|
60
|
+
use Settings > Extensions > Advanced settings > Install Extension.
|
|
61
|
+
|
|
62
|
+
### Claude Code (plugin)
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
claude plugin marketplace add EssenceAlignment/pdf-form-proof
|
|
66
|
+
claude plugin install pdf-form-proof@pdf-form-proof
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Gemini CLI (extension)
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
gemini extensions install https://github.com/EssenceAlignment/pdf-form-proof
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Command line
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
uvx --from pdf-form-proof pdf-form-inspect form.pdf
|
|
79
|
+
uvx --from pdf-form-proof pdf-form-fill form.pdf filled.pdf values.json
|
|
80
|
+
uvx --from pdf-form-proof pdf-form-verify filled.pdf --require "Sample Community Food Bank"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`values.json` maps exact field names (from `pdf-form-inspect`) to values:
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"topmostSubform[0].Page1[0].f1_01[0]": "Sample Community Food Bank",
|
|
88
|
+
"topmostSubform[0].Page1[0].Boxes3a-b_ReadOrder[0].c1_1[0]": "/1"
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Text fields take a string. A checkbox or radio takes one of its on-state values
|
|
93
|
+
(shown by inspect, for example "/1" or "/Yes"), or an empty string to clear it.
|
|
94
|
+
|
|
95
|
+
Exit codes: 0 success; 1 a finding (verify found a value that is not visible,
|
|
96
|
+
or a fill could not be read back); 2 refused (unknown field names, a missing
|
|
97
|
+
file, an existing output, or a tool such as tesseract failed).
|
|
98
|
+
|
|
99
|
+
## Example
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
$ pdf-form-verify filled.pdf --require "Sample Community Food Bank" --require "Sample Pantry Program"
|
|
103
|
+
PDF FORM PROOF - legibility check verdict: PASS
|
|
104
|
+
file: filled.pdf page 1 at 300 dpi scope: whole page
|
|
105
|
+
VALUE SOURCE TEXT RENDER VERDICT
|
|
106
|
+
Sample Community Food Bank required yes yes VISIBLE
|
|
107
|
+
Sample Pantry Program required yes yes VISIBLE
|
|
108
|
+
limit: legibility only; says nothing about whether values are correct
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Limits (read these)
|
|
112
|
+
|
|
113
|
+
- AcroForm forms only. XFA-only forms (Adobe LiveCycle dynamic forms) are
|
|
114
|
+
detected and refused, not filled.
|
|
115
|
+
- `finalize` removes the XFA packet and the NeedAppearances flag so viewers draw
|
|
116
|
+
the values from their own appearance streams. It does not flatten the form;
|
|
117
|
+
fields stay editable.
|
|
118
|
+
- Verify proves legibility, not correctness. It cannot tell you whether a value
|
|
119
|
+
is the right answer for the form.
|
|
120
|
+
- OCR can misread small, stylized, or handwritten-style fonts. A REFUSE verdict
|
|
121
|
+
means "look at the page," not "the file is broken." A tool failure (missing
|
|
122
|
+
poppler or tesseract, a render error) is reported as a tool failure, never as
|
|
123
|
+
a finding about your document.
|
|
124
|
+
- Signatures are not created. Signature fields are listed by inspect and left alone.
|
|
125
|
+
- This tool fills forms. It does not give legal, tax, benefits, or other
|
|
126
|
+
professional advice, and it does not decide what belongs in any field.
|
|
127
|
+
|
|
128
|
+
## Privacy policy
|
|
129
|
+
|
|
130
|
+
pdf-form-proof runs entirely on your own computer.
|
|
131
|
+
|
|
132
|
+
- Data collection: none. It reads only the PDF files you name and writes only
|
|
133
|
+
the output path you name.
|
|
134
|
+
- Usage and storage: rendered page images are kept in `~/.cache/pdf-form-proof`
|
|
135
|
+
only until the next verify run, which deletes them.
|
|
136
|
+
- Third-party sharing: none. It makes no network calls and sends no telemetry.
|
|
137
|
+
- Retention: nothing is retained beyond the files you create.
|
|
138
|
+
- Contact: open an issue at https://github.com/EssenceAlignment/pdf-form-proof/issues
|
|
139
|
+
|
|
140
|
+
## Origin
|
|
141
|
+
|
|
142
|
+
The fill engine and the visible-on-the-page check were built for a production
|
|
143
|
+
document pipeline after a filled form passed every text-based check and was
|
|
144
|
+
still returned because a value could not be seen on the page. The two rules
|
|
145
|
+
that came out of that: never hide a partial fill, and check the page a person
|
|
146
|
+
sees, not only the data in the file.
|
|
147
|
+
|
|
148
|
+
## License
|
|
149
|
+
|
|
150
|
+
MIT. See `LICENSE`.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pdf-form-proof
|
|
3
|
+
description: Fill a fillable (AcroForm) PDF form and prove the result is visible on the page. Use when asked to fill out, complete, or check a PDF form (W-9, grant, intake, consent, or any agency form), when a filled field "looks blank", or when a form must be verified before it is sent. Inspect exact field names, fill by name with unknown names refused, then OCR the rendered page to confirm each value shows.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# pdf-form-proof
|
|
7
|
+
|
|
8
|
+
Three steps, in order. Do not skip step 3.
|
|
9
|
+
|
|
10
|
+
## 1. Inspect
|
|
11
|
+
|
|
12
|
+
Call `pdf_form_inspect` (or run `pdf-form-inspect form.pdf`). Copy field names
|
|
13
|
+
exactly as returned. For checkboxes and radio buttons, note the `on_states`
|
|
14
|
+
list: that value (for example "/1") is what checks the box.
|
|
15
|
+
|
|
16
|
+
If `kind` is `xfa`, stop and tell the user this tool does not fill XFA forms.
|
|
17
|
+
|
|
18
|
+
## 2. Fill
|
|
19
|
+
|
|
20
|
+
Call `pdf_form_fill` with a new `output_path` and a `values` map of exact names.
|
|
21
|
+
|
|
22
|
+
- Leave `strict` on. If the result is `refused` with `unknown_fields`, fix the
|
|
23
|
+
names from step 1. Never retry with `strict=false` to make an error go away.
|
|
24
|
+
- The source file is never modified and an existing output is never overwritten.
|
|
25
|
+
- Report the returned `sha256` to the user.
|
|
26
|
+
- Ask the user for any value you do not have. Never invent a value for a form
|
|
27
|
+
field, and do not decide what an official form should say on the user's behalf.
|
|
28
|
+
|
|
29
|
+
## 3. Verify
|
|
30
|
+
|
|
31
|
+
Call `pdf_form_verify` on the output with the values you filled (one call per page).
|
|
32
|
+
|
|
33
|
+
- PASS: every value is VISIBLE. Say so, and repeat the limit: this proves the
|
|
34
|
+
values show, not that they are correct.
|
|
35
|
+
- REFUSE with `kind: finding`: list each value marked INVISIBLE, RENDER-ONLY or
|
|
36
|
+
MISSING. INVISIBLE means it is in the file but not on the page; the usual
|
|
37
|
+
fix is re-filling with `finalize=true`, or a shorter value for a small box.
|
|
38
|
+
- REFUSE with `kind: tool_failure`: say which program failed (poppler or
|
|
39
|
+
tesseract) and how to install it. Make no claim about the document.
|
|
40
|
+
|
|
41
|
+
## Limits
|
|
42
|
+
|
|
43
|
+
AcroForm only. No signatures. OCR can misread small or stylized fonts. This
|
|
44
|
+
skill fills forms; it does not give legal, tax, or benefits advice.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pdf-form-proof",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Fill fillable PDF forms, then prove every value is visible on the rendered page.",
|
|
5
|
+
"mcpServers": {
|
|
6
|
+
"pdf-form-proof": {
|
|
7
|
+
"command": "uvx",
|
|
8
|
+
"args": ["--from", "${extensionPath}", "pdf-form-proof"],
|
|
9
|
+
"cwd": "${extensionPath}"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"contextFileName": "GEMINI.md"
|
|
13
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"manifest_version": "0.4",
|
|
3
|
+
"name": "pdf-form-proof",
|
|
4
|
+
"display_name": "PDF Form Proof",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"description": "Fill fillable PDF forms, then prove every value is visible on the rendered page.",
|
|
7
|
+
"long_description": "Inspect exact field names, fill AcroForm PDFs by name (unknown names are refused and nothing is written; the source is never modified), then render the page and OCR it to confirm each value is VISIBLE, not only stored in the file. Runs locally with no network calls. The verify tool needs poppler and tesseract installed.",
|
|
8
|
+
"author": {
|
|
9
|
+
"name": "EssenceAlignment",
|
|
10
|
+
"url": "https://github.com/EssenceAlignment"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/EssenceAlignment/pdf-form-proof"
|
|
15
|
+
},
|
|
16
|
+
"homepage": "https://github.com/EssenceAlignment/pdf-form-proof",
|
|
17
|
+
"support": "https://github.com/EssenceAlignment/pdf-form-proof/issues",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"keywords": [
|
|
20
|
+
"pdf",
|
|
21
|
+
"forms",
|
|
22
|
+
"acroform",
|
|
23
|
+
"ocr",
|
|
24
|
+
"verification",
|
|
25
|
+
"nonprofit"
|
|
26
|
+
],
|
|
27
|
+
"server": {
|
|
28
|
+
"type": "uv",
|
|
29
|
+
"entry_point": "run_server.py",
|
|
30
|
+
"mcp_config": {
|
|
31
|
+
"command": "uv",
|
|
32
|
+
"args": [
|
|
33
|
+
"run",
|
|
34
|
+
"--directory",
|
|
35
|
+
"${__dirname}",
|
|
36
|
+
"run_server.py"
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"tools": [
|
|
41
|
+
{
|
|
42
|
+
"name": "pdf_form_inspect",
|
|
43
|
+
"description": "List every fillable field with exact name, type, and checkbox on-states."
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"name": "pdf_form_fill",
|
|
47
|
+
"description": "Fill fields by exact name into a new PDF; refuses unknown names; never overwrites."
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"name": "pdf_form_verify",
|
|
51
|
+
"description": "OCR the rendered page and confirm each value is visible, not only stored."
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"name": "pdf_sha256",
|
|
55
|
+
"description": "SHA-256 fingerprint of a file."
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
"compatibility": {
|
|
59
|
+
"platforms": [
|
|
60
|
+
"darwin",
|
|
61
|
+
"linux",
|
|
62
|
+
"win32"
|
|
63
|
+
],
|
|
64
|
+
"runtimes": {
|
|
65
|
+
"python": ">=3.10"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "pdf-form-proof"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Fill fillable PDF forms, then prove every value is visible on the rendered page. MCP server and CLI."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
license = { text = "MIT" }
|
|
8
|
+
authors = [{ name = "EssenceAlignment" }]
|
|
9
|
+
keywords = ["pdf", "pdf-form", "acroform", "form-filling", "mcp", "ocr", "verification", "nonprofit"]
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Programming Language :: Python :: 3",
|
|
12
|
+
"License :: OSI Approved :: MIT License",
|
|
13
|
+
"Topic :: Office/Business",
|
|
14
|
+
]
|
|
15
|
+
dependencies = [
|
|
16
|
+
"mcp>=1.10,<2",
|
|
17
|
+
"pypdf>=4.0",
|
|
18
|
+
"pillow>=10.0",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[project.urls]
|
|
22
|
+
Homepage = "https://github.com/EssenceAlignment/pdf-form-proof"
|
|
23
|
+
Issues = "https://github.com/EssenceAlignment/pdf-form-proof/issues"
|
|
24
|
+
|
|
25
|
+
[project.scripts]
|
|
26
|
+
pdf-form-proof = "pdf_form_proof.server:main"
|
|
27
|
+
pdf-form-inspect = "pdf_form_proof.cli:inspect_main"
|
|
28
|
+
pdf-form-fill = "pdf_form_proof.cli:fill_main"
|
|
29
|
+
pdf-form-verify = "pdf_form_proof.legibility:main"
|
|
30
|
+
|
|
31
|
+
[build-system]
|
|
32
|
+
requires = ["hatchling"]
|
|
33
|
+
build-backend = "hatchling.build"
|
|
34
|
+
|
|
35
|
+
[tool.hatch.build.targets.wheel]
|
|
36
|
+
packages = ["src/pdf_form_proof"]
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Entry point for the MCPB (desktop extension) bundle: runs the stdio MCP server."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "src"))
|
|
7
|
+
|
|
8
|
+
from pdf_form_proof.server import main # noqa: E402
|
|
9
|
+
|
|
10
|
+
if __name__ == "__main__":
|
|
11
|
+
main()
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
+
"name": "io.github.EssenceAlignment/pdf-form-proof",
|
|
4
|
+
"title": "PDF Form Proof",
|
|
5
|
+
"description": "Fill fillable PDF forms, then prove every value is visible on the rendered page.",
|
|
6
|
+
"version": "0.1.0",
|
|
7
|
+
"repository": {
|
|
8
|
+
"url": "https://github.com/EssenceAlignment/pdf-form-proof",
|
|
9
|
+
"source": "github"
|
|
10
|
+
},
|
|
11
|
+
"websiteUrl": "https://github.com/EssenceAlignment/pdf-form-proof",
|
|
12
|
+
"packages": [
|
|
13
|
+
{
|
|
14
|
+
"registryType": "pypi",
|
|
15
|
+
"registryBaseUrl": "https://pypi.org",
|
|
16
|
+
"identifier": "pdf-form-proof",
|
|
17
|
+
"version": "0.1.0",
|
|
18
|
+
"transport": {
|
|
19
|
+
"type": "stdio"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pdf-form-proof
|
|
3
|
+
description: Fill a fillable (AcroForm) PDF form and prove the result is visible on the page. Use when asked to fill out, complete, or check a PDF form (W-9, grant, intake, consent, or any agency form), when a filled field "looks blank", or when a form must be verified before it is sent. Inspect exact field names, fill by name with unknown names refused, then OCR the rendered page to confirm each value shows.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# pdf-form-proof
|
|
7
|
+
|
|
8
|
+
Three steps, in order. Do not skip step 3.
|
|
9
|
+
|
|
10
|
+
## 1. Inspect
|
|
11
|
+
|
|
12
|
+
Call `pdf_form_inspect` (or run `pdf-form-inspect form.pdf`). Copy field names
|
|
13
|
+
exactly as returned. For checkboxes and radio buttons, note the `on_states`
|
|
14
|
+
list: that value (for example "/1") is what checks the box.
|
|
15
|
+
|
|
16
|
+
If `kind` is `xfa`, stop and tell the user this tool does not fill XFA forms.
|
|
17
|
+
|
|
18
|
+
## 2. Fill
|
|
19
|
+
|
|
20
|
+
Call `pdf_form_fill` with a new `output_path` and a `values` map of exact names.
|
|
21
|
+
|
|
22
|
+
- Leave `strict` on. If the result is `refused` with `unknown_fields`, fix the
|
|
23
|
+
names from step 1. Never retry with `strict=false` to make an error go away.
|
|
24
|
+
- The source file is never modified and an existing output is never overwritten.
|
|
25
|
+
- Report the returned `sha256` to the user.
|
|
26
|
+
- Ask the user for any value you do not have. Never invent a value for a form
|
|
27
|
+
field, and do not decide what an official form should say on the user's behalf.
|
|
28
|
+
|
|
29
|
+
## 3. Verify
|
|
30
|
+
|
|
31
|
+
Call `pdf_form_verify` on the output with the values you filled (one call per page).
|
|
32
|
+
|
|
33
|
+
- PASS: every value is VISIBLE. Say so, and repeat the limit: this proves the
|
|
34
|
+
values show, not that they are correct.
|
|
35
|
+
- REFUSE with `kind: finding`: list each value marked INVISIBLE, RENDER-ONLY or
|
|
36
|
+
MISSING. INVISIBLE means it is in the file but not on the page; the usual
|
|
37
|
+
fix is re-filling with `finalize=true`, or a shorter value for a small box.
|
|
38
|
+
- REFUSE with `kind: tool_failure`: say which program failed (poppler or
|
|
39
|
+
tesseract) and how to install it. Make no claim about the document.
|
|
40
|
+
|
|
41
|
+
## Limits
|
|
42
|
+
|
|
43
|
+
AcroForm only. No signatures. OCR can misread small or stylized fonts. This
|
|
44
|
+
skill fills forms; it does not give legal, tax, or benefits advice.
|