Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion packages/mcp-core/src/skillDefinitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"description": "Read-only access to core Sentry data: issues, events, traces, replays, releases, monitors, profiles, documentation, and project metadata",
"defaultEnabled": true,
"order": 1,
"toolCount": 35,
"toolCount": 36,
"tools": [
{
"name": "find_alert_rules",
Expand Down Expand Up @@ -152,6 +152,11 @@
"description": "Get detailed information about a specific Sentry trace by ID.\n\nUSE THIS TOOL WHEN USERS:\n- Provide a specific trace ID (e.g., 'a4d1aae7216b47ff8117cf4e09ce9d0a')\n- Ask to 'show me trace [TRACE-ID]', 'explain trace [TRACE-ID]'\n- Want high-level overview and link to view trace details in Sentry\n- Need trace statistics and span breakdown\n- Want an overview first, then a guided pivot into additional spans or events\n\nDO NOT USE for:\n- General searching for traces (use search_events with trace queries)\n- Complete span enumeration or branch-by-branch reconstruction (use search_events scoped to the trace)\n\nTRIGGER PATTERNS:\n- 'Show me trace abc123' → use get_trace_details\n- 'Explain trace a4d1aae7216b47ff8117cf4e09ce9d0a' → use get_trace_details\n- 'What is trace [trace-id]' → use get_trace_details\n\n<examples>\n### Get trace overview\n```\nget_trace_details(organizationSlug='my-organization', traceId='a4d1aae7216b47ff8117cf4e09ce9d0a')\n```\n\n### Focus a single span\n```\nget_trace_details(organizationSlug='my-organization', traceId='a4d1aae7216b47ff8117cf4e09ce9d0a', spanId='aa8e7f3384ef4ff5')\n```\n</examples>\n\n<hints>\n- Trace IDs are 32-character hexadecimal strings\n- This returns a condensed trace overview, not a full span dump\n- Provide `spanId` to focus on a single span within the trace\n- If the response says it shows a subset of spans, use search_events to inspect the rest of the trace\n</hints>",
"requiredScopes": ["event:read"]
},
{
"name": "inspect_replay_timeline",
"description": "Inspect the timestamped activity timeline for a specific Sentry replay.\n\nUse this tool when you need to:\n- Reconstruct what a user did before an error or frustrating interaction\n- Inspect navigation, clicks, console messages, network activity, and performance spans\n- Focus on a time window around a known moment in a replay\n\n<examples>\ninspect_replay_timeline(replayUrl='https://my-org.sentry.io/explore/replays/7e07485f-12f9-416b-8b14-26260799b51f/')\ninspect_replay_timeline(organizationSlug='my-org', replayId='7e07485f-12f9-416b-8b14-26260799b51f', eventTypes=['click', 'error', 'network'])\ninspect_replay_timeline(replayUrl='https://my-org.sentry.io/explore/replays/7e07485f-12f9-416b-8b14-26260799b51f/', aroundTimestamp='2026-07-23T19:14:21Z', windowSeconds=30)\n</examples>\n\n<hints>\n- aroundTimestamp is an absolute ISO-8601 timestamp; windowSeconds applies before and after it\n- Use get_replay_details for replay metadata and related issues or traces\n</hints>",
"requiredScopes": ["org:read", "project:read", "event:read"]
},
{
"name": "search_ai_conversations",
"description": "Search Sentry AI Conversations and return one summary row per conversation.\n\nUse this tool to find or list AI Conversations. Results are conversation summaries, not raw span rows.\nUse get_ai_conversation_details with a conversationId to fetch the transcript. Use get_sentry_resource for Sentry conversation URLs.\n\n<examples>\nsearch_ai_conversations(organizationSlug='my-org', query='failed conversations', period='7d')\nsearch_ai_conversations(organizationSlug='my-org', query='checkout', project='backend')\n</examples>",
Expand Down
236 changes: 236 additions & 0 deletions packages/mcp-core/src/toolDefinitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -2236,6 +2236,242 @@
"skills": ["inspect"],
"surface": "catalog"
},
{
"name": "inspect_replay_timeline",
"description": "Inspect the timestamped activity timeline for a specific Sentry replay.\n\nUse this tool when you need to:\n- Reconstruct what a user did before an error or frustrating interaction\n- Inspect navigation, clicks, console messages, network activity, and performance spans\n- Focus on a time window around a known moment in a replay\n\n<examples>\ninspect_replay_timeline(replayUrl='https://my-org.sentry.io/explore/replays/7e07485f-12f9-416b-8b14-26260799b51f/')\ninspect_replay_timeline(organizationSlug='my-org', replayId='7e07485f-12f9-416b-8b14-26260799b51f', eventTypes=['click', 'error', 'network'])\ninspect_replay_timeline(replayUrl='https://my-org.sentry.io/explore/replays/7e07485f-12f9-416b-8b14-26260799b51f/', aroundTimestamp='2026-07-23T19:14:21Z', windowSeconds=30)\n</examples>\n\n<hints>\n- aroundTimestamp is an absolute ISO-8601 timestamp; windowSeconds applies before and after it\n- Use get_replay_details for replay metadata and related issues or traces\n</hints>",
"inputSchema": {
"type": "object",
"properties": {
"replayUrl": {
"type": "string",
"format": "uri",
"description": "The URL of the replay. e.g. https://my-organization.sentry.io/explore/replays/7e07485f-12f9-416b-8b14-26260799b51f/"
},
"organizationSlug": {
"type": "string",
"description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool."
},
"replayId": {
"type": "string",
"description": "The replay ID. e.g. `7e07485f-12f9-416b-8b14-26260799b51f`"
},
"regionUrl": {
"anyOf": [
{
"type": "string",
"description": "The region URL for the organization you're querying, if known. For Sentry's Cloud Service (sentry.io), this is typically the region-specific URL like 'https://us.sentry.io'. For self-hosted Sentry installations, this parameter is usually not needed and should be omitted. You can find the correct regionUrl from the organization details using the `find_organizations()` tool."
},
{
"type": "null"
}
]
},
"aroundTimestamp": {
"description": "Optional absolute ISO-8601 timestamp to inspect around.",
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"windowSeconds": {
"description": "Seconds before and after aroundTimestamp to include. Defaults to 30.",
"type": "integer",
"minimum": 1,
"maximum": 300
},
"eventTypes": {
"description": "Optional event categories to include.",
"minItems": 1,
"type": "array",
"items": {
"type": "string",
"enum": [
"navigation",
"click",
"error",
"console",
"network",
"performance",
"other"
]
}
},
"limit": {
"description": "Maximum timeline events to return. Defaults to 50.",
"type": "integer",
"minimum": 1,
"maximum": 200
}
}
},
"outputSchema": {
"type": "object",
"properties": {
"organizationSlug": {
"type": "string"
},
"replayId": {
"type": "string"
},
"replayUrl": {
"type": "string",
"format": "uri"
},
"startedAt": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": ["available", "archived", "unavailable"]
},
"unavailableReason": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"filters": {
"type": "object",
"properties": {
"aroundTimestamp": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"windowSeconds": {
"type": "number"
},
"eventTypes": {
"type": "array",
"items": {
"type": "string",
"enum": [
"navigation",
"click",
"error",
"console",
"network",
"performance",
"other"
]
}
},
"limit": {
"type": "number"
}
},
"required": [
"aroundTimestamp",
"windowSeconds",
"eventTypes",
"limit"
],
"additionalProperties": false
},
"totalMatchingEvents": {
"type": "number"
},
"omittedCount": {
"type": "number"
},
"events": {
"type": "array",
"items": {
"type": "object",
"properties": {
"timestampMs": {
"type": "number"
},
"offsetMs": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
]
},
"type": {
"type": "string",
"enum": [
"navigation",
"click",
"error",
"console",
"network",
"performance",
"other"
]
},
"label": {
"type": "string"
},
"details": {
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"value": {
"anyOf": [
{
"type": "string"
},
{
"type": "number"
},
{
"type": "boolean"
}
]
}
},
"required": ["key", "value"],
"additionalProperties": false
}
}
},
"required": ["timestampMs", "offsetMs", "type", "label", "details"],
"additionalProperties": false
}
}
},
"required": [
"organizationSlug",
"replayId",
"replayUrl",
"startedAt",
"status",
"unavailableReason",
"filters",
"totalMatchingEvents",
"omittedCount",
"events"
],
"additionalProperties": false
},
"requiredScopes": ["org:read", "project:read", "event:read"],
"skills": ["inspect"],
"surface": "catalog"
},
{
"name": "remove_team_from_project",
"description": "Revoke a team's access to an existing Sentry project.\n\nUse this tool when you need to:\n- Remove a team from a project\n- Revoke team access without changing project metadata\n- Check project team assignments before removing access\n\nBe careful when using this tool because it revokes project access.\n\n<examples>\nremove_team_from_project(organizationSlug='my-organization', projectSlug='my-project', teamSlug='my-team')\n</examples>\n\n<hints>\n- The team must already be assigned to the project.\n- This tool will not remove the last team assigned to a project.\n</hints>",
Expand Down
66 changes: 34 additions & 32 deletions packages/mcp-core/src/tools/catalog/index.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,51 @@
import whoami from "./whoami";
import type { ToolConfig } from "../types";
import addIssueNote from "./add-issue-note";
import addTeamToProject from "./add-team-to-project";
import analyzeIssueWithSeer from "./analyze-issue-with-seer";
import createDsn from "./create-dsn";
import createProject from "./create-project";
import createTeam from "./create-team";
import findAlertRules from "./find-alert-rules";
import findDashboards from "./find-dashboards";
import findDsns from "./find-dsns";
import findMonitors from "./find-monitors";
import findOrganizations from "./find-organizations";
import findTeams from "./find-teams";
import findProjects from "./find-projects";
import findReleases from "./find-releases";
import getReleaseDetails from "./get-release-details";
import findDashboards from "./find-dashboards";
import getDashboardDetails from "./get-dashboard-details";
import findMonitors from "./find-monitors";
import getMonitorDetails from "./get-monitor-details";
import findAlertRules from "./find-alert-rules";
import findTeams from "./find-teams";
import getAIConversationDetails from "./get-ai-conversation-details";
import getAlertRule from "./get-alert-rule";
import getIssueDetails from "./get-issue-details";
import getDashboardDetails from "./get-dashboard-details";
import getDoc from "./get-doc";
import getEventAttachment from "./get-event-attachment";
import getEventStacktrace from "./get-event-stacktrace";
import getIssueActivity from "./get-issue-activity";
import getIssueBreadcrumbs from "./get-issue-breadcrumbs";
import getIssueDetails from "./get-issue-details";
import getIssueTagValues from "./get-issue-tag-values";
import getIssueUserReports from "./get-issue-user-reports";
import getTraceDetails from "./get-trace-details";
import getSpanDetails from "./get-span-details";
import getReplayDetails from "./get-replay-details";
import getEventAttachment from "./get-event-attachment";
import updateIssue from "./update-issue";
import searchEvents from "./search-events";
import createTeam from "./create-team";
import createProject from "./create-project";
import updateProject from "./update-project";
import addTeamToProject from "./add-team-to-project";
import removeTeamFromProject from "./remove-team-from-project";
import createDsn from "./create-dsn";
import findDsns from "./find-dsns";
import updateDsn from "./update-dsn";
import analyzeIssueWithSeer from "./analyze-issue-with-seer";
import searchDocs from "./search-docs";
import getDoc from "./get-doc";
import searchIssues from "./search-issues";
import searchIssueEvents from "./search-issue-events";
import getLatestBaseSnapshot from "./get-latest-base-snapshot";
import getMonitorDetails from "./get-monitor-details";
import getProfile from "./get-profile";
import getProfileDetails from "./get-profile-details";
import getReleaseDetails from "./get-release-details";
import getReplayDetails from "./get-replay-details";
import getSentryResource from "./get-sentry-resource";
import getSnapshot from "./get-snapshot";
import getSnapshotImage from "./get-snapshot-image";
import getLatestBaseSnapshot from "./get-latest-base-snapshot";
import getAIConversationDetails from "./get-ai-conversation-details";
import getSpanDetails from "./get-span-details";
import getTraceDetails from "./get-trace-details";
import inspectReplayTimeline from "./inspect-replay-timeline";
import removeTeamFromProject from "./remove-team-from-project";
import searchAIConversations from "./search-ai-conversations";
import addIssueNote from "./add-issue-note";
import type { ToolConfig } from "../types";
import searchDocs from "./search-docs";
import searchEvents from "./search-events";
import searchIssueEvents from "./search-issue-events";
import searchIssues from "./search-issues";
import updateDsn from "./update-dsn";
import updateIssue from "./update-issue";
import updateProject from "./update-project";
import whoami from "./whoami";

/**
* Catalog of ordinary Sentry MCP operations.
Expand Down Expand Up @@ -77,6 +78,7 @@ const catalogTools = {
get_trace_details: getTraceDetails,
get_span_details: getSpanDetails,
get_replay_details: getReplayDetails,
inspect_replay_timeline: inspectReplayTimeline,
get_event_attachment: getEventAttachment,
update_issue: updateIssue,
search_events: searchEvents,
Expand Down
Loading
Loading