Rename MCP server identifier from state-hub to dev-hub

Introduce canonical MCP_SERVER_NAME constants, shared registration helpers,
and a migrate_mcp_config.py script for ~/.claude.json upgrades. Registration,
patch, and custodian CLI checks accept both dev-hub and legacy state-hub during
transition. API root metadata and session-protocol template reflect the new name.
This commit is contained in:
2026-06-22 20:46:14 +02:00
parent 18a5e2d6f0
commit 398f458374
11 changed files with 198 additions and 23 deletions

View File

@@ -0,0 +1,30 @@
"""Helpers for ~/.claude.json MCP server registration checks."""
from __future__ import annotations
import json
from pathlib import Path
from mcp_server.constants import LEGACY_MCP_SERVER_NAME, MCP_SERVER_NAME
def load_claude_json(path: Path | None = None) -> dict | None:
claude_json = path or Path.home() / ".claude.json"
if not claude_json.exists():
return None
return json.loads(claude_json.read_text())
def mcp_server_registered(config: dict | None) -> bool:
if not config:
return False
servers = config.get("mcpServers", {})
return MCP_SERVER_NAME in servers or LEGACY_MCP_SERVER_NAME in servers
def resolve_mcp_server_name(config: dict) -> str | None:
servers = config.get("mcpServers", {})
if MCP_SERVER_NAME in servers:
return MCP_SERVER_NAME
if LEGACY_MCP_SERVER_NAME in servers:
return LEGACY_MCP_SERVER_NAME
return None

View File

@@ -0,0 +1,51 @@
#!/usr/bin/env python3
"""Rename legacy state-hub MCP registration to dev-hub in ~/.claude.json."""
from __future__ import annotations
import json
import shutil
from datetime import datetime, timezone
from pathlib import Path
from mcp_server.constants import LEGACY_MCP_SERVER_NAME, MCP_SERVER_NAME
CLAUDE_JSON = Path.home() / ".claude.json"
def migrate_config(config: dict) -> tuple[dict, bool]:
servers = config.setdefault("mcpServers", {})
if MCP_SERVER_NAME in servers:
return config, False
if LEGACY_MCP_SERVER_NAME not in servers:
return config, False
servers[MCP_SERVER_NAME] = servers.pop(LEGACY_MCP_SERVER_NAME)
return config, True
def main() -> None:
if not CLAUDE_JSON.exists():
print(f"ERROR: {CLAUDE_JSON} not found.")
raise SystemExit(1)
config = json.loads(CLAUDE_JSON.read_text())
migrated_config, changed = migrate_config(config)
if not changed:
if MCP_SERVER_NAME in config.get("mcpServers", {}):
print(f"OK: '{MCP_SERVER_NAME}' already registered.")
else:
print(
f"Nothing to migrate: neither '{LEGACY_MCP_SERVER_NAME}' nor "
f"'{MCP_SERVER_NAME}' found in mcpServers."
)
return
stamp = datetime.now(tz=timezone.utc).strftime("%Y%m%dT%H%M%SZ")
backup = CLAUDE_JSON.with_name(f".claude.json.bak-{stamp}")
shutil.copy2(CLAUDE_JSON, backup)
CLAUDE_JSON.write_text(json.dumps(migrated_config, indent=2) + "\n")
print(f"Backed up: {backup}")
print(f"Migrated: mcpServers['{LEGACY_MCP_SERVER_NAME}'] → mcpServers['{MCP_SERVER_NAME}']")
if __name__ == "__main__":
main()

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env python3
"""
Patch ~/.claude.json to add the cwd field to the state-hub MCP entry.
Patch ~/.claude.json to add the cwd field to the dev-hub MCP entry.
claude mcp add-json silently drops the cwd field. Run this script after
any claude mcp add-json call to restore it.
@@ -11,22 +11,35 @@ import json
import os
from pathlib import Path
from mcp_server.constants import LEGACY_MCP_SERVER_NAME, MCP_SERVER_NAME
from scripts.mcp_registration import load_claude_json, resolve_mcp_server_name
CLAUDE_JSON = Path.home() / ".claude.json"
STATE_HUB_DIR = Path(__file__).resolve().parent.parent # state-hub/
STATE_HUB_DIR = Path(__file__).resolve().parent.parent
def main() -> None:
if not CLAUDE_JSON.exists():
config = load_claude_json(CLAUDE_JSON)
if config is None:
print(f"ERROR: {CLAUDE_JSON} not found. Run 'claude mcp add-json' first.")
raise SystemExit(1)
config = json.loads(CLAUDE_JSON.read_text())
servers = config.setdefault("mcpServers", {})
if "state-hub" not in servers:
print("ERROR: 'state-hub' not found in ~/.claude.json. Run 'claude mcp add-json' first.")
server_name = resolve_mcp_server_name(config)
if server_name is None:
print(
f"ERROR: neither '{MCP_SERVER_NAME}' nor '{LEGACY_MCP_SERVER_NAME}' "
f"found in ~/.claude.json. Run 'claude mcp add-json' first."
)
raise SystemExit(1)
entry = servers["state-hub"]
if server_name == LEGACY_MCP_SERVER_NAME:
print(
f"NOTE: patching legacy '{LEGACY_MCP_SERVER_NAME}' entry. "
"Run scripts/migrate_mcp_config.py to rename to dev-hub."
)
entry = servers[server_name]
cwd_str = str(STATE_HUB_DIR)
if entry.get("cwd") == cwd_str:
@@ -35,8 +48,8 @@ def main() -> None:
entry["cwd"] = cwd_str
CLAUDE_JSON.write_text(json.dumps(config, indent=2) + "\n")
print(f"Patched: ~/.claude.json state-hub.cwd = {cwd_str}")
print(f"Patched: ~/.claude.json {server_name}.cwd = {cwd_str}")
if __name__ == "__main__":
main()
main()

View File

@@ -1,6 +1,7 @@
## Session Protocol
State Hub: http://127.0.0.1:8000
Dev Hub (State Hub API): http://127.0.0.1:8000
MCP server name in `~/.claude.json`: `dev-hub`
**Step 1 — Orient**

View File

@@ -3,7 +3,7 @@ set -euo pipefail
STATE_HUB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
CLAUDE_JSON="${CLAUDE_JSON:-$HOME/.claude.json}"
SERVER_NAME="${STATE_HUB_MCP_NAME:-state-hub}"
SERVER_NAME="${STATE_HUB_MCP_NAME:-dev-hub}"
API_BASE="${API_BASE:-}"
MCP_URL="${MCP_URL:-}"
DRY_RUN=0

View File

@@ -112,11 +112,12 @@ if not f.exists():
print('MISSING_FILE')
else:
d = json.loads(f.read_text())
print('OK' if 'state-hub' in d.get('mcpServers', {}) else 'NOT_REGISTERED')
servers = d.get('mcpServers', {})
print('OK' if 'dev-hub' in servers or 'state-hub' in servers else 'NOT_REGISTERED')
")"
case "$MCP_OK" in
MISSING_FILE) echo "WARNING: ~/.claude.json not found. MCP server not registered." ;;
NOT_REGISTERED) echo "WARNING: 'state-hub' not in ~/.claude.json. See global CLAUDE.md §MCP Server Registration." ;;
NOT_REGISTERED) echo "WARNING: 'dev-hub' not in ~/.claude.json. See global CLAUDE.md §MCP Server Registration." ;;
*) echo " MCP OK" ;;
esac
fi