Repository navigation
fix(tools): stop the MCP repo generator from overwriting evolved repos - #309
Merged
Merged
Conversation
create_mcp_repos.py was written as a one-time bootstrap and was never guarded against re-runs. Running it against an existing repo replaced server.py, deleted and recreated base/, rewrote the generated docs, committed the result as "initial commit", and pushed it to origin. History survived -- it is an ordinary commit on top, not a force-push -- but HEAD moved to the stale generated version. Measured 2026-08-10: all 13 target repos have evolved past their generated state, 75 commits and roughly 29 merged PRs between them. The blast radius was the whole MCP fleet, not a single repo. Existing repos are now skipped unless --force is passed, and a plain run exits 1 instead of reporting success, so re-running cannot look like a no-op. --dry-run reports the decision for every target and writes nothing. mcp-session-mgr is additionally marked canonical and is never regenerated even with --force. It is what settings.json runs, and it leads the in-engine copy by mcp 2.x support, an O_CREAT|O_EXCL claim-file mutex and a merged path-traversal fix -- all three of which regeneration would silently revert. Verified: a plain run writes nothing (repo HEADs and working trees identical before and after) and exits 1; --dry-run exits 0; the canonical guard holds under --force. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
piyushmakhija28
force-pushed
the
fix/generator-non-destructive
branch
from
August 10, 2026 13:47
67ee2db to
58fd3ae
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The hazard
scripts/tools/create_mcp_repos.pywas written as a one-time bootstrap and was never guarded against re-runs. Running it against a repo that already exists::778server.py:786-787rmtree(base/)thencopytree:791-795SHARED_UTILSfiles:798-802README.md,CLAUDE.md,requirements.txt,.gitignore,.env.example:811-815git add -A+git commit -m "feat: initial commit -- ...":819-833gh repo create --push, orgit push -u origin mainSo it does not merely overwrite locally — it commits the overwrite and pushes it to origin. History survives (an ordinary commit on top, not a force-push), but
HEADmoves to the stale generated version.Blast radius
Measured 2026-08-10: all 13 target repos have evolved past their generated state — 75 commits and roughly 29 merged PRs between them. This was the whole MCP fleet, not one repo.
The fix
--forceis passed.--dry-runreports the decision for every target and writes nothing.mcp-session-mgris marked canonical and is never regenerated, even with--force.Why
mcp-session-mgris canonicalIt is the server
settings.jsonactually runs, and it leads the in-enginesrc/mcp/session_mcp_server.pyby mcp 2.x support, anO_CREAT|O_EXCLclaim-file mutex, and a merged path-traversal fix. Regenerating it fromsrc/mcp/would silently revert all three — including the security fix — into the only path Claude calls.CANONICAL_REPOSis a set, so removing a name from it is an explicit assertion thatsrc/mcp/is once again ahead.Verification
HEADs and working trees byte-identical before and after1--dry-runexit code0, 14 skipped, 0 written--force--force--forcewas deliberately not run end-to-end, since doing so would overwrite the other twelve repos. The canonical guard was exercised by calling_guard_existing_repodirectly.Context
This is P1.0 of the session-management remediation — a blocking precondition for Phase 1.
create_mcp_repos.pywas DO-NOT-RUN until this landed. Recorded indocs/policies/session-management-policy.md§7.🤖 Generated with Claude Code