diff --git a/mcp/__init__.py b/mcp/__init__.py index 5867cde4..6154f804 100644 --- a/mcp/__init__.py +++ b/mcp/__init__.py @@ -21,7 +21,11 @@ Configure in Claude Desktop, Windsurf, Cline, Continue, VS Code: } """ +# `semantica.__version__` is the authoritative package version — see +# semantica/mcp_server/__init__.py for why it is used directly rather than +# importlib.metadata.version("semantica"). +from semantica import __version__ + from .server import SemanticaMCPServer, main -__all__ = ["SemanticaMCPServer", "main"] -__version__ = "0.4.0" +__all__ = ["SemanticaMCPServer", "main", "__version__"] diff --git a/mcp/resources/registry.py b/mcp/resources/registry.py index 052ee8c4..0f1d5ac4 100644 --- a/mcp/resources/registry.py +++ b/mcp/resources/registry.py @@ -10,6 +10,7 @@ from __future__ import annotations import json import logging +from mcp import __version__ from mcp.session import get_graph log = logging.getLogger("semantica.mcp.resources") @@ -60,7 +61,7 @@ def _read_decisions_list(uri: str) -> dict: def _read_schema_info(uri: str) -> dict: info = { - "version": "0.4.0", + "version": __version__, "node_types": [ "Entity", "decision", "Decision", "Event", "Concept", "Person", "Organisation", "Location", diff --git a/mcp/server.py b/mcp/server.py index 371343a5..3cd935be 100644 --- a/mcp/server.py +++ b/mcp/server.py @@ -17,6 +17,7 @@ import logging import sys from typing import Any +from mcp import __version__ from mcp.resources import RESOURCE_DEFINITIONS, handle_resource_read from mcp.tools import TOOL_DEFINITIONS @@ -63,7 +64,7 @@ def _handle_initialize(req_id: Any, params: dict) -> dict: }, "serverInfo": { "name": "semantica-mcp", - "version": "0.4.0", + "version": __version__, }, }) diff --git a/tests/test_mcp_package_version.py b/tests/test_mcp_package_version.py new file mode 100644 index 00000000..72e4aa55 --- /dev/null +++ b/tests/test_mcp_package_version.py @@ -0,0 +1,54 @@ +"""Regression tests for version reporting in the top-level `mcp` package +(issue #863). + +Covers the same stale-version bug as `test_mcp_server_version.py` for the +standalone `mcp/` server (run via `python -m mcp.server`), which is a +separate implementation from `semantica.mcp_server` and was not covered +by that fix. `semantica.__version__` is the authoritative package +version (see semantica/mcp_server/__init__.py), so all three surfaces +are asserted against it directly. +""" + +import json +import os +import sys +import unittest + +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) + +import mcp +import semantica +from mcp.resources.registry import _read_schema_info +from mcp.server import _handle_initialize + +_EXPECTED = semantica.__version__ + + +class TestMCPPackageVersion(unittest.TestCase): + def test_package_version_matches_authoritative_source(self): + self.assertEqual(mcp.__version__, _EXPECTED) + + def test_package_version_is_not_stale_literal(self): + self.assertNotEqual(mcp.__version__, "0.4.0") + + def test_initialize_server_info_version_matches_package(self): + response = _handle_initialize(1, {}) + self.assertEqual(response["result"]["serverInfo"]["version"], _EXPECTED) + + def test_initialize_server_info_version_is_not_stale_literal(self): + response = _handle_initialize(1, {}) + self.assertNotEqual(response["result"]["serverInfo"]["version"], "0.4.0") + + def test_schema_info_resource_version_matches_package(self): + resource = _read_schema_info("semantica://schema/info") + info = json.loads(resource["text"]) + self.assertEqual(info["version"], _EXPECTED) + + def test_schema_info_resource_version_is_not_stale_literal(self): + resource = _read_schema_info("semantica://schema/info") + info = json.loads(resource["text"]) + self.assertNotEqual(info["version"], "0.4.0") + + +if __name__ == "__main__": + unittest.main()