◉ANTIGRAVITY LABJP
Articles/Integrations
⬡ Integrations/2026-04-07Advanced

Antigravity × MCP in Practice — Spotting Dead Servers and Measuring What Tool Definitions Actually Cost

The MCP servers listed in your Antigravity settings.json may no longer exist. Here is a runnable audit script that checks npm for deprecation, measured token costs for tool definitions, and a rewrite on SDK 2.x — all reproducible on your own machine.

mcp15model-context-protocolintegrations21toolsproduction71202624

✦ Premium Article

Half the servers in my config were no longer being published

It started with a line that stopped working.

I reopened an Antigravity settings.json I had not touched in a while and restarted the servers listed under mcpServers. Several failed to come up, silently. Before chasing logs, the right question was simpler: is this package still being distributed at all?

The answer from the npm registry was worse than I expected. Of the servers in that once-common configuration, six were marked deprecated and two did not exist. A config file gives you no warning for either — the server just fails to start.

The MCP specification is stable. Its reference implementations are not. So instead of ranking servers, this piece starts somewhere more useful: how to verify mechanically that your config is still alive, and what each server actually costs you once it is connected. Every step here is reproducible, and I would rather you re-measure these numbers on your own machine than take mine.

Auditing settings.json mechanically

The first change is to stop evaluating config files from memory. This script pulls the npm package name out of each mcpServers entry and checks the registry's dist-tags, time, and deprecated fields.

#!/usr/bin/env node
// mcp-audit.mjs — checks whether the npm packages listed in a
// settings.json mcpServers block are still alive.
import { readFileSync } from "node:fs";
 
const configPath = process.argv[2];
if (!configPath) {
  console.error("usage: node mcp-audit.mjs <path-to-settings.json>");
  process.exit(2);
}
 
const cfg = JSON.parse(readFileSync(configPath, "utf8"));
const servers = cfg.mcpServers ?? {};
 
// Pull the first argument that looks like an npm package name (skip -y, --db-path, etc.)
function pickPackage(entry) {
  const args = entry.args ?? [];
  if (!/^(npx|pnpx|bunx)$/.test(entry.command ?? "")) return null;
  return args.find((a) => !a.startsWith("-") && /^(@[\w.-]+\/)?[\w.-]+$/.test(a)) ?? null;
}
 
const STALE_DAYS = 365;
let worst = 0;
 
for (const [name, entry] of Object.entries(servers)) {
  const pkg = pickPackage(entry);
  if (!pkg) { console.log(`-  ${name}: not an npm-distributed server, skipping`); continue; }
 
  const res = await fetch(`https://registry.npmjs.org/${pkg.replace("/", "%2f")}`);
  if (res.status === 404) { console.log(`❌ ${name}: ${pkg} does not exist on npm`); worst = Math.max(worst, 2); continue; }
  if (!res.ok) { console.log(`?  ${name}: ${pkg} lookup failed (HTTP ${res.status})`); continue; }
 
  const doc = await res.json();
  const latest = doc["dist-tags"]?.latest;
  const published = doc.time?.[latest];
  const deprecated = doc.versions?.[latest]?.deprecated;
  const ageDays = Math.floor((Date.now() - Date.parse(published)) / 86400000);
 
  if (deprecated) {
    console.log(`❌ ${name}: ${pkg}@${latest} is deprecated — ${String(deprecated).slice(0, 60)}`);
    worst = Math.max(worst, 2);
  } else if (ageDays > STALE_DAYS) {
    console.log(`⚠️  ${name}: ${pkg}@${latest} last published ${ageDays} days ago (${published.slice(0, 10)})`);
    worst = Math.max(worst, 1);
  } else {
    console.log(`✅ ${name}: ${pkg}@${latest} (published ${published.slice(0, 10)}, ${ageDays} days ago)`);
  }
}
 
process.exit(worst);

No dependencies — Node 22's built-in fetch is enough. Feeding it a configuration of the kind that circulated widely produces this:

❌ github: @modelcontextprotocol/server-github@2025.4.8 is deprecated — Package no longer supported.
❌ postgres: @modelcontextprotocol/server-postgres@0.6.2 is deprecated — Package no longer supported.
❌ sqlite: @modelcontextprotocol/server-sqlite does not exist on npm
❌ notion: @notionhq/client-mcp does not exist on npm
✅ filesystem: @modelcontextprotocol/server-filesystem@2026.7.10 (published 2026-07-10, 42 days ago)
✅ playwright: @playwright/mcp@0.0.79 (published 2026-08-06, 15 days ago)
-  internal: not an npm-distributed server, skipping
exit=2

The 0/1/2 exit codes exist so this can live in CI. I run it monthly now. Config files start rotting the moment you write them, and the one thing worth automating is noticing that they have.

STALE_DAYS is set to 365 because MCP reference implementations ship on roughly annual cycles. If your config mixes in internal servers that release quarterly, tighten that threshold to match reality.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦A runnable audit script that flags deprecated or missing npm packages in your settings.json, with exit codes you can wire into CI
✦Measured token cost of tool definitions across four official reference servers: 37 tools consuming 9,426 tokens before the conversation starts
✦An SDK 2.x rewrite plus verified results for what a model actually reads when your handler throws
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

Related Articles

⬡ Integrations2026-09-05
Pointing GOOGLE_GEMINI_BASE_URL at Your Own Gateway Does Not Change Who Holds the Key
I pointed the Antigravity CLI at a gateway of my own and recorded exactly which credentials travelled with it. Authorization is dropped across a cross-origin redirect, but the API key header survives every hop. Here is the measurement, and how I moved the key off my laptop.
⬡ Integrations2026-08-08
The MCP Server I Thought I Killed Was Still Holding the Port: 84 Teardown Trials
Closing a session should stop the MCP servers it started. Across 84 trials of four teardown strategies, a process-group SIGTERM left zero orphans — until the child called setsid, at which point it left 100%. Includes a full descendant-sweep implementation.
⬡ Integrations2026-04-30
Stateful AI Agents on Antigravity × Cloudflare Durable Objects — One Session, One Instance, One Place to Manage Conversation, Tools, and Cost
How to deploy an Antigravity AgentKit 2.0 agent onto Cloudflare Durable Objects so that conversation history, tool-call state, and token spend live inside a single instance per session — with the actual code and production cost numbers from my own deployment.