diff --git a/Dockerfile b/Dockerfile index b76710d..16c943c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,7 @@ FROM python:3.13-alpine +EXPOSE 8000 + # Install package manager COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ @@ -18,4 +20,6 @@ COPY src src RUN uv sync \ --locked +ENV CORDRA_RUN_MODE=http + CMD ["uv", "run", "cordra-mcp"] diff --git a/src/cordra_mcp/config.py b/src/cordra_mcp/config.py index ba8a307..0aab328 100644 --- a/src/cordra_mcp/config.py +++ b/src/cordra_mcp/config.py @@ -1,5 +1,7 @@ """Configuration settings for the MCP Cordra server.""" +from typing import Literal + from pydantic import Field, field_validator from pydantic_settings import BaseSettings, SettingsConfigDict @@ -16,6 +18,10 @@ class CordraConfig(BaseSettings): default="https://localhost:8443", description="Base URL of the Cordra repository", ) + host: str = Field( + default="0.0.0.0", + description="The host under which the MCP server runs when deployed as http run_mode", + ) username: str | None = Field( default=None, description="Username for Cordra authentication" ) @@ -26,6 +32,9 @@ class CordraConfig(BaseSettings): default=True, description="Whether to verify SSL certificates" ) timeout: int = Field(default=30, description="Request timeout in seconds") + run_mode: Literal["stdio", "http"] | None = Field( + default="stdio", description="Run mode for the MCP client" + ) log_level: str = Field( default="INFO", description="Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)", diff --git a/src/cordra_mcp/server.py b/src/cordra_mcp/server.py index ee5754f..034021e 100644 --- a/src/cordra_mcp/server.py +++ b/src/cordra_mcp/server.py @@ -17,10 +17,10 @@ from .client import ( from .config import CordraConfig # Initialize the MCP server -mcp = FastMCP("cordra-mcp") +config = CordraConfig() +mcp = FastMCP("cordra-mcp", host=config.host, port=8000) # Initialize Cordra client at startup -config = CordraConfig() cordra_client = CordraClient(config) logger = logging.getLogger(__name__) @@ -311,8 +311,11 @@ async def initialize_server() -> None: def main() -> None: """Main entry point for the MCP server.""" - asyncio.run(initialize_server()) - mcp.run() + if config.run_mode == "stdio": + asyncio.run(initialize_server()) + mcp.run() + else: + mcp.run(transport="streamable-http") if __name__ == "__main__":