Skip to content

Split plexosdb_mcp.server into focused state tool-registration and CLI modules #158

Description

@pesap

Split plexosdb_mcp.server into focused state, tool-registration, and CLI modules

Executor instructions: Follow this issue step by step. Run every
verification command and confirm the expected result before moving on. If any
STOP condition is true, stop and report instead of improvising.

Drift check (run first): git diff --stat a11b6a3..HEAD -- src/plexosdb-mcp/src/plexosdb_mcp/server.py src/plexosdb-mcp/src/plexosdb_mcp/__init__.py src/plexosdb-mcp/src/plexosdb_mcp/__main__.py src/plexosdb-mcp/tests/test_mcp_server.py docs/source/howtos/mcp_server.md
If any in-scope file changed since this issue was written, compare the
Current behavior excerpts against live code before proceeding. If they do not
match, stop and ask for /plan to refresh this issue.

Status

Current behavior

The new MCP adapter keeps session state, empty-model bootstrapping, parser
helpers, all MCP tool registration groups, admin/capabilities metadata, CLI
argument parsing, one-shot diagnostic commands, and runtime entrypoint logic in a
single module.

  • src/plexosdb-mcp/src/plexosdb_mcp/server.py is 1014 lines at the planned commit.
$ wc -l src/plexosdb-mcp/src/plexosdb_mcp/server.py
1014 src/plexosdb-mcp/src/plexosdb_mcp/server.py
  • src/plexosdb-mcp/src/plexosdb_mcp/server.py mixes multiple ownership areas in one file.
# src/plexosdb-mcp/src/plexosdb_mcp/server.py:30,130,180,208,362,507,621,691,719,762,787,840,922,962,1002
30:class MCPServerState:
130:def _bootstrap_empty_model(db: PlexosDB) -> None:
180:def _register_session_tools(mcp: Any, server_state: MCPServerState) -> None:
208:def _register_object_tools(mcp: Any, server_state: MCPServerState) -> None:
362:def _register_edit_tools(mcp: Any, server_state: MCPServerState) -> None:
507:def _register_discovery_catalog_tools(mcp: Any, server_state: MCPServerState) -> None:
621:def _register_discovery_query_tools(mcp: Any, server_state: MCPServerState) -> None:
691:def _register_export_tools(mcp: Any, server_state: MCPServerState) -> None:
719:def _register_admin_tools(mcp: Any, server_state: MCPServerState) -> None:
762:def build_mcp_server(state: MCPServerState | None = None, *, read_only: bool | None = None) -> Any:
787:def _parse_cli_args(argv: list[str] | None = None) -> argparse.Namespace:
840:def _run_cli_command(command: str, xml_path: str | None = None) -> None:
922:def _run_capabilities_command() -> None:
962:def _main_impl(argv: list[str] | None) -> None:
1002:def main(argv: list[str] | None = None) -> None:
  • Public package exports currently come through src/plexosdb-mcp/src/plexosdb_mcp/__init__.py.
# src/plexosdb-mcp/src/plexosdb_mcp/__init__.py
from plexosdb_mcp.server import (
    MCPServerState,
    build_mcp_server,
    main,
)

__all__ = ("MCPServerState", "build_mcp_server", "main")

Desired behavior or Goal

Refactor the MCP adapter into focused modules while preserving public behavior.
The server.py file should become a small orchestration/compatibility module,
not the owner of every concern. Maintainers should be able to change CLI
behavior, tool registration, session state, and diagnostic metadata without
scrolling through a thousand-line mixed-concern file.

Acceptance criteria

Non-goals

Work Plan

Validation

  • uv run --project src/plexosdb-mcp pytest -q -c src/plexosdb-mcp/pyproject.toml src/plexosdb-mcp/tests exits 0.
  • uv run --project src/plexosdb-mcp plexosdb-mcp health --json exits 0 and prints JSON with "ok": true.
  • uv run --project src/plexosdb-mcp plexosdb-mcp capabilities --json exits 0 and returns the same tool categories as before the refactor.
  • python - <<'PY'\nfrom plexosdb_mcp import MCPServerState, build_mcp_server, main\nprint(MCPServerState, build_mcp_server, main)\nPY exits 0 when run in the nested project environment.
  • wc -l src/plexosdb-mcp/src/plexosdb_mcp/server.py reports fewer than 500 lines.
  • uv run prek run --show-diff-on-failure --color=always --all-files --hook-stage pre-push exits 0 before handoff.

Documentation

  • Update docs/source/howtos/mcp_server.md only if import paths, CLI commands, or public behavior described there changes. Otherwise use None.

Testing

  • Update src/plexosdb-mcp/tests/test_mcp_server.py imports only as needed to follow the new module layout.
  • Preserve all behavior assertions; this is a refactor, so tests should prove behavior did not change.
  • If new internal helpers are non-trivial, add focused unit tests near existing MCP tests rather than relying only on smoke coverage.

Risks

Breaking-change

Medium. The intended behavior is unchanged, but moving entrypoint, registration, and state logic can break public imports or the console script if compatibility exports are missed.

Review-size

Medium. This should stay under about 500 changed lines by moving cohesive blocks rather than rewriting behavior. If the refactor starts changing behavior or adding abstractions, stop and split.

Implementation notes

Scope

In scope:

  • src/plexosdb-mcp/src/plexosdb_mcp/server.py
  • New focused modules under src/plexosdb-mcp/src/plexosdb_mcp/, for example:
    • state.py for MCPServerState and empty-session bootstrapping
    • parsing.py for enum/env/read-only helpers
    • tools.py or tools/*.py for MCP tool registration groups
    • cli.py for argument parsing and one-shot diagnostic commands
  • src/plexosdb-mcp/src/plexosdb_mcp/__init__.py
  • src/plexosdb-mcp/src/plexosdb_mcp/__main__.py
  • src/plexosdb-mcp/tests/test_mcp_server.py
  • docs/source/howtos/mcp_server.md only if public docs need path/behavior updates

Out of scope:

Suggested steps

  1. Start with characterization: run the nested MCP test suite and capture current health, version, doctor, and capabilities JSON shapes.
  2. Move MCPServerState and _bootstrap_empty_model into a state-focused module.
    • Keep compatibility imports from server.py or __init__.py so external imports continue to work.
  3. Move CLI parsing and one-shot command functions into a CLI-focused module.
    • Keep main available through plexosdb_mcp.__main__ and plexosdb_mcp.__init__.
  4. Move MCP tool registration groups into one or more tool-focused modules.
    • Preserve tool names exactly.
  5. Leave server.py as a small compatibility/orchestration module exporting MCPServerState, build_mcp_server, and main.
  6. Run focused validation and broad pre-push validation.

Test details

  • Model import compatibility tests after existing package import style in src/plexosdb-mcp/tests/test_mcp_server.py.
  • Use the existing FakeFastMCP tool registry to assert registration did not lose or rename tools.

Maintenance notes

  • Future MCP tool additions should land in the relevant tool-registration module rather than growing server.py again.
  • Reviewers should verify this PR mostly moves code and preserves behavior; semantic changes should be pushed to their own issues.

Metadata

Metadata

Assignees

No one assigned

    Labels

    improveGenerated improvement work packettech-debtTechnical debt and architecture cleanupworkon-readyReady for autonomous /workon execution

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions