# Install in any MCP client
URL: /documentation/getting-started/install-mcp-client



## Goal [#goal]

Register Strata19 in any client that can start a local MCP server, and confirm the server itself works before blaming the client's configuration.

This is the generic route. It applies to every client in [Supported hosts](/documentation/reference/hosts) that has no Strata19 manifest — Cursor, Zed, VS Code, Windsurf, Cline, Continue, Kiro, OpenCode, the Copilot CLI, and the rest. If your host is Claude Code, Codex, Claude Desktop, or Antigravity, use [Install the plugin](/documentation/getting-started/install) instead: those have a manifest, so they also get the plugin's skills and lifecycle hooks.

What you give up here is exactly that. A hand-registered server provides the MCP tools and nothing else: no skills, no `SessionStart` binding, and no `Stop` completion gate. The tools are the same tools; the automatic parts are absent, and [verification](/documentation/plugin/verification) becomes something you ask for rather than something that runs on its own.

## Before you start [#before-you-start]

* A copy of the `plugins/strata19/` directory on disk. It is self-contained — `server/facade-stdio.js` is a committed, pre-built single-file bundle with the tree-sitter WASM grammars beside it, so there is no build step and no `npm install`.
* The **absolute** path to a Node.js 22.5 or newer binary. Find it with `command -v node`, then check `node --version`. Both halves matter, and the reasons are in step 3.
* The absolute path to the repository you want Strata19 to answer about.
* No Strata19 account and no model API key.

## Steps [#steps]

<Steps>
  <Step>
    ### Check the server runs, before touching any client config [#check-the-server-runs-before-touching-any-client-config]

    The server has a one-shot self-diagnosis that never starts the JSON-RPC loop. Run it directly:

    ```bash
    /absolute/path/to/node /path/to/plugins/strata19/server/facade-stdio.js --doctor /absolute/path/to/your/repo
    ```

    It prints a JSON report. The fields that decide whether the rest of this page is worth doing:

    ```json
    {
      "ok": true,
      "issues": [],
      "process": { "node": "v22.22.3", "platform": "darwin", "arch": "arm64" },
      "projectRoot": { "path": "/absolute/path/to/your/repo", "source": "bound", "selfInstall": false },
      "natives": { "treeSitter": { "loaded": true, "error": null }, "sqliteBackend": "node:sqlite" }
    }
    ```

    `projectRoot.path` must be your repository and `selfInstall` must be `false` — `true` means the server resolved to its own install folder, which is the failure this check exists to catch early. `natives.treeSitter.loaded` must be `true`, or the deep code index is unavailable and `issues` will say why. A non-empty `issues` array here is a server problem, and no amount of client configuration will fix it.
  </Step>

  <Step>
    ### Find your client's config file and its grouping key [#find-your-clients-config-file-and-its-grouping-key]

    Clients agree on the shape of a server entry and disagree about the key they group servers under. [Supported hosts](/documentation/reference/hosts) has the location and the key for every client this project has researched.

    This is worth the lookup rather than a guess. A server registered under the wrong key is not rejected — the file parses, the client starts cleanly, and it simply lists no Strata19 tools, which reads exactly like a server that failed to launch. VS Code uses `servers`, Zed uses `context_servers`, OpenCode uses `mcp`, Hermes uses `mcp_servers`, and most of the rest use `mcpServers`.
  </Step>

  <Step>
    ### Register the server [#register-the-server]

    Using `mcpServers` as the example key — substitute yours:

    ```json
    {
      "mcpServers": {
        "strata19": {
          "command": "/absolute/path/to/node",
          "args": ["/path/to/plugins/strata19/server/facade-stdio.js"],
          "env": {
            "STRATA19_PROJECT_ROOT": "/absolute/path/to/your/repo"
          }
        }
      }
    }
    ```

    Three things in that block are load-bearing, and each corresponds to a real failure:

    `command` must be an absolute path to Node, not the string `node`. A GUI-launched client spawns MCP servers with a stripped `PATH` — `/usr/bin:/bin:/usr/sbin:/sbin` — which omits both Homebrew and nvm installs, so a bare `node` fails at spawn with `ENOENT` and the client reports zero tools with no visible error.

    That Node must be 22.5 or newer. The server declares `"engines": {"node": ">=22.5.0"}` because the checkpoint and work-item stores use the built-in `node:sqlite`. Copying another server's entry from the same config file as a template is the common way an entry ends up pointing at an older runtime.

    `args` must be an absolute path to the bundle. The plugin manifests rely on host-specific mechanisms to locate it — `${CLAUDE_PLUGIN_ROOT}` substitution on Claude Code, a cache search on Codex and Antigravity — and none of those exist here. A relative path resolves against whatever working directory the client happens to use, which for a GUI client is usually `/`.

    `STRATA19_PROJECT_ROOT` is optional but recommended. The server resolves a repository from an explicit root, then a repository bound this session, then a workspace root the client declared, then its own working directory. Clients that declare workspace roots at `initialize` are handled automatically; clients that do not leave the server falling back to a working directory that may not be a repository at all. Setting it removes the ambiguity, and matters most when more than one repository is open.

    Some clients need one extra field. The Copilot CLI requires `"type": "local"` and a `"tools": ["*"]` allowlist, or it exposes none of the server's tools. VS Code requires an explicit `"type": "stdio"`. Continue's config is YAML and its server list is a list rather than an object. Check your client's row before assuming the block above is complete.
  </Step>

  <Step>
    ### Restart the client and bind a repository [#restart-the-client-and-bind-a-repository]

    MCP configuration is read at startup by most clients. Restart, then ask:

    > Initialize Strata19 for this repository and show me the project status.
  </Step>
</Steps>

## Verify [#verify]

The response names your repository: the resolved root path, and a repository identity taken from the Git remote origin, or the directory name when there is no origin. That is the only proof that matters. A config file the client accepted, and a server the client lists as connected, both stop short of showing which repository it is answering about — and answering confidently about the wrong repository is the failure mode this check catches.

Binding returns immediately and does not build the code index. The first question that needs the index pays for it, once. [How Strata19 runs](/documentation/getting-started/how-it-works) explains what that costs and why nothing has hung.

## If it doesn't work [#if-it-doesnt-work]

**The client connects to the server but lists no Strata19 tools.** Almost always the grouping key. Check your client's row in [Supported hosts](/documentation/reference/hosts); a wrong key parses cleanly and is silently ignored. On the Copilot CLI, a missing `"tools": ["*"]` allowlist produces the same symptom for a different reason.

**The client reports the server as failed, or reports nothing at all.** The server did not spawn. Run the `--doctor` command from step 1 by hand: if it prints a report, the bundle and Node are fine and the problem is in the client entry — most often a relative path or a bare `node`. The launcher also appends a timestamped line to `~/.strata19/mcp-launch-error.log` when it cannot locate its bundle, which is the only trace left on clients that swallow a failed spawn entirely.

**Tool names come back as not found.** A few hosts reject the dotted `strata19.<tool>` names the server advertises by default. Set `STRATA19_TOOL_NAME_SEPARATOR` to `_` in the entry's `env` block and the server advertises `strata19_<tool>` instead; it keeps accepting the dotted names either way, so the change is additive. Antigravity needs this. Most clients do not.

**`--doctor` reports `selfInstall: true`.** The server resolved to its own install directory rather than a repository, so spec lookups would come back permanently empty and its state database would be written inside the plugin copy. Set `STRATA19_PROJECT_ROOT` to your repository's absolute path.

**The deep code index is unavailable.** `natives.treeSitter.loaded` is `false` and `issues` names a loader error. The tree-sitter grammars ship as committed WASM assets in `server/wasm/` beside the bundle, so this means the copy is incomplete rather than that an install step is missing — copy the whole `plugins/strata19/` directory, not just the bundle file.

See [Troubleshooting](/documentation/reference/troubleshooting) for failures beyond installation.

## Related [#related]

* [Supported hosts](/documentation/reference/hosts) — config location and grouping key for every known client
* [Install the plugin](/documentation/getting-started/install) — the four hosts that also get skills and hooks
* [How Strata19 runs](/documentation/getting-started/how-it-works) — binding, indexing, and the first slow call
* [Configuration](/documentation/reference/configuration) — every `STRATA19_*` setting the entry's `env` block can carry
* [Troubleshooting](/documentation/reference/troubleshooting) — diagnose problems after the server is connected
