Skip to content
Merged
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
479 changes: 413 additions & 66 deletions packages/mcp-core/src/api-client/client.ts

Large diffs are not rendered by default.

59 changes: 59 additions & 0 deletions packages/mcp-core/src/api-client/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,65 @@ export const MonitorStatSchema = z

export const MonitorStatsSchema = z.array(MonitorStatSchema);

/**
* Uptime monitor (detector) schemas.
*
* Verified against getsentry/sentry:
* - src/sentry/uptime/endpoints/serializers.py (UptimeDetectorSerializer)
* - src/sentry/uptime/endpoints/validators.py (UptimeMonitorValidator)
* - src/sentry/uptime/models.py (IntervalSeconds, SupportedHTTPMethods)
* Response fields are camelCase from CamelSnakeSerializer.
*/
export const UptimeMonitorSchema = z
.object({
id: ApiResourceIdSchema,
projectSlug: z.string(),
environment: z.string().nullable().optional(),
name: z.string(),
status: z.string(),
uptimeStatus: z.union([z.number(), z.string()]).optional(),
mode: z.number().optional(),
owner: ApiActorSchema.nullable().optional(),
recoveryThreshold: z.number().optional(),
downtimeThreshold: z.number().optional(),
url: z.string(),
method: z.string().optional(),
body: z.string().nullable().optional(),
headers: z
.array(z.tuple([z.string(), z.string()]))
.or(z.array(z.array(z.string())))
.optional(),
intervalSeconds: z.number(),
timeoutMs: z.number(),
traceSampling: z.boolean().optional(),
responseCaptureEnabled: z.boolean().optional(),
assertion: z.unknown().nullable().optional(),
})
.passthrough();

export const UptimeMonitorListSchema = z.array(UptimeMonitorSchema);

export const UptimeCheckSchema = z
.object({
uptimeCheckId: z.string().optional(),
timestamp: z.string().optional(),
scheduledCheckTime: z.string().optional(),
checkStatus: z.string().optional(),
checkStatusReason: z.string().nullable().optional(),
assertionFailureData: z.unknown().nullable().optional(),
httpStatusCode: z.number().nullable().optional(),
durationMs: z.number().optional(),
traceId: z.string().optional(),
traceItemId: z.string().optional(),
incidentStatus: z.number().optional(),
environment: z.string().optional(),
region: z.string().optional(),
regionName: z.string().optional(),
})
.passthrough();

export const UptimeCheckListSchema = z.array(UptimeCheckSchema);

export const ReleaseDetailsSchema = ReleaseSchema.extend({
adoptionStages: z.unknown().optional(),
authors: z.array(ApiActorSchema).optional(),
Expand Down
8 changes: 8 additions & 0 deletions packages/mcp-core/src/api-client/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ import type {
MonitorSchema,
MonitorStatsSchema,
MonitorStatSchema,
UptimeCheckListSchema,
UptimeCheckSchema,
UptimeMonitorListSchema,
UptimeMonitorSchema,
MetricAlertRuleListSchema,
MetricAlertRuleSchema,
OrganizationListSchema,
Expand Down Expand Up @@ -141,6 +145,8 @@ export type IssueComment = z.infer<typeof IssueCommentSchema>;
export type Monitor = z.infer<typeof MonitorSchema>;
export type MonitorCheckIn = z.infer<typeof MonitorCheckInSchema>;
export type MonitorStat = z.infer<typeof MonitorStatSchema>;
export type UptimeMonitor = z.infer<typeof UptimeMonitorSchema>;
export type UptimeCheck = z.infer<typeof UptimeCheckSchema>;

// Individual event types
export type ErrorEvent = z.infer<typeof ErrorEventSchema>;
Expand Down Expand Up @@ -187,6 +193,8 @@ export type IssueCommentList = z.infer<typeof IssueCommentListSchema>;
export type MonitorList = z.infer<typeof MonitorListSchema>;
export type MonitorCheckInList = z.infer<typeof MonitorCheckInListSchema>;
export type MonitorStats = z.infer<typeof MonitorStatsSchema>;
export type UptimeMonitorList = z.infer<typeof UptimeMonitorListSchema>;
export type UptimeCheckList = z.infer<typeof UptimeCheckListSchema>;
export type EventAttachmentList = z.infer<typeof EventAttachmentListSchema>;
export type TagList = z.infer<typeof TagListSchema>;
export type ClientKeyList = z.infer<typeof ClientKeyListSchema>;
Expand Down
33 changes: 29 additions & 4 deletions packages/mcp-core/src/skillDefinitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
{
"id": "inspect",
"name": "Inspect Issues & Events",
"description": "Read-only access to core Sentry data: issues, events, traces, replays, releases, monitors, profiles, documentation, and project metadata",
"description": "Read-only access to core Sentry data: issues, events, traces, replays, releases, cron monitors, uptime monitors, profiles, documentation, and project metadata",
"defaultEnabled": true,
"order": 1,
"toolCount": 35,
"toolCount": 37,
"tools": [
{
"name": "find_alert_rules",
Expand Down Expand Up @@ -42,6 +42,11 @@
"description": "Find teams in an organization in Sentry.\n\nUse this tool when you need to:\n- View teams in a Sentry organization\n- Find a team's slug and numeric ID to aid other tool requests\n- Search for specific teams by name or slug\n\nReturns up to 25 results. When hasMore is true, use the query parameter to narrow down results.",
"requiredScopes": ["team:read"]
},
{
"name": "find_uptime_monitors",
"description": "Find Sentry uptime monitors.\n\nUse this tool when you need to:\n- List HTTP uptime monitors in an organization\n- Find a monitor by name or URL before getting details\n- Check monitor status, owner, project, interval, or target URL\n- When `hasMore` is true, narrow results with project, environment, owner, or query filters\n\nThis is separate from cron monitors (`find_monitors`).\n\n<examples>\nfind_uptime_monitors(organizationSlug='my-organization')\nfind_uptime_monitors(organizationSlug='my-organization', projectSlug='backend', query='api')\n</examples>",
"requiredScopes": ["org:read", "project:read"]
},
{
"name": "get_ai_conversation_details",
"description": "Fetch the chronological transcript and debugging details for one AI conversation.\n\nReturns a timeline of user messages, assistant messages, and tool calls, with trace/span IDs for deeper debugging. To discover or list conversations, use search_ai_conversations.",
Expand Down Expand Up @@ -152,6 +157,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": "get_uptime_monitor_details",
"description": "Get details for a Sentry uptime monitor, including recent checks.\n\nUse this tool when you need to:\n- Inspect an uptime monitor's URL, interval, thresholds, and status\n- Review recent HTTP check results (success/failure, status code, duration)\n- Debug why an uptime monitor is failing\n\nThis is separate from cron monitors (`get_monitor_details`).\n\nRequest bodies are never returned. Sensitive header values are redacted.\n\n<examples>\nget_uptime_monitor_details(organizationSlug='my-organization', projectSlug='backend', uptimeMonitorId='12345')\nget_uptime_monitor_details(organizationSlug='my-organization', projectSlug='backend', uptimeMonitorId='12345', period='7d', checkLimit=20)\n</examples>",
"requiredScopes": ["project: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 Expand Up @@ -383,10 +393,10 @@
{
"id": "project-management",
"name": "Manage Projects & Teams",
"description": "Create and modify projects, teams, and DSNs",
"description": "Create and modify projects, teams, DSNs, and uptime monitors",
"defaultEnabled": false,
"order": 5,
"toolCount": 12,
"toolCount": 15,
"tools": [
{
"name": "add_team_to_project",
Expand All @@ -408,6 +418,16 @@
"description": "Create a new team in Sentry.\n\nUSE THIS TOOL WHEN USERS WANT TO:\n- 'Create a new team'\n- 'Set up a team called [X]'\n- 'I need a team for my project'\n\nBe careful when using this tool!\n\n<examples>\n### Create a new team\n```\ncreate_team(organizationSlug='my-organization', name='the-goats')\n```\n</examples>\n\n<hints>\n- If any parameter is ambiguous, you should clarify with the user what they meant.\n</hints>",
"requiredScopes": ["team:write"]
},
{
"name": "create_uptime_monitor",
"description": "Create a Sentry HTTP uptime monitor.\n\nUse this tool when you need to:\n- Start monitoring a URL for availability\n- Create a new uptime check with interval and timeout\n\nBe careful when using this tool!\n\nRequired fields match Sentry's uptime API: name, url, intervalSeconds, timeoutMs.\nAdvanced response assertions are not supported in this MVP; configure them in the Sentry UI if needed.\n\n<examples>\ncreate_uptime_monitor(organizationSlug='my-organization', projectSlug='backend', name='API Health', url='https://api.example.com/health', intervalSeconds=60, timeoutMs=5000)\ncreate_uptime_monitor(organizationSlug='my-organization', projectSlug='backend', name='Checkout', url='https://example.com/checkout', intervalSeconds=300, timeoutMs=10000, method='GET', environment='production')\n</examples>",
"requiredScopes": ["project:write"]
},
{
"name": "delete_uptime_monitor",
"description": "Delete a Sentry HTTP uptime monitor.\n\nUse this tool when you need to permanently remove an uptime monitor.\n\nBe careful when using this tool! Deletion cannot be undone.\n\n<examples>\ndelete_uptime_monitor(organizationSlug='my-organization', projectSlug='backend', uptimeMonitorId='12345')\n</examples>",
"requiredScopes": ["project:write"]
},
{
"name": "find_dsns",
"description": "List all Sentry DSNs for a specific project.\n\nUse this tool when you need to:\n- Retrieve a SENTRY_DSN for a specific project\n\n<hints>\n- If the user passes a parameter in the form of name/otherName, its likely in the format of <organizationSlug>/<projectSlug>.\n- If only one parameter is provided, and it could be either `organizationSlug` or `projectSlug`, its probably `organizationSlug`, but if you're really uncertain you might want to call `find_organizations()` first.\n</hints>",
Expand Down Expand Up @@ -443,6 +463,11 @@
"description": "Update project metadata in Sentry, such as name, slug, and platform.\n\nBe careful when using this tool!\n\nUse this tool when you need to:\n- Update a project's name or slug to fix onboarding mistakes\n- Change the platform assigned to a project\n\n<examples>\n### Update a project's name and slug\n\n```\nupdate_project(organizationSlug='my-organization', projectSlug='old-project', name='New Project Name', slug='new-project-slug')\n```\n\n### Update platform\n\n```\nupdate_project(organizationSlug='my-organization', projectSlug='my-project', platform='python')\n```\n\n</examples>\n\n<hints>\n- If the user passes a parameter in the form of name/otherName, it's likely in the format of <organizationSlug>/<projectSlug>.\n- Team access changes are handled by separate project-management tools.\n- If any parameter is ambiguous, you should clarify with the user what they meant.\n- When updating the slug, the project will be accessible at the new slug after the update\n- Do not update the slug from a project-scoped session; reconnect with an organization-scoped or unconstrained session first.\n</hints>",
"requiredScopes": ["project:write"]
},
{
"name": "update_uptime_monitor",
"description": "Update a Sentry HTTP uptime monitor.\n\nUse this tool when you need to:\n- Change URL, interval, timeout, method, headers, or body\n- Enable or disable a monitor (`status`)\n- Update owner, environment, or failure thresholds\n\nBe careful when using this tool!\n\nOmit a field to leave it unchanged. Pass explicit `null` to clear `owner`, `environment`, or `body`.\n\n<examples>\nupdate_uptime_monitor(organizationSlug='my-organization', projectSlug='backend', uptimeMonitorId='12345', status='disabled')\nupdate_uptime_monitor(organizationSlug='my-organization', projectSlug='backend', uptimeMonitorId='12345', intervalSeconds=300, timeoutMs=8000)\nupdate_uptime_monitor(organizationSlug='my-organization', projectSlug='backend', uptimeMonitorId='12345', owner=null)\n</examples>",
"requiredScopes": ["project:write"]
},
{
"name": "whoami",
"description": "Identify the authenticated user in Sentry.\n\nUse this tool when you need to:\n- Get the user's name and email address.",
Expand Down
4 changes: 2 additions & 2 deletions packages/mcp-core/src/skills.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const SKILLS: Record<Skill, SkillDefinition> = {
id: "inspect",
name: "Inspect Issues & Events",
description:
"Read-only access to core Sentry data: issues, events, traces, replays, releases, monitors, profiles, documentation, and project metadata",
"Read-only access to core Sentry data: issues, events, traces, replays, releases, cron monitors, uptime monitors, profiles, documentation, and project metadata",
defaultEnabled: true,
order: 1,
},
Expand Down Expand Up @@ -60,7 +60,7 @@ export const SKILLS: Record<Skill, SkillDefinition> = {
"project-management": {
id: "project-management",
name: "Manage Projects & Teams",
description: "Create and modify projects, teams, and DSNs",
description: "Create and modify projects, teams, DSNs, and uptime monitors",
defaultEnabled: false,
order: 5,
},
Expand Down
Loading
Loading