Once a week a job of mine installs every Python MCP server in the official registry, starts it, and asks it for its tools. There are 4,881 of them. In the newest run 2,200 started. 932 did not, and all 932 fail for the same reason: they were written for version 1 of the mcp SDK, and a fresh install now gets version 2.

Most of them need one line to work again. Here is how I found that out, the one line, and the part of the number I do not trust.

It started as a pile of "crashed"

I run mcpcost, an open-source probe of the MCP registry. Remote servers get a connection once a day. Package servers get installed in a container with no version pins, the same thing uvx does on your laptop, and then started with the network off.

At first the board had a status I did not look at closely: crashed. The process exits before it answers initialize. A server can crash for a hundred reasons, so I treated it as noise.

At the end of October I finally grouped the crashes by the last line of their output. I expected a long tail. I got this, 762 times:

ModuleNotFoundError: No module named 'mcp.server.fastmcp' 

Half of all crashed PyPI servers. One line.

What happened on 28 July

mcp 2.0.0 went to PyPI on 28 July 2026. It renamed FastMCP to MCPServer and moved it to a new module. from mcp.server.fastmcp import FastMCP is the first line of a lot of Python MCP servers, and these packages declare the dependency as mcp>=1.something. No upper bound. So pip and uv now pick 2.x, and the first import fails.

When I grouped the rest of the errors yesterday, four more texts turned out to be the same upgrade:

Error Servers What changed in mcp 2.0
No module named 'mcp.server.fastmcp' 787 FastMCP is now MCPServer in mcp.server.mcpserver
'Server' object has no attribute 'list_tools' 131 The lowlevel Server has no decorators. Handlers go to the constructor as on_list_tools=...
cannot import name 'FastMCP' from 'mcp.server' 10 The same rename
cannot import name 'McpError' 3 It is MCPError now
cannot import name 'streamablehttp_client' 1 Removed. Use streamable_http_client

That is 932 servers, 19 % of the Python servers in the registry, three and a half months after the release.

Does a pin fix it? I made the probe try

A count of broken things is not much use. I wanted to know if the obvious fix works, so I changed the probe: when a package stops at the FastMCP import, install it one more time with mcp<2 and start it again.

The first test run had nine packages. Eight started.

The packages are checked in a weekly cycle, so the full answer took a week to arrive. It is in now: 694 of the 787 start and list their tools with the pin. That is 88 %. The other 93 still do not start.

If you only want the server to start

uvx --with "mcp<2" <package> 

In a client config, put --with and mcp<2 in front of the package name in the args of uvx. With pip it is pip install "mcp<2" in the server's environment.

If you publish the server

One line in your dependencies, then a release:

dependencies = ["mcp>=1.2,<2"] 

The SDK's own migration guide says the same thing: keep a <2 bound until you have moved your code. For a FastMCP server the move itself is small:

# before from mcp.server.fastmcp import FastMCP mcp = FastMCP("Demo") # after from mcp.server.mcpserver import MCPServer mcp = MCPServer("Demo") 

@mcp.tool(), @mcp.resource() and @mcp.prompt() did not change. If you use the lowlevel Server with @server.list_tools(), the change is bigger, because the decorators are gone. I put the before and after for each of the five errors, with the list of servers that hit it, on one page per error.

The part of the number I do not trust

932 is the number of registry entries that stop. It is not the number of broken projects, and the difference matters.

A registry entry names one version of a package. The probe installs that version, because that is what a client that reads the registry gets. But publishers do not always update the entry when they release.

So I took the 21 entries with the most GitHub stars and checked each one by hand:

  • 10 have a newer release on PyPI than the version in the registry. At least 3 of those releases already have the fix, a pin or a real migration. The package is fine. The registry entry is old.
  • 3 more had the problem in their own issue tracker, open or already closed.
  • 6 showed no sign that anybody knew. The newest release still breaks, and nobody had reported it. I opened an issue for each of them today.
  • 2 I could not judge. One repository does not hold the server's code, and one package does not start with the pin either.

Twenty-one entries is a small sample, and the most-starred repositories are the best maintained ones, so do not stretch it over the other 900. But it changed how I read my own number. Some of it is a Python problem. Some of it is a stale registry problem that only looks like one.

Two more limits. The probe retries with mcp<2 only for the FastMCP error, so for the 131 list_tools servers I do not know yet how many a pin saves. And everything runs in a container with the network off. A server that needs the network at start-up gets a different status and is not in these numbers at all.

Why almost nobody notices

This is the part I find interesting.

The publisher's machine still has mcp 1.x in an environment from last spring. Their tests pass. Their own client config works. The server only fails for somebody who installs it today, and that person usually shrugs and tries the next server in the list.

The SDK team did react. About a month after the release they made the error say more. It does not stop at No module named now. The full text says that this is mcp 2.x, that FastMCP was renamed, and it links to the migration guide. It is a good error message. It just goes to the wrong person: the user reads it, and the user is not the one who can publish a fix.

That is the reason for the six issues. An error message cannot reach a publisher. A person can.

Check yours

Every server in the registry has a page with its newest result at https://mcpcost.ulehla.dev/s/<registry name>. If your assistant speaks MCP you can also ask it: the board is an MCP server too, at https://mcpcost.ulehla.dev/mcp, with no sign-in (how to add it). The probe and the data are open source: github.com/ondraulehla/mcpcost.

If you publish a Python MCP server, I would like to know two things. Did you pin, or did you migrate? And what broke that the guide did not warn you about? The lowlevel Server change looks like the hard one from here, and I have 131 servers that say so, but I have not done that migration myself.