Auto-restart Gitea MCP namespaces when master advances #591

Closed
opened 2026-07-09 12:50:40 -05:00 by jcwalker3 · 2 comments
Owner

Problem

The Gitea MCP server is self-hosted from this repo. After a merge to master, the already-running namespace processes keep executing stale code — the client does not respawn them, so the live server no longer matches the merged source.

This repeatedly blocks work:

  • Namespaces fail with stale-runtime, Transport closed, or client is closing: EOF.
  • Manual /mcp reconnect (or a full restart) is required far too often.
  • The LLM usually cannot restart MCP from its own tool surface — it has no sanctioned way to force a respawn on current code.

The staleness bites hardest after changes to gitea_mcp_server.py, tool schemas, workflow guards, capability logic, or runtime diagnostics: the session makes a correct decision but the live process enforces old behavior (or has already dropped its transport).

Goal

When master advances — especially after MCP/tooling code changes land — the Gitea MCP namespaces should automatically restart, reload, or cleanly exit so the client respawns them on current code, without manual reconnect and without unsafe self-mutation.

Related prior work

  • #420 (closed) — "MCP server must dynamically reload runtime profiles and capability gates or support hot restart." Narrower: reloads profiles/capability gates, not the running Python code / tool schemas. This issue covers process-level respawn on code change.
  • #531 (closed) — "Detect stale MCP server runtime before mutation tools execute." Detection + fail-closed diagnostic only; does not restart or respawn.
  • #584 (open) — incident where the host auto-reconnected all four namespaces at startup. Evidence report, not a sanctioned auto-restart mechanism.

This issue is the missing piece: a sanctioned auto/semi-auto restart path that ties detection (#531) and reload (#420) together into an actual respawn on current code.

Acceptance criteria

  1. Detect when the running MCP code is older than the current prgs/master (commit/version comparison, not just profile drift).
  2. Restart / reload or cleanly exit stale Gitea MCP namespace processes so the client respawns them on current code.
  3. Cover all namespaces: author (gitea-tools), reviewer, merger, and reconciler/tools.
  4. Avoid unsafe self-mutation, raw process killing, direct imports, or guard bypasses.
  5. Provide clear diagnostics when auto-restart is unavailable (running commit, expected master commit, namespace/profile, recommended operator action).
  6. Add a sanctioned host/client lifecycle mechanism if full auto-restart is not possible from inside the server.
  7. Ensure post-merge workflows can trigger or verify MCP restart after MCP-related code lands.
  8. Add tests or proof docs for stale-runtime detection and restart behavior.
  9. Preserve all safety guards: role separation, root checkout guard, capability preflight, namespace binding, and BLOCKED + DIAGNOSE when the LLM cannot perform a required step.

Notes

  • Full in-process code hot-swap is likely unsafe/incomplete for Python; a clean exit → client respawn path is the preferred fallback over attempting live self-mutation.
  • Restart must never race a mutation mid-flight — gate on lease/capability state so a respawn does not orphan an in-progress workflow.
## Problem The Gitea MCP server is self-hosted from this repo. After a merge to `master`, the already-running namespace processes keep executing **stale code** — the client does not respawn them, so the live server no longer matches the merged source. This repeatedly blocks work: * Namespaces fail with `stale-runtime`, `Transport closed`, or `client is closing: EOF`. * Manual `/mcp reconnect` (or a full restart) is required far too often. * The LLM usually **cannot** restart MCP from its own tool surface — it has no sanctioned way to force a respawn on current code. The staleness bites hardest after changes to `gitea_mcp_server.py`, tool schemas, workflow guards, capability logic, or runtime diagnostics: the session makes a correct decision but the live process enforces old behavior (or has already dropped its transport). ## Goal When `master` advances — especially after MCP/tooling code changes land — the Gitea MCP namespaces should **automatically restart, reload, or cleanly exit** so the client respawns them on current code, without manual reconnect and without unsafe self-mutation. ## Related prior work * **#420** (closed) — "MCP server must dynamically reload runtime profiles and capability gates or support hot restart." Narrower: reloads profiles/capability gates, not the running Python code / tool schemas. This issue covers process-level respawn on code change. * **#531** (closed) — "Detect stale MCP server runtime before mutation tools execute." Detection + fail-closed diagnostic only; does not restart or respawn. * **#584** (open) — incident where the host auto-reconnected all four namespaces at startup. Evidence report, not a sanctioned auto-restart mechanism. This issue is the missing piece: a sanctioned auto/semi-auto restart path that ties detection (#531) and reload (#420) together into an actual respawn on current code. ## Acceptance criteria 1. Detect when the running MCP code is older than the current `prgs/master` (commit/version comparison, not just profile drift). 2. Restart / reload or cleanly exit stale Gitea MCP namespace processes so the client respawns them on current code. 3. Cover **all** namespaces: author (`gitea-tools`), reviewer, merger, and reconciler/tools. 4. Avoid unsafe self-mutation, raw process killing, direct imports, or guard bypasses. 5. Provide clear diagnostics when auto-restart is unavailable (running commit, expected master commit, namespace/profile, recommended operator action). 6. Add a sanctioned host/client lifecycle mechanism if full auto-restart is not possible from inside the server. 7. Ensure post-merge workflows can trigger or verify MCP restart after MCP-related code lands. 8. Add tests or proof docs for stale-runtime detection **and** restart behavior. 9. Preserve all safety guards: role separation, root checkout guard, capability preflight, namespace binding, and BLOCKED + DIAGNOSE when the LLM cannot perform a required step. ## Notes * Full in-process code hot-swap is likely unsafe/incomplete for Python; a **clean exit → client respawn** path is the preferred fallback over attempting live self-mutation. * Restart must never race a mutation mid-flight — gate on lease/capability state so a respawn does not orphan an in-progress workflow.
jcwalker3 added the mcpgiteareliabilityworkflowenhancement labels 2026-07-09 12:50:42 -05:00
jcwalker3 added the status:pr-open label 2026-07-09 13:58:08 -05:00
Owner

Canonical Issue State

STATE: open — incident evidence recorded; auto-restart still not live after master advances
WHO_IS_NEXT: reviewer
NEXT_ACTION: Review and land PR #593 (or equivalent) so MCP namespaces detect master advance and restart on current code
NEXT_PROMPT:

Review/merge PR #593 (Closes #591): auto-restart Gitea MCP namespaces when stale or git HEAD advances. Prove detection of older-than-master runtime and clean client respawn path for all namespaces (author/reviewer/merger/reconciler).

WHAT_HAPPENED: After #595 merged (ac531dd), retry formal APPROVE of PR #592 required gitea_cleanup_stale_review_decision_lock. Live gitea-reviewer catalog lacked the tool. Root workspace still at 6913ac9 (4 behind prgs/master). MCP processes still execute root mcp_server.py. Formal review not submitted. Durable note also on PR #592 comment 8619.
WHY: No sanctioned auto-restart after master advances (#591 gap). LLM cannot force MCP respawn. Detection/restart acceptance criteria for this issue are still unmet in production host behavior.
RELATED_PRS: #593 (open implementation), #595 (merged tool that was unavailable until restart), #592 (blocked consumer)
BLOCKERS: none for this issue body itself; consumer PR #592 remains infra-stalled until root is at prgs/master with MCP restarted OR #593 lands and auto-restart fires — unblock when live gitea-reviewer exposes tools from current master after HEAD advances
VALIDATION: whoami OK; tool search miss; git rev-list HEAD..prgs/master = 4; process cmdline shows Gitea-Tools/mcp_server.py from behind tree
LAST_UPDATED_BY: prgs-reviewer (sysadmin) 2026-07-09 incident report

## Canonical Issue State STATE: open — incident evidence recorded; auto-restart still not live after master advances WHO_IS_NEXT: reviewer NEXT_ACTION: Review and land PR #593 (or equivalent) so MCP namespaces detect master advance and restart on current code NEXT_PROMPT: ```text Review/merge PR #593 (Closes #591): auto-restart Gitea MCP namespaces when stale or git HEAD advances. Prove detection of older-than-master runtime and clean client respawn path for all namespaces (author/reviewer/merger/reconciler). ``` WHAT_HAPPENED: After #595 merged (ac531dd), retry formal APPROVE of PR #592 required gitea_cleanup_stale_review_decision_lock. Live gitea-reviewer catalog lacked the tool. Root workspace still at 6913ac9 (4 behind prgs/master). MCP processes still execute root mcp_server.py. Formal review not submitted. Durable note also on PR #592 comment 8619. WHY: No sanctioned auto-restart after master advances (#591 gap). LLM cannot force MCP respawn. Detection/restart acceptance criteria for this issue are still unmet in production host behavior. RELATED_PRS: #593 (open implementation), #595 (merged tool that was unavailable until restart), #592 (blocked consumer) BLOCKERS: none for this issue body itself; consumer PR #592 remains infra-stalled until root is at prgs/master with MCP restarted OR #593 lands and auto-restart fires — unblock when live gitea-reviewer exposes tools from current master after HEAD advances VALIDATION: whoami OK; tool search miss; git rev-list HEAD..prgs/master = 4; process cmdline shows Gitea-Tools/mcp_server.py from behind tree LAST_UPDATED_BY: prgs-reviewer (sysadmin) 2026-07-09 incident report
Owner

Canonical Issue State

STATE: open — recovery evidence: process restart alone is insufficient; client must re-list tools after master advances
WHO_IS_NEXT: reviewer
NEXT_ACTION: Land PR #593 with proof that client list_tools is refreshed (not only process respawn), covering mid-session master advances that add tools
NEXT_PROMPT:

Review PR #593 for #591: ensure auto-restart also forces client tool rediscovery after tool surface changes land on master (e.g. gitea_cleanup_stale_review_decision_lock from #595).

WHAT_HAPPENED: After root reached ac531dd and Gitea MCP processes were force-respawned, a fresh stdio MCP client listed 74 tools including gitea_cleanup_stale_review_decision_lock. The existing Grok session continued to omit that tool from search_tool/use_tool. Disk tool-descriptor cache under ~/.grok/projects/.../mcps/*/tools was stale (Jul 8, 68 tools) and did not auto-refresh. Cross-link: PR #592 comment 8645.
WHY: #591 acceptance needs client reconnect/relist, not only killing/restarting Python MCP workers.
RELATED_PRS: #593, #595, #592
BLOCKERS: none for coding #591; consumer workflows remain gated until client rediscovery exists — unblock when client list_tools after master tool-surface change includes new tools without a full manual session restart
VALIDATION: list_tools has_cleanup=True on fresh process; session catalog miss; PR #592 comment 8645
LAST_UPDATED_BY: prgs-reviewer (sysadmin) 2026-07-09

## Canonical Issue State STATE: open — recovery evidence: process restart alone is insufficient; client must re-list tools after master advances WHO_IS_NEXT: reviewer NEXT_ACTION: Land PR #593 with proof that client list_tools is refreshed (not only process respawn), covering mid-session master advances that add tools NEXT_PROMPT: ```text Review PR #593 for #591: ensure auto-restart also forces client tool rediscovery after tool surface changes land on master (e.g. gitea_cleanup_stale_review_decision_lock from #595). ``` WHAT_HAPPENED: After root reached ac531dd and Gitea MCP processes were force-respawned, a fresh stdio MCP client listed 74 tools including gitea_cleanup_stale_review_decision_lock. The existing Grok session continued to omit that tool from search_tool/use_tool. Disk tool-descriptor cache under ~/.grok/projects/.../mcps/*/tools was stale (Jul 8, 68 tools) and did not auto-refresh. Cross-link: PR #592 comment 8645. WHY: #591 acceptance needs client reconnect/relist, not only killing/restarting Python MCP workers. RELATED_PRS: #593, #595, #592 BLOCKERS: none for coding #591; consumer workflows remain gated until client rediscovery exists — unblock when client list_tools after master tool-surface change includes new tools without a full manual session restart VALIDATION: list_tools has_cleanup=True on fresh process; session catalog miss; PR #592 comment 8645 LAST_UPDATED_BY: prgs-reviewer (sysadmin) 2026-07-09
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Scaled-Tech-Consulting/Gitea-Tools#591