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
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-757 — get_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
- 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.
- Add a small helper that returns a JSON-serializable copy of the category map.
- Use it in
get_server_config() and _run_capabilities_command().
- 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.
- 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.
- 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.
Centralize MCP capability metadata so runtime, CLI, tests, and docs do not drift
Status
a11b6a3, 2026-07-08Current 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-757—get_server_config()hard-codes categories.src/plexosdb-mcp/src/plexosdb_mcp/server.py:922-955—_run_capabilities_command()repeats the same category map.docs/source/howtos/mcp_server.md:7-18— docs hard-code a count and tool list.src/plexosdb-mcp/tests/test_mcp_server.py:581andsrc/plexosdb-mcp/tests/test_mcp_server.py:787-788— tests assert category presence but not equality with registered tools.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
capabilitiescommand as the source of truth.Acceptance criteria
src/plexosdb-mcp/src/plexosdb_mcp/server.pycontains 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.get_server_config()["categories"]andcapabilitiescommandpayload["tools"]are equal.build_mcp_server(), with no undocumented extras or omissions.docs/source/howtos/mcp_server.mdremoves the brittle hard-coded count or updates the wording soplexosdb-mcp capabilitiesis the source of truth for the current tool list.Non-goals
get_server_config()orplexosdb-mcp capabilities.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/testsexits 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-pushexits 0 before handoff.Documentation
docs/source/howtos/mcp_server.mdto avoid a manually maintained numeric tool count.plexosdb-mcp capabilities --jsonfor the authoritative current list.Testing
src/plexosdb-mcp/tests/test_mcp_server.pyto compareget_server_config()categories and CLI capabilities output.capabilities --jsonandget_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.pysrc/plexosdb-mcp/tests/test_mcp_server.pydocs/source/howtos/mcp_server.mdOut 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.pyand root package internals — no root API changes are needed.Suggested steps
MCP_TOOL_CATEGORIES: dict[str, tuple[str, ...]]insrc/plexosdb-mcp/src/plexosdb_mcp/server.py.get_server_config()and_run_capabilities_command().src/plexosdb-mcp/tests/test_mcp_server.py.FakeFastMCP.tools.keys()after registration.docs/source/howtos/mcp_server.md.plexosdb-mcp capabilities --jsonfor the complete current list.Test details
plexosdb-mcp capabilitiesoutput using the existingcapsyspattern intest_smoke_capabilities_subcommand.FakeFastMCPregistry intest_build_mcp_server_registers_tool_categoriesstyle tests.Maintenance notes
categoriesforget_server_config()andtoolsfor the capabilities command.