MCP Server
Glasstrace exposes seven debugging tools to AI coding agents via the Model Context Protocol (MCP). Your agent connects once, then queries traces, errors, candidate matches, and root cause analysis directly from your development session.
Server description
Section titled “Server description”When your agent connects, Glasstrace describes itself as a server-side debugging trace source for Next.js applications. It explains that inbound requests are traced from route handler through database calls, with bounded error evidence and timing.
Use Glasstrace when an HTTP error, failed API call, unexpected server behavior, or database error cannot be diagnosed from client-side symptoms alone. A typical workflow is:
- Call
get_latest_errorfirst to inspect the most recent server-side failure and span tree. - If more than one error may exist, call
get_error_listto review recent errors before drilling into one trace. - If you know a route fragment, tRPC procedure, method, status, or rough recent activity window but not the exact trace lookup, call
find_trace_candidatesbefore exact lookup. Candidate discovery helps choose evidence; it is not root-cause proof. - Call
get_root_causefor AI analysis when your tier supports enrichment. If it returnsstatus: "pending", wait a few seconds and call it again. - After fixing the issue, call
get_test_suggestionsto generate regression and prevention test ideas.
Glasstrace is observational only. It does not modify code, run tests, restart servers, interact with the browser, or run in production by default.
Connection
Section titled “Connection”| Setting | Value |
|---|---|
| Endpoint | https://api.glasstrace.dev/mcp |
| Protocol | Streamable HTTP |
| Auth | Authorization: Bearer <your-api-key> |
The bearer token is either your anonymous key (from .glasstrace/anon_key, generated automatically by the SDK) or your developer key (GLASSTRACE_API_KEY environment variable).
Test connectivity with curl:
curl -X POST https://api.glasstrace.dev/mcp \ -H "Authorization: Bearer <your-api-key>" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}},"id":1}'A successful response returns a JSON-RPC result with the server’s capabilities and tool list.
Glasstrace registers seven tools with the MCP server. Each tool returns a ToolResponseWrapper envelope:
// Success{ success: true, data: { /* tool-specific response */ } }
// Failure{ success: false, diagnostic: { reason: string, message: string, upgradeUrl?: string, dataPreserved?: boolean, searchedScope?: object, recoveryActions?: object[], notAbsenceProof?: boolean } }get_latest_error
Section titled “get_latest_error”Returns the most recent error trace in your session, including the full span tree. This is the tool your agent should call first when something breaks.
Parameters
Section titled “Parameters”None. This tool operates on the current session automatically.
Response
Section titled “Response”interface GetLatestErrorResponse { summary: TraceSummary; spans: SpanSummary[];}Tier gating
Section titled “Tier gating”Available on all tiers (Anonymous, Free Trial, Pro).
Example
Section titled “Example”Request:
{}Response:
{ "success": true, "data": { "summary": { "traceId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d", "route": "POST /api/polls/create", "statusCode": 500, "error": "PrismaClientKnownRequestError: Unique constraint failed on the fields: (`slug`)", "errorCategory": "foreign-key-violation", "affectedComponent": "prisma", "duration": 142, "timestamp": 1712534400000, "enrichmentStatus": "completed" }, "spans": [ { "name": "POST /api/polls/create", "layer": "server", "duration": 142, "status": "ERROR", "error": "PrismaClientKnownRequestError", "children": [ { "name": "prisma:client:operation polls.create", "layer": "database", "duration": 38, "status": "ERROR", "error": "Unique constraint failed on the fields: (`slug`)" } ] } ] }}Error responses
Section titled “Error responses”{ "success": false, "diagnostic": { "reason": "no_traces_found", "message": "No error traces found in the current session. This could mean no errors have occurred, or traces have expired." }}get_error_list
Section titled “get_error_list”Lists recent error traces with filtering and pagination. Use this to see the scope of failures in a session before choosing one trace to inspect with get_trace or get_root_cause.
Parameters
Section titled “Parameters”interface GetErrorListParams { statusCode?: number; route?: string; timeWindow?: TimeWindow; sessionId?: string; includeFrameworkInternal?: boolean; cursor?: string; limit?: number;}Response
Section titled “Response”interface GetErrorListResponse { items: ErrorListItem[]; totalCount: number; cursor?: string; hasMore: boolean;}Tier gating
Section titled “Tier gating”Available on all tiers (Anonymous, Free Trial, Pro).
Example
Section titled “Example”Request:
{ "statusCode": 404, "sessionId": "abcdef1234567890", "limit": 10}Response:
{ "success": true, "data": { "items": [ { "traceId": "6038964b-a843-402e-be8b-42d4ed81f0f6", "route": "/_not-found", "method": "GET", "statusCode": 404, "error": "Not Found", "duration": 31, "timestamp": 1712534400000, "requestIdentity": { "displayRoute": "GET /api/health", "originalPath": "/api/health", "sanitizedPath": "/api/health", "frameworkFallbackRoute": "/_not-found", "method": "GET", "operationKind": "route_handler" }, "summaryProvenance": { "route": { "source": "root_request", "confidence": "high", "evidencePath": "route" }, "method": { "source": "root_request", "confidence": "high", "evidencePath": "method" }, "statusCode": { "source": "root_request", "confidence": "high", "evidencePath": "statusCode" }, "duration": { "source": "root_request", "confidence": "high", "evidencePath": "duration" }, "error": { "source": "root_request", "confidence": "high", "evidencePath": "error" } } } ], "totalCount": 1, "hasMore": false }}find_trace_candidates
Section titled “find_trace_candidates”Finds candidate traces before exact lookup. Use this when your agent knows a
route fragment, concrete URL, tRPC procedure, HTTP method, status code,
session, or recent activity window but does not yet know the exact trace ID or
safe get_trace arguments.
Candidate discovery is not root-cause evidence. It returns tenant-scoped
candidates, confidence labels, the effective time window searched, and exact
follow-up arguments for get_trace, get_root_cause, and sometimes
get_session_timeline. Agents should use a suggested exact lookup before
citing trace evidence as the cause of a bug.
If timeWindow is omitted, the tool searches a bounded recent window and
returns effectiveTimeWindow.defaulted: true with serverNow, start, and
end. No candidates means no candidate matched that credential-scoped search;
it is not proof that a route was never exercised or that a bug is absent.
Parameters
Section titled “Parameters”| Name | Type | Default | Description |
|---|---|---|---|
routeLike | string | — | Prompt locator, route fragment, or tRPC procedure such as polls.comments.list, comments, or inviteMember. |
url | string | — | Concrete path or transport route such as /api/trpc, /api/trpc/polls.comments.list, or /api/private/polls/123/results. |
procedure | string | — | Exact tRPC procedure name when known. Prefer this over a vague routeLike fragment. |
method | string | — | HTTP method such as GET or POST. Add when the bug report names a method. |
statusCode | number | — | HTTP status filter. Useful for error-oriented discovery; a 200 candidate is not proof of success. |
timeWindow | { start: number, end: number } | last 60 minutes | Optional for discovery. If omitted, the response exposes the defaulted effective window. |
sessionId | string | — | Exact same-credential session ID when known. Returned session IDs are evidence-selection metadata, not user identity. |
includeFrameworkInternal | boolean | false | Include framework/runtime routes such as Next.js fallback routes when debugging framework behavior. |
cursor | string | — | Opaque pagination cursor from a previous candidate response. |
limit | number | 10 | Number of candidates per page (max 20). |
At least one locator is required: routeLike, url, procedure, method,
statusCode, timeWindow, or sessionId.
Response
Section titled “Response”interface FindTraceCandidatesResponse { query: { routeLike?: string; url?: string; procedure?: string; method?: string; statusCode?: number; timeWindow?: { start: number; end: number }; sessionId?: string; includeFrameworkInternal?: boolean; cursor?: string; limit?: number; }; effectiveTimeWindow: { start: number; end: number; serverNow: number; defaulted: boolean; retentionBounded?: boolean; }; candidates: Array<{ traceId: string; confidence: "exact" | "high" | "medium" | "low"; matchReasons: string[]; route: string; method: string; statusCode: number; timestamp: number; duration: number; sessionId?: string | null; requestIdentity?: RequestIdentity; summaryProvenance?: SummaryProvenance; suggestedFollowups: { getTrace: { url: string; method: string; statusCode?: number; timeWindow: { start: number; end: number }; limit: number; }; getRootCause: { traceId: string }; getSessionTimeline?: { sessionId: string }; }; }>; ambiguity?: { ambiguous: boolean; message: string; }; diagnostic?: { reason: "no_candidates_in_window" | "ambiguous_locator" | "empty_session" | "filters_too_restrictive" | "credential_has_no_traces" | "possible_instrumentation_gap"; message: string; searchedScope: object; recoveryActions: Array<{ label: string; suggestedParams?: Record<string, unknown> }>; notAbsenceProof: true; }; cursor?: string; hasMore: boolean;}Tier gating
Section titled “Tier gating”Available on all tiers (Anonymous, Free Trial, Pro).
Example — route fragment discovery
Section titled “Example — route fragment discovery”Request:
{ "routeLike": "polls.comments.list"}Response:
{ "success": true, "data": { "query": { "routeLike": "polls.comments.list", "timeWindow": { "start": 1712530800000, "end": 1712534400000 } }, "effectiveTimeWindow": { "start": 1712530800000, "end": 1712534400000, "serverNow": 1712534400000, "defaulted": true }, "candidates": [ { "traceId": "6038964b-a843-402e-be8b-42d4ed81f0f6", "confidence": "exact", "matchReasons": ["tRPC procedure matched polls.comments.list"], "route": "/api/trpc", "method": "POST", "statusCode": 500, "timestamp": 1712534350000, "duration": 81, "sessionId": "abcdef1234567890", "suggestedFollowups": { "getTrace": { "url": "/api/trpc/polls.comments.list", "method": "POST", "statusCode": 500, "timeWindow": { "start": 1712530800000, "end": 1712534400000 }, "limit": 10 }, "getRootCause": { "traceId": "6038964b-a843-402e-be8b-42d4ed81f0f6" }, "getSessionTimeline": { "sessionId": "abcdef1234567890" } } } ], "hasMore": false }}Example — no candidates
Section titled “Example — no candidates”{ "success": true, "data": { "query": { "routeLike": "inviteMember", "timeWindow": { "start": 1712530800000, "end": 1712534400000 } }, "effectiveTimeWindow": { "start": 1712530800000, "end": 1712534400000, "serverNow": 1712534400000, "defaulted": true }, "candidates": [], "diagnostic": { "reason": "no_candidates_in_window", "message": "No candidate traces matched this discovery query in the effective time window. This is not proof the route was never exercised; it only describes the credential-scoped window searched.", "searchedScope": { "credentialScoped": true, "effectiveTimeWindow": { "start": 1712530800000, "end": 1712534400000, "serverNow": 1712534400000, "defaulted": true } }, "recoveryActions": [ { "label": "Retry with a concrete URL, tRPC procedure, or a wider explicit timeWindow.", "suggestedParams": { "timeWindow": { "start": 1712527200000, "end": 1712534400000 } } } ], "notAbsenceProof": true }, "hasMore": false }}get_trace
Section titled “get_trace”Search for traces by URL, HTTP method, status code, time window, or correlation ID. Results are paginated (default 20 per page, max 100).
Trace searches must include timeWindow so returned traces are tied to the
current debugging context instead of an unrelated older session. URL, method,
status code, correlation ID, and cursor filters narrow the search, but they do
not replace the time window.
Parameters
Section titled “Parameters”| Name | Type | Default | Description |
|---|---|---|---|
url | string | — | Filter by request URL (exact match on route) |
method | string | — | Filter by HTTP method (GET, POST, etc.) |
statusCode | number | — | Filter by HTTP status code |
timeWindow | { start: number, end: number } | — | Filter by timestamp range (milliseconds since epoch) |
correlationId | string | — | Filter by browser extension correlation ID |
cursor | string | — | Pagination cursor from a previous response |
limit | number | 20 | Number of results per page (max 100) |
All parameters are optional.
The schema keeps filters optional for compatibility, but the MCP server returns
invalid_input unless timeWindow is present.
Response
Section titled “Response”interface GetTraceResponse { items: Array<{ summary: TraceSummary; spans: SpanSummary[]; }>; cursor?: string; hasMore: boolean;}Tier gating
Section titled “Tier gating”Available on all tiers (Anonymous, Free Trial, Pro).
Example
Section titled “Example”Request:
{ "url": "/api/polls", "method": "POST", "statusCode": 500, "timeWindow": { "start": 1712534100000, "end": 1712534700000 }, "limit": 5}Response:
{ "success": true, "data": { "items": [ { "summary": { "traceId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d", "route": "POST /api/polls/create", "method": "POST", "statusCode": 500, "error": "Unique constraint failed on the fields: (`slug`)", "duration": 142, "timestamp": 1712534400000, "requestIdentity": { "displayRoute": "POST /api/polls/create", "originalPath": "/api/polls/create", "sanitizedPath": "/api/polls/create", "method": "POST", "operationKind": "route_handler" }, "summaryProvenance": { "route": { "source": "root_request", "confidence": "high", "evidencePath": "route" }, "method": { "source": "root_request", "confidence": "high", "evidencePath": "method" }, "statusCode": { "source": "root_request", "confidence": "high", "evidencePath": "statusCode" }, "duration": { "source": "root_request", "confidence": "high", "evidencePath": "duration" }, "error": { "source": "root_request", "confidence": "high", "evidencePath": "error" } } }, "spans": [ { "name": "POST /api/polls/create", "layer": "server", "duration": 142, "status": "ERROR", "children": [] } ] } ], "cursor": "eyJ0IjoxNzEyNTM0NDAwMDAwLCJpIjoiYWJjMTIzIn0", "hasMore": true }}Error responses
Section titled “Error responses”{ "success": false, "diagnostic": { "reason": "no_traces_found", "message": "No traces matched the credential-scoped get_trace filters in the searched time window. This is not proof the route or bug is absent; it only means this exact filter set found no traces.", "searchedScope": { "credentialScoped": true, "credentialScope": "authenticated_credential", "effectiveTimeWindow": { "start": 1712534100000, "end": 1712534700000, "serverNow": 1712534700000, "defaulted": false }, "filters": { "url": "/api/polls" } }, "recoveryActions": [ { "label": "Use candidate discovery for route fragments, tRPC procedures, or uncertain URLs.", "tool": "find_trace_candidates", "suggestedParams": { "routeLike": "/api/polls", "timeWindow": { "start": 1712534100000, "end": 1712534700000 } } } ], "notAbsenceProof": true }}get_root_cause
Section titled “get_root_cause”Returns AI-powered root cause analysis for a specific trace. The enrichment pipeline runs asynchronously after trace ingestion. This tool returns immediately with whatever data is available — it never blocks on an LLM call.
Parameters
Section titled “Parameters”| Name | Type | Default | Description |
|---|---|---|---|
traceId | string | — | Required. The trace ID to analyze. |
Response
Section titled “Response”The response is a discriminated union based on status:
// status: "completed" — enrichment finished successfullyinterface GetRootCauseCompleted { status: "completed"; rootCause: string; affectedComponent: string; errorCategory: string; suggestedFix: string; confidence: number; // 0 to 1 relatedContext?: string; codeLocation?: { file: string; line: number; column?: number };}
// status: "pending" — enrichment is still runninginterface GetRootCausePending { status: "pending"; message: string; estimatedWaitMs?: number;}
// status: "failed" — enrichment failedinterface GetRootCauseFailed { status: "failed"; reason: string; message: string;}
// status: "unavailable" — anonymous tier (no enrichment)interface GetRootCauseUnavailable { status: "unavailable"; summary: TraceSummary; spans: SpanSummary[]; message: string; upgradeUrl?: string;}Tier gating
Section titled “Tier gating”- Anonymous: Returns
status: "unavailable"with raw trace data (TraceSummary and span tree included). No AI analysis. - Free Trial / Pro: Returns enrichment result (
completed,pending, orfailed).
Example — completed enrichment
Section titled “Example — completed enrichment”Request:
{ "traceId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"}Response:
{ "success": true, "data": { "status": "completed", "rootCause": "The slug generation does not check for existing slugs before inserting. When two polls have the same title, the derived slug collides.", "affectedComponent": "prisma", "errorCategory": "foreign-key-violation", "suggestedFix": "Add a uniqueness check or append a random suffix to the slug before inserting.", "confidence": 0.92, "codeLocation": { "file": "src/app/api/polls/create/route.ts", "line": 24 } }}Example — pending enrichment
Section titled “Example — pending enrichment”{ "success": true, "data": { "status": "pending", "message": "Root cause analysis is in progress. Call again in a few seconds.", "estimatedWaitMs": 3000 }}Example — anonymous tier
Section titled “Example — anonymous tier”{ "success": true, "data": { "status": "unavailable", "summary": { "traceId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d", "route": "POST /api/polls/create", "statusCode": 500, "error": "Unique constraint failed on the fields: (`slug`)", "duration": 142, "timestamp": 1712534400000 }, "spans": [ { "name": "POST /api/polls/create", "layer": "server", "duration": 142, "status": "ERROR", "children": [] } ], "message": "AI root cause analysis requires a trial or pro account. Raw trace data is included above.", "upgradeUrl": "https://glasstrace.dev/signup" }}Error responses
Section titled “Error responses”Enrichment failed:
{ "success": false, "diagnostic": { "reason": "enrichment_failed", "message": "Automated analysis was inconclusive. Please try again or investigate manually." }}get_test_suggestions
Section titled “get_test_suggestions”Returns regression test ideas based on trace data and (optionally) the import graph. The response has three parts:
- Part 1 — Coverage map (paid tier only): Shows which code paths are tested and untested, derived from the import graph. Requires
coverageMapEnabledon your tier (Free Trial or Pro). Enable import graph capture by settingGLASSTRACE_COVERAGE_MAP=truein your project. - Part 2 — Regression tests: Specific test cases to catch the error that occurred.
- Part 3 — Prevention tests: Broader test ideas to prevent similar errors.
Parts 2 and 3 are available on all tiers. Anonymous users receive Parts 2 and 3 only — the coverage map field will contain empty arrays.
Parameters
Section titled “Parameters”| Name | Type | Default | Description |
|---|---|---|---|
traceId | string | — | Required. The trace ID to generate test suggestions for. |
Response
Section titled “Response”interface GetTestSuggestionsResponse { coverage: { testedPaths: string[]; untestedPaths: string[]; coveragePercent: number; // 0 to 100 }; regressionTests: Array<{ name: string; description: string; targetPath: string; }>; preventionTests: Array<{ name: string; description: string; targetPath: string; }>;}Tier gating
Section titled “Tier gating”- Anonymous: Parts 2 and 3 only (regression and prevention tests). Coverage map fields return empty arrays and
coveragePercent: 0. - Free Trial / Pro: All three parts, including coverage map. Requires
coverageMapEnabledfeature flag (truefor Free Trial and Pro).
Example
Section titled “Example”Request:
{ "traceId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"}Response (paid tier, with coverage map):
{ "success": true, "data": { "coverage": { "testedPaths": ["src/app/api/polls/create/route.ts"], "untestedPaths": ["src/app/api/polls/[id]/route.ts", "src/lib/slug.ts"], "coveragePercent": 33 }, "regressionTests": [ { "name": "duplicate slug collision", "description": "Create two polls with identical titles and verify the second receives a unique slug.", "targetPath": "src/app/api/polls/create/route.ts" } ], "preventionTests": [ { "name": "slug uniqueness validation", "description": "Verify that the slug generation function appends a suffix when a collision is detected.", "targetPath": "src/lib/slug.ts" } ] }}Error responses
Section titled “Error responses”The handler always returns success: true. When the coverage map is unavailable (anonymous tier or no import graph), the coverage fields contain empty arrays and coveragePercent: 0. Regression and prevention tests are always generated from trace data.
{ "success": false, "diagnostic": { "reason": "no_traces_found", "message": "No trace found with ID a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d." }}get_session_timeline
Section titled “get_session_timeline”Returns a chronological timeline of traces in a session (default 200, max 500). When results are truncated, hasMore is true so the caller knows additional pages exist. Use this to understand the sequence of requests your application handled.
Parameters
Section titled “Parameters”| Name | Type | Default | Description |
|---|---|---|---|
sessionId | string | — | Filter by session ID. If omitted, uses the current session. |
Response
Section titled “Response”interface GetSessionTimelineResponse { items: TraceSummary[]; cursor?: string; hasMore: boolean;}Tier gating
Section titled “Tier gating”Available on all tiers (Anonymous, Free Trial, Pro).
Example
Section titled “Example”Request:
{ "sessionId": "abcdef1234567890"}Response:
{ "success": true, "data": { "items": [ { "traceId": "11111111-1111-4111-8111-111111111111", "route": "GET /api/polls", "method": "GET", "statusCode": 200, "duration": 45, "timestamp": 1712534400000, "requestIdentity": { "displayRoute": "GET /api/polls", "originalPath": "/api/polls", "sanitizedPath": "/api/polls", "method": "GET", "operationKind": "route_handler" } }, { "traceId": "22222222-2222-4222-8222-222222222222", "route": "POST /api/polls/create", "method": "POST", "statusCode": 500, "error": "Unique constraint failed", "duration": 142, "timestamp": 1712534460000, "requestIdentity": { "displayRoute": "POST /api/polls/create", "originalPath": "/api/polls/create", "sanitizedPath": "/api/polls/create", "method": "POST", "operationKind": "route_handler" }, "summaryProvenance": { "route": { "source": "root_request", "confidence": "high", "evidencePath": "route" }, "method": { "source": "root_request", "confidence": "high", "evidencePath": "method" }, "statusCode": { "source": "root_request", "confidence": "high", "evidencePath": "statusCode" }, "duration": { "source": "root_request", "confidence": "high", "evidencePath": "duration" }, "error": { "source": "root_request", "confidence": "high", "evidencePath": "error" } } }, { "traceId": "33333333-3333-4333-8333-333333333333", "route": "GET /api/polls", "method": "GET", "statusCode": 200, "duration": 38, "timestamp": 1712534520000, "requestIdentity": { "displayRoute": "GET /api/polls", "originalPath": "/api/polls", "sanitizedPath": "/api/polls", "method": "GET", "operationKind": "route_handler" } } ], "hasMore": false }}Error responses
Section titled “Error responses”{ "success": false, "diagnostic": { "reason": "no_traces_found", "message": "No traces found for this session. The session may have expired or no requests have been captured yet." }}Response types
Section titled “Response types”TraceSummary
Section titled “TraceSummary”Every tool that returns trace data uses the TraceSummary type:
interface TraceSummary { traceId: string; clientAction?: string; route: string; method: string; statusCode: number; error?: string; errorEvidence?: ErrorEvidencePacket; errorCode?: string; errorCategory?: "foreign-key-violation" | "auth-failure" | "timeout" | "not-found" | "validation-error" | "connection-error" | "unknown"; affectedComponent?: string; duration: number; // milliseconds timestamp: number; // milliseconds since epoch correlationConfidence?: "high" | "medium" | "low"; sourceLocation?: { file: string; line: number; mapped: boolean }; enrichmentStatus?: "pending" | "processing" | "completed" | "failed";}errorEvidence is present on failing trace summaries when Glasstrace can
provide a bounded error packet or explicit missing-evidence state. It can
include a schema-safe exception message and a stack summary. When the SDK did
not emit stack frames, framework diagnostics, or structured log evidence, the
packet marks those facts as missing rather than fabricating a cause.
interface ErrorEvidencePacket { exceptionMessage?: string; exceptionType?: string; stack?: StackSummary; frameworkErrorSummary?: string; responseSnippet?: string; externalLogEvidenceMissing?: boolean; missingExceptionDetails?: boolean; capture: { capturePolicy: { stackFrames: "disabled" | "mapped_only" | "captured" | "missing" | "unknown"; }; redaction: { applied: boolean; rules: string[]; omittedFields: string[]; truncationApplied: boolean; }; safeForAgent: boolean; }; redactionNotes?: string[];}
interface StackSummary { frames: Array<{ functionName?: string; file?: string; line?: number; column?: number; sourceKind: "mapped_source" | "compiled_source" | "framework_internal" | "dependency" | "unknown"; mapped: boolean; inApp: boolean; redactionNotes?: string[]; }>; frameCountObserved?: number; frameCountReturned: number; framesOmitted: boolean | "unknown"; source: "exception.stacktrace" | "sdk_parsed_frames" | "source_location_attributes" | "framework_error_payload" | "missing"; confidence: "high" | "medium" | "low"; redactionNotes: string[];}SpanSummary
Section titled “SpanSummary”Span trees represent the request lifecycle:
interface SpanSummary { name: string; layer: "server" | "database" | "external"; duration: number; // milliseconds status: string; error?: string; children?: SpanSummary[];}Request identity and summary provenance
Section titled “Request identity and summary provenance”Trace summaries and error-list items may include two optional evidence fields:
requestIdentityis a sanitized description of the request or logical operation. It can distinguish a framework route pattern from the original path that the user requested, name a tRPC procedure, identify a tRPC batch, or label middleware and framework fallback routes.summaryProvenanceexplains where the primary summary fields came from. Each entry records a source such asroot_request,child_span_fallback,ingestion_derived, ormissing, plus a confidence value and, when available, an evidence path.
Use requestIdentity.displayRoute for the most agent-friendly route label when
it is present. Use summaryProvenance when deciding whether a field is strong
request evidence or a lower-confidence fallback. Both fields are optional, so
older traces and some framework paths may omit them.
For framework fallback traces, requestIdentity.originalPath may recover the
user-requested path while summaryProvenance.route still describes the stored
summary route value, such as /_not-found or /_error.
interface RequestIdentity { displayRoute: string; originalPath?: string; sanitizedPath?: string; routePattern?: string; frameworkFallbackRoute?: string; transportRoute?: string; logicalOperation?: string; method: string; framework?: "nextjs" | "express" | "hono" | "remix" | "unknown"; operationKind?: "http_route" | "route_handler" | "trpc_procedure" | "server_action" | "middleware" | "framework_internal" | "unknown"; trpc?: { transportPath: string; procedureName?: string; batch?: { memberIndex?: number; memberCount: number; memberProcedures?: string[]; attributionConfidence: "exact" | "inferred" | "unknown"; }; };}
interface SummaryProvenance { route: FieldProvenance; method: FieldProvenance; statusCode: FieldProvenance; duration: FieldProvenance; error: FieldProvenance; sourceKind?: FieldProvenance;}
interface FieldProvenance { source: "root_request" | "root_span" | "child_span_fallback" | "framework_metadata" | "ingestion_derived" | "enrichment_derived" | "missing"; confidence: "high" | "medium" | "low"; evidencePath?: string; notes?: string;}ToolDiagnostic
Section titled “ToolDiagnostic”Error and empty-state responses use the ToolDiagnostic type:
interface ToolDiagnostic { reason: "no_traces_found" | "ttl_expired" | "subscription_required" | "enrichment_pending" | "enrichment_failed" | "database_unreachable" | "tier_insufficient" | "data_not_available" | "invalid_input" | "internal_error"; message: string; upgradeUrl?: string; dataPreserved?: boolean; searchedScope?: { credentialScoped?: boolean; credentialScope?: string; effectiveTimeWindow?: { start: number; end: number; serverNow: number; defaulted: boolean; retentionBounded?: boolean; }; sessionId?: string; filters?: Record<string, string | number | boolean>; }; recoveryActions?: Array<{ label: string; tool?: string; suggestedParams?: Record<string, unknown>; }>; notAbsenceProof?: boolean;}ToolResponseWrapper
Section titled “ToolResponseWrapper”Every MCP tool response is wrapped in this envelope:
// Success{ success: true, data: { /* tool-specific response */ } }
// Failure{ success: false, diagnostic: ToolDiagnostic }Tier gating
Section titled “Tier gating”Feature availability
Section titled “Feature availability”| Feature | Anonymous | Free Trial | Pro |
|---|---|---|---|
get_latest_error | All data | All data | All data |
find_trace_candidates | All data | All data | All data |
get_trace | All data | All data | All data |
get_error_list | All data | All data | All data |
get_session_timeline | All data | All data | All data |
get_root_cause — raw trace | Yes | Yes | Yes |
get_root_cause — AI analysis | No | Yes | Yes |
get_test_suggestions — regression tests (Part 2) | Yes | Yes | Yes |
get_test_suggestions — prevention tests (Part 3) | Yes | Yes | Yes |
get_test_suggestions — coverage map (Part 1) | No | Yes | Yes |
Rate limits
Section titled “Rate limits”| Limit | Anonymous | Free Trial | Pro |
|---|---|---|---|
| Traces per minute | 100 | 500 | 2,000 |
| Storage TTL | 48 hours | 7 days | 90 days |
| Max trace size | 500 KB | 1 MB | 2 MB |
| Concurrent sessions | 1 (advisory) | 1 (advisory) | 10 |
Anonymous mode does not include LLM enrichment. Free Trial and Pro both use the best enrichment model (Anthropic).
Concurrent session limits are advisory, not enforced. If you exceed your tier’s limit, traces from all sessions are still accepted. The dashboard shows a nudge suggesting an upgrade.
Anonymous mode is free, requires no account, and never expires. Sign up for a Free Trial to enable AI-powered root cause analysis and the coverage map.
Agent setup
Section titled “Agent setup”If you ran npx @glasstrace/sdk init, your agent’s MCP configuration was generated automatically. The instructions below are for manual setup or verification.
Manual fallback for any agent:
npx @glasstrace/sdk mcp addClaude Code
Section titled “Claude Code”Config file: .mcp.json (project root)
{ "mcpServers": { "glasstrace": { "type": "http", "url": "https://api.glasstrace.dev/mcp", "headers": { "Authorization": "Bearer <your-api-key>" } } }}Or register via CLI:
claude mcp add-json glasstrace '{"type":"http","url":"https://api.glasstrace.dev/mcp","headers":{"Authorization":"Bearer <your-api-key>"}}' --scope projectCodex CLI
Section titled “Codex CLI”Config file: .codex/config.toml (project) or ~/.codex/config.toml (global)
[mcp_servers.glasstrace]url = "https://api.glasstrace.dev/mcp"bearer_token_env_var = "GLASSTRACE_API_KEY"Set the environment variable in .env.local or export it in your shell:
export GLASSTRACE_API_KEY="<your-api-key>"Or register via CLI:
codex mcp add glasstrace --url https://api.glasstrace.dev/mcpGemini CLI
Section titled “Gemini CLI”Config file: .gemini/settings.json (project) or ~/.gemini/settings.json (global)
{ "mcpServers": { "glasstrace": { "httpUrl": "https://api.glasstrace.dev/mcp", "headers": { "Authorization": "Bearer <your-api-key>" } } }}Or register via CLI:
gemini mcp add --transport http --header "Authorization: Bearer <your-api-key>" glasstrace https://api.glasstrace.dev/mcpCursor
Section titled “Cursor”Config file: .cursor/mcp.json (project) or ~/.cursor/mcp.json (global). Requires Cursor v0.48.0+.
{ "mcpServers": { "glasstrace": { "url": "https://api.glasstrace.dev/mcp", "headers": { "Authorization": "Bearer <your-api-key>" } } }}Cursor does not have a CLI registration command. Create the config file directly.
Windsurf
Section titled “Windsurf”Config file: ~/.codeium/windsurf/mcp_config.json (global only — no project-scoped config).
{ "mcpServers": { "glasstrace": { "serverUrl": "https://api.glasstrace.dev/mcp", "headers": { "Authorization": "Bearer <your-api-key>" } } }}Windsurf also supports environment variable interpolation:
{ "mcpServers": { "glasstrace": { "serverUrl": "https://api.glasstrace.dev/mcp", "headers": { "Authorization": "Bearer ${env:GLASSTRACE_API_KEY}" } } }}Windsurf does not have a CLI registration command. Create the config file directly.