Implement configuration loader module

This commit implements a robust configuration loader using Pydantic Settings that handles:

Features:
- Environment variable loading with .env file support
- Type validation and field constraints
- Gitea configuration (URL, token, owner, repo)
- HTTP server configuration (host, port)
- Optional HTTP authentication token
- Optional tool filtering (enabled/disabled tool lists)

Implementation:
- GiteaSettings class with Pydantic validation
- URL validation ensuring http:// or https:// prefix
- Helper properties for parsing comma-separated tool lists
- get_gitea_mcp_env() method to pass config to wrapped MCP server
- load_settings() factory function with optional env_file path

Documentation:
- .env.example template with all configuration options
- Comprehensive docstrings and type hints

This module unblocks both the tool filtering (#12) and HTTP authentication middleware (#13) implementations.

Closes #11

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-03 16:07:40 -05:00
parent b041d1568a
commit 6c8e6b4b0a
3 changed files with 132 additions and 1 deletions

16
.env.example Normal file
View File

@@ -0,0 +1,16 @@
# Gitea Configuration
GITEA_URL=https://gitea.example.com
GITEA_TOKEN=your_gitea_api_token_here
GITEA_OWNER=your_username_or_org
GITEA_REPO=your_repo_name
# HTTP Server Configuration
HTTP_HOST=127.0.0.1
HTTP_PORT=8000
# Authentication Configuration (Optional)
# AUTH_TOKEN=your_bearer_token_here
# Tool Filtering Configuration (Optional)
# ENABLED_TOOLS=list_issues,create_issue,update_issue
# DISABLED_TOOLS=delete_issue,close_milestone

View File

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

View File

@@ -0,0 +1,113 @@
"""Configuration settings for Gitea HTTP MCP wrapper."""
from pathlib import Path
from typing import Optional
from pydantic import Field, field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict
class GiteaSettings(BaseSettings):
"""Configuration settings loaded from environment or .env file."""
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
case_sensitive=False,
extra="ignore",
)
# Gitea Configuration
gitea_url: str = Field(
...,
description="Gitea instance URL (e.g., https://git.example.com)",
)
gitea_token: str = Field(
...,
description="Gitea API token for authentication",
)
gitea_owner: str = Field(
...,
description="Default repository owner/organization",
)
gitea_repo: str = Field(
...,
description="Default repository name",
)
# HTTP Server Configuration
http_host: str = Field(
default="127.0.0.1",
description="HTTP server bind address",
)
http_port: int = Field(
default=8000,
ge=1,
le=65535,
description="HTTP server port",
)
# Authentication Configuration
auth_token: Optional[str] = Field(
default=None,
description="Bearer token for HTTP authentication (optional)",
)
# Tool Filtering Configuration
enabled_tools: Optional[str] = Field(
default=None,
description="Comma-separated list of enabled tools (optional, enables all if not set)",
)
disabled_tools: Optional[str] = Field(
default=None,
description="Comma-separated list of disabled tools (optional)",
)
@field_validator("gitea_url")
@classmethod
def validate_gitea_url(cls, v: str) -> str:
"""Ensure Gitea URL is properly formatted."""
if not v.startswith(("http://", "https://")):
raise ValueError("gitea_url must start with http:// or https://")
return v.rstrip("/")
@property
def enabled_tools_list(self) -> Optional[list[str]]:
"""Parse enabled_tools into a list."""
if not self.enabled_tools:
return None
return [tool.strip() for tool in self.enabled_tools.split(",") if tool.strip()]
@property
def disabled_tools_list(self) -> Optional[list[str]]:
"""Parse disabled_tools into a list."""
if not self.disabled_tools:
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:
"""
Load settings from environment or .env file.
Args:
env_file: Optional path to .env file. If not provided, searches for .env in current directory.
Returns:
GiteaSettings instance with loaded configuration.
Raises:
ValidationError: If required settings are missing or invalid.
"""
if env_file:
return GiteaSettings(_env_file=env_file)
return GiteaSettings()