GrantKit
The linter and compiler for grant proposals. Grants as files; agents bring the AI.
GrantKit is a stateless, local-first engine. It reads a grant.yaml plus your
Markdown responses and it lints them, compiles them into one submission
document, and reports a machine-readable status — with no cloud service and no
AI calls of its own. Point Claude Code (or any agent) at the files to do the
writing; GrantKit keeps them correct.
Why files
Grant portals trap your content in web forms where your tools can't reach it. GrantKit keeps the whole proposal as plain files in a git repo:
- Agents read the full context — every section, limit, and rule is on disk.
- Changes are reviewable diffs, not opaque form edits.
- Git gives you history and rollback.
- You bring the AI you already use — GrantKit itself calls no model.
Think of it as eslint + tsc for a grant: grantkit check is the linter,
grantkit build is the compiler, and funder rule packs are the config.
Install
pip install grantkit # core engine
pip install "grantkit[pdf]" # + PDF output (WeasyPrint)
pip install "grantkit[docx]" # + DOCX output (python-docx)
pip install "grantkit[mcp]" # + MCP server for agents
pip install "grantkit[all]" # everything
Quickstart
# 1. Scaffold a project from a funder rule pack
grantkit init --funder nuffield-rda
# 2. Write — with Claude Code, Cursor, or your editor
claude "draft responses/b_case_for_importance.md from our repo README"
# 3. Lint against the funder's rules
grantkit check
# 4. Compile the submission document (+ a shareable review page)
grantkit build --format pdf --share
The five verbs
| Verb | What it does |
|---|---|
grantkit init [--funder PACK] |
Scaffold grant.yaml, responses/, budget.yaml, references.bib. |
grantkit check [--json] [--strict] [--urls] |
Lint the proposal. Non-zero exit on errors (warnings fail only with --strict). |
grantkit build [--format md|html|pdf|docx] [--share] |
Compile responses into one document; always writes status.json. |
grantkit review [--pack] |
Emit a structured review packet for an AI agent (no AI calls). |
grantkit status [--json] |
Completion %, per-section word counts, deadline countdown. |
Every verb takes an optional path to the grant directory (default .).
What check catches
- Required sections present and non-empty; word / character / page limits.
- Placeholder text left behind (
[TO BE COMPLETED],TODO,lorem ipsum). - Markdown that a plain-text portal would paste literally.
- Citations (
[@key]) that don't resolve againstreferences.bib. - Budget arithmetic (fringe/indirect) and funder caps; optional BLS salary and GSA per-diem sanity when those API keys are set.
- Funder formatting rules from the rule pack — including the full NSF PAPPG content engine (prohibited URLs/emails, required Intellectual Merit / Broader Impacts, etc.).
- US/UK spelling for the funder's locale.
- Link liveness (
--urls, opt-in — the only thing that touches the network).
Funder rule packs
A rule pack is a YAML file under grantkit/data/funders/ describing one
funder: its sections and limits, formatting rules (each with a citation),
budget caps, portal quirks, spelling locale, and review rubric. Three ship
today:
| Pack id | Funder | Notes |
|---|---|---|
nsf-pappg |
National Science Foundation | PAPPG 24-1; full content engine + merit-review rubric. |
nuffield-rda |
Nuffield Foundation | RDA full application; en-GB; plain-text portal. |
pbif |
Public Benefit Innovation Fund | Section list only; no limits published. |
Contributing a pack
- Copy an existing pack in
grantkit/data/funders/and edit it. The stem of the filename is the pack id (acme-fund.yaml→acme-fund). - Only encode values you can source. Leave a limit
nullif the funder doesn't publish one — never invent a number. Add aprovenance:note and comments citing where each value came from. - Set
locale(en-US/en-GB) andportal.accepts_markdown. - Run
python -c "from grantkit.packs import load_pack; load_pack('acme-fund')"— it validates against the schema on load — and add a case totests/test_packs.py.
The full schema is documented in grantkit/packs/schema.py.
CI for grants
Add the composite action to lint every push and publish the review page and
status.json as build artifacts:
# .github/workflows/grant.yml
name: Grant
on: [push, pull_request]
jobs:
grantkit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: GrantKit/grantkit@v0.2.0
with:
path: . # directory containing grant.yaml
strict: "false" # set "true" to fail on warnings too
Errors always fail the job; the assembled.html review page and status.json
are uploaded as artifacts on every run.
MCP server for agents
Expose the engine to an agent over the Model Context Protocol:
pip install "grantkit[mcp]"
grantkit-mcp # stdio transport
Tools: grant_check(path), grant_status(path), grant_build(path, format) —
each returning the same JSON structures the CLI emits.
status.json
grantkit build and grantkit status --json always write a status.json
describing completion, per-section word counts, and the current check results.
It is GrantKit's stable, machine-readable contract for other tools (dashboards,
CRMs, agents). The exact shape is documented in
docs/artifacts.md.
Development
git clone https://github.com/GrantKit/grantkit.git
cd grantkit
pip install -e ".[dev]"
ruff check . && black --check . && mypy grantkit && pytest
Issues and tasks are tracked in GitHub Issues.
License
MIT — see LICENSE. Created by PolicyEngine.
Metadata
Release files for grantkit 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| grantkit-0.2.1.tar.gz | 130.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| grantkit-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 251.7 kB
Release files / grantkit-0.2.1.tar.gz
| Download URL | grantkit-0.2.1.tar.gz |
|---|---|
| Size | 130.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
aef03d938a301157d821ccf02ab86f2f8e8391548465ac3b3b43b7f3403d1b6a
|
|
BLAKE2b-256 checksum How to use checksums |
d0935c2c06dee09f40c4e402ca0847378fde83754057e050881f7d1107b180dd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 7, 2026.
Transparency logRelease files / grantkit-0.2.1-py3-none-any.whl
| Download URL | grantkit-0.2.1-py3-none-any.whl |
|---|---|
| Size | 121.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ac7b6a2f0e6c397c1c9458180bc4a1c579d2da14d9a23dda03cf32dbea1fed7d
|
|
BLAKE2b-256 checksum How to use checksums |
40697494d6fc935ee7709cd9796f957bf14af04853294167d09056edcd6cfdad
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 7, 2026.
Transparency log