changelogforge
README.md
# changelogforge
A release is ready, the pull requests are merged, and now
someone has to turn that list into the changelog section
readers will actually scan. changelogforge does that one
job: it takes the merged pull requests for a release, sorts
them into labelled groups, and renders the section as
Markdown in a fixed, predictable shape.
- **Grouping by label** — each pull request joins the first
label in `group_order` that it carries. The default order
is `feature`, `bugfix`, `documentation`, `maintenance`,
and you can supply your own list to rename, reorder, add,
or drop groups. Matching is exact and case-sensitive.
- **An other group** — a pull request carrying none of the
group labels lands in a final group whose heading is
`Other changes`. Groups that end up empty are left out
entirely, and the other group only appears when it has
something in it.
- **Stable ordering** — groups follow `group_order` with
the other group always last, and inside a group the pull
requests are sorted by number ascending, so the same
input always renders the same section.
- **Exact Markdown** — the version heading sits at
`heading_level` (default 2) and group headings one level
deeper. The result also returns the grouped structure
itself, so a caller can render the same data another way.
Version and date are printed in the heading exactly as
given; neither is parsed or reformatted. Pull request
numbers must be unique across the list — a repeat is a
validation error naming both occurrences, for example
`pull_requests[2].number duplicates pull_requests[0].number`
— and every other malformed field is likewise an error
naming its path, with no partial section produced. The
computation is pure and local: no network, no
configuration, no files read beyond the input you pass in.
## CLI
```bash
npx @reneturcios/changelogforge generate --input args.json
npx @reneturcios/changelogforge --version
```
`args.json` contains the full arguments object:
```json
{
"version": "1.2.0",
"date": "2026-10-27",
"pull_requests": [
{ "number": 7, "title": "Add export button", "labels": ["feature"] },
{ "number": 12, "title": "Fix crash on empty input", "labels": ["bugfix"] },
{ "number": 15, "title": "Tidy internals" }
]
}
```
`labels` defaults to `[]` per pull request, `group_order`
to `["feature", "bugfix", "documentation", "maintenance"]`,
and `heading_level` to `2`. The rendered section is printed
as JSON:
```json
{
"version": "1.2.0",
"date": "2026-10-27",
"groups": [
{ "group": "feature", "heading": "feature", "pull_requests": [{ "number": 7, "title": "Add export button" }] },
{ "group": "bugfix", "heading": "bugfix", "pull_requests": [{ "number": 12, "title": "Fix crash on empty input" }] },
{ "group": "other", "heading": "Other changes", "pull_requests": [{ "number": 15, "title": "Tidy internals" }] }
],
"markdown": "## 1.2.0 (2026-10-27)\n\n### feature\n\n- Add export button (#7)\n\n### bugfix\n\n- Fix crash on empty input (#12)\n\n### Other changes\n\n- Tidy internals (#15)",
"total_pull_requests": 3
}
```
Exit codes: `0` on success, `1` on a runtime error (including
an unreadable or invalid input file, or invalid input), `2`
on a usage error.
## MCP server
```bash
npx -y @reneturcios/changelogforge mcp
```
MCP client config:
```json
{
"mcpServers": {
"changelogforge": {
"command": "npx",
"args": ["-y", "@reneturcios/changelogforge", "mcp"]
}
}
}
```
### Tools
- `generate_changelog` — Render a release changelog section
from merged pull requests, grouped by label.
- `version` (string, required) — release version label,
printed verbatim in the heading
- `date` (string, required) — release date, printed
verbatim in the heading
- `pull_requests` (array, required, at least one) — merged
pull requests as `{number, title, labels?}` objects;
`number` is unique across the list
- `group_order` (array of strings, optional) — labels that
define groups, in output order
- `heading_level` (integer, optional, 1–5) — Markdown
heading level for the version heading
Returns `{version, date, groups, markdown,
total_pull_requests}`.
## Docker
```bash
docker run -i ghcr.io/cloudcorprecords/changelogforge
docker run --rm -v "$PWD:/w" ghcr.io/cloudcorprecords/changelogforge generate --input /w/args.json
```
## Development
```bash
npm install
npm run build # tsc -> dist/
npm test # tsx --test test/*.test.ts (pure local, no network)
npm run dev # run the CLI from source
```
## License
MIT — Copyright (c) 2026 Rene Turcios
This server cannot be deployed
Maintenance
ActivityNo data
ResponsivenessOutdated data