feat: update config & cors

This commit is contained in:
Sun-ZhenXing
2025-10-02 16:20:15 +08:00
parent 477888de17
commit 0ffc5b69b4
13 changed files with 273 additions and 208 deletions

View File

@@ -2,8 +2,6 @@ import sys
import click
from mcp_template_python.utils.log import UVICORN_LOGGING_CONFIG
from .__about__ import __module_name__, __version__
from .app import MCP_MAP
from .config import settings
@@ -27,7 +25,7 @@ def run_server(
host=host,
port=port,
reload=reload,
log_config=UVICORN_LOGGING_CONFIG,
log_config=None,
**kwargs,
)
@@ -41,8 +39,8 @@ def run_server(
@click.option(
"--mcp",
type=click.Choice(list(MCP_MAP.keys()), case_sensitive=False),
default=settings.default_mcp,
help=f"Select the MCP to run in STDIO mode (default: {settings.default_mcp})",
default=settings.mcp.default_mcp,
help=f"Select the MCP to run in STDIO mode (default: {settings.mcp.default_mcp})",
)
@click.option(
"--host",

View File

@@ -4,7 +4,7 @@ from mcp.server.fastmcp import FastMCP
from mcp_template_python.config import settings
mcp = FastMCP("math", instructions=settings.instructions)
mcp = FastMCP("math", instructions=settings.mcp.instructions)
@mcp.tool()

View File

@@ -0,0 +1,3 @@
from .app import settings
__all__ = ["settings"]

View File

@@ -0,0 +1,46 @@
from dotenv import load_dotenv
from pydantic_settings import BaseSettings, SettingsConfigDict
from mcp_template_python.config.cors import CORSSettings
from .mcp import MCPSettings
load_dotenv()
class AppSettings(BaseSettings):
"""
Configuration settings for the MCP template application.
"""
model_config = SettingsConfigDict(
env_prefix="APP_",
extra="allow",
)
mcp: MCPSettings = MCPSettings()
"""MCP settings, defaults to MCPSettings()."""
cors: CORSSettings = CORSSettings()
"""CORS settings, defaults to CORSSettings()."""
title: str = "MCP Template Application"
"""Title of the MCP application, defaults to 'MCP Template Application'."""
description: str = "A template application for MCP using FastAPI."
"""Description of the MCP application, defaults to 'A template application for MCP using FastAPI.'"""
default_host: str = "127.0.0.1"
"""Default host for the MCP server, defaults to 127.0.0.1."""
default_port: int = 3001
"""Default port for the MCP server, defaults to 3001."""
log_level: str = "INFO"
"""Logging level for the MCP server, defaults to 'info'."""
rich_console: bool = False
"""Enable rich console output, defaults to False."""
settings = AppSettings()

View File

@@ -0,0 +1,24 @@
from pydantic_settings import BaseSettings, SettingsConfigDict
class CORSSettings(BaseSettings):
"""
Configuration settings for CORS (Cross-Origin Resource Sharing).
"""
model_config = SettingsConfigDict(
env_prefix="CORS_",
extra="allow",
)
allow_origins: str = "*"
"""CORS allow origins, defaults to '*'."""
allow_credentials: bool = True
"""CORS allow credentials, defaults to True."""
allow_methods: str = "*"
"""CORS allow methods, defaults to '*'."""
allow_headers: str = "*"
"""CORS allow headers, defaults to '*'."""

View File

@@ -1,10 +1,7 @@
from dotenv import load_dotenv
from pydantic_settings import BaseSettings, SettingsConfigDict
load_dotenv()
class Settings(BaseSettings):
class MCPSettings(BaseSettings):
"""
Configuration settings for the MCP template application.
"""
@@ -14,21 +11,9 @@ class Settings(BaseSettings):
extra="allow",
)
app_title: str = "MCP Template Application"
"""Title of the MCP application, defaults to 'MCP Template Application'."""
app_description: str = "A template application for MCP using FastAPI."
"""Description of the MCP application, defaults to 'A template application for MCP using FastAPI.'"""
default_mcp: str = "math"
"""Default MCP to be used by the application."""
default_host: str = "127.0.0.1"
"""Default host for the MCP server, defaults to 127.0.0.1."""
default_port: int = 3001
"""Default port for the MCP server, defaults to 3001."""
instructions: str | None = None
"""Instructions to be used by the MCP server, defaults to None."""
@@ -40,9 +25,3 @@ class Settings(BaseSettings):
enable_streamable_http: bool = True
"""Enable streamable HTTP for the MCP server."""
websocket_path: str = "/ws"
"""Path for the WebSocket endpoint."""
settings = Settings()

View File

@@ -1,6 +1,7 @@
import contextlib
from fastapi import FastAPI, Response
from fastapi.middleware.cors import CORSMiddleware
from .__about__ import __version__
from .app import MCP_MAP
@@ -17,12 +18,20 @@ async def lifespan(app: FastAPI):
app = FastAPI(
title=settings.app_title,
description=settings.app_description,
title=settings.title,
description=settings.description,
version=__version__,
lifespan=lifespan,
)
app.add_middleware(
CORSMiddleware,
allow_origins=settings.cors.allow_origins.split(","),
allow_credentials=settings.cors.allow_credentials,
allow_methods=settings.cors.allow_methods.split(","),
allow_headers=settings.cors.allow_headers.split(","),
)
@app.get("/")
async def root():
@@ -38,11 +47,11 @@ async def health():
}
if settings.enable_helpers_router:
if settings.mcp.enable_helpers_router:
app.include_router(helpers_router)
for name, mcp in MCP_MAP.items():
if settings.enable_sse:
if settings.mcp.enable_sse:
app.mount(f"/{name}/compatible", mcp.sse_app())
if settings.enable_streamable_http:
if settings.mcp.enable_streamable_http:
app.mount(f"/{name}", mcp.streamable_http_app())

View File

@@ -1,44 +0,0 @@
from typing import Any
from rich.console import Console
from rich.logging import RichHandler
class UvicornRichHandler(RichHandler):
def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(
console=Console(stderr=True), rich_tracebacks=True, *args, **kwargs
)
UVICORN_LOGGING_CONFIG = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"default": {
"()": "uvicorn.logging.DefaultFormatter",
"fmt": "%(message)s",
"use_colors": False,
},
"access": {
"()": "uvicorn.logging.AccessFormatter",
"fmt": '%(client_addr)s - "%(request_line)s" %(status_code)s', # noqa: E501
"use_colors": False,
},
},
"handlers": {
"default": {
"formatter": "default",
"class": "mcp_template_python.utils.log.UvicornRichHandler",
},
"access": {
"formatter": "access",
"class": "mcp_template_python.utils.log.UvicornRichHandler",
},
},
"loggers": {
"uvicorn": {"handlers": ["default"], "level": "INFO", "propagate": False},
"uvicorn.error": {"level": "INFO"},
"uvicorn.access": {"handlers": ["access"], "level": "INFO", "propagate": False},
},
}