diff --git a/src/godotiq/__init__.py b/src/godotiq/__init__.py
index 362f694..472068a 100644
--- a/src/godotiq/__init__.py
+++ b/src/godotiq/__init__.py
@@ -1 +1,14 @@
 """GodotIQ — The definitive MCP for AI-assisted Godot development."""
+
+from importlib.metadata import PackageNotFoundError, version
+
+
+def _get_version() -> str:
+    """Read version from package metadata (single source of truth: pyproject.toml)."""
+    try:
+        return version("godotiq")
+    except PackageNotFoundError:
+        return "0.0.0-dev"
+
+
+__version__: str = _get_version()
diff --git a/src/godotiq/server.py b/src/godotiq/server.py
index bbaf9c5..3c60721 100644
--- a/src/godotiq/server.py
+++ b/src/godotiq/server.py
@@ -9,6 +9,7 @@ from pathlib import Path
 
 from mcp.server.fastmcp import FastMCP
 
+from godotiq import __version__
 from godotiq.session import GodotIQSession, discover_project_root
 
 # --- Startup logging to stderr so diagnostics are visible in MCP hosts ---
@@ -77,7 +78,7 @@ async def godotiq_ping(detail: str = "normal") -> dict:
     Args:
         detail: Output verbosity — "brief" (summary), "normal" (default), or "full" (everything).
     """
-    return {"status": "ok", "version": "0.1.0"}
+    return {"status": "ok", "version": __version__}
 
 
 # Tool imports — each module registers tools on the mcp instance
diff --git a/tests/test_scaffolding_int.py b/tests/test_scaffolding_int.py
index 4a4b7c4..7faec83 100644
--- a/tests/test_scaffolding_int.py
+++ b/tests/test_scaffolding_int.py
@@ -134,7 +134,8 @@ class TestMcpServerPingToolRegistered:
         result = await mcp.call_tool("godotiq_ping", {})
         assert len(result) == 1
         payload = json.loads(result[0].text)
-        assert payload == {"status": "ok", "version": "0.1.0"}
+        from godotiq import __version__
+        assert payload == {"status": "ok", "version": __version__}
 
         # main() exists and is callable
         from godotiq.server import main
diff --git a/tests/test_server.py b/tests/test_server.py
index afc2863..79bf476 100644
--- a/tests/test_server.py
+++ b/tests/test_server.py
@@ -33,7 +33,8 @@ class TestPingTool:
     async def test_ping_returns_expected(self) -> None:
         result = await mcp.call_tool("godotiq_ping", {})
         payload = json.loads(result[0].text)
-        assert payload == {"status": "ok", "version": "0.1.0"}
+        from godotiq import __version__
+        assert payload == {"status": "ok", "version": __version__}
 
 
 class TestParserStubs:
diff --git a/tests/test_version.py b/tests/test_version.py
new file mode 100644
index 0000000..4fa5d3d
--- /dev/null
+++ b/tests/test_version.py
@@ -0,0 +1,53 @@
+"""Tests for dynamic __version__ and version propagation to godotiq_ping."""
+
+import json
+import re
+
+import pytest
+
+
+class TestVersionAttribute:
+    """Verify __version__ is accessible, correct type, and plausible format."""
+
+    def test_version_is_importable_from_top_level(self):
+        """__version__ can be imported directly from godotiq."""
+        from godotiq import __version__
+        assert __version__ is not None
+
+    def test_version_is_a_string(self):
+        """__version__ must be a str."""
+        from godotiq import __version__
+        assert isinstance(__version__, str)
+
+    def test_version_matches_expected(self):
+        """__version__ should equal the version in pyproject.toml (currently 0.1.0)."""
+        from godotiq import __version__
+        assert __version__ == "0.1.0"
+
+    def test_version_looks_like_semver_or_dev(self):
+        """__version__ should be a semver string or the dev fallback."""
+        from godotiq import __version__
+        assert re.match(r"^\d+\.\d+\.\d+", __version__) or __version__ == "0.0.0-dev"
+
+
+class TestPingUsesDynamicVersion:
+    """Verify godotiq_ping returns __version__ rather than a hardcoded string."""
+
+    @pytest.mark.asyncio
+    async def test_ping_version_matches_package_version(self):
+        """The version in godotiq_ping response must equal godotiq.__version__."""
+        from godotiq import __version__
+        from godotiq.server import mcp
+
+        result = await mcp.call_tool("godotiq_ping", {})
+        payload = json.loads(result[0].text)
+        assert payload["version"] == __version__
+
+    @pytest.mark.asyncio
+    async def test_ping_version_key_exists(self):
+        """godotiq_ping response must include a 'version' key."""
+        from godotiq.server import mcp
+
+        result = await mcp.call_tool("godotiq_ping", {})
+        payload = json.loads(result[0].text)
+        assert "version" in payload
