Private beta · invite-only

Cartographer developer setup

Cartographer builds an incremental tree-sitter symbol index of a repo and serves it to your agent as tools — one call answers “where is X used / what do I open to change it” instead of a grep-and-read loop. Most queries are zero-token, and the org’s shared graph is versioned like git.

AppleLinuxGitmacOS · Linux · Git Bash
curl -fsSL https://api.anchoragelabs.dev/cli/install.sh | sh
Windows PowerShell
irm https://api.anchoragelabs.dev/cli/install.ps1 | iex

Measured on a real repo: a “where/impact” question costs ~103k tokens via grep-and-read vs ~300 via one Cartographer call.

Step 01

Install the CLI

Prerequisite: Node 22+ — the bundle is pure JS + WASM run by your Node. No native binaries, no repo access, no pnpm, no build.

AppleLinuxGitmacOS · Linux · Git Bash · WSL
curl -fsSL https://api.anchoragelabs.dev/cli/install.sh | sh
Windows PowerShell
irm https://api.anchoragelabs.dev/cli/install.ps1 | iex
install.sh is a POSIX-sh script — it does not run in PowerShell. Use install.ps1 there (needs Windows 10+ for the built-in tar.exe), or run the sh installer inside Git Bash / WSL.

What the installers do: verify the download against the release’s published sha256, install to ~/.cartographer/current (versioned dirs, previous installs kept), and put a cartographer launcher on your PATH (~/.local/bin on Unix; a cartographer.cmd shim + user-PATH entry on Windows — open a new terminal after the Windows install).

bash
cartographer --help    # verify the install

Step 02

Authenticate

One token authenticates the CLI, the shared graph, and the hosted MCP:

  1. 1.Open https://api.anchoragelabs.devSign in with GitHub (org-gated — you must be an approved org member).
  2. 2.Account → reveal token. Copy it and export it:
shell profile
export ANCHORAGE_API_TOKEN=anch_yourname_xxxxxxxx
# Windows PowerShell:  $env:ANCHORAGE_API_TOKEN = "anch_yourname_xxxxxxxx"
Keep it out of code and chat. Shell profile or a secret manager — never commit it, never paste it into a conversation. Revealing again rotates it.

Step 03

Pull the shared graph before you start

bash
cd <your-repo>
cartographer pull        # org's latest graph for this repo → local index
cartographer status      # three axes: your tree / your index / the hosted head

status tells you where you stand against the org graph: FRESH (in sync), AHEAD (you have unpushed structure), BEHIND (pull), DIVERGED (pull, re-index, push). Working on a repo you haven’t cloned? Pull it anyway:

bash
cartographer pull --out ~/graphs/aleph --repo your-org/aleph
cartographer impact getUser ~/graphs/aleph --shared   # query with NO source tree

(--shared serves the pulled snapshot as-is — a normal query would rescan the empty dir and prune it.)

Step 04

Index and query locally

bash
cartographer init                    # first time in a repo: facts + symbol index
cartographer watch                   # keep the index current while you edit
cartographer impact startRun         # blast radius: defs, refs, dependents, tests
cartographer refs startRun           # definitions + every reference
cartographer tests-for src/store.ts  # which tests cover this file
cartographer log                     # org graph history: who pushed what, when
cartographer graph-diff <idA> <idB>  # structural delta between two snapshots

Every query delta-refreshes the index first, so results always reflect your working tree. The index is a gitignored SQLite file (.anchorage/index/symbols.db) — nothing leaves your machine until you push.

Step 05

Push after you change code

bash
cartographer push        # snapshot your index → org graph `latest`

Push is safe by default: it’s an immutable snapshot plus a compare-and-swap ref advance. If a teammate (or the Anchorage worker) pushed since you last synced, you get a 409 naming the current head — never a silent overwrite:

bash
push rejected: your-org/x latest advanced to g8c1e… (commit 4fa1b2c9, by …)
fix: cartographer pull   # then re-index and push
    or: cartographer push --force-with-lease=g8c1e…

Re-pushing identical content is a no-op (“up to date”, zero bytes uploaded).

Step 06

Install the agent plugins (MCP)

Two servers, one token:

  • Hosted MCPhttps://mcp.anchoragelabs.dev/mcp. Zero install. Tools: graph_lookup, graph_log, plus the Anchorage run tools (submit_run, wait_for_run, review_pr, …).
  • Local MCP — the installed CLI serves your checkout with the full 10-tool set (repo_map, find_references, impact, locate_change, tests_for, symbol_outline, repo_facts, repo_context, context_for_task, graph_status). Start it with:
bash
CARTOGRAPHER_MCP_DEV_TOKEN=pick-a-secret cartographer mcp --port 3100
# your agent then sends:  Authorization: Bearer pick-a-secret

Below: exact install per agent. ${ANCHORAGE_API_TOKEN} must be exported in the environment the agent starts from. For the local server, swap the URL for http://localhost:3100/mcp and the token for your CARTOGRAPHER_MCP_DEV_TOKEN.

Claude Code

Create (or extend) .mcp.json at the repo root — or ~/.claude.json for all projects:

.mcp.json
{
  "mcpServers": {
    "anchorage": {
      "type": "http",
      "url": "https://mcp.anchoragelabs.dev/mcp",
      "headers": { "Authorization": "Bearer ${ANCHORAGE_API_TOKEN}" }
    }
  }
}

claude.ai (web)

Settings → Connectors → Add custom connector → https://mcp.anchoragelabs.dev/mcp. The browser opens a Connect Anchorage page — paste your API token once (OAuth handles the rest).

Cursor

~/.cursor/mcp.json (global) or .cursor/mcp.json (per repo):

mcp.json
{
  "mcpServers": {
    "anchorage": {
      "url": "https://mcp.anchoragelabs.dev/mcp",
      "headers": { "Authorization": "Bearer ${ANCHORAGE_API_TOKEN}" }
    }
  }
}

Codex

~/.codex/config.toml — newer Codex speaks HTTP MCP directly:

config.toml
[mcp_servers.anchorage]
url = "https://mcp.anchoragelabs.dev/mcp"
http_headers = { Authorization = "Bearer ${ANCHORAGE_API_TOKEN}" }

Gemini CLI

~/.gemini/settings.json:

settings.json
{
  "mcpServers": {
    "anchorage": {
      "httpUrl": "https://mcp.anchoragelabs.dev/mcp",
      "headers": { "Authorization": "Bearer ${ANCHORAGE_API_TOKEN}" }
    }
  }
}

GitHub Copilot (VS Code)

.vscode/mcp.json in the workspace (the inputs entry prompts once for the token and stores it outside the repo — never hard-code it here):

.vscode/mcp.json
{
  "inputs": [
    { "type": "promptString", "id": "anchorage-token",
      "description": "Anchorage client token", "password": true }
  ],
  "servers": {
    "anchorage": {
      "type": "http",
      "url": "https://mcp.anchoragelabs.dev/mcp",
      "headers": { "Authorization": "Bearer ${input:anchorage-token}" }
    }
  }
}

OpenCode

opencode.json (repo) or ~/.config/opencode/opencode.json:

opencode.json
{
  "mcp": {
    "anchorage": {
      "type": "remote",
      "url": "https://mcp.anchoragelabs.dev/mcp",
      "enabled": true,
      "headers": { "Authorization": "Bearer ${ANCHORAGE_API_TOKEN}" }
    }
  }
}

Any stdio-only agent (fallback)

Bridge stdio ↔ HTTP with mcp-remote:

json
{
  "mcpServers": {
    "anchorage": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://mcp.anchoragelabs.dev/mcp",
               "--header", "Authorization: Bearer ${ANCHORAGE_API_TOKEN}"]
    }
  }
}

Support matrix

Agent / editorNative HTTP MCPConfig fileToken
Claude Code Yes.mcp.jsonANCHORAGE_API_TOKEN
claude.ai (web)connector + OAuthSettings → Connectorspasted once
Cursor Yes~/.cursor/mcp.jsonANCHORAGE_API_TOKEN
Codexversion-dependent~/.codex/config.tomlANCHORAGE_API_TOKEN
Gemini CLIyes (httpUrl)~/.gemini/settings.jsonANCHORAGE_API_TOKEN
GitHub Copilot (VS Code) Yes.vscode/mcp.jsonprompted input
OpenCodeyes (remote)opencode.jsonANCHORAGE_API_TOKEN
Anything stdio-onlyvia mcp-remoteagent-specificsame
Sanity-check prompt (works in every agent): “Call graph_lookup for <a symbol you know> in <owner/repo> and report the graphId and commit sha the answer came from.” A wired setup names a graph.graphId (g + 32 hex) and a commit; a broken one falls back to grep.

Step 07

One-command verification

bash
cartographer status --json   # with ANCHORAGE_API_TOKEN exported

Healthy output has "fresh": true (tree vs index) and a "remote": { "freshness": "fresh" | "ahead" | … } block (index vs org graph). If the remote block is missing, your token isn’t exported.

Step 08

Give your agents the Anchorage Skill

Installing the plugin gives agents the tools; the skill makes them use the graph instead of grepping. Paste the contents of anchorage-agent-skill.md into each agent’s instructions:

AgentWhere to paste
Claude Code / Codex / OpenCodeCLAUDE.md / AGENTS.md at the repo root
Cursor.cursor/rules
Gemini CLIGEMINI.md
GitHub Copilot.github/copilot-instructions.md
Reviewers / custom promptsthe reviewer system prompt

The skill is Cartographer-scoped: sync-before-work, graph-before-grep tool selection, mandatory impact / tests_for before changing public symbols, 409/lease recovery, version-stamped answers, and honesty/fallback rules.

Step 09

Bring your own LLM (optional)

Core queries are zero-token. Two optional commands call a model: cartographer narrate (plain-language repo summary) and cartographer map --llm (architecture claims). Configure your own key:

bash
export ANCHORAGE_LLM_PROVIDER=anthropic      # anthropic · openai · openai-compatible · bedrock
export ANCHORAGE_LLM_API_KEY=sk-ant-...       # your own key — BYO, never shared
export ANCHORAGE_LLM_MODEL=claude-sonnet-4-6

Step 10

Cheat sheet & troubleshooting

Daily: pull → work (impact / refs / tests-for, agent tools) → push. Keep cartographer watch running during long sessions.

SymptomFix
401 from server / MCPToken rotated or you're not an org member — re-reveal at the deck, re-export.
claude.ai connector: "Authorization … failed"Remove + re-add the connector, paste your CURRENT token in the Connect page.
Push rejected with 409Someone pushed first — cartographer pull, re-index, push (or --force-with-lease=<head>).
Empty results after pullAdd --shared (a tree-less snapshot must not be rescanned).
Stale local indexcartographer refresh
cartographer: command not found (Unix)Add ~/.local/bin to PATH.
cartographer not found (Windows)Open a NEW terminal (PATH was updated at install).
checksum MISMATCH at installDo not install; retry, then report in #cartographer.
hosted graph_lookup empty for a repoThat repo's graph hasn't been pushed yet — cartographer log --repo owner/name shows history.
Full per-client integration docs live at docs/integrations/. Questions → #cartographer.