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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

issue_kit_mcp-0.1.0.tar.gz (43.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

issue_kit_mcp-0.1.0-py3-none-any.whl (37.7 kB view details)

Uploaded Python 3

File details

Details for the file issue_kit_mcp-0.1.0.tar.gz.

File metadata

  • Download URL: issue_kit_mcp-0.1.0.tar.gz
  • Upload date:
  • Size: 43.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for issue_kit_mcp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 4d5c9b8d3ac241ddfe0006385b1882f9237332e5e4e500edef7e8852e26979f7
MD5 d8052769fd188992f081d9c3c8372444
BLAKE2b-256 9c5d75a2061885d94670a10735821f3a1beb337d099157d9373223334c4fd14c

See more details on using hashes here.

Provenance

The following attestation bundles were made for issue_kit_mcp-0.1.0.tar.gz:

Publisher: release.yml on ignatenkofi/issue-kit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file issue_kit_mcp-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: issue_kit_mcp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 37.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for issue_kit_mcp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 db198c02bfbd7a3bbf453e72481cc7dbcf648fdb878cebf011bb576ee6c0501d
MD5 70c38ddca3e592ccdb5b47b653fa468e
BLAKE2b-256 aa032703af197639e542845c6483f47e70561841b82a34cd3679ae62c52a3300

See more details on using hashes here.

Provenance

The following attestation bundles were made for issue_kit_mcp-0.1.0-py3-none-any.whl:

Publisher: release.yml on ignatenkofi/issue-kit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page