Skip to content

Restore mcp.server.fastmcp as a deprecated import alias for MCPServer - #3189

Closed
maxisbey wants to merge 2 commits into
mainfrom
fastmcp-import-shim
Closed

Restore mcp.server.fastmcp as a deprecated import alias for MCPServer#3189
maxisbey wants to merge 2 commits into
mainfrom
fastmcp-import-shim

Conversation

@maxisbey

Copy link
Copy Markdown
Contributor

Adds a deprecated mcp.server.fastmcp import path so the single most common line in v1 code, from mcp.server.fastmcp import FastMCP, resolves again on v2 (with an MCPDeprecationWarning) instead of raising ModuleNotFoundError, and makes MCPServer's constructor keyword-only after name.

Motivation and Context

from mcp.server.fastmcp import FastMCP is the first line of nearly every v1 server, and of most tutorial and LLM-generated code, so it's row 1 of the migration guide's "changes almost every project hits" table. For decorator-built servers the rename is genuinely most of the port: the README-shaped v1 quickstart (FastMCP("Demo") + @mcp.tool() / @mcp.resource() / @mcp.prompt() + mcp.run()) runs unmodified on v2 given only the class alias. This is the one v1 name where the alias alone rescues real programs, which is the line for shimming it — mcp.types and McpError stay hard breaks because an alias there saves nobody.

Scope is deliberately narrow:

  • Package init only. FastMCP, Context, Image, Audio, Icon (v1's exact __all__) resolve to the v2 objects; mcp.server.fastmcp.server, .prompts.base, etc. still raise ModuleNotFoundError, since nothing beneath them is behaviour-equivalent.
  • The warning is honest. It says this is not just a rename (default server name, transport params off the constructor, sync handlers on a worker thread) and links the guide. MCPDeprecationWarning subclasses UserWarning, so it shows without -W. Removed in v3.
  • from mcp.server import FastMCP is not restored (v1 exported it there too): that needs a module-level __getattr__ on mcp.server, which loosens static checking of every from mcp.server import ... for all downstream users.
  • No API-reference page — the doc generator skips deprecated shim modules.

The keyword-only constructor closes the one hazard the shim would otherwise make silent. v2 inserted title/description ahead of instructions, so a v1 FastMCP("Demo", "You answer questions about the weather.") used to run without complaint and land the instructions in title; with the import erroring, users at least met the guide first. Now that the import warns and continues, that call raises TypeError instead — for shim users and mechanical-rename users alike, matching what the lowlevel Server already does. The migration guide's constructor section is rewritten from "silently misassigns" to "raises".

How Has This Been Tested?

  • New tests/server/test_fastmcp.py: the import warns with the replacement named, and the five re-exports are the v2 objects (FastMCP is MCPServer, v1 __all__ preserved). Full suite: ./scripts/test at 100% coverage, strict-no-cover clean; pyright 0 errors.
  • Ran an unmodified v1 README-shaped server end-to-end through the old import against an in-process Client: tool call, resource template, and prompt all round-trip; the warning is attributed to the user's own import line (stacklevel correct) and fires once per process.
  • Probed the edges: from mcp.server.fastmcp.prompts import baseModuleNotFoundError; positional FastMCP('Demo', 'instructions') → the TypeError quoted in the guide; python -W error::UserWarning -c 'import mcp.server.fastmcp' → raises the warning cleanly by category; from mcp.server import FastMCP → still ImportError.
  • Regenerated docs/api/ before and after: no fastmcp page either way.

Breaking Changes

  • MCPServer(...) no longer accepts title, description, instructions, website_url, icons, version, auth_server_provider, or token_verifier positionally — pass them by keyword (the migration guide already recommended this; the signature now enforces it). Documented in docs/migration.md.
  • The new import path is additive (previously it did not exist), gated behind a deprecation warning.

Types of changes

  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

AI Disclaimer

`from mcp.server.fastmcp import FastMCP` (and the Context, Image,
Audio, Icon names v1 exported alongside it) resolves again, to the v2
objects, and emits MCPDeprecationWarning at import. Only the package
init is shimmed; the fastmcp submodule tree still raises
ModuleNotFoundError. The alias is removed in v3.

MCPServer's constructor now takes everything after `name` as
keyword-only, matching the lowlevel Server. A v1 call that passed
`instructions` positionally previously landed the text in the new
`title` parameter silently; it now raises TypeError, which matters
more once the old import path stops forcing users through the guide.
@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

📚 Documentation preview

Preview https://pr-3189.mcp-python-docs.pages.dev
Deployment https://22ebe0d6.mcp-python-docs.pages.dev
Commit 5f87d39
Triggered by @maxisbey
Updated 2026-07-27 20:14:27 UTC

@cubic-dev-ai cubic-dev-ai 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.

No issues found across 5 files

Re-trigger cubic

The rename section still called it a simple rename with no functional
changes, contradicting the bridge paragraph and the runtime warning,
and it claimed the warning enumerates the silent behaviour changes when
it points at the guide instead.

No-Verification-Needed: doc-only change
Comment on lines +1 to +16
"""Deprecated import path: `FastMCP` was renamed to `MCPServer` in v2.

This module keeps `from mcp.server.fastmcp import FastMCP` working so v1 code
runs, but importing it emits an `MCPDeprecationWarning`. It is not a
behaviour-preserving alias: v2 changed defaults and semantics beyond the name
(the default server name, transport parameters moving off the constructor,
sync handlers running on a worker thread). Read the migration guide before
relying on it:

https://py.sdk.modelcontextprotocol.io/v2/migration/

Only this package init is shimmed. Submodules such as
`mcp.server.fastmcp.server` or `mcp.server.fastmcp.prompts.base` no longer
exist; their contents live under `mcp.server.mcpserver`. This module is removed
in v3.
"""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 docs/whats-new.md line 19 still says the old mcp.server.fastmcp import path "is gone rather than deprecated" — after this PR that sentence is wrong on both counts, since the path exists again and emits an MCPDeprecationWarning (only its submodules still raise ModuleNotFoundError). A one-sentence edit to whats-new.md (mirroring the updated symptom row in docs/migration.md) brings it in line.

Extended reasoning...

What's wrong: docs/whats-new.md line 19, in the "FastMCP is now MCPServer" section, reads: "This is the first thing every v1 server hits, because the old import path is gone rather than deprecated." This PR's headline change is precisely that the old import path is no longer gone and is now deprecated: the new src/mcp/server/fastmcp/__init__.py shim makes from mcp.server.fastmcp import FastMCP (plus Context, Image, Audio, Icon) resolve to the v2 objects while emitting an MCPDeprecationWarning. The sentence is therefore false on both counts once this PR merges.

Why it slipped through: the PR did update the docs for this behaviour change — docs/migration.md's quick-reference table now says MCPDeprecationWarning: mcp.server.fastmcp is deprecated, or ModuleNotFoundError for its submodules, and a new paragraph in the "FastMCP renamed" section describes the bridge. But docs/whats-new.md covers the same rename in its own words and wasn't touched, so the two pages now contradict each other about the PR's central feature. AGENTS.md asks that changes affecting user-visible behaviour update the relevant docs/ pages in the same PR, which suggests this is an oversight rather than a scoping decision.

Concrete walkthrough: a v1 user upgrading to v2 reads whats-new.md, which tells them their first symptom will be an import error because "the old import path is gone." They then run their server: from mcp.server.fastmcp import FastMCP succeeds with a warning, and FastMCP("Demo") works (it's MCPServer under the old name). The doc's claim doesn't match what they observe — and worse, a user who trusts the doc might not realize the warning-emitting shim is a temporary bridge removed in v3. Meanwhile migration.md (correctly) tells the same reader the path "is not gone entirely."

Impact: documentation-only. Nothing breaks at runtime; the shim, warning, and tests in this PR all behave as intended. The cost is reader confusion between two docs pages describing the same rename, on the exact behaviour this PR changes.

Fix: a one-sentence edit to docs/whats-new.md line 19, e.g.: "This is the first thing every v1 server hits — the top-level import now resolves with an MCPDeprecationWarning (removed in v3), while submodules like mcp.server.fastmcp.server still raise ModuleNotFoundError." That matches the framing the PR already adopted in docs/migration.md.

All three verifiers confirmed the finding; two rated it nit and one normal. Since the code is correct and only a doc sentence is stale, this doesn't warrant blocking the merge — nit severity.

@maxisbey

Copy link
Copy Markdown
Contributor Author

I don't think this is worth doing

@maxisbey maxisbey closed this Jul 28, 2026
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