Build repository graphs once, query them with precision.
Complete reference for the gph CLI, the REST API, authentication flows, and deployment guidance.
Quickstart
From zero to querying your first graph in under three minutes.
Create an account
Sign up at /auth/sign-up or use GitHub OAuth. You can also use the CLI immediately if you already have a server URL and API key.
Index a repository
Run gph login (opens your browser to authorize), pick a repo with gph use, then gph index ./your-repo. Only changed files are processed on subsequent runs.
Query & export
Run gph search "your question" or gph query "natural language question" to retrieve token-bounded context. Use gph export to generate an agent-ready JSON bundle.
Installation
The gph CLI is a Node.js package. Install it globally or use it via npx.
# Global install (beta) npm install -g @graphchat/gph@beta # Sign in via your browser (recommended) gph login # Or, headless: gph login --key sk-graphchat-...
Requires Node.js 18 or later. The CLI stores credentials in ~/.graphchat/credentials.json and configuration in ~/.graphchat/config.json.
Authentication
graphchat uses two separate auth flows:
Web / browser
Email + password or GitHub OAuth. Sessions are maintained via HTTP-only cookies. The dashboard and graph UI use this flow.
CLI
Run gph login — the CLI opens your browser to confirm a one-time code against your existing graphchat session and auto-creates a CLI-scoped API key on approval. For headless setups, mint an API key (sk-graphchat-…) under Settings → API Keys and run gph login --key sk-graphchat-…. Either path yields a short-lived JWT access token plus a refresh token that auto-renews it.
Browser (device-code) flow
# 1. Run:
gph login
# Internally:
# POST /api/auth/cli/start → { device_code, user_code, verify_url_complete, ... }
# Browser opens verify_url_complete; you press “Authorize CLI”.
# CLI polls POST /api/auth/cli/poll { device_code } until approved,
# then receives { access_token, refresh_token, expires_in }.
# A CLI-scoped API key is created on your account on approval —
# revoke it any time under Settings → API Keys.API key exchange flow (headless)
# 1. Mint a key in the dashboard, then:
gph login --key sk-graphchat-abc123
# Internally this calls:
# POST /api/auth/exchange { "api_key": "sk-graphchat-abc123" }
# → { access_token, refresh_token, expires_in }
# All subsequent gph commands attach:
# Authorization: Bearer <access_token>Access tokens expire after a short window; the CLI automatically calls POST /api/auth/refresh before any request when expiry is imminent. To log out and revoke the refresh token:
gph logout
CLI Reference
Every gph command authenticates via the stored JWT and hits the configured server URL. Global help: gph --help. Per-command help: gph <cmd> --help.
gph login--key <api_key>--server <url>Authenticate the CLI. With no flags, opens your browser to confirm a one-time code and signs you in via your existing graphchat session — a CLI-scoped API key is auto-created on approval. Pass --key sk-graphchat-... for headless setups (CI, Docker). Tokens are stored locally and auto-refreshed before expiry.
gph login gph login --key sk-graphchat-abc123 gph login --server https://your.graphchat.host
gph github loginConnect your GitHub account to graphchat using the GitHub device-code flow. The CLI prints a short code and opens github.com/login/device in your browser — paste the code, authorize, and the CLI stores your GitHub token automatically. Required before `gph github repos`, `gph github import`, and `gph github sync` on private repos.
gph github login
gph github repos--search <query>--org <org>--jsonBrowse and import GitHub repositories your account has access to. Displays an interactive list; selecting a repo prompts for a branch and triggers graph ingestion. `--search` filters by name, `--org` scopes to an organization, `--json` emits machine-readable output.
gph github repos gph github repos --search graphchat gph github repos --org my-org --json
gph github import [url]Import a GitHub repository directly by URL or `owner/repo` shorthand and set it as the active repo — no need to run `gph use` afterwards. If `url` is omitted, falls back to the same interactive picker as `gph github repos`. After import, the CLI prints a `gph index` hint.
gph github import https://github.com/org/repo gph github import org/repo gph github import
gph github sync--repo <id>Trigger an incremental re-sync of a GitHub-connected repo on the server — only files changed since the last sync are re-processed. Defaults to the currently selected repo; pass `--repo` to target a specific one.
gph github sync gph github sync --repo cebd9df0-b5d7-4090-ac3d-353ee2be3f86
gph github statusCheck whether a GitHub account is connected to your graphchat session. Prints the connected GitHub login name, or a message prompting you to run `gph github login`.
gph github status
gph github logoutDisconnect your GitHub account from graphchat. Revokes the stored GitHub access token on the server. If the token was already revoked or the endpoint is unavailable, prints manual-revocation instructions.
gph github logout
gph logoutRevokes the stored refresh token on the server and removes local credentials. After logout, any cached access token is also invalidated.
gph logout
gph status--jsonShows the currently authenticated user, server URL, and token expiry. Use --json for machine-readable output.
gph status gph status --json
gph repos--jsonLists all repositories accessible to the current user. The currently selected repo (see `gph use`) is marked with a `*`. Subcommands: `gph repos add --name <name> [--select]` to create one, `gph repos delete <id>` to remove (clears the selection if it was the active repo).
gph repos gph repos add --name my-api --select gph repos delete my-api-id
gph use [id]--clearSelects the active repository for subsequent commands so you can drop the `--repo` flag from `gph index`, `gph export`, `gph query`, `gph explain`, `gph path`, `gph watch`, and `gph report`. With no `id`, opens an interactive picker. `--clear` removes the selection. The selection is also cleared automatically if the selected repo is deleted via `gph repos delete`.
gph use gph use cebd9df0-b5d7-4090-ac3d-353ee2be3f86 gph use --clear
gph index <path>--repo <id>Indexes a local repository path and pushes it to the graph service. The path is resolved to an absolute path; only files within it are included. Reuses prior state so only changed files are re-processed. `--repo` is optional — defaults to the repo selected via `gph use`.
gph index ./src gph index ./src --repo my-api-id
gph search <query>--repo <id>--budget <tokens>--confidence <level>--json--agentVector + graph search across indexed repos. The --budget flag caps the token count of returned results, dropping lower-confidence nodes first. --agent emits a compact format ready to paste into an AI chat prompt. --confidence accepts EXTRACTED | INFERRED | SPECULATIVE.
gph search "authentication middleware" --budget 1500 gph search "JWT guard" --repo backend --confidence EXTRACTED --agent
gph query <question>--repo <id>--mode <knn|bfs|dfs>--hops <n>--budget <tokens>--jsonGraph-expanded retrieval. Embeds your natural-language question, runs vector KNN to pick seed nodes, then traverses the graph from those seeds. --mode knn (default) returns neighbours by similarity; bfs / dfs walk structural edges. --hops controls expansion depth, --budget caps the response in tokens.
gph query "how does login work?" --repo my-api-id gph query "request lifecycle" --repo backend --mode bfs --hops 3 --budget 3000
gph explain <label>--repo <id>AI-generated explanation of a single node, grounded in the graph. The CLI looks up the node by label (case-insensitive exact match), pulls its strongest neighbours, and asks the configured LLM to describe what it is, how it relates to those neighbours, and any caveats. Uses your active LLM provider from Settings → Model.
gph explain AuthService --repo my-api-id gph explain ResponseInterceptor --repo backend
gph path <source> <target>--repo <id>Finds the shortest path between two named symbols in the graph and prints every hop. Useful for understanding how middleware or dependency chains connect.
gph path AuthService JwtGuard --repo my-api-id gph path ResponseInterceptor DatabaseService --repo backend
gph watch <path>--repo <id>--debounce <ms>--on-commit--stopKeeps the graph in sync with a working directory. Default mode runs a local file watcher (chokidar) and re-indexes after a debounce window — only the diff is uploaded; source code stays on your machine. With --on-commit, installs idempotent post-commit / post-checkout / post-merge git hooks that re-index in the background. Use --stop with --on-commit to remove the hooks.
gph watch ./src --repo my-api-id gph watch ./src --repo my-api-id --debounce 3000 gph watch ./src --repo my-api-id --on-commit gph watch ./src --repo my-api-id --stop
gph report--repo <id>--out <file>Generates a GRAPH_REPORT.md audit report summarising god nodes, top communities, surprise edges, and file coverage stats. Ready to paste into a PR description or agent prompt.
gph report --repo my-api-id --out GRAPH_REPORT.md gph report --repo backend --out ./reports/backend.md
gph export--repo <id>--out <file>Exports a full agent context payload for a named repo as a structured JSON bundle. The bundle includes graph metadata, communities, nodes, and edges — ready to feed into any LLM session.
gph export --repo my-api-id --out context.json gph export --repo backend --out ./context/backend.json
API Reference
All API routes are prefixed with /api. Authenticated routes require an Authorization: Bearer <access_token> header. Responses are JSON. Rate limiting is enforced per user via a Redis sliding-window counter.
Authentication
/api/auth/registerpublicCreate a new user account. Returns access + refresh tokens.
{ "email": "you@example.com", "password": "..." }/api/auth/loginpublicAuthenticate with email + password. Returns access + refresh tokens.
{ "email": "you@example.com", "password": "..." }/api/auth/githubpublicSign in via GitHub OAuth. Supply the GitHub OAuth code.
{ "code": "<oauth_code>" }/api/auth/sessionauth requiredReturns the current authenticated user (name, email, role).
/api/auth/logoutpublicRevokes a refresh token. Supply the refresh token in the body.
{ "refresh_token": "..." }GitHub Integration
/api/auth/github/cli/startpublicStart the GitHub device-code flow. Returns device_code, user_code, verification_uri, and expires_in. The CLI opens the verification URL so the user can authorise access on github.com/login/device.
/api/auth/github/cli/pollauth requiredPoll for device-code authorisation. Returns { status: "pending" } while waiting; on success stores the GitHub access token on the authenticated user and returns { status: "authorized" }.
{ "device_code": "..." }/api/auth/github/reposauth requiredList GitHub repositories accessible via the stored GitHub token. Accepts ?search=, ?org=, and ?page= query params. Returns 401 if GitHub is not yet connected — run gph github login first.
?search=graphchat&org=my-org&page=1
/api/auth/github/tokenauth requiredRevoke and remove the stored GitHub access token for the current user. Returns 204 on success.
API Keys (CLI auth)
/api/auth/keysauth requiredMint a new API key for the current user. The plaintext (sk-graphchat-…) is returned once and never stored.
{ "label": "my-ci-key", "scopes": ["search", "export"] }/api/auth/keysauth requiredList all API keys belonging to the current user (IDs, labels, scopes, created date).
/api/auth/keys/:idauth requiredPermanently revoke an API key by its ID. Returns 204 on success.
/api/auth/exchangepublicTrade an API key for a fresh JWT access + refresh token pair. This is what gph login calls internally.
{ "api_key": "sk-graphchat-..." }/api/auth/refreshpublicTrade a refresh token for a new access token. The CLI calls this automatically before expiry.
{ "refresh_token": "..." }Repositories
/api/reposauth requiredList all repos for the current user with metadata (branch, node count, last sync).
/api/repos/:idauth requiredGet a single repo by ID including full graph metadata.
/api/reposauth requiredCreate / register a new repo. Supply name, remote URL, and branch.
{ "name": "my-api", "url": "https://github.com/org/repo", "branch": "main" }/api/repos/import/github/branchesauth requiredList available branches for a GitHub repo before importing.
{ "repoUrl": "https://github.com/org/repo" }/api/repos/import/githubauth requiredImport a GitHub repository and trigger initial graph ingestion.
{ "repoUrl": "https://github.com/org/repo", "branch": "main" }/api/repos/:id/sync/githubauth requiredTrigger an incremental re-sync for a repo — only changed files are re-processed.
/api/repos/:idauth requiredDelete a repo and all associated graph data.
Graph & Search
/api/nodes/searchauth requiredVector + graph search. Supply query, optional repoId, budget (token cap), and confidence filter.
{ "query": "auth middleware", "repoId": "...", "budget": 1500, "confidence": "EXTRACTED" }/api/graph/pathauth requiredShortest path between two node labels. Returns ordered hop array.
?repoId=...&source=AuthService&target=JwtGuard
/api/graph/communities/:repoIdauth requiredReturns all Leiden communities for a repo with member counts and top nodes.
/api/graph/community/:communityId/promptauth requiredReturns a token-bounded, agent-ready context bundle for a single community (cached in Redis).
/api/graph/report/:repoIdauth requiredReturns the GRAPH_REPORT.md content as a string — god nodes, surprise edges, coverage stats.
/api/graph/analyzeauth requiredRun graph analysis (community detection, god-node scoring) on an already-ingested repo.
{ "repoId": "..." }/api/graph/ingestauth requiredReceives a client-extracted graph payload (the CLI runs Tree-sitter locally and ships only nodes + edges). Source code never reaches the API. This is the endpoint behind gph index and gph watch.
{ "repoId": "...", "nodes": [...], "edges": [...] }/api/graph/queryauth requiredGraph-expanded retrieval. Embeds the question, runs vector KNN to pick seed nodes, then asks the sidecar to expand from those seeds. Backs gph query.
{ "repoId": "...", "query": "how does login work?", "mode": "knn", "hops": 2, "budget": 2000 }/api/ai/explainauth requiredGenerates a natural-language explanation of a node, grounded in its graph neighbours. Backs gph explain.
{ "repoId": "...", "label": "AuthService" }/api/ai/suggestauth requiredReturns a structured ContextNode draft (type / label / content / tags) for free-text input. Used by the dashboard UI when adding manual notes.
{ "repoId": "...", "input": "JWT auth middleware" }System
/api/healthpublicReturns service health, Redis cache hit rate, and DB status.
/api/health/configpublicReturns non-sensitive runtime configuration (model, chunk size, rate-limit defaults).
Deployment
graphchat is an Nx monorepo with three deployable apps: the Next.js web frontend, the NestJS API, and the Python graph service. Run them together via Docker Compose or deploy each independently.
Heads up: the repository will be open-sourced soon, so you'll be able to clone, audit, and self-host the entire stack.
Run through Nx (development)
Use pnpm nx serve web, pnpm nx serve api to start apps locally. Nx caches build artifacts so cold starts after the first run are fast.
pnpm nx serve web pnpm nx serve api
Docker Compose (production)
The repository root contains a docker-compose.yml that wires up the web app, API, graph service, Postgres, and Redis together.
docker compose up --build
Environment variables
Copy .env.example to .env and set DATABASE_URL, REDIS_URL, JWT_SECRET (use a long random string in production), GITHUB_CLIENT_ID, and GITHUB_CLIENT_SECRET.
cp .env.example .env # Edit .env with your secrets
Point the CLI at your server
By default the CLI targets the hosted graphchat server. To use a self-hosted instance, pass --server on login or set serverUrl in ~/.graphchat/config.json.
gph login --key sk-graphchat-... --server https://your.host.com