* 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): 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.