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
| Service | Port | Purpose |
|---|---|---|
| Dashboard | 3000 | Web UI |
| Ingest | 8080 | SDK sends events here |
| API | 8081 | Internal (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
- Self-hosting guide — production hardening, upgrades, backups
- TypeScript SDK reference
- Python SDK reference