◉ANTIGRAVITY LABJP
Articles/Integrations
⬡ Integrations/2026-10-22Intermediate

The Project-Local mcp_config.json Is Read, but No MCP Server Starts — Checking With a One-File Probe

Antigravity CLI logs that it is using a project-local config, yet the MCP servers in it never start. Based on reports in the official repository, here is what that log line may and may not promise, plus a tiny probe server you can use to check your own setup.

MCP29Antigravity CLI40troubleshooting121configuration8

You want a different MCP server per project, so you drop a config file at the root of the repository. It's the most natural thing to try.

You start the CLI, and the log says it is using the project's file. But the tool list shows only the servers from your home-level config. The file you wrote is apparently being read, and yet nothing new has appeared.

From what I've read, the instinct at this point is to re-check your own syntax again and again. I'd suspect the log line first.

What I'd like to say up front

This symptom is reported in the official issue tracker (google-antigravity/antigravity-cli, issue #60). On v1.0.0, the reporter observed that:

  • the project-level .antigravitycli/mcp_config.json is discovered at startup, and the log says so
  • its mcpServers entries are ignored and no server is spawned
  • only servers in the home-level ~/.gemini/antigravity-cli/mcp_config.json actually start

I haven't tracked every CLI version myself, so below I'll keep "what the issue says" and "what you can verify on your machine" apart.

What that log line doesn't promise

The log lines quoted in the issue look roughly like this:

project: discovered project ... via /tmp/agy-test-995/.antigravitycli
project: using project ... at /private/tmp/agy-test-995/.antigravitycli/mcp_config.json

"using project" invites you to read it as "MCP servers from here will run." A later comment in the issue offers a different reading: .antigravitycli/ holds project identifiers, and it isn't one of the places where MCP config is looked up (the comment calls them customization roots).

If that's right, the line only says the project was found, not that the mcpServers inside will be used. That is a hypothesis from a commenter, not a behavior confirmed by the maintainers.

A probe that shows whether anything was spawned

To separate "my config is wrong" from "my config was never read," it helps to register a server whose startup is visible from the outside. This script appends one line to a log the moment it is spawned, and answers tools/list with a single marker tool.

What it solves: telling "configured correctly but never spawned" apart from "spawned but the tools aren't visible."

#!/usr/bin/env python3
"""Minimal MCP stdio probe. Logs one line at spawn, returns one tool from tools/list."""
import json, os, sys, time
 
MARKER = os.environ.get("PROBE_MARKER", "unnamed")
LOG = os.environ.get("PROBE_LOG", os.path.expanduser("~/probe_mcp.log"))
 
def log(msg):
    with open(LOG, "a", encoding="utf-8") as f:
        f.write(f"{time.strftime('%H:%M:%S')} pid={os.getpid()} cwd={os.getcwd()} marker={MARKER} {msg}\n")
 
log("spawned")  # proof of startup; if this line never appears, the config was not read
for line in sys.stdin:
    line = line.strip()
    if not line:
        continue
    req = json.loads(line)
    method, rid = req.get("method"), req.get("id")
    log(f"recv {method}")
    if method == "initialize":
        result = {"protocolVersion": "2024-11-05", "capabilities": {"tools": {}},
                  "serverInfo": {"name": f"probe-{MARKER}", "version": "0.1.0"}}
    elif method == "tools/list":
        result = {"tools": [{"name": f"whoami_{MARKER}", "description": "Reports which config started me",
                             "inputSchema": {"type": "object", "properties": {}}}]}
    elif rid is None:
        continue  # never answer notifications
    else:
        result = {}
    sys.stdout.write(json.dumps({"jsonrpc": "2.0", "id": rid, "result": result}) + "\n")
    sys.stdout.flush()

Why it's written this way: log("spawned") sits before the loop on purpose. Even if the protocol exchange fails, the fact that a process was born is recorded. An empty log means the config wasn't read; a log line with no visible tools points at what happens after startup. That narrows the cause by one layer.

First, confirm the probe works on its own, without the CLI:

printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' \
  '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
  | PROBE_MARKER=local PROBE_LOG=./t.log python3 probe_mcp.py
cat t.log   # four lines: spawned / recv initialize / recv notifications/initialized / recv tools/list

Move it around and only watch the log

Register the probe in two places with different markers, so the log tells you which config started it.

{
  "mcpServers": {
    "probe_project": {
      "command": "python3",
      "args": ["/path/to/probe_mcp.py"],
      "env": { "PROBE_MARKER": "project", "PROBE_LOG": "/path/to/probe.log" }
    }
  }
}

Put this once in the project's .antigravitycli/mcp_config.json, and once in the home-level config (the issue uses ~/.gemini/antigravity-cli/mcp_config.json; Antigravity 2.0 uses ~/.gemini/config/mcp_config.json), changing only the marker.

Where it lives"spawned" in probe.logHow to read it
Project root .antigravitycli/NoThe config isn't being read. Not a syntax problem
Home-levelYesThe probe is fine; the location is the cause
NeitherNoWrong path or command. Recheck the registration via agy mcp first

If the issue is accurate for your version, you'll land on the first two rows. I haven't reproduced this myself, so I'd rather you run it once and see which row you hit. It takes a few minutes.

The workaround that was reported, and what came after

One comment in the issue reported that putting the file at .agents/mcp_config.json in the workspace root, instead of .antigravitycli/, got it loaded (v1.0.3, macOS).

A later comment tried the same steps on v1.1.3 and found it no longer worked: even with the home-level configs emptied, no server started from the workspace file, and the logs showed no sign of the workspace config being looked up.

So the workaround apparently worked on one version and not on another. Running the probe on your own version is the most reliable step in this whole story.

A practical line when you want per-project separation

Several people in the thread wanted separate MCP sets per project or per launch, and a flag to pass a config file at startup was requested. What I consider workable for now:

It's modest, but once the home-level list grows, consistently prefixed names become your inventory.

Decide by whether a process actually started, not by what the log says. That's the line I'd like to come back to whenever configuration gets confusing.

What to do next

Write one probe, register it in the project root and the home-level config with different markers, and see which side logs "spawned." Once you know, you can stop spending time doubting your syntax.

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 →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

⬡ Integrations2026-08-20
Find the one broken MCP entry before Antigravity starts, with a Node script under 60 lines
A single typo in your MCP settings can take every server down with it. Here is a small preflight script that catches the mistakes statically, the real output from a deliberately broken config, and the duplicate-key trap that JSON hides from you.
⬡ Integrations2026-10-19
Connecting GitHub MCP to Antigravity CLI: The Fix Was One Word, url to serverUrl
To use GitHub MCP from Antigravity CLI, the url key in your config has to become serverUrl. Based on the official MCP docs, here are the remote and Docker setups, a small script that checks the file before you load it, where to keep the token, and the order to debug in.
⬡ Integrations2026-10-10
Figma MCP or Stitch MCP: Choosing by Whether the Screen Already Exists
When you turn a screen into code, which MCP should Antigravity talk to: Figma or Stitch? One question settles it: does the correct screen already exist? Here is the rule I use, a switching routine, and a small script for the days I can't decide.