4 Commits

Author SHA1 Message Date
Pietro Zullo e935514fc7 feat(python): add icons parameter to MCPServer constructor (#1147)
* 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
2026-03-05 10:17:58 +01:00
Pietro Zullo 869e56fcf4 fix(python): register debug routes when debug=True passed to run() (#1114)
* 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.
2026-02-27 15:32:04 +01:00
Pietro Zullo a9bc4db3ae feat(python): add protocol handlers for logging, completions, subscriptions, and DNS protection (#1004)
* feat(python): add protocol handlers for logging, completions, subscriptions, and DNS protection

Server SDK changes:
- logging/setLevel: stores client level, Context.log() filters by RFC 5424 severity
- completion/complete: default empty handler, overridable via mcp.completion()
- resources/subscribe + unsubscribe: tracks per-session subscriptions
- notify_resource_updated(): broadcasts to all subscribed sessions via WeakSet
- dns_rebinding_protection: explicit constructor parameter (default: False)
- Capabilities patch for subscribe=True

Middleware:
- Added hooks: on_set_logging_level, on_subscribe_resource, on_unsubscribe_resource, on_complete

Tests:
- 9 unit tests for log level filtering (RFC 5424)
- Updated DNS protection tests for explicit flag

Docs:
- logging.mdx: MCP protocol logging section with level filtering
- resources.mdx: subscription section with example
- middleware.mdx: new hooks documented

Refs:
- https://modelcontextprotocol.io/specification/2025-11-25/server/utilities/logging
- https://modelcontextprotocol.io/specification/2025-11-25/server/resources#subscriptions

* style: format adapter files for ruff 0.15
2026-02-14 18:53:30 -08:00
Pietro Zullo 79d017bdc2 fix(python): DNS rebinding protection for cloud/proxy deployments (#825)
* 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.
2026-01-19 15:32:58 +01:00