Jam captures and organizes bug reports with browser recordings, console logs, network requests, and environment details. AI agents can retrieve debugging context, investigate reproduction steps, and connect issues to development workflows to help teams diagnose and resolve software bugs faster.
Encrypted at rest, isolated from the model
Resolved from an AES-256-GCM vault at the moment of the call and attached to the request — the model never sees the secrets.
Try asking
Retrieve comprehensive metadata and details for a specific Jam bug report. Returns essential information including: unique identifiers, author details, description, timestamps (created/updated), type (video/screenshot), comments, and associated metadata. A reply's parentId is the comment it answers; it is null on a top-level comment. On a video Jam, a comment pinned to a playback time carries a thumbnailUrl: a public 360p JPEG link of that moment, to share with a person. This is the primary entry point for analyzing any Jam - always call this tool first to understand the context before using other tools. Once you find the cause or fix it, post one createComment that says so and mentions the creator as `@[Name](user:<author.id>)`, unless the creator is the user you act for. `links` lists the Jam's resources (pull requests, tickets, docs) and related Jams; when you fix or prove something, add the pull request with addResource and mark a proof or fix Jam as related to the bug Jam with markRelated.
Extract network activity logs captured during the Jam session. Returns HTTP/HTTPS requests and WebSocket frames including: URLs, methods (GET/POST/etc), status codes, headers, payloads, response times, and error details. The response is a JSON envelope. Filters apply server-side — each is an array, values OR within a filter, filters AND across: statusCode (e.g. ['4xx','5xx'] for all failures), contentType, host, method (e.g. ['POST','PUT'] for mutations), plus limit and after (page cursor). The envelope reports `total` matching events (if you get fewer, narrow the filter or page with `after`), and by default carries response bodies only for FAILED requests: pass bodies:'all' when you need the payload of a request that succeeded but returned the wrong data (bodies truncated to 4KB, flagged per row). Pass headers:true for request and response headers, auth and cookie headers included (secret values are redacted by the Jam extension at capture; a Jam from another source may hold raw values); `network_headers_unknown: true` then marks a request whose headers were not captured (an older index, or a request seen only through browser timing), where no header map means not captured. Each request also carries, when captured: `network_started_at` (wall-clock start, to match backend logs), `network_complete: false` (the request never finished), `network_fetch_error` (the browser's own error, e.g. net::ERR_FAILED), `network_fetch_cached`, and the browser-reported body sizes. Essential for debugging API issues, failed requests, CORS problems, and performance bottlenecks.
Retrieve browser console output captured during the Jam session. Includes JavaScript errors, warnings, info messages, debug logs, and stack traces. The response is a JSON envelope. logLevel (an array — e.g. ['error','warn'] for problems) and limit apply server-side, and the envelope reports `total` matching logs — if you get fewer than `total`, narrow the filter or page with `after`. Critical for identifying runtime errors, debugging application state issues, and understanding the sequence of events leading to bugs.
Access the complete timeline of user interactions captured in the Jam. Returns chronological sequence of: clicks, keyboard inputs, form submissions, navigation events, scroll actions, and other DOM interactions. Clicks carry `interactivity_x`/`interactivity_y` (viewport position) and `interactivity_is_trusted` (false = fired by a script, not the user). The full timeline is returned by default and is small enough to read whole — pass limit only to cap the output, and page with `after` if a capped response reports a `nextCursor`. Invaluable for reproducing bugs and understanding user behavior patterns that triggered issues.
Retrieve custom metadata set via the jam.metadata() SDK. Returns key-value pairs defined by the application developer, such as user IDs, app versions, feature flags, or any custom debugging context.
Retrieve visual screenshots and image attachments from screenshot-type Jams. Returns image data that can be analyzed for UI issues, visual bugs, layout problems, or design inconsistencies. Note: This tool only works with Jams of type 'screenshot' - use getDetails first to verify Jam type.
Extract still frames (thumbnails) from a video Jam recording as images, so you can see what was on screen. Use exactly one mode. Leave the other modes' fields unset or null. Set `overview: true` to get one overview grid: N frames evenly spaced across the whole video (N scales with duration), stitched into a single image with each cell labeled by timestamp — the fastest way to orient on a visual Jam. Or specify `at` (a list of timestamps in milliseconds) or a window with `count` and optional `fromMs` and `toMs` bounds; count alone samples the whole video evenly, including the first and last frames. Each frame is returned as an image preceded by a `t=<ms>` text anchor. Use `size` to trade detail for context budget (small=360p, medium=720p, large=1080p; not applied to the overview grid). Only works for video Jams whose recording is available on Cloudflare Stream; ineligible Jams return a single text block explaining why. Frames per call are capped at 30.
Deprecated: video intent analysis has been retired. Use getFrames with overview: true to inspect the recording and getDetails for Jam context. This tool returns only migration guidance.
Retrieve the speech transcript (captions) from a video Jam recording in WebVTT format with timestamps. Only available for video Jams where the microphone was enabled during recording. Use this to understand what the user said while recording the bug report.
Retrieve AI-generated chapters for a video Jam recording: titled segments with start/end timestamps outlining the recording's timeline. Returns { status, chapters, language }; chapters is null unless status is "ready". Each chapter is { startMs, endMs, title, thumbnailUrl? }. thumbnailUrl is a public link to a 360p JPEG from the middle of the chapter, present once the video has processed, to put in a ticket, pull request or message so a person sees the moment. To look at a chapter yourself, call getFrames with `at` set to a timestamp inside the chapter's span; the midpoint reads best, because chapter starts are usually transition frames. Status "not_requested" means chapter generation was never queued for this jam; "skipped" means the video was too short to segment.
Fetch a Jam as a citable document. Returns id, title, url, and text, with report details serialized as JSON in text. Use after search resolves a video Jam by UUID or URL in the connected workspace, or fetch a known Jam id directly. Use getDetails as the entry point for interactive investigation.
Find a video Jam in the connected team by extracting its UUID from a query string, jam.dev URL, or pasted text. Returns at most one result. Does not search titles or return screenshot or replay Jams; use searchJams for text search and other Jam types.
Search the connected team's Jams. `text` matches every term against a Jam's title, description, comments, linked issue titles, the reporter's email or external id, and its transcript; a term made of only one or two letters or digits is matched against comments only through the whole text: a comment that contains the text as typed matches when another term has three or more letters or digits, or punctuation next to them (such as `cool` or `#12`). Terms like `#12` or `v1.2` also match comments on their own. `textIn` limits which of those places a term may match in. `where` is a list of { field, op, value } filter leaves, all ANDed; the `where` description lists every field, its operators and what it means. `window` bounds created_at, `sort` orders the page, and `page` carries the limit and the opaque cursor the previous page returned. The team is the one the token was issued for and no argument can name another. Each returned Jam carries a url, the share link to hand back to the user unchanged.
Deprecated: use searchJams instead. Lists Jam bug reports with the legacy filters and pagination: search by text, filter by type (video/screenshot/replay), origin (capture surface), folder, author, URL, or creation date. Returns Jam metadata including title, origin, author, folder, and timestamps. Each returned Jam carries a url, the share link to hand back to the user unchanged: it carries search attribution.
List folders in the team with optional search and pagination. Returns folder metadata including name, short ID, Jam count, and timestamps. Use this to discover available folders for organizing Jams.
Save feedback about a Jam surface in Jam's database for Jam's agents to read. Returns the stored feedback ID. Use it when a Jam MCP tool, CLI command, doc page, or skill was wrong, stale, confusing, or missing something — and when one worked unusually well. Only for Jam's own surfaces: not for another MCP server's tools, the user's own skills or scripts, or the user's product, because Jam cannot fix those. Call it yourself; do not ask the user for approval, because no person reads it. Send at most one per session, and never for a slip you corrected yourself. Keep the body within 2000 words and 100,000 characters, and specific enough to act on: what you were doing, what you expected, what happened, and the mistake. Larger bodies are rejected without saving or truncating them. Never include secrets, customer data, source code, or stack traces — describe code rather than pasting it.
Create a folder in the team to organize Jams into. Returns the folder's id and shortId, so a follow-up updateJam call can file a Jam into it right away. Folder names are not unique — call listFolders first if you mean to reuse an existing folder rather than add another one with the same name. If your membership permits self-upgrade, this can promote you from Viewer to Creator, affect seat billing, and email team admins.
Rename a folder. Identify the folder by name, folder ID, or folder short ID. Renaming does not move any Jams — use updateJam for that. An unknown folder, or one belonging to another team, reads as not-found.
List team members with optional search and pagination. Returns user metadata including name, email, and role. Use this to find users for filtering Jams by author.
Add a new comment to a Jam bug report. The comment body supports Markdown formatting. Use this to add notes, analysis results, or follow-up information to a Jam. This can notify other users by email, and the comment is visible to people who can access the Jam, including public viewers when sharing permits it.
Rewrite a comment you previously left on a Jam, so an agent can correct or extend its own note instead of stacking a follow-up comment. Takes the comment ID returned by createComment. The new body replaces the old one entirely and is Markdown. You can only edit comments you authored. Changes are visible to people who can access the Jam, including public viewers when sharing permits it.
React to a comment on a Jam — useful for acknowledging a comment you've already acted on. Works on anyone's comment, not just your own. Adding a reaction you already left is a no-op. Supported emoji: 🐛 (Buggy), 💜 (Love it), ✅ (Fixed), 👀 (Oooo), ❓ (Unclear), 👏 (Bravo), 🔥 (Fire), 👍 (Got it). This can notify the comment author by email and is visible wherever the comment is shared.
Take back a reaction you left on a comment. Only removes your own reaction; other people's reactions with the same emoji are untouched. Removing a reaction you never left is a no-op. Supported emoji: 🐛 (Buggy), 💜 (Love it), ✅ (Fixed), 👀 (Oooo), ❓ (Unclear), 👏 (Bravo), 🔥 (Fire), 👍 (Got it). Changes are visible to people who can access the Jam, including public viewers when sharing permits it.
Update a Jam bug report: rename it, rewrite its description, or move it between folders. Every field is optional — only the ones you pass are changed. Use folder name, folder ID, folder short ID, or "root" to move to the root level. Editing the title or description requires an Admin or Creator role.
Attach a URL to a Jam, such as the pull request a proof Jam demonstrates, the CI run it came from, or another Jam. Pass a label when the page title would not say what the link is; otherwise teams with links on the share page see the host and path. Adding the same URL again changes nothing. Returns the resource. When you record proof of your work, add the pull request or ticket it proves as a resource. The URL shows on the Jam's share page, which can be public: do not pass a URL that carries a token, and a URL with a username or password is refused. Needs the permission that edits a Jam's title.
Remove a URL from a Jam's resources. Pass the URL exactly as it was added.
Mark a Jam as related to another Jam of the same team, with a type read from the first Jam: it `fixes` the target, `proves` it, or `relates_to` it (the default). Teams with links on the share page show it on both Jams; the target shows the inverse ("fixed by", "proven by"). Marking again with the same type changes nothing. Returns the relation. When you record a Jam that proves a fix, mark it as `fixes` or `proves` of the bug Jam. Use it to connect a set of Jams of one flow, such as one Jam per UI state. Needs the permission that edits a Jam's title.
Remove every relation from a Jam to another Jam, whatever its type. The target Jam's backlink goes too.
Delete a Jam. It leaves the team's lists and search results, and nobody on the team can bring it back — the dashboard has no trash or archive view to restore it from. Destructive and not recoverable: confirm with the user before calling, and never tell them the Jam can be restored afterwards.
Delete a comment from a Jam, along with its attachments. Only the comment's own author can delete it, so in practice this removes a comment you posted through createComment. Destructive and not recoverable: confirm with the user before calling. Comment IDs come from createComment's result or from getDetails.
Delete a folder and every Jam inside it. The Jams leave the team's lists and search and nobody on the team can bring them back — the dashboard has no trash or archive view to restore them from. Returns how many Jams went with the folder, as `archivedJamCount`. Destructive and not recoverable: confirm with the user before calling, never tell them the Jams can be restored afterwards, and use listFolders first so they can see what the folder holds. Takes a folder ID or short ID from listFolders, never a folder name — a name could match the wrong folder.
Create a reusable recording link that lets anyone with the URL record and submit a new Jam. Optionally target a folder and set an expiration date. IMPORTANT — logs require a connected domain: a link only captures console and network logs when it starts recording from one of the team's connected domains (a recording URL). A link created with no recordingUrlId produces a generic recorder link that captures NO logs. Before creating, call listRecordingUrls and ask the user which connected domain to record from — don't guess. If the team has no connected domains, warn the user the link won't capture logs and point them to the dashboard to connect one (https://jam.dev/docs/custom-recording-domain) before creating a logs-less link. If your membership permits self-upgrade, this can promote you from Viewer to Creator, affect seat billing, and email team admins. It also emits a recording-link-created webhook event for configured subscribers.
List the team's connected domains (recording URLs) — the domains a recording link can start from so recorded Jams capture console and network logs. Returns each domain's id, url, and verified state. Use this before createRecordingLink to pick the recordingUrlId to record from, and to tell whether the team has any connected domains at all. Only a verified domain captures logs; an unverified one must be verified from the dashboard first (https://jam.dev/docs/custom-recording-domain). An empty list means the team has no connected domains, so any link created now captures no logs.
Start verifying a connected domain (recording URL) so recorded Jams from it capture console and network logs. Returns a verifyUrl a HUMAN must open in a browser where the Jam extension or snippet is live on that domain — the recorder there confirms Jam is present and marks the domain verified. This tool does NOT verify the domain itself; it only hands back the link. After the user opens it, poll listRecordingUrls until the domain shows verified: true (the link expires in 5 minutes). Use this instead of sending the user to the dashboard to connect a domain.
Get a single recording link by its publicId. Returns the link's name, type, target folder, expiration, and the number of Jams recorded through it (jamsCreated). Use listRecordingLinkJams to page through those Jams.
List the Jams recorded through a recording link, addressed by the link's publicId. Returns each Jam's id, title, and createdAt (newest first), plus cursor pagination. Pass `cursor` (a jam id from a prior `endCursor`) to fetch the next page; `hasNextPage` indicates whether more remain.
List the team's recording links, newest first, with cursor pagination. Returns each link's publicId, name, and type. Pass `cursor` (a publicId from a prior `endCursor`) to fetch the next page; `hasNextPage` indicates whether more remain. Revoked links are excluded unless `includeRevoked` is true.
Delete a recording link by its publicId, so it stops accepting new recordings. This is a soft delete: existing Jams recorded through it are untouched. Returns the publicId and the deletedAt timestamp. An unknown, already-deleted, or another team's publicId reads as not-found.
Update a recording link by its publicId. Only the fields you pass are changed. Use it to rename the link, change the destination folder for future recordings, set the default Jam title, change the reference, set an expiration, or replace the metadata. Unknown or other-team links return not-found; revoked links cannot be edited. Existing Jams are not moved.
One endpoint, the same key, whichever client you use.
~/Library/Application Support/Claude/claude_desktop_config.json (Mac) · %APPDATA%\Claude\claude_desktop_config.json (Windows)
Replace API_KEY with your own key.
Already have an "mcpServers" section in your config? Just add the server entry inside it.
Discovery, routing, credentials, tool scoping and execution logs all happen at the gateway→connections stay ACTIVE with no work from you
Jam MCP runs through a gateway that holds the credentials, scopes the access and records every call.
Managed auth, hosted MCP servers, and every Jam MCP tool your agent needs.
Free to start.