Skip to content

Development template updates

This established utility server first adopted development tooling from justpen-mcp-dev-template at d9848a0927c238fd1b11189930a292ff60efef16. Its current development baseline is v0.6.0, commit 0629c93504af314acbf522209a130973444d06d3.

Reviewed adoption and history

The v0.4.0 adoption renders a separate reference with the real project identity, then applies reviewed development changes to the existing application. The genuine Copier record comes from that reference; it does not claim that this server was originally created by Copier. No first-run bootstrap or recopy runs over the app.

Keep .copier-answers.yml committed and let Copier maintain its source, revision and answers. The recorded initial_version = 0.0.0 describes the generated comparison baseline, not the application version. Run make version to read the utility version; template updates preserve the application version.

The explicit changelog_start_rev at standalone commit 959e9578785439ba7fbb0e25e8fa8dbbc4ec43c0 stays authoritative after enrollment. Preserve the real Git history and historical tags; do not replace that boundary with the first Copier record. The template's MIT attribution is limited to infrastructure; the utility application remains proprietary.

Update on a feature branch

Begin with a clean, committed checkout. Fetch an exact upstream commit without importing template release tags into the application's tag namespace:

git switch -c chore/update-template
git fetch --no-tags https://github.com/justpenkit/justpen-mcp-dev-template.git main:refs/remotes/template/main
template_commit=$(git rev-parse refs/remotes/template/main)
uvx --from 'copier>=9.18.2,<10' copier update --vcs-ref="$template_commit" --defaults
git diff

Codex uses codex/update-template. The update uses the source URL in the genuine Copier record and the exact fetched commit. Use a full clone, fetch before each update, and never merge the template branch or copy its release tags into this application.

--defaults reuses the recorded answers. Keep the reference's initial-version answer so Copier can compare generated baselines while preserving application version changes. Omit --defaults to review answers; use --vcs-ref=:current: when changing answers without upgrading the template. Always select a revision.

Project customizations to preserve

Copier compares the old reference, new reference and application changes. Changes to the same lines can conflict. Inspect every diff and all Git conflict entries; resolve them while preserving:

  • Actual MCP code, TOTP/QR tool names, server identity, UTILITY_MCP_LOG_LEVEL and the status: "ok" response contract. Do not import template demo behavior.
  • uv run python -m justpen_utility_mcp. The package has no cli() entrypoint or py.typed marker; metadata must not claim either.
  • Pillow/zxing-cpp runtime dependencies and Hypothesis development tests. Use the make uv-* targets for necessary dependency resolution; never copy a generator lockfile.
  • Proprietary application terms and the template's MIT attribution in root NOTICE, which remains included in wheel/source distributions.
  • The application's version, historical tags and explicit standalone changelog boundary described in the release guide.
  • Product docs, API module directives, navigation and assets.
  • .hypothesis/ ignores, build/consumer/fixture Make targets, and committed QR fixtures. Regenerate fixtures only intentionally and review the binary diff.
  • Shared agent permissions, strict lint/type/coverage rules and the unit/integration split, including real MCP consumer coverage in CI.

After resolving every conflict, run:

make uv-lock
make setup

Use make test-one TEST=... for the relevant scenario while developing an integration test or its harness. Commit/push hooks provide routine unit and strict-docs gates; do not repeat a passing gate manually. CI checks the supported Python versions, real tool/hook/release/docs integrations and the installed-wheel MCP consumer outside the checkout.

The Git pre-commit hook checks the staged diff and rejects unresolved conflict markers, including markers that were accidentally staged as resolved.

Review the final diff through a PR and use a regular merge commit. A template update does not itself bump this application's version. Do not use copier recopy as a shortcut, run bootstrap, or import generator tests and setup/cleanup machinery.

When a coding agent performs the update

The project's protected-files guard also applies to Copier updates. Claude Code and Codex must first render the update in a disposable checkout, present any direct pyproject.toml or uv.lock changes, and obtain your approval before applying them to the working project. Use the same exact template commit and answers for the preview and approved update. Ordinary dependency resolution uses the make uv-* targets.

The guard reverts a copier update run by an agent that changes protected files, because copier is not an approved route. Run copier update from a terminal after approving the preview, or approve the result with make guard-accept-changes. See the agent guide for the guard and its limits. Follow the policy even when an indirect tool can write the file.

CI job names

Template updates can rename CI jobs. One check job replaced the quality job and the check (py3.x) matrix legs. If your repository requires status checks by name, update those rules to check (and integration) after merging the update, or pull requests will wait for checks that no longer run.

See Copier's update documentation for the merge model and recovery options.