diff --git a/docs/get-started/installation.md b/docs/get-started/installation.md index 5113eba26..d39c12e39 100644 --- a/docs/get-started/installation.md +++ b/docs/get-started/installation.md @@ -34,7 +34,6 @@ You don't need to know any of this to use the SDK, but if you're wondering what * `mcp-types`: every protocol type (requests, results, content blocks) as its own package, versioned in lockstep with the SDK. Every `from mcp_types import ...` in these docs is this package. * [`anyio`](https://anyio.readthedocs.io/): the async runtime. The whole SDK is written against anyio, so it runs on either `asyncio` or `trio`. * [`pydantic`](https://docs.pydantic.dev/): what every `mcp_types` model is built on, plus all schema generation and validation. -* [`pydantic-settings`](https://docs.pydantic.dev/latest/concepts/pydantic_settings/): server configuration via `MCP_*` environment variables and `.env` files. * [`httpx2`](https://pypi.org/project/httpx2/): the HTTP client behind the Streamable HTTP and SSE *client* transports, with server-sent events support built in. * [`starlette`](https://www.starlette.io/), [`uvicorn`](https://www.uvicorn.org/), [`sse-starlette`](https://pypi.org/project/sse-starlette/), and [`python-multipart`](https://pypi.org/project/python-multipart/): the HTTP *server* transports. * [`jsonschema`](https://pypi.org/project/jsonschema/): validates a tool's structured output against its declared output schema. diff --git a/docs/migration.md b/docs/migration.md index afe095363..768c4df14 100644 --- a/docs/migration.md +++ b/docs/migration.md @@ -684,6 +684,22 @@ app = Starlette(routes=[Mount("/", app=mcp.streamable_http_app(json_response=Tru If you were mutating these via `mcp.settings` after construction (e.g., `mcp.settings.port = 9000`), pass them to `run()` / `sse_app()` / `streamable_http_app()` instead — these fields no longer exist on `Settings`. The `debug` and `log_level` parameters remain on the constructor. +### `MCP_*` environment variables and `.env` files are no longer read + +The `Settings` docstring advertised configuration via `MCP_*` environment variables and a `.env` file (e.g. `MCP_DEBUG=true`), but constructor arguments have always taken precedence, so those environment variables never took effect. `Settings` is now a plain Pydantic model rather than a `pydantic-settings` `BaseSettings`, and `pydantic-settings` is no longer a dependency of the SDK. + +If you want environment-driven configuration, read the environment yourself and pass the values to the constructor: + +```python +import os + +from mcp.server.mcpserver import MCPServer + +mcp = MCPServer("Demo", debug=os.environ.get("MCP_DEBUG") == "true") +``` + +If your own code uses `pydantic-settings`, add it to your project's dependencies directly. + ### Streamable HTTP request bodies are limited to 4 MiB V2 applies a 4 MiB default limit to Streamable HTTP POST bodies and returns HTTP 413 before parsing diff --git a/pyproject.toml b/pyproject.toml index cab256720..5ce881254 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -58,6 +58,9 @@ dev = [ # We add mcp[cli] so `uv sync` considers the extras. "mcp[cli]", "mcp-example-stories", + # pydantic-settings is used only by examples (simple-auth, mcpserver/text_me); + # keep it reachable for pyright, which covers examples/servers. + "pydantic-settings>=2.5.2", "tomli>=2.0; python_version < '3.11'", "pyright>=1.1.400", "pytest>=8.4.0", @@ -128,7 +131,6 @@ dependencies = [ "starlette>=0.27; python_version < '3.14'", "python-multipart>=0.0.9", "sse-starlette>=3.0.0", - "pydantic-settings>=2.5.2", "uvicorn>=0.31.1; sys_platform != 'emscripten'", "jsonschema>=4.20.0", "pywin32>=311; sys_platform == 'win32'", diff --git a/src/mcp/server/mcpserver/server.py b/src/mcp/server/mcpserver/server.py index c6a75ec92..33a0b08c8 100644 --- a/src/mcp/server/mcpserver/server.py +++ b/src/mcp/server/mcpserver/server.py @@ -44,8 +44,8 @@ from mcp_types import Resource as MCPResource from mcp_types import ResourceTemplate as MCPResourceTemplate from mcp_types import Tool as MCPTool +from pydantic import BaseModel from pydantic.networks import AnyUrl -from pydantic_settings import BaseSettings, SettingsConfigDict from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.middleware.authentication import AuthenticationMiddleware @@ -98,20 +98,8 @@ _CallableT = TypeVar("_CallableT", bound=Callable[..., Any]) -class Settings(BaseSettings, Generic[LifespanResultT]): - """MCPServer settings. - - All settings can be configured via environment variables with the prefix MCP_. - For example, MCP_DEBUG=true will set debug=True. - """ - - model_config = SettingsConfigDict( - env_prefix="MCP_", - env_file=".env", - env_nested_delimiter="__", - nested_model_default_partial_update=True, - extra="ignore", - ) +class Settings(BaseModel, Generic[LifespanResultT]): + """MCPServer settings, as passed to the `MCPServer` constructor.""" # Server settings debug: bool diff --git a/uv.lock b/uv.lock index 53228bc1a..b992b278a 100644 --- a/uv.lock +++ b/uv.lock @@ -838,7 +838,6 @@ dependencies = [ { name = "mcp-types" }, { name = "opentelemetry-api" }, { name = "pydantic" }, - { name = "pydantic-settings" }, { name = "pyjwt", extra = ["crypto"] }, { name = "python-multipart" }, { name = "pywin32", marker = "sys_platform == 'win32'" }, @@ -871,6 +870,7 @@ dev = [ { name = "mcp-example-stories" }, { name = "opentelemetry-sdk" }, { name = "pillow" }, + { name = "pydantic-settings" }, { name = "pyright" }, { name = "pytest" }, { name = "pytest-examples" }, @@ -899,7 +899,6 @@ requires-dist = [ { name = "mcp-types", editable = "src/mcp-types" }, { name = "opentelemetry-api", specifier = ">=1.28.0" }, { name = "pydantic", specifier = ">=2.12.0" }, - { name = "pydantic-settings", specifier = ">=2.5.2" }, { name = "pyjwt", extras = ["crypto"], specifier = ">=2.10.1" }, { name = "python-dotenv", marker = "extra == 'cli'", specifier = ">=1.0.0" }, { name = "python-multipart", specifier = ">=0.0.9" }, @@ -926,6 +925,7 @@ dev = [ { name = "mcp-example-stories", editable = "examples" }, { name = "opentelemetry-sdk", specifier = ">=1.39.1" }, { name = "pillow", specifier = ">=12.0" }, + { name = "pydantic-settings", specifier = ">=2.5.2" }, { name = "pyright", specifier = ">=1.1.400" }, { name = "pytest", specifier = ">=8.4.0" }, { name = "pytest-examples", specifier = ">=0.0.14" },