refactor(mcp): collapse umbrella MCP to one registry-mounting entrypoint (delete 17 bridges)#309
Merged
Merged
Conversation
…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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Collapses the umbrella's MCP surface (
mcp_server.py+_mcp_tools/17 bridges +_mcp_resources/7 docs) into a single thin coordinator packagescitex._mcp.The registry loop already auto-mounted peers (
scitex_dev._ecosystem.ECOSYSTEM), so the per-packageregister_<pkg>_toolsbridges were redundant or stale — the__init__docstring itself called them an anti-pattern.project.pywas outright broken (it reached intoscitex.project._mcp.handlers, which moved out toscitex_hub).The new package
_mcp/__init__.pymain()/run_server(). Path candidates extended with_server+_mcp._serverso stats/dev mount via the registry too._mcp/_compat.pysafe_mount/get_tools_sync(moved verbatim)_mcp/_resources*.py_mcp/_umbrella_tools.py+_introspect_tools.py+_notification_tools.py_mcp/_peer_extras.pyfr_*→plt_stx_*, socialia coresocial_*,scitex_dev.linter, optionalscitex_cloudmountSpecial handling
project_*file-CRUD family — its handlers moved toscitex_huband are now served by the registry-mountedhubpeer (hub_project_*). Absentscitex_hub⇒ no project tools (graceful).scitex_cloudis 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.pykept as a back-compat shim re-exportingscitex._mcpcli/mcp.py(list/doctor/start) +cli/scholarserve →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/sphinxskip-lists updatedTests
tests/scitex/test_mcp_entrypoint.py(16 cases): >0 peers mounted, brand prefix +fr_→plt_stx_rename,crossref-local→crossrefalias, umbrella-only families present, optional-peer absence doesn't crash.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