Fold all antigravity literal branches into descriptor-driven reads: getConfigDirFromHome (→ configHome.kind 'dot-home-nested'), projectLocalHookPrefix (→ hostBehaviors.hookPathStyle 'raw'), applyAgentPathRewrites (→ noPathRewrite), getProjectInstructionFile (→ projectInstructionFile 'GEMINI.md'); removed the dead inline convertClaudeAgentToAntigravityAgent branch + dead isAntigravity destructures (antigravity is already on the descriptor-agents path). subagentToolkit flipped undocumented→full (Context7: antigravity.google/docs/cli/features); namedDispatch/nested/maxDepth/backgroundDispatch stay undocumented. Byte-identical golden parity for all 16 runtimes. UPGRADE 1 (permission-writer): permissionWriter 'antigravity' + configureAntigravityPermissions merges a scoped permissions.allow block (GSD's own tree + hooks) into Antigravity's settings.json — non-destructive, idempotent, symmetric uninstall. Added to VALID_PERMISSION_WRITERS + the FinishPermissionWriter union. UPGRADE 2 (MCP companion): configureAntigravityMcpConfig writes mcp_config.json registering the gsd-core companion MCP server (Gemini-successor mcpServers schema, best-effort — raw schema unpublished). Both writers dispatch from finishInstall. settings.json is golden-excluded (HOOK_CONFIG_FILES); mcp_config.json (portable, no absolute paths) is golden-tracked → only antigravity.json changes. Tests: declarative-reference-antigravity extended (source-grep guard across 4 modules, fail-closed for the 4 undocumented sub-axes, validator acceptance) + antigravity-upgrades (permission-writer + mcp_config live-install, idempotency, user-preservation). Matrix + ADR-1016 + capability-manifest + CONTEXT.md + connect-gsd-mcp-server docs updated; changeset (Changed). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4.1 KiB
How to connect a host to the GSD companion MCP server
This guide shows you how to make a MCP-capable host (Claude Code, Codex,
OpenCode, VS Code, Antigravity CLI, Cursor, Cline, Hermes) drive GSD — run GSD
commands and read/write .planning/ state — through the companion MCP server,
with no bespoke plugin.
Once connected, three tools appear in the host alongside its others:
gsd_invoke_command, gsd_read_state, gsd_write_state. (For the tool
contracts, see the reference section below; for why this server exists and
its trust model, see ADR-1239
and the capability trust model.)
1. Add the server to your host's MCP config
The entry shape is the same everywhere; only the config file and key differ by host.
{
"gsd": {
"command": "npx",
"args": ["-y", "@opengsd/gsd-core", "gsd-mcp-server"],
"cwd": "/abs/path/to/your/project"
}
}
- Claude Code / Codex / Cursor / Cline / Hermes — under the host's
mcpServersobject (project or user config). - VS Code — in the workspace MCP servers list.
- Antigravity — under the
mcpServersblock of its standalonemcp_config.jsonprofile (not embedded insettings.json) — global at~/.gemini/antigravity/mcp_config.json(or the siblingantigravity-ide/antigravity-clidir GSD resolved into), project-local at.agents/mcp_config.json. GSD's installer configures this entry automatically (--antigravityinstalls). - OpenCode — under the
mcpkey (notmcpServers), in~/.config/opencode/opencode.jsonc(global) or./opencode.json(project). The entry shape also differs — see below. - Kilo Code — an OpenCode fork; also under the
mcpkey (notmcpServers), in~/.config/kilo/opencode.jsonc(global) or./opencode.json(project). Same entry shape as OpenCode.
Set cwd to the project whose .planning/ you want GSD to manage — the server
resolves state paths against it.
OpenCode / Kilo entry shape
OpenCode (and Kilo, which shares OpenCode's config schema) use a
type/command/timeout entry under the mcp key instead of the generic
command/args/cwd form above:
{
"mcp": {
"gsd": {
"type": "local",
"command": ["npx", "-y", "@opengsd/gsd-core", "gsd-mcp-server"],
"timeout": 10000
}
}
}
2. Restart the host
On startup the host performs the MCP initialize handshake, lists tools, and
the three GSD tools become callable.
3. Verify
Ask the host to read an existing planning file:
{ "name": "gsd_read_state", "arguments": { "path": "/abs/path/to/your/project/.planning/STATE.md" } }
It returns the file's contents. gsd_invoke_command takes
{family, subcommand, args} and returns the command-routing hub's structured
result (the same shape gsd-tools produces).
If something does not work
command not found: gsd-mcp-server— invoke vianpxas shown above, or install the package globally first (npm i -g @opengsd/gsd-core).gsd_read_statefails with ENOENT — the path is resolved literally; pass an absolute path under the project's.planning/.- The host lists no GSD tools — confirm the server starts in isolation:
npx @opengsd/gsd-core gsd-mcp-serverthen send aninitializerequest on stdin; it writes aprotocolVersionresponse and exits on EOF. - You manage multiple projects — register one
gsdentry per project with a distinct name andcwd; the server is stateless across projects.
Reference — the three tools
| Tool | Arguments | Returns |
|---|---|---|
gsd_invoke_command |
{family: string, subcommand: string, args?: unknown[]} |
the command-routing hub result ({ok, …}) as JSON text |
gsd_read_state |
{path: string} |
the file contents as text |
gsd_write_state |
{path: string, content: string} |
{ok: true, path} as JSON text |
Errors from a tool are returned as MCP tool errors (isError: true), not as
JSON-RPC protocol errors — the host surfaces them in its normal tool-failure UX.