mcp-server-trello-release
SkillProductivityCanonical build → release → tag → publish procedure for the @delorenj/mcp-server-trello repo. Use when cutting a release, bumping the version, tagging, or publishing to npm / the MCP registry — triggers: "cut a release", "release 1.x.y", "ship a new version", "bump the version", "publish to npm", "publish to the MCP registry", "tag the release", "how do I release this". Codifies the FOUR version-bearing literals that must move in lockstep (package.json, server.json ×2, src/index.ts McpServer info) plus CHANGELOG, and the exact GitHub-Actions triggers that make merging a PR the publish event. Do NOT use for generic changelog prose (docs-changelog), cross-repo semver task scaffolding (mise-versioning), or non-release tagging.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the mcp-server-trello-release skill
What this skill tells your AI
The instructions your AI receives, as published by delorenj/mcp-server-trello in .agents/skills/mcp-server-trello-release/SKILL.md and read by ahel’s review.
The release rules for @delorenj/mcp-server-trello. This repo publishes to
two registries off automation triggered by a PR merge — so a release is
not "run publish", it is "get main correct and merge the PR". Get the version
parity or the trigger semantics wrong and you desync npm from the MCP registry,
or ship a server that lies about its own version.
Every fact below was VERIFIED on 2026-07-16 against this repo. The maintainer pivots fast — re-check the workflow files and
versionbump.jsbefore leaning on any of it.llris the recency compass.
The one thing that breaks every time: version parity
There are four version literals in this repo, not one, plus the changelog.
They must all read the same X.Y.Z before you open the release PR:
| # | Location | Field | Why it matters |
|---|---|---|---|
| 1 | package.json | version | Drives the npm publish. |
| 2 | server.json | version (top level) | Drives the MCP registry publish. |
| 3 | server.json | packages[0].version | Registry cross-checks it against #2 and the npm tarball. |
| 4 | src/index.ts | new McpServer({ version }) (~line 44) | What the server reports over MCP. If stale, tools/list clients see the wrong version. |
| 5 | CHANGELOG.md | newest ## [X.Y.Z] - DATE heading | Human record + release-notes source. |
The trap: bun run versionbump:{patch,minor,major} (scripts/versionbump.js)
only edits #1. It silently leaves #2, #3, #4 behind. That is exactly how
server.json drifted to 1.5.6 while npm was on 1.7.1, and how the McpServer
literal sat at 1.7.1 into a 1.8.0 cut. Never trust versionbump alone.
Use the bundled helper instead — it sets all four literals at once and flips the changelog heading:
.agents/skills/mcp-server-trello-release/scripts/set-version.sh 1.8.0
Then always confirm parity before committing:
.agents/skills/mcp-server-trello-release/scripts/parity-check.sh
parity-check.sh exits non-zero if any of the five disagree. It is safe to wire
into CI as a release gate.
The trigger map — what publishes, and when (VERIFIED from .github/workflows/)
| Workflow | Fires on | Effect |
|---|---|---|
ci.yml | any PR/push to main | bun run test:coverage — the coverage ratchet gate. Must be green or the PR can't merge cleanly. |
publish-npm.yml | PR to main closed AND merged, or manual workflow_dispatch | npm publish via Trusted Publishing (OIDC) using package.json version. No NPM_TOKEN — auth is the workflow's OIDC id-token; the workflow intentionally omits --provenance because npm generates provenance automatically for this Trusted Publishing path. |
publish-registry.yml | push to main touching server.json/package.json, or a GitHub Release published | mcp-publisher publish (also OIDC, github-oidc login) using server.json. |
Publishing is tokenless (Trusted Publishing / OIDC), since 2026-07. npm's package settings list
delorenj / mcp-server-trello / publish-npm.ymlas a trusted publisher, so CI mints a short-lived OIDC token per run instead of a stored secret. This replaced theNPM_TOKENpath, which npm is deprecating: 2FA-bypass tokens lose sensitive actions ~Aug 2026 and direct publish ~Jan 2027. Requirements the workflow must keep satisfying:id-token: write, npm CLI ≥ 11.5.1 (wenpm install -g npm@latest), Node ≥ 22.14.0, and noNODE_AUTH_TOKEN. The trusted-publisher config fields are case-sensitive and exact — orgdelorenj, repomcp-server-trello, workflow filenamepublish-npm.yml(no path, keep the.yml), environment blank.
Read the consequences carefully — they define the whole procedure:
- Merging the release PR is the publish event. The merge closes the PR
(→ npm publish) and pushes the version files to
main(→ registry publish). There is no separate "publish" step and no localnpm publish. workflow_dispatchis the re-publish escape hatch. If the npm job fails for an infra reason (a bad CI run, a first-time trusted-publisher config), fix it and re-runpublish-npm.ymldirectly onmain—gh workflow run publish-npm.yml— instead of re-merging. It publishes whatever versionpackage.jsononmaincurrently declares. (npm rejects a re-publish of an already-published version, so this is safe to retry.)- Release only through a PR merge — never direct-push a bump to
main. A direct push fires the registry publish (paths match) but not the npm publish (needs a PR-close event). That desyncs the two registries. Always PR. - A raw annotated git tag is side-effect-free. No workflow triggers on tag
pushes — only on a GitHub Release object. So you can (and must) push
vX.Y.Zafter merge with zero risk of a double-publish. - Do NOT
gh release createunder the current config. A GitHub Release emitsrelease: published, which re-runspublish-registry.ymlfor a version already pushed viamain→ a red, duplicate publish. Push the raw tag instead. (To make GitHub Releases safe, see Recommended hardening below.)
Semver rules for this repo
- patch (
x.y.Z) — bug fix, no surface change. - minor (
x.Y.0) — new tool, new optional param, additive behavior. Most releases here. - major (
X.0.0) — a breaking change to the published tool surface: removing/renaming a tool that shipped, or making a previously-optional param required. Removing a tool that never shipped to npm is not breaking (that was the1.8.0dead-tool cleanup — minor, not major). - Tool count is a moat concern (selection accuracy degrades past ~20 tools). A
release that removes a tool is healthy; note it in the changelog
Removed.
The procedure
Phase 0 — Preflight (on a release branch, never on main)
git branch --show-current # must NOT be main
git status --short # must be clean
Phase 1 — Set the version everywhere
scripts/set-version.sh <X.Y.Z> # writes literals 1–4 and flips the changelog heading
Or by hand: edit
package.json, bothserver.jsonfields, theMcpServerliteral insrc/index.ts, and the changelog heading. Then run parity-check.
Phase 2 — Finish the changelog
set-version.sh turns ## [Unreleased] into ## [X.Y.Z] - <today>. Fill in the
Added / Changed / Fixed / Removed bullets (Keep a Changelog format).
Get today's date from date +%F.
Phase 3 — Gates (mirror CI locally, in order)
scripts/parity-check.sh # all 5 versions agree
npm run typecheck # 0 errors (guards the zod v4 / SDK types path)
npm run test:coverage # green; autoUpdate may ratchet vitest.config.ts — COMMIT that bump
npm run build # bun build succeeds
# stdio smoke: server boots and lists the expected tool count
Phase 4 — Commit
git add -A && git commit -m "chore(release): <X.Y.Z>"
Keep the version files + the ratcheted vitest.config.ts in this commit.
Phase 5 — Open the PR
git push -u origin <branch>
gh pr create --base main --title "Release <X.Y.Z>: <headline>" --body-file <notes>
State in the PR body that merging publishes (npm + registry). Wait for
ci.yml (the coverage gate) to go green.
Phase 6 — Merge = publish
Merge the PR. This auto-fires publish-npm.yml and publish-registry.yml.
Watch both Actions runs to green before declaring the release done.
Phase 7 — Tag (after merge, on main)
git checkout main && git pull
git tag -a v<X.Y.Z> -m "v<X.Y.Z>" # annotated; message can carry the changelog highlights
git push origin v<X.Y.Z> # raw tag push — no workflow side effects
This repo's tags stopped at v1.6.1 (1.7.0/1.7.1 shipped untagged). From now
on, every release gets an annotated vX.Y.Z tag.
Phase 8 — Verify
npm view @delorenj/mcp-server-trello version # == X.Y.Z
git ls-remote --tags origin | grep v<X.Y.Z> # tag present
gh run list --workflow=publish-npm.yml --limit 1 # green
gh run list --workflow=publish-registry.yml --limit 1 # green
Optionally confirm the MCP registry entry updated at
https://registry.modelcontextprotocol.io for io.github.delorenj/mcp-server-trello.
Recommended hardening (not required; each removes a footgun)
- Fix
versionbump.jsto also writeserver.json(both fields) and thesrc/index.tsMcpServerliteral — or, better, makesrc/index.tsderive its version frompackage.jsonat runtime so literal #4 can never drift again. (Mind the bundling:bun build --target nodeinlinessrc/; read the package's ownpackage.jsonby resolved path, not a barerequire.) - Add
parity-check.shas a CI step on PRs tomain, so a mismatched release can't merge. - Move to tag-driven publishing. Change
publish-npm.yml/publish-registry.ymlto trigger onpush: tags: ['v*']and drop the merge/paths triggers. Then the tag becomes the single release truth andgh release create(with auto-generated notes) becomes safe and idempotent.
When a publish fails (triage)
Both publish workflows can go red even when the code is perfect. The npm and registry failures usually chain from one root cause, so read them in order.
npm side (publish-npm.yml), Trusted-Publishing era:
Unable to authenticate/unable to find a trusted publisher/ OIDC mismatch. The OIDC identity CI presented didn't match npm's trusted-publisher record. The fields are case-sensitive and exact — re-check on npmjs.com (package → Settings → Trusted Publisher): orgdelorenj, repomcp-server-trello, workflow filenamepublish-npm.yml(filename only, keep.yml, no path), environment blank (the workflow declares noenvironment:). A rename of the workflow file, or setting a GitHub environment without adding it here, breaks the match.npm error This command requires npm version 11.5.1 or greater/ OIDC not attempted. The runner's npm is too old or Node is < 22.14.0. The workflow must keepnode-version: '22.x'and thenpm install -g npm@lateststep, and the job must keeppermissions: id-token: write. If any of those regress, npm silently falls back to token auth and fails.EOTP/E404on thePUT— historical, pre-2026-07. These were the stored-NPM_TOKENfailure modes (E404= expired/under-scoped token, npm masks bad auth as 404;EOTP= the token type still demanded a 2FA one-time password CI can't supply). Trusted Publishing removed the token entirely, so these should not recur. If you see them, someone re-introducedNODE_AUTH_TOKEN/NPM_TOKENinto the workflow — remove it; OIDC is the auth.- Re-running after a fix: trusted-publisher config changes take effect
immediately (no re-mint). Re-publish with
gh workflow run publish-npm.yml(dispatch onmain) rather than re-merging.
registry side (publish-registry.yml):
- 400
"version 'X.Y.Z' was not found (status 404) … publish version 'X.Y.Z' before registering it". Downstream, not a registry bug — the MCP registry validates that the npm version already exists before registering the server entry. It fails only because the npm publish above hasn't landed. Fix npm first, then re-run:gh run rerun <registry-run-id>.
Fix npm → confirm npm view … version == X.Y.Z → re-run registry. Never
chase the registry error in isolation.
Anti-patterns (each has bitten this repo)
- Running
versionbumpand assuming the release is versioned. → #2/#3/#4 drift. - Editing
package.jsonbut forgettingserver.json. → registry ships stale metadata. - Bumping the version but not
src/index.ts. → server reports the wrong version to every client. gh release createunder the current workflows. → duplicate/red registry publish.- Direct-pushing a bump to
main. → registry publishes, npm doesn't; the two desync. - Cutting a release with red/absent
ci.ymlcoverage. → merge blocked or main goes red. - Naming a
package.jsonscript after an npm lifecycle event (publish,prepare,pack,version, …). The repo shipped"publish": "bun run build && npm publish"; becausepublishis a lifecycle hook, CI'snpm publishre-invoked it → a recursive second publish thatE403'd ("cannot publish over previously published X.Y.Z") and false-red'd every successful release. It was masked for months only because auth failed on the first publish. Fixed 2026-07-20 by renaming it torelease. Local publish is nownpm run release. - Reading a green
publish-npmrun as proof a publish happened. The publish steps now self-skip an already-published version (guard → cleanexit 0, still green). Green means "npm/registry is at the package's declared version," not "we uploaded just now." Always confirm the actual bytes withnpm view @delorenj/mcp-server-trello version.
Signals
- GitHub stars
- 437
- Forks
- 144
- Last commit
- Aug 2026
Advanced
- Catalog kind
- skill
- Gateway key
mcp-server-trello-release- Source
- github.com/delorenj/mcp-server-trello