The linter and compiler for grant proposals — grants as files, agents bring the AI
Project description
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file grantkit-0.2.0.tar.gz.
File metadata
- Download URL: grantkit-0.2.0.tar.gz
- Upload date:
- Size: 127.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2cc396d3dbba00621eca72a2e086afc2da84235a7cbd218090b3ce805e9d1e7f
|
|
| MD5 |
723578e6b5cd0c7e0aed71123988102d
|
|
| BLAKE2b-256 |
edf8f8dcec3a5d334ab9afdeb4d77da23ad1531c89a4a0084371fa372fe96f45
|
Provenance
The following attestation bundles were made for grantkit-0.2.0.tar.gz:
Publisher:
release.yml on GrantKit/grantkit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
grantkit-0.2.0.tar.gz -
Subject digest:
2cc396d3dbba00621eca72a2e086afc2da84235a7cbd218090b3ce805e9d1e7f - Sigstore transparency entry: 2101347053
- Sigstore integration time:
-
Permalink:
GrantKit/grantkit@cc2a79ac34bb717b8b6293add62db3c4a93f1807 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/GrantKit
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@cc2a79ac34bb717b8b6293add62db3c4a93f1807 -
Trigger Event:
push
-
Statement type:
File details
Details for the file grantkit-0.2.0-py3-none-any.whl.
File metadata
- Download URL: grantkit-0.2.0-py3-none-any.whl
- Upload date:
- Size: 120.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1fe9d78cbff864b02c564a29736316188d89fb030c72311c93dbd129a249bd19
|
|
| MD5 |
2ecca68809333a3af0311d1cde30860e
|
|
| BLAKE2b-256 |
97092010b8602da989cb3e9576b8b1d9373d7ad7a15c74e5df1af1309b4c15ff
|
Provenance
The following attestation bundles were made for grantkit-0.2.0-py3-none-any.whl:
Publisher:
release.yml on GrantKit/grantkit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
grantkit-0.2.0-py3-none-any.whl -
Subject digest:
1fe9d78cbff864b02c564a29736316188d89fb030c72311c93dbd129a249bd19 - Sigstore transparency entry: 2101347600
- Sigstore integration time:
-
Permalink:
GrantKit/grantkit@cc2a79ac34bb717b8b6293add62db3c4a93f1807 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/GrantKit
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@cc2a79ac34bb717b8b6293add62db3c4a93f1807 -
Trigger Event:
push
-
Statement type: