* fix(python): respect configured inspector path
* fix(python): treat inspector path as a base prefix
* fix(python): format inspector fixes for ruff
* fix(ci): run conformance with node 22
* fix(ci): fail conformance runs with empty results
* chore(ci): drop inline conformance result validation
* docs(python): clarify inspector path behavior
* feat(python/server): add mcp_logs_only option to suppress HTTP access logs
When mcp_logs_only=True, all uvicorn access logs are suppressed. MCP
protocol logs (printed directly by MCPLoggingMiddleware) continue to
show. This eliminates the duplicate INFO: lines for MCP requests and
hides non-MCP HTTP traffic (/docs, /inspector, static files).
The implementation is simple: MCPAccessFormatter returns an empty string
when the flag is set, since the middleware already handles MCP logging
via direct stdout prints.
Closes#1162
* fix(python/server): use filter instead of empty string to suppress access logs
Replace the formatter returning "" (which still outputs a blank line)
with a proper MCPLogsOnlyFilter that drops log records entirely.
* docs: update
* docs(python): document mcp_logs_only option in server logging docs
* fix(python/server): simplify tool JSON Schema for Optional parameters
Pydantic generates {"anyOf": [{"type": "T"}, {"type": "null"}]} for
Optional[T] tool parameters. While valid JSON Schema 2020-12, this
pattern breaks description rendering in the MCP Inspector UI and fails
Gemini API validation (requires top-level type field). MCP signals
optionality via the required array, making the anyOf/null wrapper
redundant.
- Add simplify_optional_schema() utility that collapses nullable anyOf
into flat {"type": "T"} while preserving description, default, title
- Override MCPServer.add_tool() to apply simplification after Pydantic
generates the schema
- Add 12 unit tests for the schema simplifier (test_json_schema.py)
- Add 23 unit tests for tool schema output (test_list_tool_format.py)
- Update server_example.py with representative parameter patterns
including Literal enum types
* docs(python/server): add parameter types and JSON Schema section to tools docs
Document the Python-to-JSON-Schema type mapping, required/optional/nullable
parameter patterns, and Literal enum usage. Includes a note explaining the
anyOf/null simplification that mcp-use applies automatically.
* feat(python/server): add icons parameter to MCPServer constructor
Pass through the icons parameter to FastMCP so server-level icons can
be set directly in the MCPServer constructor.
* docs(python/server): document icons parameter in server overview
* docs(python): update server example with icons and Literal enum params
* style: format server_example.py
* test(python): add unit tests for icons constructor parameter
* docs: regenerate API reference for icons param
* fix(python/server): simplify tool JSON Schema for Optional parameters
Pydantic generates {"anyOf": [{"type": "T"}, {"type": "null"}]} for
Optional[T] tool parameters. While valid JSON Schema 2020-12, this
pattern breaks description rendering in the MCP Inspector UI and fails
Gemini API validation (requires top-level type field). MCP signals
optionality via the required array, making the anyOf/null wrapper
redundant.
- Add simplify_optional_schema() utility that collapses nullable anyOf
into flat {"type": "T"} while preserving description, default, title
- Override MCPServer.add_tool() to apply simplification after Pydantic
generates the schema
- Add 12 unit tests for the schema simplifier (test_json_schema.py)
- Add 23 unit tests for tool schema output (test_list_tool_format.py)
- Update server_example.py with representative parameter patterns
including Literal enum types
* docs(python/server): add parameter types and JSON Schema section to tools docs
Document the Python-to-JSON-Schema type mapping, required/optional/nullable
parameter patterns, and Literal enum usage. Includes a note explaining the
anyOf/null simplification that mcp-use applies automatically.
* fix(python/server): address PR review comments on json_schema.py
- Fix _simplify_property docstring: says "in place" but returns new dict
- Fix simplify_optional_schema docstring: document fast-path return when
no properties exist (returns original, not a copy)
- Wrap dict comprehension for line length
* style: format server_example.py
* docs: regenerate API reference for json_schema module
* fix: use WeakSet for resource subscriptions to prevent memory leak on client disconnect
Fixes#1092
Previously, resource subscriptions tracked sessions by storing id(session)
integers in plain sets. When clients disconnected without explicitly
unsubscribing, these integer IDs accumulated indefinitely since there was
no cleanup mechanism for dropped connections.
This change replaces the dict[str, set[int]] with dict[str, WeakSet],
storing weak references to session objects directly. When a session is
garbage-collected (after disconnect), its entry is automatically removed
from all subscription sets.
This also simplifies notify_resource_updated() — instead of iterating all
active sessions and checking membership by id, we now iterate the WeakSet
subscribers directly, which is both correct and more efficient.
* style: use idiomatic emptiness check for WeakSet
Replace `if not len(subscribers)` with `if not subscribers` for consistency
with the existing check in notify_resource_updated().
* fix: clean up empty subscription entries + add unit tests
- Clean up empty dict entries in notify_resource_updated() after all
sessions for a URI are GC'd, preventing stale keys from accumulating
- Add 4 unit tests for GC-driven subscription cleanup:
- test_subscription_cleanup_after_session_gc
- test_notify_skips_gc_collected_sessions
- test_notify_does_not_crash_when_all_sessions_gone
- test_multiple_uris_independent_cleanup
---------
Co-authored-by: User <user@example.com>
Co-authored-by: pietrozullo <pietro.zullo@gmail.com>
* fix(python): register debug routes when debug=True passed to run()
When MCPServer was created with debug=False (default) and run(debug=True)
was called, debug routes (/docs, /inspector, /openmcp.json) were never
registered because _add_dev_routes() only ran during __init__.
Now run(debug=True) calls _add_dev_routes() and rebuilds the Starlette
app so routes are available. Also removes dead code in ServerRunner that
could never execute due to the same ordering issue.
Closes#1099
* docs: regenerate API reference after removing debug from ServerRunner.run()
The debug parameter was removed from ServerRunner.run() since debug mode
is now fully handled in MCPServer.run() before the runner is invoked.
* Fix DNS rebinding protection for cloud/proxy deployments
- Add host/port parameters to MCPServer.__init__() and pass to FastMCP
- Default host to "0.0.0.0" (cloud-friendly, disables DNS protection)
- "127.0.0.1" auto-enables DNS protection (handled by FastMCP)
- run() can override host/port, falls back to __init__ values
- Add comprehensive docstring to __init__() explaining parameters
- Update documentation
This fixes 421 Misdirected Request errors when running behind reverse
proxies (Cloudflare, nginx, etc.) where the Host header doesn't match
the auto-configured allowed_hosts for localhost.
* Fix DNS rebinding protection for cloud/proxy deployments
- Add host/port parameters to MCPServer.__init__() and pass to FastMCP
- Default host to "0.0.0.0" (cloud-friendly, disables DNS protection)
- "127.0.0.1" auto-enables DNS protection (handled by FastMCP)
- run() can override host/port and reconfigures DNS protection accordingly
- Rebuild app when host changes in run() to apply new security settings
- Add comprehensive docstring to __init__() explaining parameters
- Add unit tests for host/port configuration and run() overrides
- Update documentation
This fixes 421 Misdirected Request errors when running behind reverse
proxies (Cloudflare, nginx, etc.) where the Host header doesn't match
the auto-configured allowed_hosts for localhost.
* ruff lint
* Bump mcp minimum version to 1.23.0
Required for TransportSecuritySettings and DNS rebinding protection
auto-configuration feature that was added in v1.23.0.
* feat(server): add bearer token authentication for Python MCP server
Add HTTP-layer bearer token authentication that returns proper 401 responses.
- BearerAuthProvider: abstract base class with verify_token() method
- AccessToken: model with token, claims, and scopes fields
- AuthMiddleware: Starlette middleware returning HTTP 401 for invalid tokens
- get_access_token() / require_auth(): context helpers for tools
Usage:
```python
class MyAuth(BearerAuthProvider):
async def verify_token(self, token: str) -> AccessToken | None:
if token != "secret":
return None
return AccessToken(token=token, claims={"user": "alice"})
server = MCPServer(name="my-server", auth=MyAuth())
```
Closes#840
* autogenerate docs
* test(server): add unit and integration tests for bearer token auth
Unit tests:
- AccessToken model creation and serialization
- BearerAuthProvider abstract class and subclassing
- get_access_token/require_auth context helpers
- AuthMiddleware 401 responses, path exclusion, CORS
Integration tests:
- MCPClient connecting to bearer auth server with valid token
- Connection failure with invalid/missing token
- Tool access to user claims and scopes
* fix(server): address code review feedback for bearer auth
- Fix CORS security: allow_credentials=False with allow_origins=["*"]
- Remove dead try/except import for auth module
- Remove PII (email) from debug logs
- Add comment explaining broad exception handling in verify_token
- Add /openmcp.json to docs excluded paths list
- Remove set_access_token from public API (internal only)
- Create AuthenticationError instead of using ValueError
- Skip middleware tests on older httpx versions (TestClient compat)
* docs: update API documentation for auth module
* fix(server): address Copilot review feedback
- Fix bearer.mdx: require_auth raises AuthenticationError, not ValueError
- Fix API docs: claims and scopes are optional with defaults, not required
- Remove deprecated SSE transport from bearer_auth_server.py test server
* autogenerate docs
* fix(server): address renvins review feedback
- Improve bearer.mdx claims documentation with explanation and examples
- Remove unnecessary cast() for AuthMiddleware in server.py
- Refactor auth tests to use pytest fixtures for cleaner setup/teardown
* docs(auth): clarify that all MCP endpoints are automatically protected
- Add "What Gets Protected" section explaining automatic protection
- Clarify that get_access_token/require_auth are for accessing token data, not protection
- Update examples to show proper usage pattern
- Improve Note at bottom to be clearer
* fix(auth): prevent path prefix bypass in auth middleware
Security fix: Use exact path matching or segment-based prefix matching
instead of simple startswith() to prevent auth bypass attacks.
Before: /docs-secret would bypass auth because it starts with /docs
After: Only /docs and /docs/* bypass auth, /docs-secret requires auth
Added tests for path matching security edge cases.
* refactor(auth): update import paths for authentication components
- Changed import statements in multiple documentation files and source files to reflect the new structure, moving authentication-related imports to the `auth` submodule.
- Updated examples to ensure clarity and consistency in usage patterns for `BearerAuthProvider`, `AccessToken`, `get_access_token`, and `require_auth`.
* Fix DNS rebinding protection for cloud/proxy deployments
- Add host/port parameters to MCPServer.__init__() and pass to FastMCP
- Default host to "0.0.0.0" (cloud-friendly, disables DNS protection)
- "127.0.0.1" auto-enables DNS protection (handled by FastMCP)
- run() can override host/port, falls back to __init__ values
- Add comprehensive docstring to __init__() explaining parameters
- Update documentation
This fixes 421 Misdirected Request errors when running behind reverse
proxies (Cloudflare, nginx, etc.) where the Host header doesn't match
the auto-configured allowed_hosts for localhost.
* Fix DNS rebinding protection for cloud/proxy deployments
- Add host/port parameters to MCPServer.__init__() and pass to FastMCP
- Default host to "0.0.0.0" (cloud-friendly, disables DNS protection)
- "127.0.0.1" auto-enables DNS protection (handled by FastMCP)
- run() can override host/port and reconfigures DNS protection accordingly
- Rebuild app when host changes in run() to apply new security settings
- Add comprehensive docstring to __init__() explaining parameters
- Add unit tests for host/port configuration and run() overrides
- Update documentation
This fixes 421 Misdirected Request errors when running behind reverse
proxies (Cloudflare, nginx, etc.) where the Host header doesn't match
the auto-configured allowed_hosts for localhost.
* ruff lint
* Bump mcp minimum version to 1.23.0
Required for TransportSecuritySettings and DNS rebinding protection
auto-configuration feature that was added in v1.23.0.
* fix(python/server): improve debug and pretty_print_jsonrpc behavior
- Make pretty_print_jsonrpc work independently of debug_level
(previously required DEBUG=2 environment variable)
- Rename run_debug to debug in server.run() for consistency
- Make run(debug=True) override server's debug_level if it was 0
- Remove aggressive signal handlers that broke thread compatibility
(uvicorn handles SIGINT/SIGTERM gracefully)
- Update all documentation to use new debug parameter name
* refactor(python/server): remove unused lupo_tool function from server_example.py
* docs: update signals API reference after simplification
* refactor: remove unused signals.py module
uvicorn already handles SIGINT/SIGTERM gracefully, so custom signal
handlers are unnecessary. Removed the signals.py file and all references
to setup_signal_handlers().
* chore: remove analysis files
* chore: add example server pretty print JSON RPC for transparency
* updated telemetry module
* chore: agent side tel - langchain adapter - client tel
* server side tel:
* update API reference
* python transports and primitive reports are publishes only if not skipped
* remove wrongly generate files
* properly typed middleware
* remove examples
* feat(docs): add middleware and session management documentation
- Introduced new documentation for middleware, detailing hooks, minimal examples, and best practices for integrating middleware in MCP servers.
- Added a session management guide explaining session ID handling, usage patterns, and examples for managing per-client state in MCP servers.
- Updated to include links to the new middleware and session management pages.
* generate docs
* remove few events
* adapter tel
* adapter tel
* api ref docs update
* google adapter fix
* fix version
* fix event naming
* server example is streamable and echo tool fix
* removed initialize middleware hook, initialize requests are not passed thorugh normal handlers
* api ref
* beta on middleware
* feat: server first implementation
* docs: docs for server and images
* chore: locked langchain dependencies in pyproject.toml (#321)
* python/release/1.3.13
* catch uvicorn logs && log session id
* fix debug logic
* docs: logging update
* fix: icon of elicitation
* fix installation paths for local clones
* docs: minor restructuring
* docs: reorganization, killed non existing pages
* docs: beta tag on server
* chore: example servers
* feat: inspector autopopulated and client only
* feat: enhance MCP logging system with customizable formats and improved middleware
* feat: implement weather alert and forecast tools in FastMCP example server
* mcp path configurable
* fix inspector
* export as FastMCP too
* chore: update fastmcp migration example
* lock inspector version
* type runner
* unhide docs and remove dangers
* migration diff
* docs and context example
* export context
* logging improvement
* pretty JSON RPC
* autoConnect url param in inspecotr
* move logging
* type check
* Server Router
* show response logs
* fallback tool name to function name in router registration
* compatibility export
* Introduced ty and prek as type checker and precommit engine respectively - moved ruff config in pyproject toml
* add ty check
* ty runs only on staged files
* ty configuration fix
* move startup info in logging
* remove bug from action
* update claude rules
* fix resource serialization
* comments on inspector errors
* abstracted runner transports
* remove redunant call for network
* fix ip getter
* add inspector mcp path
* response limit logging
* disable ty check in action
* moved transport type to types
* support sse
* show transport type in logs
* change default transport
* refactored tests to use mcp server
* removed fastmcp
* file restructuring
* test table
* sampling, elicitation, tool disabling enabling
* deprecte sse server side
* simplified report
* fix action
* remove sse deprecated test
* move tests files to allow for server integration tests
* docs
* reorg integration test files
* api-reference-doxs
* fix broken links
* telemetry
* remove feature useage from scarf