Installation

Self-host the full ScopeCall stack via Docker Compose. From clone to first trace in about 10 minutes.

ScopeCall self-hosts via Docker Compose. The stack is the same software that runs in ScopeCall Cloud — no feature gating, no stripped-down "community edition." From clone to first trace is about 10 minutes.

Requirements

  • Docker + Docker Compose v2+
  • 4 vCPU / 8 GB RAM / 50 GB disk minimum
  • An OpenAI / Anthropic / Vercel-AI-SDK app you want to observe

1. Start the stack

git clone https://github.com/scopecall/scopecall.git
cd scopecall

cp infra/.env.example infra/.env
# Generate the two required secrets:
echo "AUTH_SECRET=$(openssl rand -hex 32)" >> infra/.env
echo "INTERNAL_API_KEY=$(openssl rand -hex 32)" >> infra/.env

docker compose -f infra/docker-compose.yml pull
docker compose -f infra/docker-compose.yml up -d

Wait for all services to report healthy:

docker compose -f infra/docker-compose.yml ps

2. Create your admin account

Open http://localhost:3000/setup and create the first org + admin user. This screen only works once — after the first user exists, it redirects to the login page.

3. Generate an API key

In the dashboard, go to Settings → API Keys → Generate. Copy the sc_live_... key. We store only a hash, so the dashboard cannot show the raw key again after this screen.

4. Instrument your app

TypeScript

npm install @scopecall/scopecall-js
import { init } from "@scopecall/scopecall-js";
import OpenAI from "openai";

// init() returns the SDK instance — call once at app startup.
// `endpoint` is the full ingest URL (port 8080 in the Compose stack).
const sdk = init({
  apiKey: "sc_live_xxx",
  endpoint: "http://localhost:8080/v1/ingest",
});

const openai = new OpenAI();
sdk.instrument(openai);          // wraps chat.completions.create in place
// All calls through this client are traced automatically.

Python

pip install scopecall-py
# Or with provider extras (recommended):
pip install "scopecall-py[openai]"
pip install "scopecall-py[anthropic]"
import scopecall
from openai import OpenAI

sdk = scopecall.init(
    api_key="sc_live_xxx",
    endpoint="http://localhost:8080/v1/ingest",
)

openai_client = sdk.instrument(OpenAI())  # pass AsyncOpenAI() for async

with sdk.trace("my-workflow", user_id="u_1"):
    response = openai_client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": "Hello"}],
    )

The Python SDK ships at scopecall-py@0.2.1 alongside the v0.1.1 self-hosted stack: OpenAI + Anthropic sync/async/streaming, workflow spans, contextvars-based trace propagation across await, PII redaction, manual sdk.record_llm_call(...) for LangChain / LlamaIndex / custom wrappers, and FastAPI lifespan support. Same wire contract as the TypeScript SDK.

5. See your traces

Make an LLM call from your app, then open http://localhost:3000/dashboard/traces. Your trace appears within seconds.

Ports

ServicePortPurpose
Dashboard3000Web UI
Ingest8080SDK sends events here
API8081Internal (dashboard ↔ API)

Only 3000 and 8080 need to be reachable by you and your app respectively. The rest are internal to the Docker network.

How it fits together

Your app (SDK)
   │  HTTP batch
   ▼
Rust ingest service (:8080)     ← validates payload, auths the API key,
   │                              publishes to Kafka. Stateless.
   ▼
Redpanda (events.llm_calls)     ← durable buffer between ingest and processor.
   │
   ▼
Rust processor                  ← consumes events, recomputes cost from the
   │                              bundled pricing table, writes to ClickHouse.
   ▼
ClickHouse                      ← llm_calls (source of truth) +
                                  llm_metrics_hourly (rollup MV).

Go API (:8081)                  ← READ-ONLY against ClickHouse + Postgres.
   ├── reads ClickHouse         ← traces, cost, prompts, sessions, flow map.
   └── reads/writes Postgres    ← orgs, users, api_keys, saved views, alerts.

Next.js dashboard (:3000)       ← Auth.js sessions, proxies to Go API.

Next steps