Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ class TestExampleService:
def test_with_database(db_session):
"""Test using database session fixture."""
# db_session is automatically provided by conftest.py
from mcpgateway.models import Tool
from mcpgateway.common.models import Tool
tool = Tool(name="test_tool")
db_session.add(tool)
db_session.commit()
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/architecture/multitenancy.md
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ For emergency password resets, you can update the database directly:
python3 -c "
from mcpgateway.services.argon2_service import Argon2PasswordService
from mcpgateway.db import SessionLocal
from mcpgateway.models import EmailUser
from mcpgateway.common.models import EmailUser
service = Argon2PasswordService()
hashed = service.hash_password('new_password')
Expand Down
2 changes: 1 addition & 1 deletion mcpgateway/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@
from starlette.datastructures import UploadFile as StarletteUploadFile

# First-Party
from mcpgateway.common.models import LogLevel
from mcpgateway.config import settings
from mcpgateway.db import get_db, GlobalConfig
from mcpgateway.db import Tool as DbTool
from mcpgateway.middleware.rbac import get_current_user_with_permissions, require_permission
from mcpgateway.models import LogLevel
from mcpgateway.schemas import (
A2AAgentCreate,
A2AAgentRead,
Expand Down
2 changes: 1 addition & 1 deletion mcpgateway/cache/session_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@

# First-Party
from mcpgateway import __version__
from mcpgateway.common.models import Implementation, InitializeResult, ServerCapabilities
from mcpgateway.config import settings
from mcpgateway.db import get_db, SessionMessageRecord, SessionRecord
from mcpgateway.models import Implementation, InitializeResult, ServerCapabilities
from mcpgateway.services import PromptService, ResourceService, ToolService
from mcpgateway.services.logging_service import LoggingService
from mcpgateway.transports import SSETransport
Expand Down
8 changes: 8 additions & 0 deletions mcpgateway/common/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
"""Location: ./mcpgateway/common/__init__.py
Copyright 2025
SPDX-License-Identifier: Apache-2.0
Authors: Teryl Taylor
Common ContextForge package for shared classes and functions.
"""
104 changes: 104 additions & 0 deletions mcpgateway/common/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# -*- coding: utf-8 -*-
"""Location: ./mcpgateway/config.py
Copyright 2025
SPDX-License-Identifier: Apache-2.0
Authors: Mihai Criveti, Manav Gupta

Common MCP Gateway Configuration settings used across subpackages.
This module defines configuration settings for the MCP Gateway using Pydantic.
It loads configuration from environment variables with sensible defaults.
"""

# Standard
from functools import lru_cache

# Third-Party
from pydantic_settings import BaseSettings


class Settings(BaseSettings):
"""Validation settings for the security validator."""

# Validation patterns for safe display (configurable)
validation_dangerous_html_pattern: str = (
r"<(script|iframe|object|embed|link|meta|base|form|img|svg|video|audio|source|track|area|map|canvas|applet|frame|frameset|html|head|body|style)\b|</*(script|iframe|object|embed|link|meta|base|form|img|svg|video|audio|source|track|area|map|canvas|applet|frame|frameset|html|head|body|style)>"
)

validation_dangerous_js_pattern: str = r"(?i)(?:^|\s|[\"'`<>=])(javascript:|vbscript:|data:\s*[^,]*[;\s]*(javascript|vbscript)|\bon[a-z]+\s*=|<\s*script\b)"

validation_allowed_url_schemes: list[str] = ["http://", "https://", "ws://", "wss://"]

# Character validation patterns
validation_name_pattern: str = r"^[a-zA-Z0-9_.\-\s]+$" # Allow spaces for names
validation_identifier_pattern: str = r"^[a-zA-Z0-9_\-\.]+$" # No spaces for IDs
validation_safe_uri_pattern: str = r"^[a-zA-Z0-9_\-.:/?=&%]+$"
validation_unsafe_uri_pattern: str = r'[<>"\'\\]'
validation_tool_name_pattern: str = r"^[a-zA-Z][a-zA-Z0-9._-]*$" # MCP tool naming
validation_tool_method_pattern: str = r"^[a-zA-Z][a-zA-Z0-9_\./-]*$"

# MCP-compliant size limits (configurable via env)
validation_max_name_length: int = 255
validation_max_description_length: int = 8192 # 8KB
validation_max_template_length: int = 65536 # 64KB
validation_max_content_length: int = 1048576 # 1MB
validation_max_json_depth: int = 10
validation_max_url_length: int = 2048
validation_max_rpc_param_size: int = 262144 # 256KB

validation_max_method_length: int = 128

# Allowed MIME types
validation_allowed_mime_types: list[str] = [
"text/plain",
"text/html",
"text/css",
"text/markdown",
"text/javascript",
"application/json",
"application/xml",
"application/pdf",
"image/png",
"image/jpeg",
"image/gif",
"image/svg+xml",
"application/octet-stream",
]

# Rate limiting
validation_max_requests_per_minute: int = 60

# CLI settings
plugins_cli_markup_mode: str | None = None
plugins_cli_completion: bool = True


@lru_cache()
def get_settings() -> Settings:
"""Get cached settings instance.

Returns:
Settings: A cached instance of the Settings class.

Examples:
>>> settings = get_settings()
>>> isinstance(settings, Settings)
True
>>> # Second call returns the same cached instance
>>> settings2 = get_settings()
>>> settings is settings2
True
"""
# Instantiate a fresh Pydantic Settings object,
# loading from env vars or .env exactly once.
cfg = Settings()
# Validate that transport_type is correct; will
# raise if mis-configured.
# cfg.validate_transport()
# Ensure sqlite DB directories exist if needed.
# cfg.validate_database()
# Return the one-and-only Settings instance (cached).
return cfg


# Create settings instance
settings = get_settings()
19 changes: 18 additions & 1 deletion mcpgateway/models.py → mcpgateway/common/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
- Capability definitions

Examples:
>>> from mcpgateway.models import Role, LogLevel, TextContent
>>> from mcpgateway.common.models import Role, LogLevel, TextContent
>>> Role.USER.value
'user'
>>> Role.ASSISTANT.value
Expand Down Expand Up @@ -1360,3 +1360,20 @@ class PermissionAudit(BaseModel):

# Permission constants are imported from db.py to avoid duplication
# Use Permissions class from mcpgateway.db instead of duplicate SystemPermissions


class TransportType(str, Enum):
"""
Enumeration of supported transport mechanisms for communication between components.

Attributes:
SSE (str): Server-Sent Events transport.
HTTP (str): Standard HTTP-based transport.
STDIO (str): Standard input/output transport.
STREAMABLEHTTP (str): HTTP transport with streaming.
"""

SSE = "SSE"
HTTP = "HTTP"
STDIO = "STDIO"
STREAMABLEHTTP = "STREAMABLEHTTP"
Loading
Loading