[PATCH 22/23] mcp-server: Restructure as Python package with dynamic paths

John Kacur <[email protected]>
Newsgroups org.kernel.vger.linux-rt-users
Message-ID <[email protected]>
Restructure the MCP server into a standard Python package to enable
both development and system installation scenarios.

Directory and file changes:
- Rename mcp-server/ to rteval_mcp/ (Python package naming convention)
- Rename server.py to rteval_server.py (avoid naming conflicts)
- Add __init__.py with package metadata
- Add __main__.py to enable 'python3 -m rteval_mcp' execution
- Create rteval-mcp-server wrapper script for command-line execution
- Update all test imports from 'server' to 'rteval_server'

Configuration files now use relative paths instead of hardcoded paths:
- manifest.json: ./rteval_mcp/rteval-mcp-server
- .claude-plugin/plugin.json: ./rteval_mcp/rteval-mcp-server

The wrapper script dynamically calculates paths:
- Finds its own location using BASH_SOURCE
- Sets PYTHONPATH only when running from git (detects .git directory)
- For system installations, relies on standard site-packages location

This approach supports both development from git (./rteval-cmd pattern)
and future system packaging without path conflicts.

Assisted-by: Claude:claude-sonnet-4-5
Signed-off-by: John Kacur <[email protected]>
---
 .../.claude-plugin/plugin.json                |  6 ++--
 {mcp-server => rteval_mcp}/DEMO.md            |  0
 {mcp-server => rteval_mcp}/DEPENDENCIES.md    |  0
 {mcp-server => rteval_mcp}/Makefile           |  0
 {mcp-server => rteval_mcp}/README.md          |  4 +--
 rteval_mcp/__init__.py                        | 13 ++++++++
 rteval_mcp/__main__.py                        | 33 +++++++++++++++++++
 {mcp-server => rteval_mcp}/manifest.json      |  8 ++---
 rteval_mcp/rteval-mcp-server                  | 21 ++++++++++++
 .../server.py => rteval_mcp/rteval_server.py  |  0
 .../tests/test_histogram.py                   |  4 +--
 .../tests/test_mcp_integration.py             |  4 +--
 .../tests/test_new_tools.py                   |  4 +--
 .../tests/test_per_cpu_stats.py               |  4 +--
 14 files changed, 82 insertions(+), 19 deletions(-)
 rename {mcp-server => rteval_mcp}/.claude-plugin/plugin.json (79%)
 rename {mcp-server => rteval_mcp}/DEMO.md (100%)
 rename {mcp-server => rteval_mcp}/DEPENDENCIES.md (100%)
 rename {mcp-server => rteval_mcp}/Makefile (100%)
 rename {mcp-server => rteval_mcp}/README.md (99%)
 create mode 100644 rteval_mcp/__init__.py
 create mode 100644 rteval_mcp/__main__.py
 rename {mcp-server => rteval_mcp}/manifest.json (70%)
 create mode 100755 rteval_mcp/rteval-mcp-server
 rename mcp-server/server.py => rteval_mcp/rteval_server.py (100%)
 rename {mcp-server => rteval_mcp}/tests/test_histogram.py (95%)
 rename {mcp-server => rteval_mcp}/tests/test_mcp_integration.py (98%)
 rename {mcp-server => rteval_mcp}/tests/test_new_tools.py (97%)
 rename {mcp-server => rteval_mcp}/tests/test_per_cpu_stats.py (97%)

diff --git a/mcp-server/.claude-plugin/plugin.json b/rteval_mcp/.claude-plugin/plugin.json
similarity index 79%
rename from mcp-server/.claude-plugin/plugin.json
rename to rteval_mcp/.claude-plugin/plugin.json
index c3469c048524..e48d8c95c655 100644
--- a/mcp-server/.claude-plugin/plugin.json
+++ b/rteval_mcp/.claude-plugin/plugin.json
@@ -10,10 +10,8 @@
   "keywords": ["rteval", "real-time", "latency", "testing", "timerlat", "cyclictest"],
   "mcpServers": {
     "rteval-mcp": {
-      "command": "python3",
-      "args": [
-        "/home/jkacur/src/rteval/mcp-server/server.py"
-      ],
+      "command": "./rteval_mcp/rteval-mcp-server",
+      "args": [],
       "env": {}
     }
   }
diff --git a/mcp-server/DEMO.md b/rteval_mcp/DEMO.md
similarity index 100%
rename from mcp-server/DEMO.md
rename to rteval_mcp/DEMO.md
diff --git a/mcp-server/DEPENDENCIES.md b/rteval_mcp/DEPENDENCIES.md
similarity index 100%
rename from mcp-server/DEPENDENCIES.md
rename to rteval_mcp/DEPENDENCIES.md
diff --git a/mcp-server/Makefile b/rteval_mcp/Makefile
similarity index 100%
rename from mcp-server/Makefile
rename to rteval_mcp/Makefile
diff --git a/mcp-server/README.md b/rteval_mcp/README.md
similarity index 99%
rename from mcp-server/README.md
rename to rteval_mcp/README.md
index 370aa0e9ca71..fc54c8074754 100644
--- a/mcp-server/README.md
+++ b/rteval_mcp/README.md
@@ -74,7 +74,7 @@ sudo dnf install python3-mcp python3-mcp+cli python3-lxml
 The MCP server includes a test suite to verify functionality:
 
 ```bash
-cd mcp-server
+cd rteval_mcp
 
 # Run all tests
 make test
@@ -157,7 +157,7 @@ Which CPUs have the most variable latency?
 ### Using with MCP Inspector
 
 ```bash
-mcp dev server.py
+mcp dev rteval-mcp-server
 ```
 
 ## Complete Tool Usage Guide
diff --git a/rteval_mcp/__init__.py b/rteval_mcp/__init__.py
new file mode 100644
index 000000000000..390f2bd0f8c0
--- /dev/null
+++ b/rteval_mcp/__init__.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+#   rteval MCP Server package
+#
+#   Copyright 2026   John Kacur <[email protected]>
+#
+"""rteval MCP Server - tools for analyzing rteval results."""
+
+__version__ = "0.1.0"
+__author__ = "John Kacur"
+__email__ = "[email protected]"
diff --git a/rteval_mcp/__main__.py b/rteval_mcp/__main__.py
new file mode 100644
index 000000000000..2a027c57b0c9
--- /dev/null
+++ b/rteval_mcp/__main__.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+#   rteval MCP Server entry point
+#
+#   Copyright 2026   John Kacur <[email protected]>
+#
+"""Entry point for running rteval MCP server as a module."""
+
+import sys
+import asyncio
+from pathlib import Path
+
+# Add package directory to path for development mode
+package_dir = Path(__file__).parent
+sys.path.insert(0, str(package_dir))
+
+from rteval_server import app, stdio_server
+
+
+async def main():
+    """Run the MCP server."""
+    async with stdio_server() as (read_stream, write_stream):
+        await app.run(
+            read_stream,
+            write_stream,
+            app.create_initialization_options()
+        )
+
+
+if __name__ == "__main__":
+    asyncio.run(main())
diff --git a/mcp-server/manifest.json b/rteval_mcp/manifest.json
similarity index 70%
rename from mcp-server/manifest.json
rename to rteval_mcp/manifest.json
index 6127dcd26774..a04732245efa 100644
--- a/mcp-server/manifest.json
+++ b/rteval_mcp/manifest.json
@@ -9,12 +9,10 @@
   },
   "server": {
     "type": "python",
-    "entry_point": "server.py",
+    "entry_point": "rteval-mcp-server",
     "mcp_config": {
-      "command": "python3",
-      "args": [
-        "/home/jkacur/src/rteval/mcp-server/server.py"
-      ]
+      "command": "./rteval_mcp/rteval-mcp-server",
+      "args": []
     }
   }
 }
diff --git a/rteval_mcp/rteval-mcp-server b/rteval_mcp/rteval-mcp-server
new file mode 100755
index 000000000000..34ce8a4d0e43
--- /dev/null
+++ b/rteval_mcp/rteval-mcp-server
@@ -0,0 +1,21 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# rteval MCP Server wrapper script
+#
+# Copyright 2026 John Kacur <[email protected]>
+#
+# This wrapper executes the rteval MCP server as a Python module.
+# It works for both development (local git) and installed (system) versions.
+
+# Find the directory containing this script
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+# Parent directory is where Python should search for rteval_mcp module
+PARENT_DIR="$(dirname "$SCRIPT_DIR")"
+
+# Only set PYTHONPATH if running from a git development tree
+if [ -d "${PARENT_DIR}/.git" ]; then
+    export PYTHONPATH="${PARENT_DIR}:${PYTHONPATH}"
+fi
+
+exec python3 -m rteval_mcp "$@"
diff --git a/mcp-server/server.py b/rteval_mcp/rteval_server.py
similarity index 100%
rename from mcp-server/server.py
rename to rteval_mcp/rteval_server.py
diff --git a/mcp-server/tests/test_histogram.py b/rteval_mcp/tests/test_histogram.py
similarity index 95%
rename from mcp-server/tests/test_histogram.py
rename to rteval_mcp/tests/test_histogram.py
index 917afb1aac93..c15763663958 100644
--- a/mcp-server/tests/test_histogram.py
+++ b/rteval_mcp/tests/test_histogram.py
@@ -13,9 +13,9 @@ Test script for histogram extraction and percentile calculation.
 import sys
 from pathlib import Path
 
-# Add parent directory to path to import server module
+# Add parent directory to path to import rteval_server module
 sys.path.insert(0, str(Path(__file__).parent.parent))
-from server import extract_histogram_data, calculate_percentiles
+from rteval_server import extract_histogram_data, calculate_percentiles
 
 # Find test file relative to script location
 # From tests/ -> mcp-server/ -> rteval/
diff --git a/mcp-server/tests/test_mcp_integration.py b/rteval_mcp/tests/test_mcp_integration.py
similarity index 98%
rename from mcp-server/tests/test_mcp_integration.py
rename to rteval_mcp/tests/test_mcp_integration.py
index 0b5f2954a16f..543f4ea7c249 100644
--- a/mcp-server/tests/test_mcp_integration.py
+++ b/rteval_mcp/tests/test_mcp_integration.py
@@ -16,9 +16,9 @@ import sys
 import asyncio
 from pathlib import Path
 
-# Add parent directory to path to import server module
+# Add parent directory to path to import rteval_server module
 sys.path.insert(0, str(Path(__file__).parent.parent))
-from server import call_tool, list_tools
+from rteval_server import call_tool, list_tools
 
 
 def find_test_data():
diff --git a/mcp-server/tests/test_new_tools.py b/rteval_mcp/tests/test_new_tools.py
similarity index 97%
rename from mcp-server/tests/test_new_tools.py
rename to rteval_mcp/tests/test_new_tools.py
index a81b23bbffbb..b178146d3e4d 100644
--- a/mcp-server/tests/test_new_tools.py
+++ b/rteval_mcp/tests/test_new_tools.py
@@ -12,9 +12,9 @@ import sys
 import asyncio
 from pathlib import Path
 
-# Add parent directory to path to import server module
+# Add parent directory to path to import rteval_server module
 sys.path.insert(0, str(Path(__file__).parent.parent))
-from server import extract_rteval_data
+from rteval_server import extract_rteval_data
 
 
 async def test_find_best_worst():
diff --git a/mcp-server/tests/test_per_cpu_stats.py b/rteval_mcp/tests/test_per_cpu_stats.py
similarity index 97%
rename from mcp-server/tests/test_per_cpu_stats.py
rename to rteval_mcp/tests/test_per_cpu_stats.py
index 6ec07dbf39fe..851cbd710165 100644
--- a/mcp-server/tests/test_per_cpu_stats.py
+++ b/rteval_mcp/tests/test_per_cpu_stats.py
@@ -12,9 +12,9 @@ import sys
 import asyncio
 from pathlib import Path
 
-# Add parent directory to path to import server module
+# Add parent directory to path to import rteval_server module
 sys.path.insert(0, str(Path(__file__).parent.parent))
-from server import call_tool
+from rteval_server import call_tool
 
 
 async def main():
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.