Skip to content

chore: bump mcp SDK to 2.3.0 - #130

Merged
ChiragAgg5k merged 4 commits into
mainfrom
chore/bump-mcp-sdk-2.3.0
Oct 9, 2026
Merged

ChiragAgg5k merged 4 commits into
mainfrom
chore/bump-mcp-sdk-2.3.0

Conversation

@ChiragAgg5k

@ChiragAgg5k ChiragAgg5k commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

Summary

Bumps the mcp Python SDK from 2.0.0 to 2.3.0 and raises the floor in pyproject.toml from mcp[cli]>=2,<3 to mcp[cli]>=2.3,<3. The floor is required: the server now passes Server(get_tool_input_schema=...), which only exists from 2.3.0 (11 unit tests fail with TypeError on 2.0.0). It also stops installs from resolving the 2.0.0 release that answers notification POSTs with a 400.

Transitive lockfile changes: mcp-types 2.0.0 -> 2.3.0, httpx2 and httpcore2 2.9.1 -> 2.13.1 (2.3.0 requires httpx2>=2.10), and httpx2-jsfetch 1.0 is added, but only for sys_platform == 'emscripten', so nothing changes on Linux or macOS.

Two small fixes ride along because the upgrade exposed them:

  • Phantom tools/list telemetry. On the 2026-07-28 HTTP entry the SDK checks Mcp-Param-* headers on every tools/call that has arguments. With no schema lookup it ran our tools/list handler to get the schema, so each tool call also recorded a tools/list in mcp.* metrics. The server now passes get_tool_input_schema, which finds the schema by name (python-sdk#3630).
  • stdio initialize result. run_stdio built InitializationOptions by hand. That gave stdio clients a different serverInfo.name (appwrite) from the one HTTP clients see (Appwrite MCP Server), left out instructions, icons and websiteUrl, and sent "experimental": {}, which 2.3.0 drops everywhere else (python-sdk#3614). It now calls server.create_initialization_options(), the same path the HTTP transport uses. Visible effect: stdio clients now receive the server instructions and see the same server name as HTTP clients.

This prepares for #127 (MCP events) by moving us to the current 2.x line, but it does not complete it: 2.3.0 still has no events support (modelcontextprotocol/python-sdk#3640).

What we gain

Version Upstream PR Effect on appwrite-mcp
2.1.0 #3326 A notification POST (e.g. notifications/cancelled) on the hosted 2026-07-28 entry now gets 202 instead of a 400 JSON-RPC error, on both / and /mcp. Covered by a new regression test that drives the real Starlette app.
2.3.0 #3630 Adds Server(get_tool_input_schema=...). We use it so tools/call no longer runs a hidden tools/list (which inflated tools/list counts in telemetry). Covered by a regression test.
2.3.0 #3614 HTTP initialize stops sending an empty experimental capability. stdio now does the same because it shares the SDK path (see Summary). Covered by a regression test.
2.3.0 #3628 Legacy requests may arrive with no _meta or params. _client_identity_from_ctx already handles ctx.meta is None, and MCPIdentityMiddleware already handles missing params. No test or wire assertion relied on the empty forms.

Not applicable

Stateful-session changes (#3395 idle expiry and session cap, DELETE and refused-open cleanup): we run StreamableHTTPSessionManager(stateless=True). MCPServer-only changes (#3314 handler-exception logging, #3320 content-block returns, #3620 x-mcp-header registration, #3626 subscriptions=False, #3624); client-side changes (#3394 outputSchema $ref resolution: our catalogs have no outputSchema; #3223 cache-hint fields: we emit none; #3397 redirects, #3398/#3435 OAuth client issuer, #3600 max_sse_event_size, #3627, #3635); #3447 AuthSettings.validate_token_resource: we use BearerAuthBackend directly, so no deprecation warning; #3336 SSE/OAuth body limit: no SSE transport and no SDK OAuth endpoints; #3354 boolean sub-schemas: none in our generated schemas.

Verification

All commands ran on Python 3.12.8, matching CI:

  • uv lock --upgrade-package mcp: mcp 2.0.0 -> 2.3.0
  • uv run --group dev ruff check src tests: passed
  • uv run --group dev black --check src tests: 48 files unchanged
  • uv run --group dev pyright: 0 errors, 0 warnings
  • uv run python -m unittest discover -s tests/unit -v: 265 tests OK
  • New regression tests against mcp==2.0.0 (uv run --with mcp==2.0.0 --with mcp-types==2.0.0 ...): the notification test fails with 400 != 202 : {"code":-32600,"message":"Body must be a single JSON-RPC request object"}. The two fix tests fail on the parent commit without their fix (['tools/list', 'tools/call'] != ['tools/call'] and 'appwrite' != 'Appwrite MCP Server').
  • Catalog check (scratch script, not committed): both catalogs register. OAuth has 1016 hidden tools and API key has 676. Every tool passes mcp.types.Tool validation and Draft202012Validator.check_schema, with 0 outputSchema, 0 $ref and 0 boolean sub-schemas. An in-process mcp.Client connected in legacy mode (2025-11-25) and auto mode (2026-07-28) lists the public tools and calls appwrite_search_tools without errors.
  • docker build -t appwrite-mcp:ci .: image built successfully locally, and the CI Docker build job passed.
  • Integration tests: not run locally because no APPWRITE_* credentials were available. In CI: 24 tests, 10 passed, 14 skipped because CI also has no live Appwrite credentials (skipped 'Valid Appwrite credentials are required...').

Changelog

  • Updated the MCP Python SDK to 2.3.0. The minimum supported version is now 2.3.
  • Hosted server: on the 2026-07-28 protocol, notification POSTs such as notifications/cancelled are now accepted with 202 instead of rejected with 400.
  • Hosted server: tool calls no longer record an extra tools/list in usage metrics.
  • Self-hosted (stdio): the server now sends its instructions, icon and website URL during initialize, and reports the same server name as the hosted server.

Raise the floor to >=2.3 so installs can no longer resolve 2.0.0, which
rejects notification POSTs on the 2026-07-28 HTTP entry with a 400 and
lacks Server(get_tool_input_schema=...). Pulls httpx2/httpcore2 2.13.1
and mcp-types 2.3.0 transitively.
Drive the real hosted app and assert a POSTed notifications/cancelled is
answered with 202 on both / and /mcp. mcp 2.0.0 rejected it with a 400
JSON-RPC error (python-sdk#3326).
On the 2026-07-28 HTTP entry the SDK validates Mcp-Param-* headers on
every tools/call. Without Server(get_tool_input_schema=...) it does that
by running our tools/list handler, which recorded a phantom tools/list
in telemetry for each tool call. mcp 2.3.0 (python-sdk#3630) lets the
server answer the lookup by name instead.
run_stdio hand-built InitializationOptions, so stdio clients got a
different serverInfo name than HTTP clients, no instructions, icons or
website URL, and an empty experimental capability that mcp 2.3.0 now
omits everywhere else (python-sdk#3614). Use
Server.create_initialization_options() like the HTTP transport does.
@hansi-codes

hansi-codes Bot commented Oct 9, 2026

Copy link
Copy Markdown

🟢 Tier S · Ready to merge

No actionable defects found in the dependency update or server behavior changes.

Raises the MCP SDK minimum to 2.3.0 and updates the lockfile’s resolved SDK dependencies. The server now supplies direct tool-schema lookup and builds stdio initialization metadata through the SDK, with regression coverage for hosted notifications, tool-call telemetry, and stdio metadata.

Verdict New comments Fixed Still open
✅ Approved 0 0 0
📂 Walkthrough · 5
File Change
pyproject.toml Raises the minimum supported MCP SDK version to 2.3.
uv.lock Updates MCP and related transitive dependency resolutions.
src/mcp_server_appwrite/server.py Adds direct public-tool schema lookup and uses SDK-generated stdio initialization options.
tests/unit/test_http_app.py Adds hosted HTTP regression coverage for notifications and tool-call telemetry.
tests/unit/test_server.py Adds regression coverage for stdio initialization metadata.

Reviewed 40a8280 · Details · Comment @hansi-codes review to re-run, or mention @hansi-codes with a question.

@hansi-codes hansi-codes Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Tier S · Looks good to merge. Summary

@ChiragAgg5k
ChiragAgg5k merged commit 32616df into main Oct 9, 2026
5 checks passed
@ChiragAgg5k
ChiragAgg5k deleted the chore/bump-mcp-sdk-2.3.0 branch October 9, 2026 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant