SDK Documentation

Code intelligence as infrastructure

Deploy the self-hosted gateway, point it at your repos, and call the engine from any machine over REST or the Python / TypeScript clients. Type-accurate context and cross-repo blast-radius for your agents, bots, and pipelines. Your code never leaves your network.

REST · M2MPython & TypeScriptSelf-hosted · Air-gapped ready
Overview

Introduction

The vexp SDK is a self-hosted, machine-to-machine code-intelligence engine. It indexes hundreds of repositories into a live dependency graph and serves two things over a simple REST API: the exact context a model needs for a task, and the cross-repo blast-radius of a change. You bring the agent, bot, or pipeline; vexp gives it grounding.

It is delivered as a gateway you run on your own infrastructure plus thin clients for Python and TypeScript. There is no SaaS, no account, and no egress: indexing, serving, and license validation all happen inside your network. The engine is the same one behind the vexp VS Code extension and CLI, exposed for automation rather than a single developer.

The SDK is REST / M2M only. The MCP interface used by the editor and CLI is deliberately not exposed here, so the SDK complements your per-seat tools rather than replacing them.

Concepts

Architecture

A deployment is one gateway fronting one or more index shards. Your repositories are distributed across shards; the gateway routes each call to the shards that own the relevant repos and merges the result into a single response. Memory tracks the active working set rather than the total repo count, so the footprint stays flat as the fleet grows: you add a worker to scale, not a bigger box.

PieceWhat it isWhere it runs
gatewayREST ingress, auth, routing, metricsYour network
shardsIndexed repositories + graphYour network
clientsPython / TypeScript wrappers over RESTYour machines
license.jwtOffline-validated capacity entitlementMounted in the gateway
Setup

Deploy the gateway

Run the public gateway image on a host inside your network. Give it a workspace directory (/srv/vexp below) that holds your repo checkouts plus a .vexp/ folder with workspace.json (the repos it serves, see Multi-repo workspaces) and your license.jwt.

First, index the repos once (and again after large changes). The gateway serves the index, it does not build it on startup:

docker
$ docker run --rm \
-e VEXP_HOME=/var/lib/vexp \
-v /srv/vexp:/var/lib/vexp \
ghcr.io/vexp-ai/vexp-gateway:latest \
bulk-index --workspace /var/lib/vexp

Then start the gateway. VEXP_HOME tells it where to read the license; --bearer sets the request-auth token:

docker
$ docker run -d --name vexp-gateway \
-p 7777:7777 \
-e VEXP_HOME=/var/lib/vexp \
-v /srv/vexp:/var/lib/vexp \
ghcr.io/vexp-ai/vexp-gateway:latest \
gateway --workspace /var/lib/vexp --bind 0.0.0.0:7777 \
--bearer "$VEXP_TOKEN" --shards 2

Confirm it is serving and that every shard is reachable:

bash
$ curl -s http://localhost:7777/health
# { "status": "ok", "shards": 2 }
$ curl -s -H "Authorization: Bearer $VEXP_TOKEN" http://localhost:7777/ready
# { "ready": true, "shards_total": 2, "shards_reachable": 2 }
Security

Authentication

Every request except GET /health is authenticated with a bearer token, sent in the Authorization header. The token is the one you set with --bearer at deploy time. A missing or wrong token returns 401.

http
Authorization: Bearer <your-token>

The token is distinct from your license. The license.jwt mounted in the gateway is an offline-validated entitlement that sets your capacity tier and limits; it is never sent over the wire and nothing calls home. Webhooks can be additionally verified with an HMAC secret (see Indexing & freshness).

REST API

Tool API

The primary ingress is a single endpoint: POST /v1/tools/{tool}. You pass the tool name in the path and its parameters as a JSON body; the gateway fans the call out to the right shards and returns one merged result.

ToolPurposeKey params
run_pipelineContext + impact + memory in one calltask, repos?, preset?, max_tokens?
get_context_capsuleRetrieve the relevant code for a queryquery, repos?
get_impact_graphCross-repo blast-radius of a symbolsymbol_fqn
index_incrementalRe-index changed filesrepo?, files?, mode
index_statusIndex health and stats

Example request

bash
$ curl -X POST http://localhost:7777/v1/tools/run_pipeline \
-H "Authorization: Bearer $VEXP_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "task": "why does checkout fail", "repos": ["payments-gateway"] }'

Example response

Retrieval tools return a list of pivots — the ranked code locations for the task — alongside an optional compressed output.

json
{
"output": "Checkout.createSession throws when the gateway token is expired ...",
"pivots": [
{
"repo": "payments-gateway",
"file_path": "src/checkout/session.ts",
"fqn": "Checkout.createSession",
"score": 0.94
}
],
"status": "ok"
}
Clients

Python client

The Python client is dependency-free (standard library only), so it runs anywhere, including air-gapped CI.

bash
$ pip install vexp-sdk
python
from vexp_sdk import VexpClient
vx = VexpClient("http://localhost:7777", token="...")
# Context + impact for a task
res = vx.run_pipeline("why does checkout fail", repos=["payments-gateway"])
for p in res["pivots"]:
print(p["repo"], p["file_path"], p["score"])
# Cross-repo blast-radius of a symbol
impact = vx.impact_graph("payments.Checkout.create_session")
# Drive a re-index after a deploy
vx.index_incremental(repo="payments-gateway", mode="incremental")

VexpClient(base_url, token=None, timeout=60.0) also exposes health(), context_capsule(query, **kw), index_status(), and a generic call(tool, **params). Non-2xx responses raise VexpError.

Clients

TypeScript client

The TypeScript client uses the built-in fetch with a timeout and ships typed results.

bash
$ npm install vexp-sdk
typescript
import { VexpClient } from 'vexp-sdk'
const vx = new VexpClient('http://localhost:7777', { token: process.env.VEXP_TOKEN })
const res = await vx.runPipeline('why does checkout fail', { repos: ['payments-gateway'] })
for (const p of res.pivots) {
console.log(p.repo, p.file_path, p.score)
}
await vx.impactGraph('payments.Checkout.createSession')
await vx.indexIncremental({ repo: 'payments-gateway', mode: 'incremental' })

new VexpClient(baseUrl, { token, timeoutMs }) also exposes health(), contextCapsule(query, params?), indexStatus(), and a generic call<T>(tool, params?). Errors throw VexpError; results are typed via PipelineResult and Pivot.

Operations

Indexing & freshness

Repos are indexed once with the bulk-index step above, then kept fresh incrementally. There are two ways to drive updates:

1. On demand

Call index_incremental from your deploy or CI step to re-index changed files. Pass mode: "full" to rebuild a repo from scratch, or a files list to scope the update.

2. From your VCS webhook

Point your provider's push / PR webhook at POST /webhook/{provider} and the gateway re-indexes the changed files automatically. Set VEXP_WEBHOOK_SECRET to verify the payload signature (GitHub uses X-Hub-Signature-256).

http
POST /webhook/github
X-Hub-Signature-256: sha256=...
# re-indexes the files in the push, on the shard that owns the repo
Configuration

Multi-repo workspaces

A workspace config lists the repositories the gateway serves. Each repo gets an alias you use to scope calls (the repos parameter). The gateway distributes repos across shards for you.

workspace.json
{
"name": "acme",
"repos": [
{ "alias": "payments-gateway", "path": "/var/lib/vexp/repos/payments-gateway" },
{ "alias": "web", "path": "/var/lib/vexp/repos/web" },
{ "alias": "shared-lib", "path": "/var/lib/vexp/repos/shared-lib" }
]
}

Omit repos on a call to query the whole workspace, or pass a subset to scope it. Cross-repo links let blast-radius cross service boundaries, so a change in shared-lib surfaces its impact in payments-gateway and web.

Operations

Ops endpoints

Beyond the tool API, the gateway exposes standard operational endpoints for health checks, readiness gating, and metrics scraping.

EndpointAuthReturns
GET /healthNoLiveness + shard count
GET /readyYes200 when all shards reachable, else 503
GET /metricsYesPrometheus exposition (requests, errors, per-tool latency)

Use /ready as your load-balancer readiness probe so traffic only reaches a gateway whose shards are all serving. Scrape /metrics into Prometheus for per-tool request, error, and latency series.

Trust

Security & isolation

The SDK is built to run where your code already lives, with nothing leaving your perimeter.

PropertyHow
Self-hostedRuns on your servers; one container or many.
Air-gapped readyIndexes, serves, and validates the license fully offline.
No egressYour code and queries never leave your network.
On-prem modelThe optional AI layer runs locally; no third-party AI calls.
REST onlyNo MCP surface, so it cannot be wired into editors as a seat bypass.
Plans

Plans & limits

Capacity is shaped by repositories, not seats, and enforced from the offline license. Start free to evaluate, then size a plan against your fleet.

PlanReposCallsFor
DevUp to 530 / dayEvaluation and prototyping (30-day)
StartupUp to 10UnlimitedSmall fleets in production
EnterpriseHundreds+UnlimitedFleet-scale, capacity license

Sizing is by repositories under index. Talk to us with your repo count and we will size a capacity plan to fit.