A mid-run profile switch (reviewer -> author -> reviewer) left workflow-load proof, reviewer lease binding, the review decision lock, live namespace health, and preflight identity/capability stamps intact, so a formal verdict could be recorded under contaminated session state. - gitea_activate_profile now invalidates all review-critical session state on a cross-profile switch, in memory and in durable state keyed by either profile identity, and reports the invalidation + re-preflight requirement. - Full reviewer preflight (whoami, load_review_workflow, resolve_task_capability(review_pr), head re-pin, lease re-acquire) is required before any formal verdict after a switch; switching back cannot resurrect the stale run. - Namespace provenance: optional launcher-declared GITEA_MCP_NAMESPACE is reported by whoami/runtime context/capability resolution, and a declared namespace that disagrees with a task's required namespace fails closed. - Docs: supported pattern is separate session/namespace per role, not in-process profile hopping mid-review.
4.6 KiB
MCP namespace health diagnostics (#543)
Gitea MCP tools can be registered in the Python FastMCP server while the IDE's
live MCP namespace is still unusable. The failure usually appears as
client is closing: EOF, transport closed, or an empty response when calling
a tool such as gitea_whoami.
Do not treat static tool registration as proof that review or merge workflows can proceed. A reviewer or merger flow must have client-namespace evidence that the required tool is callable through the configured IDE MCP namespace.
Probe sources (do not confuse them)
| Source | How obtained | Proves IDE namespace? |
|---|---|---|
client_namespace |
Tool call through the IDE-managed MCP client | Yes |
offline_spawn |
test_mcp_conn.py subprocess JSON-RPC handshake |
No (offline only) |
gitea_assess_mcp_namespace_health accepts probe_source and only sets
ide_namespace_proven=true for client_namespace success. Offline spawn
success never clears review/merge mutation gates.
Client-namespace health check (canonical)
- Through the IDE client, call a cheap tool on the target namespace
(
gitea_whoamiorgitea_list_profiles). - Feed the live result into:
gitea_assess_mcp_namespace_health(
namespace="gitea-merger", # or reviewer / author / tools
registered_tools=[...], # optional static list
probe_result={"success": true, "result": {...}},
probe_source="client_namespace",
)
- A healthy client-namespace assessment is recorded in the MCP session and
consulted by live
gitea_submit_pr_review/gitea_merge_prgates. - If the probe fails with EOF, recover via client reconnect only — see
docs/mcp-namespace-eof-recovery.md. Do not kill PIDs or touch MCP config mtimes as a recovery procedure.
Offline spawn probe (non-authoritative)
python3 test_mcp_conn.py --config ~/.gemini/config/mcp_config.json
This script spawns a separate server process from config, performs
JSON-RPC initialize → tools/list → tools/call, and classifies the
result with probe_source=offline_spawn. Use it for offline debugging of
launch command / registration. It does not prove the IDE-managed
namespace is healthy.
By default the script checks:
| Namespace | Required tool |
|---|---|
gitea-author |
gitea_whoami |
gitea-reviewer |
gitea_whoami |
gitea-merger |
gitea_whoami |
gitea-tools |
gitea_list_profiles |
Recovery (canonical)
When a namespace returns EOF, follow
docs/mcp-namespace-eof-recovery.md in order:
- Confirm blast radius (Gitea namespace vs all MCP servers).
- Reconnect the namespace through the client (IDE reconnect / relaunch).
- Do not repair via shell imports, raw JSON-RPC, PID kills, or config mtime touches — those do not restore the client's closed transport.
- Re-verify the specific required tool through the target namespace.
- Resume review/merge only after a successful
client_namespaceassessment.
Enforcement
- State machine (read-only): feed
blocks_merge_workflowfrom aclient_namespaceassessment intogitea_assess_review_merge_state_machine(live_namespace_broken=...). - Live mutations:
gitea_submit_pr_reviewandgitea_merge_prcall_live_namespace_health_gateand fail closed when the session has a recorded unhealthy or non-client probe for the required namespace (gitea-reviewerfor review,gitea-mergerfor merge).
When blocked, repair the IDE namespace and re-record a healthy
client_namespace assessment before retrying the mutation.
Namespace provenance (#690)
A server process cannot derive the name of the client-managed namespace it is
registered under, so the launcher may declare it with the
GITEA_MCP_NAMESPACE environment variable (e.g. GITEA_MCP_NAMESPACE=gitea-reviewer).
gitea_whoami,gitea_get_runtime_context, andgitea_resolve_task_capabilityreportnamespace_provenance: the declared client namespace, the active execution profile, and — for tasks with a required namespace (review_pr/submit_review→gitea-reviewer,merge_pr→gitea-merger) — amismatchverdict.- A declared namespace that disagrees with the requested task's required
namespace fails closed (
allowed_in_current_session=falsewith a STOP guidance entry). - An undeclared namespace is reported as
namespace_source="unknown"and is never treated as proof either way. - A profile switch via
gitea_activate_profileclears all recorded live namespace-health assessments; re-probe through the client before further review/merge mutations.