From 507513984131e38c538ff347aa0d8747ec16ce0d Mon Sep 17 00:00:00 2001 From: lmiranda Date: Tue, 3 Feb 2026 17:59:57 -0500 Subject: [PATCH] refactor: Rename package to gitea_mcp_remote and update configuration Issue #19 - Foundation for Sprint 01: Core Architecture Correction Changes: - Renamed package directory: gitea_http_wrapper -> gitea_mcp_remote - Updated config/settings.py: - Made gitea_repo optional (allow None) - Added mcp_auth_mode field (default: "optional") - Changed HTTP defaults: 0.0.0.0:8080 (was 127.0.0.1:8000) - Removed get_gitea_mcp_env() method (no longer needed) - Updated all import paths throughout codebase - Updated filtering/filter.py: Changed ValueError to warning when both enabled_tools and disabled_tools are specified - Updated test files with new import paths - Updated test_filtering.py to test warning instead of ValueError - Updated pyproject.toml, pytest.ini, and README.md references All modules preserved - only import paths and configuration updated. Co-Authored-By: Claude Opus 4.5 --- README.md | 8 +++--- pyproject.toml | 4 +-- pytest.ini | 2 +- src/gitea_http_wrapper/config/__init__.py | 5 ---- .../__init__.py | 0 src/gitea_mcp_remote/config/__init__.py | 5 ++++ .../config/settings.py | 25 ++++++++----------- .../filtering/__init__.py | 0 .../filtering/filter.py | 11 ++++---- .../middleware/__init__.py | 0 .../middleware/auth.py | 0 .../server.py | 8 +++--- .../tests/__init__.py | 0 .../tests/conftest.py | 0 .../tests/test_config.py | 2 +- .../tests/test_filtering.py | 18 ++++++++----- .../tests/test_middleware.py | 2 +- 17 files changed, 46 insertions(+), 44 deletions(-) delete mode 100644 src/gitea_http_wrapper/config/__init__.py rename src/{gitea_http_wrapper => gitea_mcp_remote}/__init__.py (100%) create mode 100644 src/gitea_mcp_remote/config/__init__.py rename src/{gitea_http_wrapper => gitea_mcp_remote}/config/settings.py (84%) rename src/{gitea_http_wrapper => gitea_mcp_remote}/filtering/__init__.py (100%) rename src/{gitea_http_wrapper => gitea_mcp_remote}/filtering/filter.py (93%) rename src/{gitea_http_wrapper => gitea_mcp_remote}/middleware/__init__.py (100%) rename src/{gitea_http_wrapper => gitea_mcp_remote}/middleware/auth.py (100%) rename src/{gitea_http_wrapper => gitea_mcp_remote}/server.py (97%) rename src/{gitea_http_wrapper => gitea_mcp_remote}/tests/__init__.py (100%) rename src/{gitea_http_wrapper => gitea_mcp_remote}/tests/conftest.py (100%) rename src/{gitea_http_wrapper => gitea_mcp_remote}/tests/test_config.py (99%) rename src/{gitea_http_wrapper => gitea_mcp_remote}/tests/test_filtering.py (89%) rename src/{gitea_http_wrapper => gitea_mcp_remote}/tests/test_middleware.py (99%) diff --git a/README.md b/README.md index 928a2e1..ff59196 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,7 @@ cp .env.example .env nano .env # Run the server -gitea-http-wrapper +gitea-mcp-remote ``` The server will start on the configured host/port (default: `http://127.0.0.1:8000`). @@ -237,10 +237,10 @@ pip install -e ".[dev]" pytest # Run with coverage -pytest --cov=gitea_http_wrapper +pytest --cov=gitea_mcp_remote # Run specific test file -pytest src/gitea_http_wrapper/tests/test_config.py +pytest src/gitea_mcp_remote/tests/test_config.py ``` ### Project Structure @@ -248,7 +248,7 @@ pytest src/gitea_http_wrapper/tests/test_config.py ``` gitea-mcp-remote/ ├── src/ -│ └── gitea_http_wrapper/ +│ └── gitea_mcp_remote/ │ ├── __init__.py │ ├── server.py # Main HTTP server │ ├── config/ diff --git a/pyproject.toml b/pyproject.toml index dac0c8a..6525281 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,7 +44,7 @@ dev = [ ] [project.scripts] -gitea-http-wrapper = "gitea_http_wrapper.server:main" +gitea-mcp-remote = "gitea_mcp_remote.server:main" [project.urls] Homepage = "https://github.com/lmiranda/gitea-mcp-remote" @@ -55,7 +55,7 @@ where = ["src"] [tool.pytest.ini_options] asyncio_mode = "auto" -testpaths = ["src/gitea_http_wrapper/tests"] +testpaths = ["src/gitea_mcp_remote/tests"] python_files = ["test_*.py"] python_classes = ["Test*"] python_functions = ["test_*"] diff --git a/pytest.ini b/pytest.ini index f1aa661..2b370ea 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,5 +1,5 @@ [pytest] -testpaths = src/gitea_http_wrapper/tests +testpaths = src/gitea_mcp_remote/tests python_files = test_*.py python_classes = Test* python_functions = test_* diff --git a/src/gitea_http_wrapper/config/__init__.py b/src/gitea_http_wrapper/config/__init__.py deleted file mode 100644 index 9f9ee4a..0000000 --- a/src/gitea_http_wrapper/config/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -"""Configuration loader module.""" - -from .settings import GiteaSettings, load_settings - -__all__ = ["GiteaSettings", "load_settings"] diff --git a/src/gitea_http_wrapper/__init__.py b/src/gitea_mcp_remote/__init__.py similarity index 100% rename from src/gitea_http_wrapper/__init__.py rename to src/gitea_mcp_remote/__init__.py diff --git a/src/gitea_mcp_remote/config/__init__.py b/src/gitea_mcp_remote/config/__init__.py new file mode 100644 index 0000000..5b7062b --- /dev/null +++ b/src/gitea_mcp_remote/config/__init__.py @@ -0,0 +1,5 @@ +"""Configuration module for Gitea MCP HTTP transport.""" + +from gitea_mcp_remote.config.settings import GiteaSettings, load_settings + +__all__ = ["GiteaSettings", "load_settings"] diff --git a/src/gitea_http_wrapper/config/settings.py b/src/gitea_mcp_remote/config/settings.py similarity index 84% rename from src/gitea_http_wrapper/config/settings.py rename to src/gitea_mcp_remote/config/settings.py index 5dd7374..9041327 100644 --- a/src/gitea_http_wrapper/config/settings.py +++ b/src/gitea_mcp_remote/config/settings.py @@ -1,4 +1,4 @@ -"""Configuration settings for Gitea HTTP MCP wrapper.""" +"""Configuration settings for Gitea MCP HTTP transport.""" from pathlib import Path from typing import Optional @@ -30,18 +30,18 @@ class GiteaSettings(BaseSettings): ..., description="Default repository owner/organization", ) - gitea_repo: str = Field( - ..., - description="Default repository name", + gitea_repo: str | None = Field( + default=None, + description="Default repository name (optional)", ) # HTTP Server Configuration http_host: str = Field( - default="127.0.0.1", + default="0.0.0.0", description="HTTP server bind address", ) http_port: int = Field( - default=8000, + default=8080, ge=1, le=65535, description="HTTP server port", @@ -52,6 +52,10 @@ class GiteaSettings(BaseSettings): default=None, description="Bearer token for HTTP authentication (optional)", ) + mcp_auth_mode: str = Field( + default="optional", + description="MCP authentication mode: 'required', 'optional', or 'none'", + ) # Tool Filtering Configuration enabled_tools: Optional[str] = Field( @@ -85,15 +89,6 @@ class GiteaSettings(BaseSettings): return None return [tool.strip() for tool in self.disabled_tools.split(",") if tool.strip()] - def get_gitea_mcp_env(self) -> dict[str, str]: - """Get environment variables for the wrapped Gitea MCP server.""" - return { - "GITEA_BASE_URL": self.gitea_url, - "GITEA_API_TOKEN": self.gitea_token, - "GITEA_DEFAULT_OWNER": self.gitea_owner, - "GITEA_DEFAULT_REPO": self.gitea_repo, - } - def load_settings(env_file: Optional[Path] = None) -> GiteaSettings: """ diff --git a/src/gitea_http_wrapper/filtering/__init__.py b/src/gitea_mcp_remote/filtering/__init__.py similarity index 100% rename from src/gitea_http_wrapper/filtering/__init__.py rename to src/gitea_mcp_remote/filtering/__init__.py diff --git a/src/gitea_http_wrapper/filtering/filter.py b/src/gitea_mcp_remote/filtering/filter.py similarity index 93% rename from src/gitea_http_wrapper/filtering/filter.py rename to src/gitea_mcp_remote/filtering/filter.py index 01999c6..e8e6bfa 100644 --- a/src/gitea_http_wrapper/filtering/filter.py +++ b/src/gitea_mcp_remote/filtering/filter.py @@ -1,7 +1,10 @@ """Tool filtering for Claude Desktop compatibility.""" +import logging from typing import Any +logger = logging.getLogger(__name__) + class ToolFilter: """ @@ -22,13 +25,11 @@ class ToolFilter: Args: enabled_tools: List of tool names to enable. If None, all tools are enabled. disabled_tools: List of tool names to disable. Takes precedence over enabled_tools. - - Raises: - ValueError: If both enabled_tools and disabled_tools are specified. """ if enabled_tools is not None and disabled_tools is not None: - raise ValueError( - "Cannot specify both enabled_tools and disabled_tools. Choose one filtering mode." + logger.warning( + "Both enabled_tools and disabled_tools specified. " + "Disabled list takes precedence over enabled list." ) self.enabled_tools = set(enabled_tools) if enabled_tools else None diff --git a/src/gitea_http_wrapper/middleware/__init__.py b/src/gitea_mcp_remote/middleware/__init__.py similarity index 100% rename from src/gitea_http_wrapper/middleware/__init__.py rename to src/gitea_mcp_remote/middleware/__init__.py diff --git a/src/gitea_http_wrapper/middleware/auth.py b/src/gitea_mcp_remote/middleware/auth.py similarity index 100% rename from src/gitea_http_wrapper/middleware/auth.py rename to src/gitea_mcp_remote/middleware/auth.py diff --git a/src/gitea_http_wrapper/server.py b/src/gitea_mcp_remote/server.py similarity index 97% rename from src/gitea_http_wrapper/server.py rename to src/gitea_mcp_remote/server.py index 8155f0b..397a5d2 100644 --- a/src/gitea_http_wrapper/server.py +++ b/src/gitea_mcp_remote/server.py @@ -16,9 +16,9 @@ from starlette.requests import Request from starlette.responses import JSONResponse from starlette.routing import Route -from gitea_http_wrapper.config import GiteaSettings, load_settings -from gitea_http_wrapper.filtering import ToolFilter -from gitea_http_wrapper.middleware import ( +from gitea_mcp_remote.config import GiteaSettings, load_settings +from gitea_mcp_remote.filtering import ToolFilter +from gitea_mcp_remote.middleware import ( BearerAuthMiddleware, HealthCheckBypassMiddleware, ) @@ -298,7 +298,7 @@ def main() -> None: # Run server uvicorn.run( - "gitea_http_wrapper.server:app", + "gitea_mcp_remote.server:app", host=settings.http_host, port=settings.http_port, log_level="info", diff --git a/src/gitea_http_wrapper/tests/__init__.py b/src/gitea_mcp_remote/tests/__init__.py similarity index 100% rename from src/gitea_http_wrapper/tests/__init__.py rename to src/gitea_mcp_remote/tests/__init__.py diff --git a/src/gitea_http_wrapper/tests/conftest.py b/src/gitea_mcp_remote/tests/conftest.py similarity index 100% rename from src/gitea_http_wrapper/tests/conftest.py rename to src/gitea_mcp_remote/tests/conftest.py diff --git a/src/gitea_http_wrapper/tests/test_config.py b/src/gitea_mcp_remote/tests/test_config.py similarity index 99% rename from src/gitea_http_wrapper/tests/test_config.py rename to src/gitea_mcp_remote/tests/test_config.py index 812ae80..156d29a 100644 --- a/src/gitea_http_wrapper/tests/test_config.py +++ b/src/gitea_mcp_remote/tests/test_config.py @@ -6,7 +6,7 @@ from pathlib import Path import pytest from pydantic import ValidationError -from gitea_http_wrapper.config import GiteaSettings, load_settings +from gitea_mcp_remote.config import GiteaSettings, load_settings class TestGiteaSettings: diff --git a/src/gitea_http_wrapper/tests/test_filtering.py b/src/gitea_mcp_remote/tests/test_filtering.py similarity index 89% rename from src/gitea_http_wrapper/tests/test_filtering.py rename to src/gitea_mcp_remote/tests/test_filtering.py index 69069fe..d078e68 100644 --- a/src/gitea_http_wrapper/tests/test_filtering.py +++ b/src/gitea_mcp_remote/tests/test_filtering.py @@ -2,18 +2,24 @@ import pytest -from gitea_http_wrapper.filtering import ToolFilter +from gitea_mcp_remote.filtering import ToolFilter class TestToolFilter: """Test ToolFilter class.""" - def test_init_with_both_lists_raises(self): - """Test that specifying both enabled and disabled lists raises error.""" - with pytest.raises(ValueError) as exc_info: - ToolFilter(enabled_tools=["tool1"], disabled_tools=["tool2"]) + def test_init_with_both_lists_logs_warning(self, caplog): + """Test that specifying both enabled and disabled lists logs warning.""" + import logging - assert "Cannot specify both" in str(exc_info.value) + with caplog.at_level(logging.WARNING): + filter = ToolFilter(enabled_tools=["tool1"], disabled_tools=["tool2"]) + + assert "Both enabled_tools and disabled_tools specified" in caplog.text + assert "Disabled list takes precedence" in caplog.text + + # Verify disabled list takes precedence + assert not filter.should_include_tool("tool2") def test_passthrough_mode(self): """Test passthrough mode (no filtering).""" diff --git a/src/gitea_http_wrapper/tests/test_middleware.py b/src/gitea_mcp_remote/tests/test_middleware.py similarity index 99% rename from src/gitea_http_wrapper/tests/test_middleware.py rename to src/gitea_mcp_remote/tests/test_middleware.py index 30baddc..8d3db82 100644 --- a/src/gitea_http_wrapper/tests/test_middleware.py +++ b/src/gitea_mcp_remote/tests/test_middleware.py @@ -6,7 +6,7 @@ from starlette.responses import JSONResponse from starlette.routing import Route from starlette.testclient import TestClient -from gitea_http_wrapper.middleware import ( +from gitea_mcp_remote.middleware import ( BearerAuthMiddleware, HealthCheckBypassMiddleware, )