Skip to content

Commit 3212591

Browse files
authored
Stop advertising MCP_* env vars for MCPServer settings; drop pydantic-settings (#3170)
1 parent 7163d82 commit 3212591

5 files changed

Lines changed: 24 additions & 19 deletions

File tree

docs/get-started/installation.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ You don't need to know any of this to use the SDK, but if you're wondering what
3434
* `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.
3535
* [`anyio`](https://anyio.readthedocs.io/): the async runtime. The whole SDK is written against anyio, so it runs on either `asyncio` or `trio`.
3636
* [`pydantic`](https://docs.pydantic.dev/): what every `mcp_types` model is built on, plus all schema generation and validation.
37-
* [`pydantic-settings`](https://docs.pydantic.dev/latest/concepts/pydantic_settings/): server configuration via `MCP_*` environment variables and `.env` files.
3837
* [`httpx2`](https://pypi.org/project/httpx2/): the HTTP client behind the Streamable HTTP and SSE *client* transports, with server-sent events support built in.
3938
* [`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.
4039
* [`jsonschema`](https://pypi.org/project/jsonschema/): validates a tool's structured output against its declared output schema.

docs/migration.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,22 @@ app = Starlette(routes=[Mount("/", app=mcp.streamable_http_app(json_response=Tru
684684

685685
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.
686686

687+
### `MCP_*` environment variables and `.env` files are no longer read
688+
689+
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.
690+
691+
If you want environment-driven configuration, read the environment yourself and pass the values to the constructor:
692+
693+
```python
694+
import os
695+
696+
from mcp.server.mcpserver import MCPServer
697+
698+
mcp = MCPServer("Demo", debug=os.environ.get("MCP_DEBUG") == "true")
699+
```
700+
701+
If your own code uses `pydantic-settings`, add it to your project's dependencies directly.
702+
687703
### Streamable HTTP request bodies are limited to 4 MiB
688704

689705
V2 applies a 4 MiB default limit to Streamable HTTP POST bodies and returns HTTP 413 before parsing

pyproject.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ dev = [
5858
# We add mcp[cli] so `uv sync` considers the extras.
5959
"mcp[cli]",
6060
"mcp-example-stories",
61+
# pydantic-settings is used only by examples (simple-auth, mcpserver/text_me);
62+
# keep it reachable for pyright, which covers examples/servers.
63+
"pydantic-settings>=2.5.2",
6164
"tomli>=2.0; python_version < '3.11'",
6265
"pyright>=1.1.400",
6366
"pytest>=8.4.0",
@@ -128,7 +131,6 @@ dependencies = [
128131
"starlette>=0.27; python_version < '3.14'",
129132
"python-multipart>=0.0.9",
130133
"sse-starlette>=3.0.0",
131-
"pydantic-settings>=2.5.2",
132134
"uvicorn>=0.31.1; sys_platform != 'emscripten'",
133135
"jsonschema>=4.20.0",
134136
"pywin32>=311; sys_platform == 'win32'",

src/mcp/server/mcpserver/server.py

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@
4444
from mcp_types import Resource as MCPResource
4545
from mcp_types import ResourceTemplate as MCPResourceTemplate
4646
from mcp_types import Tool as MCPTool
47+
from pydantic import BaseModel
4748
from pydantic.networks import AnyUrl
48-
from pydantic_settings import BaseSettings, SettingsConfigDict
4949
from starlette.applications import Starlette
5050
from starlette.middleware import Middleware
5151
from starlette.middleware.authentication import AuthenticationMiddleware
@@ -98,20 +98,8 @@
9898
_CallableT = TypeVar("_CallableT", bound=Callable[..., Any])
9999

100100

101-
class Settings(BaseSettings, Generic[LifespanResultT]):
102-
"""MCPServer settings.
103-
104-
All settings can be configured via environment variables with the prefix MCP_.
105-
For example, MCP_DEBUG=true will set debug=True.
106-
"""
107-
108-
model_config = SettingsConfigDict(
109-
env_prefix="MCP_",
110-
env_file=".env",
111-
env_nested_delimiter="__",
112-
nested_model_default_partial_update=True,
113-
extra="ignore",
114-
)
101+
class Settings(BaseModel, Generic[LifespanResultT]):
102+
"""MCPServer settings, as passed to the `MCPServer` constructor."""
115103

116104
# Server settings
117105
debug: bool

uv.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)