Skip to content

SDK Reference

Call registerGlasstrace() in your instrumentation.ts file. It configures OpenTelemetry, registers Prisma instrumentation, attaches a Glasstrace span exporter, and starts a non-blocking init call to the Glasstrace backend.

registerGlasstrace() accepts an optional GlasstraceOptions object:

NameTypeDefaultDescription
apiKeystringundefinedGlasstrace API key. Overrides GLASSTRACE_API_KEY env var. If omitted and no env var is set, anonymous mode activates with an auto-generated gt_anon_xxx key.
endpointstring (URL)undefinedGlasstrace ingestion endpoint URL. Overrides the default (https://glasstrace.vercel.app).
forceEnablebooleanundefinedWhen true, the SDK stays active even in production environments. Overrides GLASSTRACE_FORCE_ENABLE env var.
verbosebooleanundefinedWhen true, the SDK logs detailed startup and export information to stdout.

voidregisterGlasstrace() is synchronous from the caller’s perspective. It applies cached config immediately and fires a background POST /v1/sdk/init call that updates config when it resolves.

Register Glasstrace in your instrumentation file:

instrumentation.ts
import { registerGlasstrace } from "@glasstrace/sdk";
export function register() {
registerGlasstrace();
}

Pass options explicitly:

registerGlasstrace({
apiKey: "<your-api-key>",
verbose: true,
});

If the SDK detects a production environment (NODE_ENV=production or VERCEL_ENV=production) and forceEnable is not set, it logs a warning and returns a no-op. No OTel setup occurs, no init call is made, and no spans are exported.

{
"level": "warn",
"message": "Glasstrace disabled: production environment detected. Set GLASSTRACE_FORCE_ENABLE=true to override."
}

If the background init call fails (network error, invalid key), the SDK continues operating with cached or default config. Errors are logged when verbose is enabled but never thrown to the caller.


Wrap your Next.js config with withGlasstraceConfig() to enable source map generation and upload during next build.

NameTypeDefaultDescription
nextConfigNextConfigYour existing Next.js configuration object.

Returns the augmented NextConfig with source map generation enabled and a post-build hook that uploads .map files to the Glasstrace backend.

Wrap your Next.js config:

next.config.ts
import { withGlasstraceConfig } from "@glasstrace/sdk";
const nextConfig = {
// your existing config
};
export default withGlasstraceConfig(nextConfig);

withGlasstraceConfig() hooks into the Next.js build process:

  1. Enables source map generation if not already enabled
  2. After build completion, collects .map files from the output
  3. Uploads them via POST /v1/source-maps with the build hash and API key auth

Source maps enable the Glasstrace backend to resolve compiled stack traces to TypeScript file paths and line numbers.

Source map upload requires a gt_dev_xxx API key. In anonymous mode, withGlasstraceConfig() enables local source map generation but skips the upload. The SDK logs a message explaining that source-mapped stack traces require a dev key.

{
"level": "info",
"message": "Source map upload skipped: no GLASSTRACE_API_KEY set. Source maps are generated locally but not uploaded."
}

If the upload fails (network error, auth failure), the build completes normally. Source map upload never blocks or fails the build.

{
"level": "warn",
"message": "Source map upload failed: 401 Unauthorized. Verify your GLASSTRACE_API_KEY."
}

One-time scaffolding command that sets up Glasstrace in your Next.js project.

FileActionDescription
instrumentation.tsCreate (or prompt before overwriting)Calls registerGlasstrace() with Prisma initialization order comment
next.config.ts / next.config.jsModifyWraps existing config with withGlasstraceConfig()
.env.localCreate or appendAdds GLASSTRACE_API_KEY= placeholder
.gitignoreCreate or appendAdds .glasstrace/ entry. Also consider adding MCP config files (.mcp.json, .cursor/mcp.json) if they contain tokens.
.mcp.json, .cursor/mcp.json, etc.CreateMCP config files for detected AI agents

The init command has no required flags. It detects your project structure and prompts interactively.

NameTypeDefaultDescription
(no flags)Runs interactive scaffolding with auto-detection

The CLI detects:

  • Whether instrumentation.ts already exists (prompts before overwriting)
  • Whether next.config.js or next.config.ts is present (wraps the detected format)
  • Which AI agent CLIs are installed (Claude Code, Codex, Cursor, Windsurf, Gemini)

Running init a second time prompts before overwriting existing files. It does not duplicate .gitignore entries or .env.local variables.

Terminal window
npx @glasstrace/sdk init
{
"error": "no_next_config",
"message": "Could not find next.config.js or next.config.ts. Run this command from your Next.js project root."
}

Register the Glasstrace MCP server with your AI coding agents. This command detects installed agents and writes native MCP configuration files for each one.

NameTypeDefaultDescription
--dry-runflagfalsePrint what would be written without making changes.
--forceflagfalseOverwrite existing MCP config entries without prompting.
AgentConfig FileKey Format
Claude Code.mcp.json{ "type": "http", "url": "..." }
Cursor.cursor/mcp.json{ "url": "..." }
Windsurf~/.codeium/windsurf/mcp_config.json{ "serverUrl": "..." }
Codex.codex/config.toml or codex mcp add CLIbearer_token_env_var
Gemini.gemini/settings.json{ "httpUrl": "..." }

Each agent’s config points to https://api.glasstrace.dev/mcp with a Bearer auth header containing the anonymous key from .glasstrace/anon_key (or your GLASSTRACE_API_KEY if set).

Preview changes without writing:

Terminal window
npx @glasstrace/sdk mcp add --dry-run

Force overwrite existing config:

Terminal window
npx @glasstrace/sdk mcp add --force
{
"error": "no_agents_detected",
"message": "No supported AI agents detected. Install Claude Code, Cursor, Windsurf, Codex, or Gemini CLI, then retry."
}
{
"error": "no_anon_key",
"message": "No anonymous key found. Run 'npx @glasstrace/sdk init' first, or set GLASSTRACE_API_KEY."
}

Glasstrace attaches glasstrace.* semantic attributes to every span at export time. These attributes provide structured context for the MCP debugging tools.

AttributeDescription
glasstrace.trace.type'server' — distinguishes from client events
glasstrace.session.idTime-bounded session identifier
glasstrace.correlation.idFrom x-gt-cid header if present
glasstrace.environmentFrom GLASSTRACE_ENV or derived from origin
glasstrace.routee.g. 'POST /api/orders'
glasstrace.http.methodGET, POST, PUT, DELETE, etc.
glasstrace.http.status_codee.g. 500, 200, 403
glasstrace.http.duration_msWall-clock request duration
glasstrace.error.messageError message text
glasstrace.error.codee.g. 'P2003' for Prisma
glasstrace.error.categorye.g. 'foreign-key-violation', 'auth-failure', 'timeout'
glasstrace.error.fieldAffected field (e.g. 'orders.userId')
glasstrace.orm.provider'prisma', 'drizzle', or 'none'
glasstrace.orm.modele.g. 'Order', 'User'
glasstrace.orm.operatione.g. 'create', 'findMany', 'delete'
glasstrace.orm.duration_msORM query duration
glasstrace.fetch.urlOutbound request URL
glasstrace.fetch.methodOutbound GET, POST, etc.
glasstrace.fetch.status_codeOutbound response status
glasstrace.fetch.duration_msOutbound round-trip duration
glasstrace.fetch.targetClassified target: 'supabase', 'stripe', 'internal', 'unknown'
glasstrace.env.referencedArray of env var names referenced in error context
glasstrace.source.fileSource-mapped TypeScript file path
glasstrace.source.lineSource-mapped line number
glasstrace.source.mappedBoolean — whether source mapping was applied

Attributes are enriched at export time by the GlasstraceExporter, not at span creation. This means attributes reflect the final state of the span (resolved API key, computed session ID) rather than an in-progress state.

The glasstrace.fetch.target attribute classifies outbound HTTP requests by URL pattern. For example, requests to *.supabase.co are classified as 'supabase', requests to *.stripe.com as 'stripe', and requests to your own app’s origin as 'internal'. Unrecognized URLs are classified as 'unknown'.


GET /__glasstrace/config — a localhost endpoint that the Glasstrace browser extension uses to discover the anonymous key and session ID.

The discovery endpoint is registered only when all three conditions are true:

  1. Anonymous mode — no GLASSTRACE_API_KEY is set
  2. Development environmentNODE_ENV is not 'production'
  3. SDK is active — not disabled by the production guard

When any condition fails, the endpoint does not exist.

{
"key": "gt_anon_<generated-key>",
"sessionId": "<current-session-id>"
}

The discovery endpoint only exists in development on localhost. It exposes the anonymous key (not a paid API key) to allow the browser extension to correlate client-side events with server traces without requiring the developer to copy keys manually.

When you set a GLASSTRACE_API_KEY (a gt_dev_xxx key from a paid account), the endpoint ceases to exist. The extension then authenticates via session token from sign-in, not anonymous discovery.

If the endpoint is accessed in a context where it should not be active, the middleware is not registered and the request falls through to the host framework’s default 404 handling. The exact response format depends on the framework (e.g. Next.js serves its own 404 page).


The @glasstrace/sdk/drizzle subpath export provides a Drizzle ORM adapter that creates OpenTelemetry spans for database queries.

import { GlasstraceDrizzleLogger } from "@glasstrace/sdk/drizzle";

The adapter is a separate subpath export to avoid pulling in Drizzle as a dependency for developers who only use Prisma. Drizzle is declared as an optional peer dependency.

Pass the logger when creating your Drizzle instance:

import { drizzle } from "drizzle-orm/node-postgres";
import { GlasstraceDrizzleLogger } from "@glasstrace/sdk/drizzle";
const db = drizzle(client, {
logger: new GlasstraceDrizzleLogger(),
});

The adapter implements Drizzle’s Logger interface and creates an OTel span for each query with:

AttributeValue
glasstrace.orm.provider'drizzle'
glasstrace.orm.modelExtracted from SQL (best-effort)
glasstrace.orm.operationExtracted from SQL (e.g. 'SELECT', 'INSERT')
glasstrace.orm.duration_msQuery execution time

Query parameters are included by default. Set CaptureConfig.queryParamValues to false in the dashboard to redact them.

{
"level": "warn",
"message": "GlasstraceDrizzleLogger: failed to parse SQL for model extraction. Span created with orm.model='unknown'."
}

The import graph is an opt-in feature that captures the module dependency structure of your test files. It powers the get_test_suggestions MCP tool’s coverage map.

Enable import graph capture by setting CaptureConfig.importGraph to true in the dashboard capture settings. Import graph requires a paid tier (Free Trial or Pro).

You can also enable it via environment variable during setup:

Terminal window
GLASSTRACE_COVERAGE_MAP=true

The SDK performs lightweight static analysis of import and require statements in your test files. It builds a map from test file paths to their imported module paths. No code is executed — the analysis uses pattern matching on import statements, not the TypeScript compiler.

Test files are discovered by checking vitest.config, jest.config, or conventional paths (__tests__/, *.test.ts, *.spec.ts).

The import graph is built and uploaded during the SDK init call (POST /v1/sdk/init). It runs at server startup, not continuously.

The get_test_suggestions MCP tool uses the import graph to generate a coverage map (Part 1) that identifies which test files cover which modules. When an error occurs in a specific module, the tool can suggest the most relevant test files.

The import graph is typically under 50KB even for large projects. It adds negligible overhead to server startup.

Without the import graph, get_test_suggestions still works — it provides test ideas based on trace patterns (Parts 2 and 3). The coverage map (Part 1) is the import-graph-dependent part.

{
"error": "tier_restricted",
"message": "Import graph capture requires a paid tier (Free Trial or Pro). Sign up at https://glasstrace.dev to enable.",
"upgrade_url": "https://glasstrace.dev"
}

Glasstrace uses deterministic session IDs to group traces from the same developer, project, and time window.

Session IDs are computed via:

SHA-256(apiKey + origin + date + window_index)

Truncated to 16 hex characters.

ComponentSourceExample
apiKeyYour API key or auto-generated anonymous keygt_anon_<key>
originHostname + port (or GLASSTRACE_ENV if set)localhost:3000
dateCurrent date (UTC)2026-04-08
window_indexIncrements after 4 hours of inactivity0, 1, 2

The SDK tracks the last activity timestamp in memory. On each span export, it checks if more than 4 hours have elapsed since the last activity. If so, it increments the window index and derives a new session ID.

The window index resets daily (the date component in the hash changes).

  • Server restarts typically do not create new sessions — the same inputs produce the same hash. Note: a restart resets the in-memory window_index to 0, so if it had incremented (after a 4-hour gap) the session ID will change.
  • Different ports (localhost:3000 vs localhost:3001) are separate sessions — they represent different services
  • Different days start new sessions — the date component changes
  • 4-hour gaps start new sessions — the window index increments
  • Custom environments — set GLASSTRACE_ENV to use a fixed environment name (e.g. staging) instead of hostname + port
{
"level": "warn",
"message": "Session ID derivation failed: missing apiKey. Using fallback session ID."
}