Fix server info bug (#614)
Name, title, version, etc. for an `MCPApp` were being overwritten by its
internal `MCPServer`.
⚠️ this is blocking `arcade deploy` from working
This commit is contained in:
parent
4d0ae0cdce
commit
83c0eeab2b
7 changed files with 323 additions and 27 deletions
|
|
@ -20,6 +20,7 @@ from loguru import logger
|
||||||
|
|
||||||
from arcade_mcp_server.exceptions import ServerError
|
from arcade_mcp_server.exceptions import ServerError
|
||||||
from arcade_mcp_server.server import MCPServer
|
from arcade_mcp_server.server import MCPServer
|
||||||
|
from arcade_mcp_server.settings import MCPSettings, ServerSettings
|
||||||
from arcade_mcp_server.types import Prompt, PromptMessage, Resource
|
from arcade_mcp_server.types import Prompt, PromptMessage, Resource
|
||||||
from arcade_mcp_server.worker import run_arcade_mcp
|
from arcade_mcp_server.worker import run_arcade_mcp
|
||||||
|
|
||||||
|
|
@ -59,7 +60,7 @@ class MCPApp:
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
name: str = "ArcadeMCP",
|
name: str = "ArcadeMCP",
|
||||||
version: str = "1.0.0dev",
|
version: str = "0.1.0",
|
||||||
title: str | None = None,
|
title: str | None = None,
|
||||||
instructions: str | None = None,
|
instructions: str | None = None,
|
||||||
log_level: str = "INFO",
|
log_level: str = "INFO",
|
||||||
|
|
@ -102,6 +103,15 @@ class MCPApp:
|
||||||
# Public handle to the MCPServer (set by caller for runtime ops)
|
# Public handle to the MCPServer (set by caller for runtime ops)
|
||||||
self.server: MCPServer | None = None
|
self.server: MCPServer | None = None
|
||||||
|
|
||||||
|
self._mcp_settings = MCPSettings(
|
||||||
|
server=ServerSettings(
|
||||||
|
name=self.name,
|
||||||
|
version=self.version,
|
||||||
|
title=self.title,
|
||||||
|
instructions=self.instructions,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
self._load_env()
|
self._load_env()
|
||||||
if not logger._core.handlers: # type: ignore[attr-defined]
|
if not logger._core.handlers: # type: ignore[attr-defined]
|
||||||
self._setup_logging(transport == "stdio")
|
self._setup_logging(transport == "stdio")
|
||||||
|
|
@ -227,6 +237,7 @@ class MCPApp:
|
||||||
host=host,
|
host=host,
|
||||||
port=port,
|
port=port,
|
||||||
reload=reload,
|
reload=reload,
|
||||||
|
mcp_settings=self._mcp_settings,
|
||||||
**self.server_kwargs,
|
**self.server_kwargs,
|
||||||
)
|
)
|
||||||
elif transport == "stdio":
|
elif transport == "stdio":
|
||||||
|
|
@ -237,6 +248,7 @@ class MCPApp:
|
||||||
asyncio.run(
|
asyncio.run(
|
||||||
run_stdio_server(
|
run_stdio_server(
|
||||||
catalog=self._catalog,
|
catalog=self._catalog,
|
||||||
|
settings=self._mcp_settings,
|
||||||
**self.server_kwargs,
|
**self.server_kwargs,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ from arcade_mcp_server.middleware import (
|
||||||
MiddlewareContext,
|
MiddlewareContext,
|
||||||
)
|
)
|
||||||
from arcade_mcp_server.session import InitializationState, NotificationManager, ServerSession
|
from arcade_mcp_server.session import InitializationState, NotificationManager, ServerSession
|
||||||
from arcade_mcp_server.settings import MCPSettings
|
from arcade_mcp_server.settings import MCPSettings, ServerSettings
|
||||||
from arcade_mcp_server.types import (
|
from arcade_mcp_server.types import (
|
||||||
LATEST_PROTOCOL_VERSION,
|
LATEST_PROTOCOL_VERSION,
|
||||||
BlobResourceContents,
|
BlobResourceContents,
|
||||||
|
|
@ -109,8 +109,8 @@ class MCPServer:
|
||||||
self,
|
self,
|
||||||
catalog: ToolCatalog,
|
catalog: ToolCatalog,
|
||||||
*,
|
*,
|
||||||
name: str = "ArcadeMCP",
|
name: str | None = None,
|
||||||
version: str = "0.1.0",
|
version: str | None = None,
|
||||||
title: str | None = None,
|
title: str | None = None,
|
||||||
instructions: str | None = None,
|
instructions: str | None = None,
|
||||||
settings: MCPSettings | None = None,
|
settings: MCPSettings | None = None,
|
||||||
|
|
@ -136,17 +136,29 @@ class MCPServer:
|
||||||
arcade_api_key: Arcade API key (overrides settings)
|
arcade_api_key: Arcade API key (overrides settings)
|
||||||
arcade_api_url: Arcade API URL (overrides settings)
|
arcade_api_url: Arcade API URL (overrides settings)
|
||||||
"""
|
"""
|
||||||
self.name = name or self.__class__.__name__
|
|
||||||
self._started = False
|
self._started = False
|
||||||
self._lock = asyncio.Lock()
|
self._lock = asyncio.Lock()
|
||||||
|
|
||||||
# Server identity
|
# Settings (load first so we can use values from it)
|
||||||
self.version = version
|
|
||||||
self.title = title or name
|
|
||||||
self.instructions = instructions or self._default_instructions()
|
|
||||||
|
|
||||||
# Settings
|
|
||||||
self.settings = settings or MCPSettings.from_env()
|
self.settings = settings or MCPSettings.from_env()
|
||||||
|
|
||||||
|
# Server info
|
||||||
|
self.name = name if name else self.settings.server.name
|
||||||
|
self.version = version if version else self.settings.server.version
|
||||||
|
if title:
|
||||||
|
self.title = title
|
||||||
|
elif (
|
||||||
|
self.settings.server.title
|
||||||
|
and self.settings.server.title != ServerSettings.model_fields["title"].default
|
||||||
|
):
|
||||||
|
self.title = self.settings.server.title
|
||||||
|
else:
|
||||||
|
self.title = self.name
|
||||||
|
|
||||||
|
self.instructions = (
|
||||||
|
instructions or self.settings.server.instructions or self._default_instructions()
|
||||||
|
)
|
||||||
|
|
||||||
self.auth_disabled = auth_disabled or self.settings.arcade.auth_disabled
|
self.auth_disabled = auth_disabled or self.settings.arcade.auth_disabled
|
||||||
|
|
||||||
# Initialize Arcade client
|
# Initialize Arcade client
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ class ServerSettings(BaseSettings):
|
||||||
description="Server version",
|
description="Server version",
|
||||||
)
|
)
|
||||||
title: str | None = Field(
|
title: str | None = Field(
|
||||||
default="Arcade MCP",
|
default="ArcadeMCP",
|
||||||
description="Server title for display",
|
description="Server title for display",
|
||||||
)
|
)
|
||||||
instructions: str | None = Field(
|
instructions: str | None = Field(
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,7 @@ def create_arcade_mcp(
|
||||||
await logger.complete()
|
await logger.complete()
|
||||||
logger.debug("Server lifespan shutdown complete.")
|
logger.debug("Server lifespan shutdown complete.")
|
||||||
|
|
||||||
|
# Use settings for FastAPI app metadata
|
||||||
app = FastAPI(
|
app = FastAPI(
|
||||||
title=(mcp_settings.server.title or mcp_settings.server.name),
|
title=(mcp_settings.server.title or mcp_settings.server.name),
|
||||||
description=(mcp_settings.server.instructions or ""),
|
description=(mcp_settings.server.instructions or ""),
|
||||||
|
|
@ -122,7 +123,6 @@ def create_arcade_mcp(
|
||||||
docs_url="/docs" if not mcp_settings.arcade.auth_disabled else None,
|
docs_url="/docs" if not mcp_settings.arcade.auth_disabled else None,
|
||||||
redoc_url="/redoc" if not mcp_settings.arcade.auth_disabled else None,
|
redoc_url="/redoc" if not mcp_settings.arcade.auth_disabled else None,
|
||||||
lifespan=lifespan,
|
lifespan=lifespan,
|
||||||
**kwargs,
|
|
||||||
)
|
)
|
||||||
otel_handler.instrument_app(app)
|
otel_handler.instrument_app(app)
|
||||||
app.add_middleware(AddTrailingSlashToPathMiddleware)
|
app.add_middleware(AddTrailingSlashToPathMiddleware)
|
||||||
|
|
@ -221,6 +221,8 @@ def create_arcade_mcp_factory() -> FastAPI:
|
||||||
show_packages = os.environ.get("ARCADE_MCP_SHOW_PACKAGES", "false").lower() == "true"
|
show_packages = os.environ.get("ARCADE_MCP_SHOW_PACKAGES", "false").lower() == "true"
|
||||||
server_name = os.environ.get("ARCADE_MCP_SERVER_NAME")
|
server_name = os.environ.get("ARCADE_MCP_SERVER_NAME")
|
||||||
server_version = os.environ.get("ARCADE_MCP_SERVER_VERSION")
|
server_version = os.environ.get("ARCADE_MCP_SERVER_VERSION")
|
||||||
|
server_title = os.environ.get("ARCADE_MCP_SERVER_TITLE")
|
||||||
|
server_instructions = os.environ.get("ARCADE_MCP_SERVER_INSTRUCTIONS")
|
||||||
|
|
||||||
# Rediscover tools since there have been changes
|
# Rediscover tools since there have been changes
|
||||||
try:
|
try:
|
||||||
|
|
@ -244,19 +246,24 @@ def create_arcade_mcp_factory() -> FastAPI:
|
||||||
if otel_enable:
|
if otel_enable:
|
||||||
logger.info("OpenTelemetry is enabled")
|
logger.info("OpenTelemetry is enabled")
|
||||||
|
|
||||||
# Build kwargs for server creation
|
# Build settings with server metadata from env vars
|
||||||
kwargs = {}
|
from arcade_mcp_server.settings import ServerSettings
|
||||||
if server_name:
|
|
||||||
kwargs["name"] = server_name
|
mcp_settings = MCPSettings.from_env()
|
||||||
if server_version:
|
if server_name or server_version or server_title or server_instructions:
|
||||||
kwargs["version"] = server_version
|
# Override server settings if any were provided via env vars
|
||||||
|
mcp_settings.server = ServerSettings(
|
||||||
|
name=server_name or mcp_settings.server.name,
|
||||||
|
version=server_version or mcp_settings.server.version,
|
||||||
|
title=server_title or mcp_settings.server.title,
|
||||||
|
instructions=server_instructions or mcp_settings.server.instructions,
|
||||||
|
)
|
||||||
|
|
||||||
return create_arcade_mcp(
|
return create_arcade_mcp(
|
||||||
catalog=catalog,
|
catalog=catalog,
|
||||||
mcp_settings=None,
|
mcp_settings=mcp_settings,
|
||||||
debug=debug,
|
debug=debug,
|
||||||
otel_enable=otel_enable,
|
otel_enable=otel_enable,
|
||||||
**kwargs,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -270,6 +277,7 @@ def run_arcade_mcp(
|
||||||
tool_package: str | None = None,
|
tool_package: str | None = None,
|
||||||
discover_installed: bool = False,
|
discover_installed: bool = False,
|
||||||
show_packages: bool = False,
|
show_packages: bool = False,
|
||||||
|
mcp_settings: MCPSettings | None = None,
|
||||||
**kwargs: Any,
|
**kwargs: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
|
|
@ -287,10 +295,13 @@ def run_arcade_mcp(
|
||||||
os.environ["ARCADE_MCP_TOOL_PACKAGE"] = tool_package
|
os.environ["ARCADE_MCP_TOOL_PACKAGE"] = tool_package
|
||||||
os.environ["ARCADE_MCP_DISCOVER_INSTALLED"] = str(discover_installed)
|
os.environ["ARCADE_MCP_DISCOVER_INSTALLED"] = str(discover_installed)
|
||||||
os.environ["ARCADE_MCP_SHOW_PACKAGES"] = str(show_packages)
|
os.environ["ARCADE_MCP_SHOW_PACKAGES"] = str(show_packages)
|
||||||
if kwargs.get("name"):
|
if mcp_settings:
|
||||||
os.environ["ARCADE_MCP_SERVER_NAME"] = kwargs["name"]
|
os.environ["ARCADE_MCP_SERVER_NAME"] = mcp_settings.server.name
|
||||||
if kwargs.get("version"):
|
os.environ["ARCADE_MCP_SERVER_VERSION"] = mcp_settings.server.version
|
||||||
os.environ["ARCADE_MCP_SERVER_VERSION"] = kwargs["version"]
|
if mcp_settings.server.title:
|
||||||
|
os.environ["ARCADE_MCP_SERVER_TITLE"] = mcp_settings.server.title
|
||||||
|
if mcp_settings.server.instructions:
|
||||||
|
os.environ["ARCADE_MCP_SERVER_INSTRUCTIONS"] = mcp_settings.server.instructions
|
||||||
|
|
||||||
# import string is required for reload mode
|
# import string is required for reload mode
|
||||||
app_import_string = "arcade_mcp_server.worker:create_arcade_mcp_factory"
|
app_import_string = "arcade_mcp_server.worker:create_arcade_mcp_factory"
|
||||||
|
|
@ -307,6 +318,7 @@ def run_arcade_mcp(
|
||||||
else:
|
else:
|
||||||
app = create_arcade_mcp(
|
app = create_arcade_mcp(
|
||||||
catalog=catalog,
|
catalog=catalog,
|
||||||
|
mcp_settings=mcp_settings,
|
||||||
debug=debug,
|
debug=debug,
|
||||||
otel_enable=otel_enable,
|
otel_enable=otel_enable,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,46 @@ class TestMCPApp:
|
||||||
"""Create an MCP app."""
|
"""Create an MCP app."""
|
||||||
return MCPApp(name="TestMCPApp", version="1.0.0")
|
return MCPApp(name="TestMCPApp", version="1.0.0")
|
||||||
|
|
||||||
|
def test_mcp_app_initialization(self):
|
||||||
|
"""Test MCPApp initialization creates proper settings."""
|
||||||
|
app = MCPApp(
|
||||||
|
name="TestApp",
|
||||||
|
version="1.5.0",
|
||||||
|
title="Test Title",
|
||||||
|
instructions="Test instructions",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert app.name == "TestApp"
|
||||||
|
assert app.version == "1.5.0"
|
||||||
|
assert app.title == "Test Title"
|
||||||
|
assert app.instructions == "Test instructions"
|
||||||
|
|
||||||
|
assert app._mcp_settings is not None
|
||||||
|
assert app._mcp_settings.server.name == "TestApp"
|
||||||
|
assert app._mcp_settings.server.version == "1.5.0"
|
||||||
|
assert app._mcp_settings.server.title == "Test Title"
|
||||||
|
assert app._mcp_settings.server.instructions == "Test instructions"
|
||||||
|
|
||||||
|
def test_mcp_app_initialization_defaults(self):
|
||||||
|
"""Test MCPApp initialization with default values."""
|
||||||
|
app = MCPApp()
|
||||||
|
|
||||||
|
assert app.name == "ArcadeMCP"
|
||||||
|
assert app.version == "0.1.0"
|
||||||
|
|
||||||
|
assert app._mcp_settings.server.name == "ArcadeMCP"
|
||||||
|
assert app._mcp_settings.server.version == "0.1.0"
|
||||||
|
|
||||||
|
def test_mcp_app_initialization_partial_values(self):
|
||||||
|
"""Test MCPApp initialization with partial values."""
|
||||||
|
app = MCPApp(name="PartialApp")
|
||||||
|
|
||||||
|
assert app.name == "PartialApp"
|
||||||
|
assert app.version == "0.1.0" # Default value
|
||||||
|
|
||||||
|
assert app._mcp_settings.server.name == "PartialApp"
|
||||||
|
assert app._mcp_settings.server.version == "0.1.0"
|
||||||
|
|
||||||
def test_add_tool(self, mcp_app: MCPApp):
|
def test_add_tool(self, mcp_app: MCPApp):
|
||||||
"""Test adding a tool to the MCP app."""
|
"""Test adding a tool to the MCP app."""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,12 @@ class TestMCPServer:
|
||||||
server = MCPServer(
|
server = MCPServer(
|
||||||
catalog=tool_catalog,
|
catalog=tool_catalog,
|
||||||
name="Test Server",
|
name="Test Server",
|
||||||
version="1.0.0",
|
version="1.9.0",
|
||||||
settings=mcp_settings,
|
settings=mcp_settings,
|
||||||
)
|
)
|
||||||
|
|
||||||
assert server.name == "Test Server"
|
assert server.name == "Test Server"
|
||||||
assert server.version == "1.0.0"
|
assert server.version == "1.9.0"
|
||||||
assert server.title == "Test Server"
|
assert server.title == "Test Server"
|
||||||
assert server.settings == mcp_settings
|
assert server.settings == mcp_settings
|
||||||
|
|
||||||
|
|
@ -58,6 +58,126 @@ class TestMCPServer:
|
||||||
assert server2.title == "Custom Title"
|
assert server2.title == "Custom Title"
|
||||||
assert server2.instructions == "Custom instructions"
|
assert server2.instructions == "Custom instructions"
|
||||||
|
|
||||||
|
def test_server_initialization_with_settings_defaults(self, tool_catalog):
|
||||||
|
"""Test server initialization uses settings when parameters not provided."""
|
||||||
|
from arcade_mcp_server.settings import MCPSettings, ServerSettings
|
||||||
|
|
||||||
|
settings = MCPSettings(
|
||||||
|
server=ServerSettings(
|
||||||
|
name="SettingsName",
|
||||||
|
version="2.0.0",
|
||||||
|
title="SettingsTitle",
|
||||||
|
instructions="Settings instructions",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Initialize without name/version - should use settings
|
||||||
|
server = MCPServer(catalog=tool_catalog, settings=settings)
|
||||||
|
|
||||||
|
assert server.name == "SettingsName"
|
||||||
|
assert server.version == "2.0.0"
|
||||||
|
assert server.title == "SettingsTitle"
|
||||||
|
assert server.instructions == "Settings instructions"
|
||||||
|
|
||||||
|
def test_server_initialization_parameters_override_settings(self, tool_catalog):
|
||||||
|
"""Test server initialization parameters override settings."""
|
||||||
|
from arcade_mcp_server.settings import MCPSettings, ServerSettings
|
||||||
|
|
||||||
|
settings = MCPSettings(
|
||||||
|
server=ServerSettings(
|
||||||
|
name="SettingsName",
|
||||||
|
version="2.0.0",
|
||||||
|
title="SettingsTitle",
|
||||||
|
instructions="Settings instructions",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Initialize with explicit parameters (should override settings)
|
||||||
|
server = MCPServer(
|
||||||
|
catalog=tool_catalog,
|
||||||
|
name="ParamName",
|
||||||
|
version="3.0.0",
|
||||||
|
title="ParamTitle",
|
||||||
|
instructions="Param instructions",
|
||||||
|
settings=settings,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert server.name == "ParamName"
|
||||||
|
assert server.version == "3.0.0"
|
||||||
|
assert server.title == "ParamTitle"
|
||||||
|
assert server.instructions == "Param instructions"
|
||||||
|
|
||||||
|
def test_server_initialization_title_fallback_logic(self, tool_catalog):
|
||||||
|
"""Test server initialization title fallback logic."""
|
||||||
|
from arcade_mcp_server.settings import MCPSettings, ServerSettings
|
||||||
|
|
||||||
|
# Test 1: Title parameter provided (should be used)
|
||||||
|
server1 = MCPServer(
|
||||||
|
catalog=tool_catalog,
|
||||||
|
name="TestServer",
|
||||||
|
title="ExplicitTitle",
|
||||||
|
)
|
||||||
|
assert server1.title == "ExplicitTitle"
|
||||||
|
|
||||||
|
# Test 2: No title parameter but settings has non-default title
|
||||||
|
settings2 = MCPSettings(
|
||||||
|
server=ServerSettings(
|
||||||
|
name="SettingsServer",
|
||||||
|
title="CustomSettingsTitle",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
server2 = MCPServer(catalog=tool_catalog, settings=settings2)
|
||||||
|
assert server2.title == "CustomSettingsTitle"
|
||||||
|
|
||||||
|
# Test 3: No title parameter, settings has default title (should use name)
|
||||||
|
settings3 = MCPSettings(
|
||||||
|
server=ServerSettings(
|
||||||
|
name="SettingsServer",
|
||||||
|
title="ArcadeMCP", # Default value
|
||||||
|
)
|
||||||
|
)
|
||||||
|
server3 = MCPServer(catalog=tool_catalog, settings=settings3)
|
||||||
|
assert server3.title == "SettingsServer"
|
||||||
|
|
||||||
|
# Test 4: No title parameter, no settings title (should use name)
|
||||||
|
settings4 = MCPSettings(
|
||||||
|
server=ServerSettings(
|
||||||
|
name="SettingsServer",
|
||||||
|
title=None,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
server4 = MCPServer(catalog=tool_catalog, settings=settings4)
|
||||||
|
assert server4.title == "SettingsServer"
|
||||||
|
|
||||||
|
def test_server_initialization_instructions_fallback(self, tool_catalog):
|
||||||
|
"""Test server initialization instructions fallback logic."""
|
||||||
|
from arcade_mcp_server.settings import MCPSettings, ServerSettings
|
||||||
|
|
||||||
|
# Test 1: Instructions parameter provided (should be used)
|
||||||
|
server1 = MCPServer(
|
||||||
|
catalog=tool_catalog,
|
||||||
|
instructions="Explicit instructions",
|
||||||
|
)
|
||||||
|
assert server1.instructions == "Explicit instructions"
|
||||||
|
|
||||||
|
# Test 2: No instructions parameter (should use settings)
|
||||||
|
settings2 = MCPSettings(
|
||||||
|
server=ServerSettings(
|
||||||
|
instructions="Settings instructions",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
server2 = MCPServer(catalog=tool_catalog, settings=settings2)
|
||||||
|
assert server2.instructions == "Settings instructions"
|
||||||
|
|
||||||
|
# Test 3: No instructions parameter, no settings (should use default)
|
||||||
|
settings3 = MCPSettings(
|
||||||
|
server=ServerSettings(
|
||||||
|
instructions=None,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
server3 = MCPServer(catalog=tool_catalog, settings=settings3)
|
||||||
|
assert "available tools" in server3.instructions.lower()
|
||||||
|
|
||||||
def test_handler_registration(self, tool_catalog):
|
def test_handler_registration(self, tool_catalog):
|
||||||
"""Test that all required handlers are registered."""
|
"""Test that all required handlers are registered."""
|
||||||
server = MCPServer(catalog=tool_catalog)
|
server = MCPServer(catalog=tool_catalog)
|
||||||
|
|
|
||||||
100
libs/tests/arcade_mcp_server/test_settings.py
Normal file
100
libs/tests/arcade_mcp_server/test_settings.py
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
"""Tests for MCP Settings."""
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from arcade_mcp_server.settings import MCPSettings, ServerSettings
|
||||||
|
|
||||||
|
|
||||||
|
class TestServerSettings:
|
||||||
|
"""Test ServerSettings class."""
|
||||||
|
|
||||||
|
def test_server_settings_defaults(self):
|
||||||
|
"""Test ServerSettings default values."""
|
||||||
|
settings = ServerSettings()
|
||||||
|
|
||||||
|
assert settings.name == "ArcadeMCP"
|
||||||
|
assert settings.version == "0.1.0dev"
|
||||||
|
assert settings.title == "ArcadeMCP"
|
||||||
|
assert settings.instructions is not None
|
||||||
|
assert "available tools" in settings.instructions.lower()
|
||||||
|
|
||||||
|
def test_server_settings_custom_values(self):
|
||||||
|
"""Test ServerSettings with custom values."""
|
||||||
|
settings = ServerSettings(
|
||||||
|
name="CustomServer",
|
||||||
|
version="2.0.0",
|
||||||
|
title="Custom Title",
|
||||||
|
instructions="Custom instructions",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert settings.name == "CustomServer"
|
||||||
|
assert settings.version == "2.0.0"
|
||||||
|
assert settings.title == "Custom Title"
|
||||||
|
assert settings.instructions == "Custom instructions"
|
||||||
|
|
||||||
|
def test_server_settings_partial_values(self):
|
||||||
|
"""Test ServerSettings with partial custom values."""
|
||||||
|
settings = ServerSettings(
|
||||||
|
name="PartialServer",
|
||||||
|
version="1.5.0",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert settings.name == "PartialServer"
|
||||||
|
assert settings.version == "1.5.0"
|
||||||
|
assert settings.title == "ArcadeMCP" # Default value
|
||||||
|
assert settings.instructions is not None # Default value
|
||||||
|
|
||||||
|
|
||||||
|
class TestMCPSettings:
|
||||||
|
"""Test MCPSettings class."""
|
||||||
|
|
||||||
|
def test_mcp_settings_defaults(self):
|
||||||
|
"""Test MCPSettings default values."""
|
||||||
|
settings = MCPSettings()
|
||||||
|
|
||||||
|
assert settings.server.name == "ArcadeMCP"
|
||||||
|
assert settings.server.version == "0.1.0dev"
|
||||||
|
assert settings.server.title == "ArcadeMCP"
|
||||||
|
assert settings.server.instructions is not None
|
||||||
|
|
||||||
|
def test_mcp_settings_with_custom_server(self):
|
||||||
|
"""Test MCPSettings with custom ServerSettings."""
|
||||||
|
server_settings = ServerSettings(
|
||||||
|
name="TestServer",
|
||||||
|
version="3.0.0",
|
||||||
|
title="Test Title",
|
||||||
|
instructions="Test instructions",
|
||||||
|
)
|
||||||
|
settings = MCPSettings(server=server_settings)
|
||||||
|
|
||||||
|
assert settings.server.name == "TestServer"
|
||||||
|
assert settings.server.version == "3.0.0"
|
||||||
|
assert settings.server.title == "Test Title"
|
||||||
|
assert settings.server.instructions == "Test instructions"
|
||||||
|
|
||||||
|
def test_mcp_settings_from_env(self, monkeypatch):
|
||||||
|
"""Test MCPSettings.from_env() uses environment variables."""
|
||||||
|
monkeypatch.setenv("MCP_SERVER_NAME", "EnvServer")
|
||||||
|
monkeypatch.setenv("MCP_SERVER_VERSION", "4.0.0")
|
||||||
|
monkeypatch.setenv("MCP_SERVER_TITLE", "Env Title")
|
||||||
|
monkeypatch.setenv("MCP_SERVER_INSTRUCTIONS", "Env instructions")
|
||||||
|
|
||||||
|
settings = MCPSettings.from_env()
|
||||||
|
|
||||||
|
assert settings.server.name == "EnvServer"
|
||||||
|
assert settings.server.version == "4.0.0"
|
||||||
|
assert settings.server.title == "Env Title"
|
||||||
|
assert settings.server.instructions == "Env instructions"
|
||||||
|
|
||||||
|
|
||||||
|
class TestServerSettingsTitleDefault:
|
||||||
|
"""Test that the default title value is 'ArcadeMCP'."""
|
||||||
|
|
||||||
|
def test_title_default_value(self):
|
||||||
|
"""Test that the default title value is 'ArcadeMCP'."""
|
||||||
|
settings = ServerSettings()
|
||||||
|
assert settings.title == "ArcadeMCP"
|
||||||
|
|
||||||
|
def test_title_field_default(self):
|
||||||
|
"""Test that the title field default is 'ArcadeMCP'."""
|
||||||
|
field_info = ServerSettings.model_fields["title"]
|
||||||
|
assert field_info.default == "ArcadeMCP"
|
||||||
Loading…
Reference in a new issue