Skip to main content

issue-kit

Opinionated backlog-standards toolkit: a single spec file (issue-standard.yml) declares your issue standard — label taxonomy with colors, the required .github/ISSUE_TEMPLATE set, lint rules — and issue-kit checks any number of repositories against it. MCP server and CLI over one engine.

Phase M0 is strictly read-only: it lints and reports, it never mutates a repository. The only write is standard_init, which puts the default spec on your local disk.

Design docs live in ARCHITECTURE.md, ROADMAP.md, and adr/.

Install

pip install issue-kit-mcp
# or from a checkout:
pip install -e '.[dev]'

Requires Python 3.10+.

CLI

# Write the default spec (standard 2026-07-14) to ./issue-standard.yml
issue-kit init [--path PATH] [--force]

# Lint one or more repos against the spec
issue-kit lint OWNER/REPO [OWNER/REPO ...] [--repo OWNER/REPO] [--repos-file FILE]
               [--spec PATH] [--provider github|snapshot] [--snapshots DIR]
               [--format json|text|markdown] [--ci]

# Aggregate conformance dashboard
issue-kit report OWNER/REPO ... [--repos-file FILE] [--spec PATH]
                 [--provider github|snapshot] [--snapshots DIR]
                 [--format json|text|markdown]

# Capture a repo's issues/labels/templates into a snapshot bundle (GET-only)
issue-kit snapshot OWNER/REPO --out DIR [--format json|text|markdown]

standard-init / standard-lint / standard-report / standard-snapshot are accepted aliases — the same naming the MCP tools use (snapshot is CLI-only in M0; it has no MCP double yet).

Exit codes

Shared CI contract (never masked):

code meaning
0 conformant, or advisory-only findings
1 error-severity findings present
2 config error: invalid spec, provider/auth failure, invalid arguments

stdout carries the report in the chosen format (parseable even at exit 1); stderr carries diagnostics. Default format is text on a TTY, json otherwise.

Spec resolution

--spec PATH > ISSUE_KIT_SPEC env > ./issue-standard.yml > built-in default spec. An explicit path that does not exist is a config error (exit 2).

GitHub token

The GitHub provider is read-only (issues, labels, contents) and takes its token from the same env chain MCP clients use: GITHUB_PERSONAL_ACCESS_TOKEN > GITHUB_TOKEN > GH_TOKEN. A fine-grained PAT with Issues:read, Contents:read, Metadata:read is enough. Without a token the provider runs anonymously (60 req/h, public repos only); an auth failure on a private repo is a config error, never a silent pass.

Snapshots (offline runs)

--provider snapshot --snapshots DIR reads repo state from bundle JSONs instead of the network. Bundle format (fixed contract):

{
  "repo": "owner/name",
  "fetched_at": "2026-07-14T12:00:00Z",
  "issues": [
    {"number": 1, "title": "...", "state": "open",
     "labels": [{"name": "bug", "color": "d73a4a", "description": ""}],
     "body": "..."}
  ],
  "labels": [{"name": "bug", "color": "d73a4a", "description": ""}],
  "templates": {"bug.md": "---\nname: ...\n---\n..."}
}

labels may be null — the label inventory was unavailable at capture time; label lint then covers only labels that appear on issues. templates may be null, which is treated as "no templates". Keep local snapshot captures in .snapshots/ (gitignored).

Produce a bundle with the toolkit itself instead of hand-assembling one:

issue-kit snapshot OWNER/REPO --out .snapshots
issue-kit lint OWNER/REPO --provider snapshot --snapshots .snapshots

snapshot is strictly read-only (GET issues, labels, contents), writes one <owner>__<repo>.json under --out, and serializes deterministically (sorted keys, ensure_ascii=False, indent 2) so re-captures diff cleanly. The label inventory is captured in full (not null), so an offline --provider snapshot run reproduces the live findings at capture time.

MCP server

{
  "mcpServers": {
    "issue-kit": {
      "command": "python",
      "args": ["-m", "issue_kit"]
    }
  }
}

Tools (names are a public contract): standard_init, standard_lint, standard_report. Each returns the same JSON object the CLI prints with --format json.

Lint rules (M0)

rule severity meaning
missing_type error OPEN issue without a type label
multiple_type error more than one type label
missing_priority error no P1/P2/P3 label
multiple_priority error more than one priority label
nonstandard_label advisory repo label outside the spec (may be a legitimate domain label)
missing_template error no template whose labels contains the type — matched by content, not filename: .md front matter or a GitHub Issue Forms *.yml/*.yaml top-level labels (config.yml excluded)
missing_template_config advisory no config.yml in .github/ISSUE_TEMPLATE/
missing_body_section advisory soft body-structure check (problem, todo)

Title prefixes like [P1] are intentionally not mapped to priority labels in M0 — recognizing them as relabel hints is M2 material (issues_relabel). Issues by dependabot and pull requests are excluded from checks and from the conformance denominator.

Reports contain issue numbers, titles, labels, and rule details — never issue bodies.

Development

pip install -e '.[dev]'
ruff check src tests
pytest -q

License

MIT — see LICENSE.

Metadata

Release files for issue-kit-mcp 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for issue-kit-mcp 0.1.0
File Size Uploaded
issue_kit_mcp-0.1.0.tar.gz 43.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for issue-kit-mcp 0.1.0
File Interpreter ABI Platform
issue_kit_mcp-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 80.7 kB

Release files / issue_kit_mcp-0.1.0.tar.gz

Download URL issue_kit_mcp-0.1.0.tar.gz
Size 43.0 kB
Tags Source
SHA-256 checksum
How to use checksums
4d5c9b8d3ac241ddfe0006385b1882f9237332e5e4e500edef7e8852e26979f7
BLAKE2b-256 checksum
How to use checksums
9c5d75a2061885d94670a10735821f3a1beb337d099157d9373223334c4fd14c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 31, 2026.

Transparency log

Release files / issue_kit_mcp-0.1.0-py3-none-any.whl

Download URL issue_kit_mcp-0.1.0-py3-none-any.whl
Size 37.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
db198c02bfbd7a3bbf453e72481cc7dbcf648fdb878cebf011bb576ee6c0501d
BLAKE2b-256 checksum
How to use checksums
aa032703af197639e542845c6483f47e70561841b82a34cd3679ae62c52a3300
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 31, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page