NatLabRockies / NatLabRockies/plexosdb

Centralize MCP capability metadata so runtime CLI tests and docs do not drift

Open
#157 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

improve tech-debt workon-ready
Dominant language
Python
Stars
37
Forks
21
Avg merge
1h 23m
Merged PRs (30d)
3

Description

Centralize MCP capability metadata so runtime, CLI, tests, and docs do not drift

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/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

  • Priority: P3
  • Effort: S
  • Risk: LOW
  • Depends on: #155
  • Category: tech-debt
  • Planned at: commit a11b6a3, 2026-07-08

Current behavior

MCP tool capability metadata is duplicated in multiple places. The runtime
admin tool and the one-shot CLI capabilities command each hard-code a category
map, docs hard-code the tool count/list, and tests only assert minimal category
presence.

  • src/plexosdb-mcp/src/plexosdb_mcp/server.py:719-757get_server_config() hard-codes categories.
# src/plexosdb-mcp/src/plexosdb_mcp/server.py:719-757
def _register_admin_tools(mcp: Any, server_state: MCPServerState) -> None:
    """Register administrative and server-introspection tools."""

    @mcp.tool()
    def get_server_config() -> dict[str, Any]:
        """Return server runtime configuration for host diagnostics."""
        return {
            "read_only": server_state.read_only,
            "active_sessions": server_state.active_session_count,
            "categories": {
                "session": ["health", "create_empty_session", "open_xml_session", "close_session"],
                "discovery": [
                    "list_classes",
                    "list_collections",
                    ...
                ],
                "edit": [
                    "add_object",
                    ...
                ],
                "export": ["save_xml", "to_csv"],
                "admin": ["get_server_config"],
            },
        }
  • src/plexosdb-mcp/src/plexosdb_mcp/server.py:922-955_run_capabilities_command() repeats the same category map.
# src/plexosdb-mcp/src/plexosdb_mcp/server.py:922-955
def _run_capabilities_command() -> None:
    """Print available MCP tools by category as JSON to stdout."""
    payload: dict[str, Any] = {
        "ok": True,
        "tools": {
            "session": ["health", "create_empty_session", "open_xml_session", "close_session"],
            "discovery": [
                "list_classes",
                "list_collections",
                ...
            ],
            "edit": [
                "add_object",
                ...
            ],
            "export": ["save_xml", "to_csv"],
            "admin": ["get_server_config"],
        },
        "subcommands": ["health", "version", "doctor", "capabilities"],
    }
  • docs/source/howtos/mcp_server.md:7-18 — docs hard-code a count and tool list.
# docs/source/howtos/mcp_server.md:7-18
The server exposes a curated set of **29 tools**, grouped in categories similar
to toolsets:

- Session: `health`, `create_empty_session`, `open_xml_session`, `close_session`
- Discovery: `list_objects_by_class`, `list_object_memberships`,
  ...
  • src/plexosdb-mcp/tests/test_mcp_server.py:581 and src/plexosdb-mcp/tests/test_mcp_server.py:787-788 — tests assert category presence but not equality with registered tools.
# src/plexosdb-mcp/tests/test_mcp_server.py:581
assert "discovery" in config["categories"]

# src/plexosdb-mcp/tests/test_mcp_server.py:787-788
assert set(payload["tools"]) == {"session", "discovery", "edit", "export", "admin"}
assert "health" in payload["tools"]["session"]

Desired behavior or Goal

The MCP server should define tool category metadata once and reuse it for
runtime admin output, one-shot CLI capabilities output, and tests. User-facing
docs should avoid a brittle hard-coded tool count or clearly direct users to the
capabilities command as the source of truth.

Acceptance criteria

  • src/plexosdb-mcp/src/plexosdb_mcp/server.py contains one module-level category metadata structure for MCP tool groups.
  • get_server_config() returns categories derived from that single metadata structure.
  • _run_capabilities_command() returns tools derived from that same metadata structure.
  • Tests assert that get_server_config()["categories"] and capabilities command payload["tools"] are equal.
  • Tests assert that the union of categorized tool names matches the fake FastMCP registered tool names after build_mcp_server(), with no undocumented extras or omissions.
  • docs/source/howtos/mcp_server.md removes the brittle hard-coded count or updates the wording so plexosdb-mcp capabilities is the source of truth for the current tool list.

Non-goals

  • Do not add, remove, or rename MCP tools in this issue.
  • Do not change public JSON keys returned by get_server_config() or plexosdb-mcp capabilities.
  • Do not restructure the CLI parser or change subcommand behavior.
  • Do not address release/CI wiring in this issue.

Work Plan

Validation
  • uv run --project src/plexosdb-mcp pytest -q -c src/plexosdb-mcp/pyproject.toml src/plexosdb-mcp/tests/test_mcp_server.py -k "capabilities or config" exits 0.
  • uv run --project src/plexosdb-mcp pytest -q -c src/plexosdb-mcp/pyproject.toml src/plexosdb-mcp/tests exits 0.
  • uv run sphinx-build docs/source/ docs/_build/ exits 0 after doc wording changes.
  • 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 to avoid a manually maintained numeric tool count.
  • Keep the how-to focused on usage; point users to plexosdb-mcp capabilities --json for the authoritative current list.
Testing
  • Update src/plexosdb-mcp/tests/test_mcp_server.py to compare get_server_config() categories and CLI capabilities output.
  • Add a test that builds the fake MCP server and compares registered fake tool names to the categorized metadata union.
  • Preserve the existing smoke tests for capabilities --json and get_server_config().

Risks

Breaking-change

Low. The intended public JSON shape remains unchanged. Risk is accidental tool name/category drift during refactor.

Review-size

Low. Scope is limited to one source file, one focused test file, and one docs page.

Implementation notes

Scope

In scope:

  • src/plexosdb-mcp/src/plexosdb_mcp/server.py
  • src/plexosdb-mcp/tests/test_mcp_server.py
  • docs/source/howtos/mcp_server.md

Out of scope:

  • .github/workflows/CI.yaml — covered by the MCP CI/pre-push issue this packet depends on.
  • .github/workflows/release.yaml — covered by the release/publishing issue.
  • src/plexosdb/db.py and root package internals — no root API changes are needed.
Suggested steps
  1. Add a module-level constant such as MCP_TOOL_CATEGORIES: dict[str, tuple[str, ...]] in src/plexosdb-mcp/src/plexosdb_mcp/server.py.
    • Preserve current category names and tool names exactly.
  2. Add a small helper that returns a JSON-serializable copy of the category map.
    • Use it in get_server_config() and _run_capabilities_command().
  3. Strengthen tests in src/plexosdb-mcp/tests/test_mcp_server.py.
    • Compare admin config categories to CLI capabilities tools.
    • Compare the categorized tool-name union to FakeFastMCP.tools.keys() after registration.
  4. Update docs/source/howtos/mcp_server.md.
    • Remove or soften the hard-coded numeric count.
    • Keep a concise category overview and direct users to plexosdb-mcp capabilities --json for the complete current list.
  5. Run focused MCP tests, docs build, and the broad pre-push gate.
Test details
  • Capture plexosdb-mcp capabilities output using the existing capsys pattern in test_smoke_capabilities_subcommand.
  • Use the existing FakeFastMCP registry in test_build_mcp_server_registers_tool_categories style tests.
Maintenance notes
  • Future MCP tool additions must update the single metadata structure and should fail tests if registration and metadata diverge.
  • Reviewers should verify that public output keys remain categories for get_server_config() and tools for the capabilities command.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the category maps in src/plexosdb-mcp/src/plexosdb_mcp/server.py, then read the related tests in src/plexosdb-mcp/tests/test_mcp_server.py and the tool overview in docs/source/howtos/mcp_server.md. Run the focused capabilities/config tests first. Done means both outputs derive from one metadata structure, categorized names match FakeFastMCP registration, and the docs point to the capabilities command without a brittle count.

Written by the indexing model from the issue text.

Assessment

Tech stack
markdown, python
Domain
backend, cli, documentation, testing-qa
Issue type
Refactor
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.