Skip to content

refactor(mcp): collapse umbrella MCP to one registry-mounting entrypoint (delete 17 bridges)#309

Merged
ywatanabe1989 merged 3 commits into
developfrom
chore/umbrella-mcp-collapse
May 31, 2026
Merged

refactor(mcp): collapse umbrella MCP to one registry-mounting entrypoint (delete 17 bridges)#309
ywatanabe1989 merged 3 commits into
developfrom
chore/umbrella-mcp-collapse

Conversation

@ywatanabe1989
Copy link
Copy Markdown
Owner

What

Collapses the umbrella's MCP surface (mcp_server.py + _mcp_tools/ 17 bridges + _mcp_resources/ 7 docs) into a single thin coordinator package scitex._mcp.

The registry loop already auto-mounted peers (scitex_dev._ecosystem.ECOSYSTEM), so the per-package register_<pkg>_tools bridges were redundant or stale — the __init__ docstring itself called them an anti-pattern. project.py was outright broken (it reached into scitex.project._mcp.handlers, which moved out to scitex_hub).

The new package

file role
_mcp/__init__.py THE entrypoint — builds one FastMCP, registry-mounts every non-archived/non-umbrella peer under a brand-prefixed namespace (with the historical renames/aliases), skips optional peers gracefully, exposes main()/run_server(). Path candidates extended with _server + _mcp._server so stats/dev mount via the registry too.
_mcp/_compat.py safe_mount / get_tools_sync (moved verbatim)
_mcp/_resources*.py the 7 umbrella doc resources, consolidated
_mcp/_umbrella_tools.py + _introspect_tools.py + _notification_tools.py the genuinely umbrella-only inline tools (browser, capture, docs, skills, usage, template, tunnel, introspect, notification)
_mcp/_peer_extras.py surfaces needing umbrella-side adjustment beyond a plain mount: figrecipe fr_*plt_stx_*, socialia core social_*, scitex_dev.linter, optional scitex_cloud mount

Special handling

  • project/cloud via scitex_hub: dropped the project_* file-CRUD family — its handlers moved to scitex_hub and are now served by the registry-mounted hub peer (hub_project_*). Absent scitex_hub ⇒ no project tools (graceful). scitex_cloud is not in the ecosystem registry, so it's mounted explicitly as an optional extra (cloud_*), graceful when absent.

Net effect

17 bridges + 7 resource files deleted; −1034 LoC; umbrella MCP is now a thin peer-mounting coordinator with no per-tool maintenance.

Wiring repointed in lockstep

  • pyproject: scitex-mcp-server = "scitex._mcp:main"
  • mcp_server.py kept as a back-compat shim re-exporting scitex._mcp
  • cli/mcp.py (list/doctor/start) + cli/scholar serve → scitex._mcp; doctor checks now probe mounted-server namespaces (peer tools resolve lazily in FastMCP 2.x)
  • tests/integration/test_cross_package_imports.py, scripts/check-extras-completeness.py, docs/sphinx skip-lists updated

Tests

  • New tests/scitex/test_mcp_entrypoint.py (16 cases): >0 peers mounted, brand prefix + fr_plt_stx_ rename, crossref-localcrossref alias, umbrella-only families present, optional-peer absence doesn't crash.
  • Fixed two pre-existing reds in test_thin_wrapper_consistency.py (writer/social) by enumerating lazily-mounted peer tools in _umbrella_tool_names().
  • scitex mcp doctor → all checks pass (23 peers mounted, 56 local tools).

🤖 Generated with Claude Code

…int (delete 17 bridges)

The umbrella's MCP surface was a thick per-package layer: mcp_server.py +
_mcp_tools/ (17 hand-wrap "register_<pkg>_tools" bridge files, themselves
documented as an anti-pattern) + _mcp_resources/ (7 doc files). The registry
loop already auto-mounted peers, so most bridges were redundant or stale
(project.py reached into scitex_hub's moved-out _mcp and was broken).

Collapse everything into a single thin coordinator package, scitex._mcp:

- __init__.py        THE entrypoint: builds one FastMCP, registry-mounts every
                     non-archived/non-umbrella peer (single source of truth:
                     scitex_dev._ecosystem ECOSYSTEM) under a brand-prefixed
                     namespace with the historical tool-name renames/aliases,
                     skips optional peers gracefully, exposes main()/run_server().
                     Extended the FastMCP path candidates with `_server` and
                     `_mcp._server` so stats/dev now mount via the registry too.
- _compat.py         safe_mount / get_tools_sync (moved verbatim).
- _resources*.py     the 7 umbrella doc resources, consolidated.
- _umbrella_tools.py + _introspect_tools.py + _notification_tools.py
                     the genuinely umbrella-only inline tools (no peer owns them):
                     browser, capture, docs, skills, usage, template, tunnel,
                     introspect, notification.
- _peer_extras.py    surfaces needing umbrella-side adjustment beyond a plain
                     mount: figrecipe fr_*->plt_stx_*, socialia core social_*,
                     scitex_dev.linter, optional scitex_cloud mount.

Dropped the project_* file-CRUD family: it referenced scitex.project._mcp.handlers
which moved to scitex_hub and is now superseded by the registry-mounted `hub`
peer (hub_project_*). Absent scitex_hub => no project tools (graceful).

Net effect: 17 bridges + 7 resource files deleted; -1034 LoC; umbrella MCP is a
thin peer-mounting coordinator with no per-tool maintenance.

Wiring repointed in lockstep:
- pyproject: scitex-mcp-server = "scitex._mcp:main"
- mcp_server.py kept as a back-compat shim re-exporting scitex._mcp.
- cli/mcp.py (list/doctor/start) + cli/scholar serve -> scitex._mcp; doctor
  checks now probe mounted-server namespaces (peer tools resolve lazily).
- tests/integration/test_cross_package_imports.py: drop dead _mcp_tools/
  _mcp_resources entries, add scitex._mcp.
- scripts/check-extras-completeness.py + docs/sphinx skip-lists: _mcp.

Tests: new tests/scitex/test_mcp_entrypoint.py asserts >0 peers mounted, brand
prefix + fr_->plt_stx_ rename, crossref-local->crossref alias, umbrella-only
families present, optional-peer absence doesn't crash. Also fixed two
pre-existing reds in test_thin_wrapper_consistency.py by enumerating lazily-
mounted peer tools in _umbrella_tool_names().
CI runs fastmcp==3.3.1; local dev has 2.13.2. FastMCP 2.x exposes mounted
peers via _mounted_servers (tools resolve lazily, absent from get_tools),
while 3.x folds mounted tools into list_tools() with <ns>_ prefixes and has
no stable _mounted_servers. The new test_mcp_entrypoint mount assertions and
the mcp doctor checks reached into the 2.x-only _mounted_servers attr, so
they failed on 3.x.

Add _compat.mounted_namespaces() that unions both signals (2.x mounted-server
prefixes + prefixes derived from resolvable tool names) and use it in the
entrypoint tests and the doctor's namespace/registration checks.
@ywatanabe1989 ywatanabe1989 merged commit 209cbe4 into develop May 31, 2026
7 checks passed
@ywatanabe1989 ywatanabe1989 deleted the chore/umbrella-mcp-collapse branch May 31, 2026 01:29
@github-actions github-actions Bot locked and limited conversation to collaborators May 31, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant