In October 2026, MCP server development is remote-first. The official MCP Registry lists 43,012 active servers, and 78% of the servers first published there this month come with a remote URL, up from 27% in December 2025. Half of the remote servers I sampled answer a handshake without credentials, and most of the rest ask for OAuth the way the spec describes. The 2026-07-28 spec revision removed the initialize handshake, yet only 1 of the 500 servers I probed refused it.
Every number below was measured or checked on 14 October 2026, and each one links its source or points to the method section. I build LocalCan, which gives a server on your machine a Public URL (also called a tunnel), so weigh the client section with that in mind. An AI assistant helped draft this post. The commands and numbers come from my own runs.
Headline findings
- 43,012 active servers in the official registry, out of 43,538 names and 150,595 published versions (census).
- 64% of them have a remote URL. Among servers first published in October 2026, 78% do, or 77% with bulk publishers left out. In December 2025 it was 27%.
- SSE is nearly gone from the registry. 2.6% of remote servers list only the deprecated HTTP+SSE transport.
- 52% of sampled remote servers completed the handshake with no credentials. 39% answered
401 Unauthorized, and 85% of those 401s named their OAuth metadata in the header, where clients look first (probe). - 7% of sampled remote servers were dead at the URL they list: no answer, a 404 or 405, or a server error.
- 23% of handshakes that reported a version came from a spec revision older than
2025-11-25. - The TypeScript SDK was downloaded 273.3 million times in 30 days, 8.7 times the same window a year earlier (SDK downloads).
- Hosted clients still cannot reach a server on your machine directly. Claude's custom connectors and the Claude API's MCP connector reach your server from Anthropic's cloud. ChatGPT now offers OpenAI's own tunnel as the alternative (client table).
Method and sample
Registry census. I paged through the official registry's public API (https://registry.modelcontextprotocol.io/v0.1/servers, 100 per page, 1,506 pages) on 14 October 2026 and kept the latest version of each server name. 526 names have a deprecated latest version and are left out, which leaves 43,012 active servers. "First published" is the date of a server's oldest version, so a month's count covers servers from that month that are still active today. The registry is in preview and warns that "breaking changes or data resets may occur before general availability" (registry about page↗). Entries are self-declared metadata, so a listed remote URL is a claim until something connects to it. LocalCan's own server, com.localcan/mcp, is one of the entries.
Bulk publishers. 27 namespaces publish more than 50 servers each and hold 9,094 of the 43,012. The ten largest hold 17.8%. The remote-URL shares are given both ways.
Handshake probe. The sampling frame is every active server with a Streamable HTTP remote whose URL has no {template} placeholder, one server picked at random per namespace: 16,718 servers. From that frame I drew 500 at random (seed 20261014). Each got exactly one request, the one that opens every 2025-era connection: an unauthenticated initialize POST with protocol version 2025-11-25, a 10-second timeout, redirects not followed, and a user agent that names LocalCan. The run took 50 seconds from a connection in Europe. With 500 servers the margin is about 4.4 points at 95% confidence, and because the frame is one server per namespace, the shares describe publishers more than individual listings.
Downloads. npm counts come from the npm downloads API↗ for the same 30-day window a year apart. PyPI counts come from pypistats.org↗, which leaves out known mirrors and keeps 180 days. Both count installs, CI runs included, so they measure activity, not people.
What changed in the 2026-07-28 spec?
The current revision is 2026-07-28 (versioning page↗). Its release candidate was published on 29 May 2026 and the final release on 28 July 2026 (GitHub releases↗).
| Revision | What server developers got |
|---|---|
2024-11-05 | The first release: stdio and HTTP with SSE, tools, resources, prompts |
2025-03-26 | Streamable HTTP replaces HTTP+SSE, an authorization framework based on OAuth 2.1 |
2025-06-18 | Servers must publish OAuth Protected Resource Metadata (RFC 9728), JSON-RPC batching removed, elicitation, structured tool output |
2025-11-25 | Experimental tasks, Client ID Metadata Documents as the recommended client registration, icons, incremental scope consent |
2026-07-28 | No initialize handshake, no sessions, a required server/discover, Tasks moved to an extension |
Sources: the changelog of each revision, for example 2025-06-18↗, 2025-11-25↗ and 2026-07-28↗.
The 2026-07-28 revision is the biggest break since Streamable HTTP (changelog↗). Every request now carries its protocol version and client capabilities in _meta, so the protocol keeps no state between calls. The Mcp-Session-Id header and the HTTP GET stream are gone, replaced by an opt-in subscriptions/listen stream.
Servers that need input mid-call return an input_required result instead of sending their own requests to the client. Streamable HTTP POSTs must now carry an Mcp-Method header, plus Mcp-Name for named calls such as a tool call (the capture below shows both). Roots, Sampling, Logging and Dynamic Client Registration are deprecated under a new feature lifecycle policy↗ with a minimum twelve-month deprecation window, so they become eligible for removal only in the first revision released as Current on or after 28 July 2027 (deprecated features↗).
The project changed hands the year before. Anthropic donated MCP to the Agentic AI Foundation under the Linux Foundation on 9 December 2025, with AWS, Anthropic, Block, Bloomberg, Cloudflare, Google, Microsoft and OpenAI as platinum members (Anthropic↗, AAIF members↗). The roadmap published on 22 August 2026 lists five areas of work, and the Server Card working group, which defines .well-known metadata for servers, has not shipped yet (MCP roadmap↗).
What the change looks like on the wire
To see the difference, I ran a small server on TypeScript SDK 2.3.1 and called it through a Public URL with both kinds of client. The SDK's createMcpHandler serves both protocol eras from one server factory, as in the SDK's dual-era example↗:
import { serve } from '@hono/node-server'
import { createMcpHandler, McpServer } from '@modelcontextprotocol/server'
import * as z from 'zod/v4'
const buildServer = ctx => {
const server = new McpServer({ name: 'greeting', version: '1.0.0' }, { capabilities: { tools: {} } })
server.registerTool('greet', { description: 'Greet by name', inputSchema: z.object({ name: z.string() }) },
async ({ name }) => ({ content: [{ type: 'text', text: `Hello, ${name}! (${ctx.era} era)` }] }))
return server
}
const handler = createMcpHandler(buildServer)
serve({ fetch: req => handler.fetch(req), port: 8765, hostname: '127.0.0.1' }, () => console.error('listening on http://127.0.0.1:8765/mcp'))
Then a Public URL for port 8765 with the localcan http quick tunnel:
localcan http 8765
Connecting tunnel to http://localhost:8765...
Forwarding https://quiet-mouse.local:5443 → localhost:8765
Forwarding http://quiet-mouse.local → localhost:8765
Forwarding https://quiet-mouse.localcan.dev → localhost:8765
One client per era called the greet tool at https://quiet-mouse.localcan.dev/mcp. The first used the SDK's default mode, the second probed the server with server/discover:
legacy -> legacy 2025-11-25 | Hello, legacy! (legacy era)
auto -> modern 2026-07-28 | Hello, auto! (modern era)
The traffic inspector shows what each one sent. The 2025-era client needs four requests for one tool call, the 2026-07-28 client needs two:
localcan traffic ls --host quiet-mouse.localcan.dev
ID TIME METHOD STATUS DUR PATH HOST
c2d8cf90 21:12:36 POST 200 6ms /mcp quiet-mouse.localcan.dev
2347d621 21:12:36 POST 200 3ms /mcp quiet-mouse.localcan.dev
60e53f14 21:12:35 POST 200 3ms /mcp quiet-mouse.localcan.dev
833f80bd 21:12:35 GET 405 13ms /mcp quiet-mouse.localcan.dev
e67fbdd0 21:12:35 POST 202 4ms /mcp quiet-mouse.localcan.dev
14154d73 21:12:35 POST 200 8ms /mcp quiet-mouse.localcan.dev
Read from the bottom up. The 2025-era client sends initialize and gets the answer as a server-sent event, confirms with notifications/initialized (202), tries to open the GET stream (405, the new server has none), then calls the tool. The 2026-07-28 client asks server/discover and gets back the versions it supports, then calls the tool with everything in the request. Here is that tool call, with 12 of its 18 request headers trimmed:
POST /mcp HTTP/1.1
Host: quiet-mouse.localcan.dev
accept: application/json, text/event-stream
content-type: application/json
mcp-method: tools/call
mcp-name: greet
mcp-protocol-version: 2026-07-28
{"method":"tools/call","params":{"name":"greet","arguments":{"name":"auto"},"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientInfo":{"name":"capture-auto","version":"1.0.0"},"io.modelcontextprotocol/clientCapabilities":{}}},"jsonrpc":"2.0","id":0}
The v2 client's default still speaks 2025: with no versionNegotiation option it sends "the 2025 initialize handshake, byte for byte" (SDK protocol versions doc↗). A server that drops the old handshake breaks every client still on the default, and the probe below found only one server that has dropped it.
What the registry says
Is MCP still growing?
Yes, by the registry and npm counts. New registry servers per month grew from 1,894 in March 2026 to 11,809 in September. The share that ships as a remote URL grew alongside:
| First published | New servers | Without bulk publishers | With a remote URL, without bulk |
|---|---|---|---|
| Sep 2025 | 454 | 323 | 35% |
| Oct 2025 | 293 | 207 | 35% |
| Nov 2025 | 171 | 171 | 31% |
| Dec 2025 | 274 | 274 | 27% |
| Jan 2026 | 386 | 365 | 28% |
| Feb 2026 | 1,071 | 1,070 | 29% |
| Mar 2026 | 1,894 | 1,873 | 31% |
| Apr 2026 | 2,526 | 2,020 | 44% |
| May 2026 | 2,993 | 2,132 | 44% |
| Jun 2026 | 3,806 | 2,829 | 54% |
| Jul 2026 | 5,025 | 4,595 | 58% |
| Aug 2026 | 6,464 | 5,007 | 66% |
| Sep 2026 | 11,809 | 7,493 | 75% |
| Oct 1 to 14, 2026 | 5,846 | 5,559 | 77% |
The registry opened in preview on 8 September 2025 (MCP blog↗), so the first months are thin, and servers deleted or deprecated since are missing from every row.
Across all 43,012 servers, 59.6% are remote-only, 34.6% ship only as a package you run yourself, 4.7% offer both, and 1.1% list neither (LocalCan's entry is one of those, since the server ships with the LocalCan app and CLI). Without the bulk publishers, 60.6% have a remote URL.
The official list of MCP servers is the MCP Registry itself, the source of every count in this section. The other directories count by their own rules, so their totals don't compare with the registry or with each other. On the same day Glama showed 97,619 servers (Glama↗), Smithery more than 26,700 (Smithery↗) and PulseMCP 21,710 (PulseMCP↗).
Which transports and package registries do servers use?
Of the 16,896 servers that list a package, 64.0% publish to npm, 25.6% to PyPI, 6.7% as an MCP Bundle (.mcpb, the format formerly called DXT, MCP Bundle repository↗), 6.5% as a container image, 0.9% to NuGet and 0.5% to crates.io. 97.1% of those packages run over stdio only.
Of the 27,655 servers with a remote URL, 96.1% list only Streamable HTTP, 1.3% list both Streamable HTTP and SSE, and 2.6% list only SSE. Every one of the 28,332 remote URLs uses https://. Among general-purpose hosting platforms, the most common hostname suffix is workers.dev (Cloudflare Workers) with 3,130 URLs, then vercel.app (342), railway.app (247) and onrender.com (244). A server on a custom domain hides its host, so these are floors.
Hosted vendors have been switching SSE off. Keboola stopped accepting SSE connections after 1 April 2026 (Keboola changelog↗), and Asana scheduled its V1 SSE server to shut down on 5 August 2026 (Asana docs↗). Atlassian set a 30 June 2026 cutoff for its SSE endpoint, then deferred it (atlassian-mcp-server issue #212↗).
Who publishes servers?
26,339 namespaces publish the 43,012 servers, and 23,859 of them publish exactly one. A namespace is either a GitHub user or organization (io.github.<name>, 62.6% of servers) or a domain the publisher verified through DNS or HTTP, such as com.localcan (37.4%) (registry authentication↗). The two groups build different things: 91.4% of servers under a verified domain have a remote URL, against 48.1% under a GitHub namespace.
Do remote MCP servers require authentication?
One unauthenticated initialize to each of the 500 sampled servers came back like this:
| Answer | Servers | Share |
|---|---|---|
| Completed the handshake, no credentials | 259 | 51.8% |
401, with resource_metadata pointing to OAuth discovery | 165 | 33.0% |
401, WWW-Authenticate without resource_metadata | 16 | 3.2% |
401, no WWW-Authenticate header | 12 | 2.4% |
| JSON-RPC error without a 401 | 3 | 0.6% |
| 402 Payment Required | 2 | 0.4% |
| Redirect, 403 or 429 | 8 | 1.6% |
| 404 or 405 at the listed URL | 13 | 2.6% |
| 5xx | 5 | 1.0% |
| No answer (9 timeouts, 5 DNS failures, 2 resets, 1 TLS error) | 17 | 3.4% |
Most OAuth servers use the discovery path clients try first. A server that wants OAuth must point clients to its Protected Resource Metadata, either with resource_metadata in the 401's WWW-Authenticate header or at a .well-known URL, and clients must use the header when it is there (authorization spec↗). 165 of the 193 servers that answered 401 use the header, which is 85.5%. The other 28 either serve the metadata at the .well-known path, which the probe did not request, or expect something else, such as an API key.
80 of the 500 entries declare a header in the registry (64 of them Authorization, 15 a spelling of X-API-Key), and 27 of those still completed the handshake without one. The full OAuth round trip, from the 401 to a token Claude can use, is walked through in adding OAuth 2.1 to an MCP server.
A completed handshake is an upper bound on open servers. A server can answer initialize for anyone and check credentials only on tools/call, so some of the 51.8% may still lock their tools. Two 2026 studies that went further found lower shares: 40.55% of 7,973 live remote servers "expose tools without authentication" (arXiv 2605.22333↗), and Bloomberry's scan of 1,412 company servers found no authentication on 38.7% of those where it could tell (Bloomberry↗). The NSA's AI Security Center tells organizations to "regularly scan their networks to identify insecure or unauthorized MCP servers" in its May 2026 guidance (NSA AISC PDF↗).
Nearly a quarter of servers that completed the handshake answer with a revision older than 2025-11-25. The probe asked for 2025-11-25, and a server that supports it must answer with it (lifecycle spec↗). 197 of the 257 handshakes I could parse did. The rest answered with what they have: 42 with 2025-06-18, 9 with 2025-03-26 and 8 with 2024-11-05. That is 23.0% on a revision older than the one current until July. One server answered 2026-07-28 anyway, and one refused the old handshake with "MCP-Protocol-Version must be 2026-07-28." The probe cannot tell how many servers also speak 2026-07-28, because a dual-era server answers an initialize in the 2025 dialect.
SDKs, versions and downloads
Which SDK versions are current?
The MCP project ranks its SDKs in tiers by feature completeness and maintenance commitment (SDK list↗). Latest releases and stars on 14 October 2026, from each repository on GitHub:
| SDK | Tier | Repository | Latest release | GitHub stars |
|---|---|---|---|---|
| TypeScript v2 | 1 | typescript-sdk↗ | 2.3.1, 5 Oct 2026 | 13,583 |
| TypeScript v1 | 1 | same, v1.x branch | 1.32.1, 5 Oct 2026 (npm) | same repository |
| Python | 1 | python-sdk↗ | 2.3.0, 2 Oct 2026 | 24,574 |
| C# | 1 | csharp-sdk↗ | 2.2.0, 13 Aug 2026 | 4,584 |
| Go | 1 | go-sdk↗ | 1.8.0, 14 Sep 2026 | 5,219 |
| Rust | 1 | rust-sdk↗ | rmcp 3.5.1, 5 Oct 2026 | 4,016 |
| Ruby | 1 | ruby-sdk↗ | 1.7.0, 5 Oct 2026 | 927 |
| Java | 2 | java-sdk↗ | 2.0.1, 19 Aug 2026 | 3,734 |
| Kotlin | 3 | kotlin-sdk↗ | 0.15.0, 28 Jul 2026 | 1,468 |
| PHP | 3 | php-sdk↗ | 0.8.1, 29 Aug 2026 | 1,629 |
| Swift | 3 | swift-sdk↗ | 0.12.1, 7 May 2026 | 1,508 |
Four version facts to check before you pin:
- TypeScript v2 is stable. 2.0.0 shipped on 27 July 2026 as split packages (
@modelcontextprotocol/server,@modelcontextprotocol/clientand framework adapters), and v1 keeps getting fixes "for at least six months after the v2 release" (TypeScript SDK README↗). - TypeScript v1 before 1.26.0 can leak responses between clients. Versions 1.10.0 to 1.25.3 let a shared server or transport instance mix up responses in stateless mode. Since 1.26.0,
handleRequest()"now throws if called more than once" (GHSA-345p-7cg4-v4c7↗). - MCP Inspector below 0.14.1 allows remote code execution (CVE-2025-49596, CVSS 9.4, GHSA-7f8r-222p-6f5g↗). The current Inspector is 2.11.0.
- FastMCP is on 4.1.0. 3.0 went stable on 18 February 2026, and 4.1.0 shipped on 8 October (PyPI↗). Its repository has 28,074 GitHub stars, more than the official Python SDK's 24,574. The npm package called
fastmcpis a different TypeScript project.
SDK downloads a year apart
| Package | Registry | 13 Sep to 12 Oct 2025 | 13 Sep to 12 Oct 2026 | Change |
|---|---|---|---|---|
@modelcontextprotocol/sdk (TypeScript v1) | npm | 31.3M | 273.3M | 8.7× |
@modelcontextprotocol/server (TypeScript v2) | npm | not released | 37.3M | new |
@modelcontextprotocol/client (TypeScript v2) | npm | not released | 27.5M | new |
mcp-handler (Vercel's MCP adapter) | npm | 211.5K | 5.40M | 25.5× |
mcp-remote | npm | 291.9K | 3.82M | 13.1× |
@modelcontextprotocol/inspector | npm | 351.1K | 1.64M | 4.7× |
Python has no year-old window on pypistats. The mcp package had 235.2 million downloads in the 30 days to 13 October, and FastMCP had 53.7 million (pypistats: mcp↗, fastmcp↗). Python's monthly totals did not keep climbing: mcp peaked at 329.8 million in August and fell to 230.1 million in September. The TypeScript v1 and Python packages alone add up to about 508 million a month, in line with the project's July figure of "close to half-a-billion downloads a month" across its Tier 1 SDKs (MCP blog↗). In December 2025 the figure was "97M+ monthly SDK downloads across Python and TypeScript" (Anthropic↗).
Which clients can reach a server on your machine?
The split follows where the client runs. A client on your machine can start a stdio server or call localhost. A client that runs in a vendor's cloud connects from the internet, so it needs a public HTTPS URL, or a tunnel the vendor runs.
| Client | Server on your machine | What it needs instead | Source |
|---|---|---|---|
| Claude.ai, Claude Desktop and mobile, custom connectors | No | A server "reachable over the public internet from Anthropic's IP ranges" | Claude help↗ |
Claude Desktop, local config or .mcpb | Yes, stdio | Nothing | Claude help↗ |
| Claude Code | Yes, stdio or HTTP | Nothing | Claude Code docs↗ |
| Claude API MCP connector | No, "Local STDIO servers cannot be connected directly" | A publicly exposed HTTP server | Claude API docs↗ |
| ChatGPT plugins (custom MCP servers) | Only through Secure MCP Tunnel | A public HTTPS endpoint or Secure MCP Tunnel | OpenAI docs↗ |
| OpenAI Responses API | Only through Secure MCP Tunnel (tunnel_id) | A server_url or a tunnel_id | OpenAI docs↗ |
| VS Code | Yes, stdio or HTTP, localhost included | Nothing | VS Code docs↗ |
| Cursor | Yes, stdio or HTTP, localhost included | Nothing | Cursor docs↗ |
| Gemini CLI | Yes, stdio or HTTP, localhost included | Nothing | Gemini CLI docs↗ |
| Codex CLI | Yes, stdio or Streamable HTTP | Nothing | Codex docs↗ |
| Retool agents | No, stdio "must be exposed via an HTTP gateway" | A remote-hosted server | Retool docs↗ |
Anthropic's connector guide says: "When you add a custom connector, Claude connects to your remote MCP server from Anthropic's cloud infrastructure, rather than from your local device" (Claude help↗). OpenAI's quickstart still says that during development "you need to expose it to the public internet. You can use a tool such as ngrok to open a tunnel to your local server" (OpenAI quickstart↗). The new option is Secure MCP Tunnel, an outbound tunnel-client that lets ChatGPT and the Responses API reach "an MCP server that tunnel-client can reach over stdio or HTTP from inside your network" (OpenAI docs↗).
OAuth ties a server to its URL. The client must send a resource parameter that uses "the canonical URI of the MCP server", and the server must accept only tokens issued for it (authorization spec↗). A token issued for one URL is no good at another, which is why the URL has to stay put while you test OAuth.
Two bridges solve opposite problems. The mcp-remote package turns a remote URL into a stdio process for a client that only speaks stdio, and its downloads grew 13 times in a year. A tunnel turns a server on your machine into a public HTTPS URL for a client that only connects from the cloud. The full path from a local server to a working Claude.ai connector, including the version gotchas, is in testing a local MCP server in Claude.ai.
