Merge feat/19: Rename package to gitea_mcp_remote and update configuration

This commit is contained in:
2026-02-03 18:00:38 -05:00
17 changed files with 46 additions and 44 deletions

View File

@@ -143,7 +143,7 @@ cp .env.example .env
nano .env nano .env
# Run the server # 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`). 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 pytest
# Run with coverage # Run with coverage
pytest --cov=gitea_http_wrapper pytest --cov=gitea_mcp_remote
# Run specific test file # Run specific test file
pytest src/gitea_http_wrapper/tests/test_config.py pytest src/gitea_mcp_remote/tests/test_config.py
``` ```
### Project Structure ### Project Structure
@@ -248,7 +248,7 @@ pytest src/gitea_http_wrapper/tests/test_config.py
``` ```
gitea-mcp-remote/ gitea-mcp-remote/
├── src/ ├── src/
│ └── gitea_http_wrapper/ │ └── gitea_mcp_remote/
│ ├── __init__.py │ ├── __init__.py
│ ├── server.py # Main HTTP server │ ├── server.py # Main HTTP server
│ ├── config/ │ ├── config/

View File

@@ -44,7 +44,7 @@ dev = [
] ]
[project.scripts] [project.scripts]
gitea-http-wrapper = "gitea_http_wrapper.server:main" gitea-mcp-remote = "gitea_mcp_remote.server:main"
[project.urls] [project.urls]
Homepage = "https://github.com/lmiranda/gitea-mcp-remote" Homepage = "https://github.com/lmiranda/gitea-mcp-remote"
@@ -55,7 +55,7 @@ where = ["src"]
[tool.pytest.ini_options] [tool.pytest.ini_options]
asyncio_mode = "auto" asyncio_mode = "auto"
testpaths = ["src/gitea_http_wrapper/tests"] testpaths = ["src/gitea_mcp_remote/tests"]
python_files = ["test_*.py"] python_files = ["test_*.py"]
python_classes = ["Test*"] python_classes = ["Test*"]
python_functions = ["test_*"] python_functions = ["test_*"]

View File

@@ -1,5 +1,5 @@
[pytest] [pytest]
testpaths = src/gitea_http_wrapper/tests testpaths = src/gitea_mcp_remote/tests
python_files = test_*.py python_files = test_*.py
python_classes = Test* python_classes = Test*
python_functions = test_* python_functions = test_*

View File

@@ -1,5 +0,0 @@
"""Configuration loader module."""
from .settings import GiteaSettings, load_settings
__all__ = ["GiteaSettings", "load_settings"]

View File

@@ -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"]

View File

@@ -1,4 +1,4 @@
"""Configuration settings for Gitea HTTP MCP wrapper.""" """Configuration settings for Gitea MCP HTTP transport."""
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
@@ -30,18 +30,18 @@ class GiteaSettings(BaseSettings):
..., ...,
description="Default repository owner/organization", description="Default repository owner/organization",
) )
gitea_repo: str = Field( gitea_repo: str | None = Field(
..., default=None,
description="Default repository name", description="Default repository name (optional)",
) )
# HTTP Server Configuration # HTTP Server Configuration
http_host: str = Field( http_host: str = Field(
default="127.0.0.1", default="0.0.0.0",
description="HTTP server bind address", description="HTTP server bind address",
) )
http_port: int = Field( http_port: int = Field(
default=8000, default=8080,
ge=1, ge=1,
le=65535, le=65535,
description="HTTP server port", description="HTTP server port",
@@ -52,6 +52,10 @@ class GiteaSettings(BaseSettings):
default=None, default=None,
description="Bearer token for HTTP authentication (optional)", 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 # Tool Filtering Configuration
enabled_tools: Optional[str] = Field( enabled_tools: Optional[str] = Field(
@@ -85,15 +89,6 @@ class GiteaSettings(BaseSettings):
return None return None
return [tool.strip() for tool in self.disabled_tools.split(",") if tool.strip()] 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: def load_settings(env_file: Optional[Path] = None) -> GiteaSettings:
""" """

View File

@@ -1,7 +1,10 @@
"""Tool filtering for Claude Desktop compatibility.""" """Tool filtering for Claude Desktop compatibility."""
import logging
from typing import Any from typing import Any
logger = logging.getLogger(__name__)
class ToolFilter: class ToolFilter:
""" """
@@ -22,13 +25,11 @@ class ToolFilter:
Args: Args:
enabled_tools: List of tool names to enable. If None, all tools are enabled. 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. 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: if enabled_tools is not None and disabled_tools is not None:
raise ValueError( logger.warning(
"Cannot specify both enabled_tools and disabled_tools. Choose one filtering mode." "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 self.enabled_tools = set(enabled_tools) if enabled_tools else None

View File

@@ -16,9 +16,9 @@ from starlette.requests import Request
from starlette.responses import JSONResponse from starlette.responses import JSONResponse
from starlette.routing import Route from starlette.routing import Route
from gitea_http_wrapper.config import GiteaSettings, load_settings from gitea_mcp_remote.config import GiteaSettings, load_settings
from gitea_http_wrapper.filtering import ToolFilter from gitea_mcp_remote.filtering import ToolFilter
from gitea_http_wrapper.middleware import ( from gitea_mcp_remote.middleware import (
BearerAuthMiddleware, BearerAuthMiddleware,
HealthCheckBypassMiddleware, HealthCheckBypassMiddleware,
) )
@@ -298,7 +298,7 @@ def main() -> None:
# Run server # Run server
uvicorn.run( uvicorn.run(
"gitea_http_wrapper.server:app", "gitea_mcp_remote.server:app",
host=settings.http_host, host=settings.http_host,
port=settings.http_port, port=settings.http_port,
log_level="info", log_level="info",

View File

@@ -6,7 +6,7 @@ from pathlib import Path
import pytest import pytest
from pydantic import ValidationError from pydantic import ValidationError
from gitea_http_wrapper.config import GiteaSettings, load_settings from gitea_mcp_remote.config import GiteaSettings, load_settings
class TestGiteaSettings: class TestGiteaSettings:

View File

@@ -2,18 +2,24 @@
import pytest import pytest
from gitea_http_wrapper.filtering import ToolFilter from gitea_mcp_remote.filtering import ToolFilter
class TestToolFilter: class TestToolFilter:
"""Test ToolFilter class.""" """Test ToolFilter class."""
def test_init_with_both_lists_raises(self): def test_init_with_both_lists_logs_warning(self, caplog):
"""Test that specifying both enabled and disabled lists raises error.""" """Test that specifying both enabled and disabled lists logs warning."""
with pytest.raises(ValueError) as exc_info: import logging
ToolFilter(enabled_tools=["tool1"], disabled_tools=["tool2"])
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): def test_passthrough_mode(self):
"""Test passthrough mode (no filtering).""" """Test passthrough mode (no filtering)."""

View File

@@ -6,7 +6,7 @@ from starlette.responses import JSONResponse
from starlette.routing import Route from starlette.routing import Route
from starlette.testclient import TestClient from starlette.testclient import TestClient
from gitea_http_wrapper.middleware import ( from gitea_mcp_remote.middleware import (
BearerAuthMiddleware, BearerAuthMiddleware,
HealthCheckBypassMiddleware, HealthCheckBypassMiddleware,
) )