fix: mcp registry initialization

This commit is contained in:
Timothy
2026-04-30 15:52:16 -07:00
parent 725dd1f410
commit 7b1dda7bf3
2 changed files with 42 additions and 23 deletions
+39 -11
View File
@@ -81,7 +81,30 @@ class MCPRegistry:
# ── Initialization ──────────────────────────────────────────────
def initialize(self) -> None:
"""Create directory structure and default files if missing."""
"""Create directory structure, default files, and seed bundled servers.
Every read path (queen orchestrator, pipeline stage, CLI, routes)
calls this keeping the seeding here means a fresh ``HIVE_HOME``
(e.g. the desktop's per-user dir under ``~/.config/Hive/users/<hash>/``
or ``~/Library/Application Support/Hive/users/<hash>/``) is always
populated with ``hive_tools`` / ``gcu-tools`` / ``files-tools`` /
``shell-tools`` before any agent code reads ``installed.json``.
Without this, ``load_agent_selection()`` resolves an empty registry
and emits "Server X requested but not installed" warnings even
though the server is bundled.
Idempotent already-installed entries are left untouched.
"""
self._bootstrap_io()
self._seed_defaults()
def _bootstrap_io(self) -> None:
"""Create the registry directory + empty config/installed files.
Split out from ``initialize()`` so ``_seed_defaults()`` can call it
without re-entering the seeding logic (which would recurse via
``_read_installed()`` ``initialize()``).
"""
self._base.mkdir(parents=True, exist_ok=True)
self._cache_dir.mkdir(parents=True, exist_ok=True)
@@ -92,21 +115,26 @@ class MCPRegistry:
self._write_json(self._installed_path, {"servers": {}})
def ensure_defaults(self) -> list[str]:
"""Seed the built-in local MCP servers (hive-tools, gcu-tools, files-tools).
"""Public alias kept for the ``hive mcp init`` CLI command.
Idempotent servers already present are left untouched. Skips seeding
entirely when the source-tree ``tools/`` directory cannot be located
(e.g. when Hive is installed from a wheel rather than a checkout).
Returns the list of names that were newly registered.
Returns the list of newly-registered server names so the CLI can
print them. Same idempotent seeding logic as ``initialize()``.
"""
self.initialize()
self._bootstrap_io()
return self._seed_defaults()
def _seed_defaults(self) -> list[str]:
"""Idempotently register the bundled default local servers.
Skips entirely when the source-tree ``tools/`` directory cannot
be located (e.g. wheel installs). Returns the list of names that
were newly registered.
"""
# parents: [0]=loader, [1]=framework, [2]=core, [3]=repo root
tools_dir = Path(__file__).resolve().parents[3] / "tools"
if not tools_dir.is_dir():
logger.debug(
"MCPRegistry.ensure_defaults: tools dir %s missing; skipping default seed",
"MCPRegistry._seed_defaults: tools dir %s missing; skipping default seed",
tools_dir,
)
return []
@@ -123,7 +151,7 @@ class MCPRegistry:
for canonical, stale in _STALE_DEFAULT_ALIASES.items():
if stale in existing and canonical not in existing:
logger.info(
"MCPRegistry.ensure_defaults: removing stale alias '%s' (canonical: '%s')",
"MCPRegistry._seed_defaults: removing stale alias '%s' (canonical: '%s')",
stale,
canonical,
)
@@ -146,7 +174,7 @@ class MCPRegistry:
)
added.append(name)
except MCPError as exc:
logger.warning("MCPRegistry.ensure_defaults: failed to seed '%s': %s", name, exc)
logger.warning("MCPRegistry._seed_defaults: failed to seed '%s': %s", name, exc)
if added:
logger.info("MCPRegistry: seeded default local servers: %s", added)
+3 -12
View File
@@ -44,19 +44,10 @@ class McpRegistryStage(PipelineStage):
from framework.loader.mcp_registry import MCPRegistry
from framework.orchestrator.files import FILES_MCP_SERVER_NAME
# Bundled defaults (hive_tools / gcu-tools / files-tools / shell-tools)
# are seeded inside MCPRegistry.initialize(); resolve_for_agent below
# will find them even on a fresh HIVE_HOME.
registry = MCPRegistry()
# Seed the bundled default servers (hive_tools, gcu-tools, files-tools,
# shell-tools) into the active HIVE_HOME's installed.json on first
# encounter. Idempotent — already-installed entries are left alone.
# Without this, a fresh HIVE_HOME (e.g. the desktop app's per-user
# dir under ~/.config/Hive/users/<hash>) only gets defaults via the
# `hive mcp` CLI, never via the runtime that consumes them.
try:
seeded = registry.ensure_defaults()
if seeded:
logger.info("[pipeline] McpRegistryStage: seeded defaults: %s", seeded)
except Exception as exc:
logger.warning("[pipeline] McpRegistryStage: ensure_defaults failed: %s", exc)
mcp_loaded = False
# 1. From agent.json mcp_servers refs