Start Debugging
2026-08-11 Updated 2026-08-11 migrationmcpai-agentsllm Edit on GitHub

Migrate Off the Archived MCP Reference Servers (GitHub, Postgres, Slack)

The GitHub, Postgres, and Slack MCP servers from modelcontextprotocol/servers were archived in 2025 and their npm packages are deprecated. They pin SDK 1.0.1, which cannot negotiate past protocol 2024-11-05. Here is the audit script, the current replacement for each, and the two pointers in the archive README that are themselves stale.

If your mcp.json still has a line reading npx -y @modelcontextprotocol/server-postgres, you are running a server whose last release was published on December 4, 2024 and which npm has marked deprecated. The same is true of server-github (last published April 8, 2025) and server-slack (April 25, 2025). All three were moved out of modelcontextprotocol/servers into the read-only servers-archived repository, which itself has had no commit since May 28, 2025. Budget about thirty minutes per server. Nothing crashes today, but these servers pin @modelcontextprotocol/sdk@1.0.1, which caps protocol negotiation at revision 2024-11-05 and therefore cannot do structured tool output, elicitation, or tool annotations. Two of the replacements the archive README points at are stale too, so do not follow it blindly.

What actually got archived, and what did not

Anthropic split the reference server repo in 2025. Seven servers stayed in modelcontextprotocol/servers and are still shipping: everything, fetch, filesystem, git, memory, sequentialthinking, and time. As a sanity check, @modelcontextprotocol/server-filesystem is on 2026.7.10 and carries no deprecation flag.

Fourteen went to servers-archived under a warning the README states in capitals: “NO SECURITY GUARANTEES ARE PROVIDED FOR THESE ARCHIVED SERVERS. These servers are no longer maintained. No security updates or bug fixes will be provided. Use at your own risk.”

The three that show up most often in real configs, and what to move to:

Archived packageLast publishedReplacementStatus of replacement
@modelcontextprotocol/server-github2025-04-08github/github-mcp-serverv1.9.0, released 2026-08-10
@modelcontextprotocol/server-postgres2024-12-04no official successorpick from third parties, see below
@modelcontextprotocol/server-slack2025-04-25https://mcp.slack.com/mcpGA since 2026-02-17
@modelcontextprotocol/server-gitlab2025-04-25https://gitlab.com/api/v4/mcpGitLab Duo beta, Premium and Ultimate
@modelcontextprotocol/server-puppeteer2025-05-12microsoft/playwright-mcpactive, last push 2026-08-09
@modelcontextprotocol/server-redis2025-04-25redis/mcp-redisactive, last push 2026-08-05
@modelcontextprotocol/server-sentryarchivedhttps://mcp.sentry.dev/mcphosted, returns 401 without auth
@modelcontextprotocol/server-aws-kb-retrievalarchivedawslabs/mcpactive, last push 2026-08-11

Severity is not uniform. Swapping GitHub is a strict upgrade. Swapping Postgres is a decision, because there is no vendor-blessed answer. Swapping Slack changes your auth model from a bot token in an env var to an OAuth user token, which is the one that will surprise your security review.

Why “it still works” is not a reason to stay

The deprecation notice is the boring argument. The protocol version is the real one.

@modelcontextprotocol/server-postgres@0.6.2 declares exactly two dependencies: pg and @modelcontextprotocol/sdk@1.0.1. That SDK is a hard pin, not a caret range. Install it and inspect what versions it can speak:

# verified 2026-08-11
npm install --no-save @modelcontextprotocol/server-postgres@0.6.2
# npm warn deprecated @modelcontextprotocol/server-postgres@0.6.2:
#   Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

grep -o "20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]" \
  node_modules/@modelcontextprotocol/sdk/dist/types.js | sort -u
# 2024-10-07
# 2024-11-05

Now the same constant in the current SDK, @modelcontextprotocol/sdk@1.30.0:

// node_modules/@modelcontextprotocol/sdk/dist/esm/types.js, SDK 1.30.0
export const LATEST_PROTOCOL_VERSION = '2025-11-25';
export const DEFAULT_NEGOTIATED_PROTOCOL_VERSION = '2025-03-26';
export const SUPPORTED_PROTOCOL_VERSIONS = [
  LATEST_PROTOCOL_VERSION, '2025-06-18', '2025-03-26', '2024-11-05', '2024-10-07'
];

A modern client and an archived server will still shake hands, because 2024-11-05 is in both lists. What they negotiate down to is a protocol revision from before tool annotations and resource links (2025-03-26), before structured tool output and elicitation (2025-06-18), and before icons, URL-mode elicitation, and experimental tasks (2025-11-25). Grep the two SDK builds for outputSchema and elicitation and you get 29 hits in 1.30.0 and zero in 1.0.1.

The practical effect: an archived server can only ever hand your model a blob of text. It cannot declare an outputSchema so the client parses a typed result, cannot mark a tool read-only with an annotation so a permission gate can auto-approve it, and cannot ask the user a follow-up question mid-call. If you have been wondering why your Postgres tool results arrive as an unparsed string while your other servers return structured content, this is why.

Pre-flight

Before touching anything:

Migration steps

  1. Audit every config for archived servers. Save this as audit-archived-mcp.mjs and point it at each config file. It matches both the npm package names and the old mcp/* Docker images, and exits non-zero on a hit so you can wire it into CI.

    // audit-archived-mcp.mjs, Node 20+
    // run: node audit-archived-mcp.mjs .mcp.json .cursor/mcp.json
    import { readFileSync } from "node:fs";
    
    const ARCHIVED = {
      "@modelcontextprotocol/server-github": "github/github-mcp-server",
      "@modelcontextprotocol/server-postgres": "bytebase/dbhub or crystaldba/postgres-mcp",
      "@modelcontextprotocol/server-slack": "https://mcp.slack.com/mcp or korotovsky/slack-mcp-server",
      "@modelcontextprotocol/server-gitlab": "https://gitlab.com/api/v4/mcp",
      "@modelcontextprotocol/server-puppeteer": "microsoft/playwright-mcp",
      "@modelcontextprotocol/server-redis": "redis/mcp-redis",
      "@modelcontextprotocol/server-sentry": "https://mcp.sentry.dev/mcp",
      "@modelcontextprotocol/server-sqlite": "bytebase/dbhub in sqlite mode",
      "@modelcontextprotocol/server-aws-kb-retrieval": "awslabs/mcp",
    };
    const DOCKER = /^mcp\/(github|postgres|slack|gitlab|puppeteer|redis|sentry|sqlite)$/;
    
    let findings = 0;
    for (const path of process.argv.slice(2)) {
      let cfg;
      try { cfg = JSON.parse(readFileSync(path, "utf8")); }
      catch (err) { console.error(`skip ${path}: ${err.message}`); continue; }
      const servers = cfg.mcpServers ?? cfg.servers ?? {};
      for (const [name, def] of Object.entries(servers)) {
        const args = def.args ?? [];
        const hit = args.find((a) => ARCHIVED[a]) ?? args.find((a) => DOCKER.test(a));
        if (!hit) continue;
        findings++;
        console.log(`${path}: "${name}" runs archived ${hit}\n  -> ${ARCHIVED[hit] ?? "vendor server"}`);
      }
    }
    console.log(findings ? `${findings} archived server(s)` : "no archived MCP servers found");
    process.exit(findings ? 1 : 0);

    Verify: run it against a config you know is clean and confirm it prints “no archived MCP servers found” and exits 0.

  2. Replace the GitHub server. This is the easy one, because GitHub took over development outright. The archived README says so directly: “Development for this project has been moved to GitHub in the http://github.com/github/github-mcp-server repo.” Prefer the hosted remote so you stop pinning a binary version:

    {
      "mcpServers": {
        "github": {
          "type": "http",
          "url": "https://api.githubcopilot.com/mcp/",
          "headers": { "Authorization": "Bearer ${input:github_pat}" }
        }
      }
    }

    If policy requires a local process, run the container instead of npx: ghcr.io/github/github-mcp-server:1.9.0. Either way, set GITHUB_TOOLSETS to the subset you actually use (repos,issues,pull_requests covers most work) and add GITHUB_READ_ONLY=1 if the agent has no business writing. The old server exposed everything unconditionally, which is one of the reasons it blew through the tool-use limit.

    Verify: restart the client and confirm the GitHub tools list is non-empty and shorter than before. If tools appear but every call comes back empty, you are hitting the silent PAT failure.

  3. Choose a Postgres replacement deliberately. There is no official one, and the archived server set a low bar: a single query tool wrapped in a READ ONLY transaction. Two credible options as of August 2026. bytebase/dbhub is the actively maintained one (last push 2026-08-08, 3,327 stars) and covers Postgres, MySQL, MariaDB, SQL Server, and SQLite behind one DSN:

    # DBHub, verified 2026-08-11
    npx @bytebase/dbhub@latest --transport stdio \
      --dsn "postgres://user:password@localhost:5432/dbname?sslmode=disable"

    crystaldba/postgres-mcp has the richer feature set (index tuning, EXPLAIN-plan simulation, health checks) but its last push was 2026-01-22, so you are choosing capability over maintenance velocity. Decide which of those two risks you would rather carry, and write the reason in a comment next to the config entry.

    Verify: ask the agent to list tables, then ask it to run an UPDATE. The second should be refused if you configured read-only mode.

  4. Move Slack to the hosted official server. Slack shipped its own MCP server and made it generally available on February 17, 2026 at https://mcp.slack.com/mcp, over JSON-RPC 2.0 on Streamable HTTP with OAuth 2.0 user tokens. It is not read-only: it searches messages, files, users, channels, and emoji, reads threads, posts messages, adds reactions, and creates canvases. Scopes are per-tool, so search_messages against private channels needs search:read.private, search:read.im, and search:read.mpim on top of search:read.public.

    {
      "mcpServers": {
        "slack": { "type": "http", "url": "https://mcp.slack.com/mcp" }
      }
    }

    The token model is the migration, not the URL. The archived server used a bot token in SLACK_BOT_TOKEN, so it saw whatever the bot was invited to. The official server acts as the signed-in user and honours that user’s permissions, which means results differ per operator and your workspace admin may need to approve the app first.

    Verify: run tools/list through your client’s inspector rather than trusting any blog post, including this one. Slack publishes tool definitions at runtime and has changed names and optional fields since the limited release.

  5. Delete the dead entries and re-run the audit. Remove the old blocks entirely rather than commenting them out, since most clients will happily parse and start a server you thought was disabled. Re-run step 1 across every config path from the pre-flight list and require exit code 0.

Verification pass

After all three swaps, work through this:

Rollback

Rollback is trivial and that is the trap. The archived packages are deprecated, not unpublished, so npx -y @modelcontextprotocol/server-postgres will keep resolving to 0.6.2 indefinitely and reverting the JSON restores the old behaviour in seconds. Treat that as an emergency lever with a deadline attached, not as a supported configuration. Deprecated packages do get unpublished eventually, and when that happens your agent fails at startup in whatever unattended run notices last.

Gotchas worth knowing before you start

Two pointers in the archive README are stale. It says the Slack server is “Now maintained by Zencoder” and links zencoderai/slack-mcp-server. That fork’s last push was July 16, 2025 and it has 75 stars, so following the README’s advice moves you from one unmaintained server to another. The live community option is korotovsky/slack-mcp-server, last push July 16, 2026, 1,779 stars, if you need self-hosting instead of the hosted Slack endpoint. The Postgres entry lists no replacement at all.

Registry search is literal substring matching. The official registry does carry the GitHub server, but you have to spell the query the way the name is spelled:

# 0 results
curl -s "https://registry.modelcontextprotocol.io/v0/servers?search=github%20mcp%20server"
# finds io.github.github/github-mcp-server, version 1.9.0
curl -s "https://registry.modelcontextprotocol.io/v0/servers?search=github-mcp-server"

Two more things to expect from that API. Results include every published version, so io.github.github/github-mcp-server came back 51 times in one response and you have to filter on _meta["io.modelcontextprotocol.registry/official"].isLatest. And a generic query is close to useless for picking a replacement: search=postgres returns 73 entries, dominated by repeated versions of servers from publishers nobody has heard of, with no official Postgres server anywhere in the list. Slack’s hosted server is not registered at all, so search=slack.com returns nothing. The registry is a lookup table once you know the name, not a discovery tool for finding who owns a category.

The deprecation warning is invisible in normal operation. npm install prints it, but MCP clients run npx -y, and whatever npx writes goes to stderr, where clients either swallow it or misreport it. If your client surfaces it at all, it will probably look like a server startup error rather than a warning.

Do not migrate the Git server by mistake. servers-archived contains a git directory, but @modelcontextprotocol/server-git is also a live server in the maintained repo. The archived copy is a historical snapshot from before the split.

Sources

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< Back