From 7cfd54cc2e47a61786f3bec066359ec5a3e742d1 Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2026 19:19:30 +0000 Subject: [PATCH 1/3] chore(deps): Upgrade Zod to v4 Co-Authored-By: OpenAI Codex Co-Authored-By: David Cramer --- .../mcp-cloudflare/src/server/oauth/state.ts | 2 +- .../src/server/routes/search.ts | 2 +- packages/mcp-cloudflare/vitest.config.ts | 2 +- packages/mcp-core/package.json | 3 +- .../mcp-core/scripts/generate-definitions.ts | 8 +- .../mcp-core/scripts/measure-token-cost.ts | 7 +- packages/mcp-core/src/api-client/client.ts | 2 +- packages/mcp-core/src/api-client/schema.ts | 41 +- .../src/internal/agents/callEmbeddedAgent.ts | 4 +- packages/mcp-core/src/internal/formatting.ts | 2 +- packages/mcp-core/src/toolDefinitions.json | 1065 ++++++++--------- .../src/tools/catalog-runtime/schema.ts | 8 +- .../src/tools/special/execute-tool.ts | 2 +- .../src/tools/special/search-tools.ts | 2 +- .../src/evals/utils/toolPredictionScorer.ts | 2 +- pnpm-lock.yaml | 233 ++-- pnpm-workspace.yaml | 3 +- 17 files changed, 701 insertions(+), 687 deletions(-) diff --git a/packages/mcp-cloudflare/src/server/oauth/state.ts b/packages/mcp-cloudflare/src/server/oauth/state.ts index c1be5cc9b..b0e0ed1e5 100644 --- a/packages/mcp-cloudflare/src/server/oauth/state.ts +++ b/packages/mcp-cloudflare/src/server/oauth/state.ts @@ -6,7 +6,7 @@ import { z } from "zod"; // Safe envelope: keep the full downstream AuthRequest (+permissions) under `req` // and include only iat/exp metadata at top-level to avoid collisions. export const OAuthStateSchema = z.object({ - req: z.record(z.unknown()), + req: z.record(z.string(), z.unknown()), iat: z.number().int(), exp: z.number().int(), }); diff --git a/packages/mcp-cloudflare/src/server/routes/search.ts b/packages/mcp-cloudflare/src/server/routes/search.ts index 087980d2d..b8ab104b7 100644 --- a/packages/mcp-cloudflare/src/server/routes/search.ts +++ b/packages/mcp-cloudflare/src/server/routes/search.ts @@ -85,7 +85,7 @@ export default new Hono<{ Bindings: Env }>().post("/", async (c) => { return c.json( { error: "Invalid request", - details: validationResult.error.errors, + details: validationResult.error.issues, }, 400, ); diff --git a/packages/mcp-cloudflare/vitest.config.ts b/packages/mcp-cloudflare/vitest.config.ts index 2c94ddbda..107a16573 100644 --- a/packages/mcp-cloudflare/vitest.config.ts +++ b/packages/mcp-cloudflare/vitest.config.ts @@ -48,6 +48,6 @@ export default defineConfig({ }, // Force bundling to apply the ajv alias during module resolution ssr: { - noExternal: ["@modelcontextprotocol/sdk", "agents", "zod-to-json-schema"], + noExternal: ["@modelcontextprotocol/sdk", "agents"], }, }); diff --git a/packages/mcp-core/package.json b/packages/mcp-core/package.json index fa756829b..a0e0066c5 100644 --- a/packages/mcp-core/package.json +++ b/packages/mcp-core/package.json @@ -158,8 +158,7 @@ "@sentry/mcp-server-tsconfig": "workspace:*", "msw": "catalog:", "tiktoken": "^1.0.18", - "yaml": "^2.8.3", - "zod-to-json-schema": "catalog:" + "yaml": "^2.8.3" }, "dependencies": { "@ai-sdk/anthropic": "catalog:", diff --git a/packages/mcp-core/scripts/generate-definitions.ts b/packages/mcp-core/scripts/generate-definitions.ts index 1398d291a..d77235d0e 100644 --- a/packages/mcp-core/scripts/generate-definitions.ts +++ b/packages/mcp-core/scripts/generate-definitions.ts @@ -9,7 +9,6 @@ import * as path from "node:path"; import { fileURLToPath } from "node:url"; import YAML from "yaml"; import { type ZodTypeAny, z } from "zod"; -import { zodToJsonSchema } from "zod-to-json-schema"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -33,7 +32,7 @@ function zodFieldMapToJsonSchema( ): unknown { if (!fieldMap || Object.keys(fieldMap).length === 0) return {}; const obj = z.object(fieldMap); - return zodToJsonSchema(obj, { $refStrategy: "none" }); + return z.toJSONSchema(obj, { io: "input", unrepresentable: "any" }); } // Plugin variants whose agent frontmatter gets synced by this script. @@ -161,7 +160,10 @@ function generateToolDefinitions({ // Export full JSON Schema under inputSchema for external docs inputSchema: jsonSchema, outputSchema: t.outputSchema - ? zodToJsonSchema(t.outputSchema, { $refStrategy: "none" }) + ? z.toJSONSchema(t.outputSchema, { + io: "input", + unrepresentable: "any", + }) : undefined, // Preserve tool access requirements for UIs/docs requiredScopes: t.requiredScopes, diff --git a/packages/mcp-core/scripts/measure-token-cost.ts b/packages/mcp-core/scripts/measure-token-cost.ts index b61caa916..6d47efccc 100644 --- a/packages/mcp-core/scripts/measure-token-cost.ts +++ b/packages/mcp-core/scripts/measure-token-cost.ts @@ -13,7 +13,6 @@ import * as fs from "node:fs"; import * as path from "node:path"; import { type Tiktoken, encoding_for_model } from "tiktoken"; import { type ZodTypeAny, z } from "zod"; -import { zodToJsonSchema } from "zod-to-json-schema"; // Lazy imports to avoid type bleed const toolsModule = await import("../src/tools/index.ts"); @@ -80,9 +79,9 @@ function formatToolsForMCP(tools: Record) { ? z.object(inputSchema) : z.object({}); // Use the same options as the MCP SDK to match actual payload - const jsonSchema = zodToJsonSchema(zodObject, { - strictUnions: true, - pipeStrategy: "input", + const jsonSchema = z.toJSONSchema(zodObject, { + io: "input", + unrepresentable: "any", }); return { diff --git a/packages/mcp-core/src/api-client/client.ts b/packages/mcp-core/src/api-client/client.ts index 271068f49..de6c7da5c 100644 --- a/packages/mcp-core/src/api-client/client.ts +++ b/packages/mcp-core/src/api-client/client.ts @@ -3277,7 +3277,7 @@ export class SentryApiService { eventType, eventId: bodyObj.id, validationError: parseResult.error.message, - validationIssues: parseResult.error.errors, + validationIssues: parseResult.error.issues, }, }); diff --git a/packages/mcp-core/src/api-client/schema.ts b/packages/mcp-core/src/api-client/schema.ts index c2c989e40..b3c9fe9f7 100644 --- a/packages/mcp-core/src/api-client/schema.ts +++ b/packages/mcp-core/src/api-client/schema.ts @@ -775,12 +775,14 @@ export const IssueSchema = z status: z.string(), substatus: z.string().nullable().optional(), culprit: z.string().nullable(), - type: z.union([ - z.literal("error"), - z.literal("transaction"), - z.literal("generic"), - z.unknown(), - ]), + type: z + .union([ + z.literal("error"), + z.literal("transaction"), + z.literal("generic"), + z.unknown(), + ]) + .optional(), assignedTo: AssignedToSchema.optional(), issueType: z.string().optional(), issueCategory: z.string().optional(), @@ -867,7 +869,7 @@ const StacktraceSchema = z .object({ frames: z.array(FrameInterface), framesOmitted: z.array(z.unknown()).nullable().optional(), - registers: z.record(z.unknown()).nullable().optional(), + registers: z.record(z.string(), z.unknown()).nullable().optional(), hasSystemFrames: z.boolean().nullable().optional(), }) .partial() @@ -882,7 +884,7 @@ export const ThreadEntrySchema = z current: z.boolean().nullable(), crashed: z.boolean().nullable(), state: z.string().nullable(), - heldLocks: z.record(z.unknown()).nullable().optional(), + heldLocks: z.record(z.string(), z.unknown()).nullable().optional(), stacktrace: StacktraceSchema.nullable(), rawStacktrace: StacktraceSchema.nullable().optional(), }) @@ -901,7 +903,7 @@ export const BreadcrumbSchema = z category: z.string().nullable(), level: z.string().nullable(), message: z.string().nullable(), - data: z.record(z.unknown()).nullable(), + data: z.record(z.string(), z.unknown()).nullable(), }) .partial(); @@ -981,13 +983,15 @@ const BaseEventSchema = z.object({ z.string(), z .object({ - type: z.union([ - z.literal("default"), - z.literal("runtime"), - z.literal("os"), - z.literal("trace"), - z.unknown(), - ]), + type: z + .union([ + z.literal("default"), + z.literal("runtime"), + z.literal("os"), + z.literal("trace"), + z.unknown(), + ]) + .optional(), }) .passthrough(), ) @@ -1721,7 +1725,7 @@ export const FlamegraphSchema = z.preprocess( z .object({ activeProfileIndex: z.preprocess((value) => value ?? 0, z.number()), - metadata: z.record(z.unknown()).optional(), + metadata: z.record(z.string(), z.unknown()).optional(), platform: z.string(), profiles: z.preprocess( (value) => value ?? [], @@ -1784,11 +1788,12 @@ export const ProfileFrameSchema = z raw_function: z.string().nullable().optional(), symbol: z.string().nullable().optional(), lang: z.string().nullable().optional(), - data: z.record(z.unknown()).optional(), + data: z.record(z.string(), z.unknown()).optional(), }) .passthrough(); const ProfileThreadMetadataSchema = z.record( + z.string(), z .object({ // Matches Sentry's `Profiling.ContinuousProfile.thread_metadata` type, diff --git a/packages/mcp-core/src/internal/agents/callEmbeddedAgent.ts b/packages/mcp-core/src/internal/agents/callEmbeddedAgent.ts index 845d46484..f7dfdbd1c 100644 --- a/packages/mcp-core/src/internal/agents/callEmbeddedAgent.ts +++ b/packages/mcp-core/src/internal/agents/callEmbeddedAgent.ts @@ -31,7 +31,7 @@ interface EmbeddedAgentResult { */ export async function callEmbeddedAgent< TOutput, - TSchema extends z.ZodType, + TSchema extends z.ZodType, >({ system, prompt, @@ -246,7 +246,7 @@ function extractJsonCandidates(text: string): string[] { */ function rescueFromText( text: string, - schema: z.ZodType, + schema: z.ZodType, ): TOutput | null { for (const candidate of extractJsonCandidates(text)) { try { diff --git a/packages/mcp-core/src/internal/formatting.ts b/packages/mcp-core/src/internal/formatting.ts index a78eb3a22..94cbac214 100644 --- a/packages/mcp-core/src/internal/formatting.ts +++ b/packages/mcp-core/src/internal/formatting.ts @@ -2462,7 +2462,7 @@ function stripReplayMetadata(event: Event): Event { ) : { ...event.contexts, - replay: nextReplayContext, + replay: { ...nextReplayContext, type: replayContext.type }, }; return { diff --git a/packages/mcp-core/src/toolDefinitions.json b/packages/mcp-core/src/toolDefinitions.json index 686bfc94b..7c3170b63 100644 --- a/packages/mcp-core/src/toolDefinitions.json +++ b/packages/mcp-core/src/toolDefinitions.json @@ -3,6 +3,7 @@ "name": "add_issue_note", "description": "Add a human-visible comment to a Sentry issue's activity feed.\n\nUse this tool when the user explicitly asks to leave a note/comment, or when a triage workflow needs to record a user-approved explanation.\n\n\nadd_issue_note(organizationSlug='my-organization', issueId='PROJECT-123', text='Investigating with the payments team.')\nadd_issue_note(issueUrl='https://my-organization.sentry.io/issues/PROJECT-123/', text='Resolved by deploy 1.2.3.')\n\n\n\n- This mutates visible Sentry issue state by posting a comment.\n- Do not use this for private scratch notes, secrets, credentials, or unapproved content.\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -10,6 +11,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -18,9 +20,7 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "issueId": { "type": "string", @@ -38,9 +38,7 @@ "description": "The exact comment text to add to the issue." } }, - "required": ["text"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["text"] }, "requiredScopes": ["event:write"], "skills": ["triage"], @@ -50,6 +48,7 @@ "name": "add_team_to_project", "description": "Grant a team access to an existing Sentry project.\n\nUse this tool when you need to:\n- Add another team to a project\n- Grant a team access without changing project metadata\n- Check whether a team already has project access before adding it\n\n\nadd_team_to_project(organizationSlug='my-organization', projectSlug='my-project', teamSlug='my-team')\n\n\n\n- Team access changes are separate from project metadata updates.\n- If the team is already assigned, this tool returns the current team list without making another change.\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -57,6 +56,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -65,9 +65,7 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "projectSlug": { "type": "string", @@ -78,9 +76,7 @@ "description": "The team's slug. You can find a list of existing teams in an organization with the Sentry tool `find_teams`." } }, - "required": ["organizationSlug", "projectSlug", "teamSlug"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug", "projectSlug", "teamSlug"] }, "requiredScopes": ["project:write", "team:read", "org:read"], "skills": ["project-management"], @@ -90,6 +86,7 @@ "name": "analyze_issue_with_seer", "description": "Use Seer to analyze production errors and get detailed root cause analysis with specific code fixes.\n\nUse this tool when:\n- The user explicitly asks for root cause analysis, Seer analysis, or help fixing/debugging an issue\n- You are unable to accurately determine the root cause from the issue details alone\n\nDo NOT call this tool as an automatic follow-up to get_sentry_resource.\n\nWhat this tool provides:\n- Root cause analysis with code-level explanations\n- Specific file locations and line numbers where errors occur\n- Concrete code fixes you can apply\n- Step-by-step implementation guidance\n\nThis tool automatically:\n1. Checks if analysis already exists (instant results)\n2. Starts new AI analysis if needed (~2-5 minutes)\n3. Returns complete fix recommendations\n\n\n### User: \"Run Seer on this issue\"\n\n```\nanalyze_issue_with_seer(issueUrl='https://my-org.sentry.io/issues/PROJECT-1Z43')\n```\n\n### User: \"Analyze this issue and suggest a fix\"\n\n```\nanalyze_issue_with_seer(organizationSlug='my-organization', issueId='ERROR-456')\n```\n\n\n\n- Only use when the user explicitly requests analysis or you cannot determine the root cause from issue details alone\n- Seer Autofix does not support metric alert issues (issueCategory: metric); use get_issue_details and search_events instead\n- If the user provides an issueUrl, extract it and use that parameter alone\n- The analysis includes actual code snippets and fixes, not just error descriptions\n- Results are cached - subsequent calls return instantly\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -97,6 +94,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -105,9 +103,7 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "issueId": { "type": "string", @@ -122,9 +118,7 @@ "type": "string", "description": "Optional custom instruction for the AI analysis" } - }, - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + } }, "requiredScopes": [], "skills": ["seer"], @@ -134,6 +128,7 @@ "name": "create_dsn", "description": "Create an additional DSN for an EXISTING project.\n\nUSE THIS TOOL WHEN:\n- Project already exists and needs additional DSN\n- 'Create another DSN for project X'\n- 'I need a production DSN for existing project'\n\nDO NOT USE for new projects (use create_project instead)\n\nBe careful when using this tool!\n\n\n### Create additional DSN for existing project\n```\ncreate_dsn(organizationSlug='my-organization', projectSlug='my-project', name='Production')\n```\n\n\n\n- If the user passes a parameter in the form of name/otherName, its likely in the format of /.\n- If any parameter is ambiguous, you should clarify with the user what they meant.\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -141,6 +136,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -149,9 +145,7 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "projectSlug": { "type": "string", @@ -162,9 +156,7 @@ "description": "The name of the DSN to create, for example 'Production'." } }, - "required": ["organizationSlug", "projectSlug", "name"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug", "projectSlug", "name"] }, "requiredScopes": ["project:write"], "skills": ["project-management"], @@ -174,6 +166,7 @@ "name": "create_project", "description": "Create a new project in Sentry (provisions DSN automatically).\n\nUSE THIS TOOL WHEN USERS WANT TO:\n- 'Create a new project'\n- 'Set up a project for [app/service] with team [X]'\n- 'I need a new Sentry project'\n- Create project AND need DSN in one step\n- Create project and link an existing repository\n\nReturns the created project slug and a usable SENTRY_DSN when key setup succeeds.\n\nBe careful when using this tool!\n\n\n### Create new project with team\n```\ncreate_project(organizationSlug='my-organization', teamSlug='my-team', name='my-project', platform='javascript')\n```\n### Create project with an explicit slug\n```\ncreate_project(organizationSlug='my-organization', teamSlug='my-team', name='My Project', slug='my-project', platform='javascript')\n```\n### Create project and link to a repository\n```\ncreate_project(organizationSlug='my-organization', teamSlug='my-team', name='my-project', platform='javascript', repository='getsentry/sentry')\n```\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -181,6 +174,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -189,9 +183,7 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "teamSlug": { "type": "string", @@ -202,6 +194,7 @@ "description": "The name of the project to create. Typically this is the name of the application or service. It is only used as a visual label in Sentry." }, "slug": { + "default": null, "anyOf": [ { "type": "string", @@ -210,11 +203,10 @@ { "type": "null" } - ], - "description": "Optional project slug to create.", - "default": null + ] }, "platform": { + "default": null, "anyOf": [ { "type": "string", @@ -223,11 +215,11 @@ { "type": "null" } - ], - "description": "The platform for the project. e.g., python, javascript, react, etc.", - "default": null + ] }, "repository": { + "default": null, + "description": "Optional repository name to link to the project (e.g. 'getsentry/sentry'). The repo must already be connected to the organization via a VCS integration.", "anyOf": [ { "type": "string" @@ -235,14 +227,10 @@ { "type": "null" } - ], - "default": null, - "description": "Optional repository name to link to the project (e.g. 'getsentry/sentry'). The repo must already be connected to the organization via a VCS integration." + ] } }, - "required": ["organizationSlug", "teamSlug", "name"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug", "teamSlug", "name"] }, "requiredScopes": ["project:write", "team:read", "org:read"], "skills": ["project-management"], @@ -252,6 +240,7 @@ "name": "create_team", "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\n### Create a new team\n```\ncreate_team(organizationSlug='my-organization', name='the-goats')\n```\n\n\n\n- If any parameter is ambiguous, you should clarify with the user what they meant.\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -259,6 +248,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -267,18 +257,14 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "name": { "type": "string", "description": "The name of the team to create." } }, - "required": ["organizationSlug", "name"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug", "name"] }, "requiredScopes": ["team:write"], "skills": ["project-management"], @@ -288,6 +274,7 @@ "name": "execute_sentry_tool", "description": "Execute an available Sentry MCP tool discovered through search_sentry_tools.\n\nUse this tool when you need to:\n- Call a Sentry operation returned by search_sentry_tools\n- Execute a tool by name using arguments that match its returned schema\n\n\nexecute_sentry_tool(name='find_projects', arguments={ organizationSlug: 'my-org' })\nexecute_sentry_tool(name='whoami', arguments={})\n\n\n\n- Use search_sentry_tools first if you are not sure which name or arguments to pass.\n- Arguments are validated against the target tool's schema before execution.\n- Active organization, project, and region constraints are injected automatically.\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "name": { @@ -296,15 +283,16 @@ "description": "The name of the available tool to execute." }, "arguments": { - "type": "object", - "additionalProperties": {}, "default": {}, - "description": "Arguments for the target tool, matching the schema returned by search_sentry_tools." + "description": "Arguments for the target tool, matching the schema returned by search_sentry_tools.", + "type": "object", + "propertyNames": { + "type": "string" + }, + "additionalProperties": {} } }, - "required": ["name"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["name"] }, "requiredScopes": [], "skills": ["inspect", "seer", "docs", "triage", "project-management"], @@ -314,6 +302,7 @@ "name": "find_alert_rules", "description": "Find Sentry alert rules.\n\nUse this tool when you need to:\n- List issue alert rules for a project\n- List metric alert rules for an organization or project\n- Find an alert rule ID by name before inspecting it\n- Check alert conditions, queries, triggers, actions, owner, or environment\n\n\nfind_alert_rules(organizationSlug='my-org')\nfind_alert_rules(organizationSlug='my-org', projectSlug='backend')\nfind_alert_rules(organizationSlug='my-org', kind='issue', projectSlug='backend', query='critical')\n\n\n\n- Issue alert rules are project-scoped, so `projectSlug` is required when `kind` is `issue`.\n- Metric alert rules can be listed organization-wide or project-scoped.\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -321,6 +310,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -329,17 +319,16 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "kind": { + "default": "all", "type": "string", "enum": ["all", "issue", "metric"], - "description": "Which alert rule family to search. Use `all` to include metric alerts, plus issue alerts when a project is available.", - "default": "all" + "description": "Which alert rule family to search. Use `all` to include metric alerts, plus issue alerts when a project is available." }, "projectSlug": { + "default": null, "anyOf": [ { "type": "string", @@ -348,11 +337,10 @@ { "type": "null" } - ], - "description": "The project's slug, or exact lowercase `all` when a tool supports all-projects scope. Other casing is treated as a project slug.", - "default": null + ] }, "query": { + "default": null, "anyOf": [ { "type": "string", @@ -361,11 +349,10 @@ { "type": "null" } - ], - "description": "Optional search query for alert rule name.", - "default": null + ] }, "cursor": { + "default": null, "anyOf": [ { "type": "string", @@ -374,21 +361,17 @@ { "type": "null" } - ], - "description": "Optional pagination cursor from a previous Sentry API response.", - "default": null + ] }, "limit": { + "default": 10, "type": "integer", "exclusiveMinimum": 0, "maximum": 100, - "description": "Maximum number of alert rules to return per alert family.", - "default": 10 + "description": "Maximum number of alert rules to return per alert family." } }, - "required": ["organizationSlug"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug"] }, "requiredScopes": ["org:read", "project:read"], "skills": ["inspect"], @@ -398,6 +381,7 @@ "name": "find_dashboards", "description": "Find Sentry dashboards in an organization.\n\nUse this tool when you need to:\n- List dashboards in an organization\n- Find a dashboard ID before calling get_dashboard_details\n- Search dashboards by title\n\n\nfind_dashboards(organizationSlug='my-organization')\nfind_dashboards(organizationSlug='my-organization', titleQuery='errors')\n\n\n\n- Dashboard IDs are organization-scoped.\n- Use `get_dashboard_details` after finding the correct dashboard ID.\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -405,6 +389,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -413,11 +398,10 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "titleQuery": { + "default": null, "anyOf": [ { "type": "string", @@ -426,17 +410,16 @@ { "type": "null" } - ], - "description": "Optional title substring to search for.", - "default": null + ] }, "sort": { + "default": "title", "type": "string", "enum": ["title", "-title", "dateCreated", "-dateCreated"], - "description": "Sort order for dashboard results.", - "default": "title" + "description": "Sort order for dashboard results." }, "cursor": { + "default": null, "anyOf": [ { "type": "string", @@ -445,21 +428,17 @@ { "type": "null" } - ], - "description": "Optional pagination cursor from a previous response. Reuse cursors only with the same search scope and project constraint.", - "default": null + ] }, "limit": { + "default": 10, "type": "integer", "exclusiveMinimum": 0, "maximum": 100, - "description": "Maximum number of dashboards to return.", - "default": 10 + "description": "Maximum number of dashboards to return." } }, - "required": ["organizationSlug"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug"] }, "requiredScopes": ["org:read"], "skills": ["inspect"], @@ -469,6 +448,7 @@ "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\n- If the user passes a parameter in the form of name/otherName, its likely in the format of /.\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", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -476,6 +456,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -484,18 +465,14 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "projectSlug": { "type": "string", "description": "The project's slug. You can find a list of existing projects in an organization using the `find_projects()` tool." } }, - "required": ["organizationSlug", "projectSlug"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug", "projectSlug"] }, "requiredScopes": ["project:read"], "skills": ["project-management"], @@ -505,6 +482,7 @@ "name": "find_monitors", "description": "Find Sentry cron monitors.\n\nUse this tool when you need to:\n- List cron monitors in an organization\n- Find a monitor by name or slug before getting details\n- Check monitor status, owner, project, schedule, or recent environment state\n\n\nfind_monitors(organizationSlug='my-organization')\nfind_monitors(organizationSlug='my-organization', projectSlug='backend', query='billing')\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -512,6 +490,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -520,11 +499,10 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "projectSlug": { + "default": null, "anyOf": [ { "type": "string", @@ -533,11 +511,10 @@ { "type": "null" } - ], - "description": "The project's slug, or exact lowercase `all` when a tool supports all-projects scope. Other casing is treated as a project slug.", - "default": null + ] }, "environment": { + "default": null, "anyOf": [ { "type": "string", @@ -546,11 +523,10 @@ { "type": "null" } - ], - "description": "Optional environment name to limit monitor state.", - "default": null + ] }, "owner": { + "default": null, "anyOf": [ { "type": "string", @@ -559,11 +535,10 @@ { "type": "null" } - ], - "description": "Optional owner filter, such as `user:123`, `team:456`, `myteams`, or `unassigned`.", - "default": null + ] }, "query": { + "default": null, "anyOf": [ { "type": "string", @@ -572,21 +547,17 @@ { "type": "null" } - ], - "description": "Optional search query for monitor name or slug.", - "default": null + ] }, "limit": { + "default": 10, "type": "integer", "exclusiveMinimum": 0, "maximum": 100, - "description": "Maximum number of monitors to return.", - "default": 10 + "description": "Maximum number of monitors to return." } }, - "required": ["organizationSlug"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug"] }, "requiredScopes": ["org:read"], "skills": ["inspect"], @@ -596,9 +567,11 @@ "name": "find_organizations", "description": "Find organizations that the user has access to in Sentry.\n\nUse this tool when you need to:\n- View organizations in Sentry\n- Find an organization's slug to aid other tool requests\n- Search for specific organizations by name or slug\n\nReturns up to 25 results. If you hit this limit, use the query parameter to narrow down results.", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "query": { + "default": null, "anyOf": [ { "type": "string", @@ -607,13 +580,9 @@ { "type": "null" } - ], - "description": "Search query to filter results by name or slug. Use this to narrow down results when there are many items.", - "default": null + ] } - }, - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + } }, "requiredScopes": ["org:read"], "skills": ["inspect", "seer", "docs", "triage", "project-management"], @@ -623,6 +592,7 @@ "name": "find_projects", "description": "Find projects in Sentry.\n\nUse this tool when you need to:\n- View projects in a Sentry organization\n- Find a project's slug to aid other tool requests\n- Search for specific projects by name or slug\n\nReturns up to 25 results. If you hit this limit, use the query parameter to narrow down results.", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -630,6 +600,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -638,11 +609,10 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "query": { + "default": null, "anyOf": [ { "type": "string", @@ -651,14 +621,10 @@ { "type": "null" } - ], - "description": "Search query to filter results by name or slug. Use this to narrow down results when there are many items.", - "default": null + ] } }, - "required": ["organizationSlug"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug"] }, "requiredScopes": ["project:read"], "skills": ["inspect", "seer", "docs", "triage", "project-management"], @@ -668,6 +634,7 @@ "name": "find_releases", "description": "Find releases in Sentry.\n\nUse this tool when you need to:\n- Find recent releases in a Sentry organization\n- Find the most recent version released of a specific project\n- Determine when a release was deployed to an environment\n\n\n### Find the most recent releases in the 'my-organization' organization\n\n```\nfind_releases(organizationSlug='my-organization')\n```\n\n### Find releases matching '2ce6a27' in the 'my-organization' organization\n\n```\nfind_releases(organizationSlug='my-organization', query='2ce6a27')\n```\n\n\n\n- If the user passes a parameter in the form of name/otherName, its likely in the format of /.\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -675,6 +642,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -683,11 +651,10 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "projectSlug": { + "default": null, "anyOf": [ { "type": "string", @@ -696,11 +663,10 @@ { "type": "null" } - ], - "description": "The project's slug, or exact lowercase `all` when a tool supports all-projects scope. Other casing is treated as a project slug.", - "default": null + ] }, "query": { + "default": null, "anyOf": [ { "type": "string", @@ -709,14 +675,10 @@ { "type": "null" } - ], - "description": "Search for versions which contain the provided string.", - "default": null + ] } }, - "required": ["organizationSlug"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug"] }, "requiredScopes": ["project:read"], "skills": ["inspect"], @@ -726,6 +688,7 @@ "name": "find_teams", "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. If you hit this limit, use the query parameter to narrow down results.", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -733,6 +696,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -741,11 +705,10 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "query": { + "default": null, "anyOf": [ { "type": "string", @@ -754,14 +717,10 @@ { "type": "null" } - ], - "description": "Search query to filter results by name or slug. Use this to narrow down results when there are many items.", - "default": null + ] } }, - "required": ["organizationSlug"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug"] }, "requiredScopes": ["team:read"], "skills": ["inspect", "triage", "project-management"], @@ -771,6 +730,7 @@ "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.", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -782,27 +742,26 @@ "description": "The AI conversation ID from gen_ai.conversation.id." }, "project": { - "type": "string", - "description": "Numeric project ID to scope the query. Falls back to context constraint or all projects." + "description": "Numeric project ID to scope the query. Falls back to context constraint or all projects.", + "type": "string" }, "start": { - "type": "string", - "description": "Explicit start time for the conversation lookup window." + "description": "Explicit start time for the conversation lookup window.", + "type": "string" }, "end": { - "type": "string", - "description": "Explicit end time for the conversation lookup window." + "description": "Explicit end time for the conversation lookup window.", + "type": "string" }, "regionUrl": { "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." } }, - "required": ["organizationSlug", "conversationId"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug", "conversationId"] }, "outputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "conversationId": { @@ -827,14 +786,27 @@ "end": { "type": "string" } - }, - "additionalProperties": false + } }, "startTimestamp": { - "type": ["number", "null"] + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] }, "endTimestamp": { - "type": ["number", "null"] + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] }, "traceIds": { "type": "array", @@ -875,13 +847,27 @@ "type": "string" }, "parentSpanId": { - "type": ["string", "null"] + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] }, "project": { "type": "string" }, "projectId": { - "type": ["string", "number"] + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] }, "timestamp": { "type": "number" @@ -964,8 +950,7 @@ "type": "string" } } - }, - "additionalProperties": false + } } }, "required": [ @@ -975,14 +960,13 @@ "projectId", "timestamp", "durationMs" - ], - "additionalProperties": false + ] } }, "timeline": { "type": "array", "items": { - "anyOf": [ + "oneOf": [ { "type": "object", "properties": { @@ -1028,8 +1012,7 @@ "type": "number" } }, - "required": ["totalTokens", "durationMs"], - "additionalProperties": false + "required": ["totalTokens", "durationMs"] }, "genAi": { "type": "object", @@ -1088,8 +1071,7 @@ "type": "string" } } - }, - "additionalProperties": false + } } }, "required": [ @@ -1099,8 +1081,7 @@ "timestamp", "spanId", "traceId" - ], - "additionalProperties": false + ] }, { "type": "object", @@ -1175,8 +1156,7 @@ "toolDefinitions": { "type": "string" } - }, - "additionalProperties": false + } } }, "required": [ @@ -1186,8 +1166,7 @@ "traceId", "timestamp", "durationMs" - ], - "additionalProperties": false + ] } ] } @@ -1209,9 +1188,7 @@ "totalTokens", "spanSummaries", "timeline" - ], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + ] }, "requiredScopes": ["event:read", "project:read"], "skills": ["inspect", "triage", "seer"], @@ -1221,6 +1198,7 @@ "name": "get_alert_rule", "description": "Get details for a Sentry alert rule.\n\nUse this tool when you need to inspect an alert rule's exact conditions, query, triggers, and actions before explaining or planning changes.\n\n\nget_alert_rule(organizationSlug='my-org', kind='metric', ruleIdOrName='12345')\nget_alert_rule(organizationSlug='my-org', kind='issue', projectSlug='backend', ruleIdOrName='Notify backend team')\nget_alert_rule(organizationSlug='my-org', projectSlug='backend', ruleIdOrName='P95 latency')\n\n\n\n- Use `kind='issue'` or `kind='metric'` for numeric IDs because issue and metric alerts use separate endpoints.\n- With `kind='all'`, a digit-only `ruleIdOrName` is treated as an exact alert rule name.\n- Issue alert rules are project-scoped, so `projectSlug` is required when `kind` is `issue`.\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1228,6 +1206,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -1236,17 +1215,16 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "kind": { + "default": "all", "type": "string", "enum": ["all", "issue", "metric"], - "description": "Which alert rule family to inspect. Use `issue` or `metric` for numeric IDs; `all` treats the value as an exact-name lookup.", - "default": "all" + "description": "Which alert rule family to inspect. Use `issue` or `metric` for numeric IDs; `all` treats the value as an exact-name lookup." }, "projectSlug": { + "default": null, "anyOf": [ { "type": "string", @@ -1255,9 +1233,7 @@ { "type": "null" } - ], - "description": "The project's slug, or exact lowercase `all` when a tool supports all-projects scope. Other casing is treated as a project slug.", - "default": null + ] }, "ruleIdOrName": { "type": "string", @@ -1265,9 +1241,7 @@ "description": "The alert rule's numeric ID, or an exact alert rule name." } }, - "required": ["organizationSlug", "ruleIdOrName"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug", "ruleIdOrName"] }, "requiredScopes": ["org:read", "project:read"], "skills": ["inspect"], @@ -1277,6 +1251,7 @@ "name": "get_dashboard_details", "description": "Get detailed information about a specific Sentry dashboard.\n\nUse this tool when you need to:\n- Inspect a dashboard's widgets and saved query definitions\n- View dashboard projects, environments, filters, layout, and widget IDs\n- Resolve a dashboard by exact title or numeric ID\n\n\nget_dashboard_details(organizationSlug='my-organization', dashboardIdOrTitle='12345')\nget_dashboard_details(organizationSlug='my-organization', dashboardIdOrTitle='Errors Overview')\n\n\n\n- Numeric dashboard IDs are resolved directly.\n- Title lookups require one exact case-insensitive match. Use `find_dashboards` first if uncertain.\n- This returns saved widget query definitions, not live widget data.\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1284,6 +1259,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -1292,9 +1268,7 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "dashboardIdOrTitle": { "type": "string", @@ -1302,9 +1276,7 @@ "description": "The dashboard's numeric ID or exact title." } }, - "required": ["organizationSlug", "dashboardIdOrTitle"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug", "dashboardIdOrTitle"] }, "requiredScopes": ["org:read"], "skills": ["inspect"], @@ -1314,6 +1286,7 @@ "name": "get_doc", "description": "Fetch the full markdown content of a Sentry documentation page.\n\nUse this tool when you need to:\n- Read the complete documentation for a specific topic\n- Get detailed implementation examples or code snippets\n- Access the full context of a documentation page\n- Extract specific sections from documentation\n\n\n### Get the Next.js integration guide\n\n```\nget_doc(path='/platforms/javascript/guides/nextjs.md')\n```\n\n\n\n- Use the path from search_docs results for accurate fetching\n- Paths should end with .md extension\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "path": { @@ -1321,9 +1294,7 @@ "description": "The documentation path (e.g., '/platforms/javascript/guides/nextjs.md'). Get this from search_docs results." } }, - "required": ["path"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["path"] }, "requiredScopes": [], "skills": ["inspect", "docs"], @@ -1333,6 +1304,7 @@ "name": "get_event_attachment", "description": "Download attachments from a Sentry event.\n\nUse this tool when you need to:\n- Download files attached to a specific event\n- Access screenshots, log files, or other attachments uploaded with an error report\n- Retrieve attachment metadata and download URLs\n\n\n### Download a specific attachment by ID\n\n```\nget_event_attachment(organizationSlug='my-organization', projectSlug='my-project', eventId='c49541c747cb4d8aa3efb70ca5aba243', attachmentId='12345')\n```\n\n### List all attachments for an event\n\n```\nget_event_attachment(organizationSlug='my-organization', projectSlug='my-project', eventId='c49541c747cb4d8aa3efb70ca5aba243')\n```\n\n\n\n\n- If `attachmentId` is provided, the specific attachment will be downloaded as an embedded resource\n- If `attachmentId` is omitted, all attachments for the event will be listed with download information\n- The `projectSlug` is required to identify which project the event belongs to\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1348,6 +1320,7 @@ "description": "The ID of the event." }, "attachmentId": { + "default": null, "anyOf": [ { "type": "string", @@ -1356,11 +1329,10 @@ { "type": "null" } - ], - "description": "The ID of the attachment to download.", - "default": null + ] }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -1369,14 +1341,10 @@ { "type": "null" } - ], - "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.", - "default": null + ] } }, - "required": ["organizationSlug", "projectSlug", "eventId"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug", "projectSlug", "eventId"] }, "requiredScopes": ["event:read"], "skills": ["inspect"], @@ -1386,6 +1354,7 @@ "name": "get_event_stacktrace", "description": "Get a full thread stacktrace from a specific Sentry event.\n\nUse this tool when you need to:\n- Fetch the full stacktrace for a thread listed in issue details\n- Inspect a non-crashed thread from an event with multiple threads\n- Get Sentry's default selected thread stacktrace when no thread is specified\n\n\nget_event_stacktrace(organizationSlug='my-org', issueId='PROJECT-123')\nget_event_stacktrace(organizationSlug='my-org', issueId='PROJECT-123', eventId='abc123', thread=259)\nget_event_stacktrace(organizationSlug='my-org', issueId='PROJECT-123', thread='main')\n\n\n\n- `thread` is optional. If omitted, this returns the same default thread Sentry selects: first crashed thread, then first thread with a stacktrace, then first thread.\n- Pass `thread` as a numeric Thread ID or exact thread Name from the issue details thread list.\n- If the issue details show only one useful thread, omit `thread`.\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1393,6 +1362,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -1401,35 +1371,33 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "issueId": { "type": "string", "description": "The Issue ID. e.g. `PROJECT-1Z43`" }, "eventId": { - "type": "string", "default": "latest", - "description": "The event ID for the issue. Defaults to `latest`." + "description": "The event ID for the issue. Defaults to `latest`.", + "type": "string" }, "thread": { + "description": "Optional thread selector. Pass a numeric thread ID, or an exact thread name string. If omitted, returns the same default thread Sentry selects: first crashed thread, then first thread with a stacktrace, then first thread.", "anyOf": [ { - "type": "integer" + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 }, { "type": "string", "minLength": 1 } - ], - "description": "Optional thread selector. Pass a numeric thread ID, or an exact thread name string. If omitted, returns the same default thread Sentry selects: first crashed thread, then first thread with a stacktrace, then first thread." + ] } }, - "required": ["organizationSlug", "issueId"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug", "issueId"] }, "requiredScopes": ["event:read"], "skills": ["inspect", "triage", "seer"], @@ -1439,6 +1407,7 @@ "name": "get_issue_activity", "description": "Get the activity feed and comments for a Sentry issue.\n\nUse this tool when you need to:\n- Review prior comments before triaging an issue\n- Understand who resolved, ignored, assigned, or commented on an issue\n- See recent issue activity that is not included in `get_issue_details`\n\n\nget_issue_activity(organizationSlug='my-organization', issueId='PROJECT-123')\nget_issue_activity(issueUrl='https://my-organization.sentry.io/issues/PROJECT-123/')\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1446,6 +1415,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -1454,9 +1424,7 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "issueId": { "type": "string", @@ -1468,18 +1436,16 @@ "description": "The URL of the issue. e.g. https://my-organization.sentry.io/issues/PROJECT-1Z43" }, "includeComments": { - "type": "boolean", - "default": true + "default": true, + "type": "boolean" }, "limit": { + "default": 25, "type": "integer", "exclusiveMinimum": 0, - "maximum": 100, - "default": 25 + "maximum": 100 } - }, - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + } }, "requiredScopes": ["event:read"], "skills": ["inspect", "triage"], @@ -1489,6 +1455,7 @@ "name": "get_issue_details", "description": "Get detailed information about a specific Sentry issue by ID.\n\nUSE THIS TOOL WHEN USERS:\n- Provide a specific issue ID (e.g., 'CLOUDFLARE-MCP-41', 'PROJECT-123')\n- Ask to 'explain [ISSUE-ID]', 'tell me about [ISSUE-ID]'\n- Want details/stacktrace/analysis for a known issue\n- Provide a Sentry issue URL\n\nDO NOT USE for:\n- General searching or listing issues (use search_issues)\n\nTRIGGER PATTERNS:\n- 'Explain ISSUE-123' → use get_issue_details\n- 'Tell me about PROJECT-456' → use get_issue_details\n- 'What happened in [issue URL]' → use get_issue_details\n\n\n### With Sentry URL (recommended - simplest approach)\n```\nget_issue_details(issueUrl='https://sentry.sentry.io/issues/6916805731/?project=4509062593708032&query=is%3Aunresolved')\n```\n\n### With issue ID and organization\n```\nget_issue_details(organizationSlug='my-organization', issueId='CLOUDFLARE-MCP-41')\n```\n\n### With event ID and organization\n```\nget_issue_details(organizationSlug='my-organization', eventId='c49541c747cb4d8aa3efb70ca5aba243')\n```\n\n\n\n- **IMPORTANT**: If user provides a Sentry URL, pass the ENTIRE URL to issueUrl parameter unchanged\n- When using issueUrl, all other parameters are automatically extracted - don't provide them separately\n- If using issueId (not URL), then organizationSlug is required\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1496,6 +1463,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -1504,9 +1472,7 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "issueId": { "type": "string", @@ -1521,9 +1487,7 @@ "format": "uri", "description": "The URL of the issue. e.g. https://my-organization.sentry.io/issues/PROJECT-1Z43" } - }, - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + } }, "requiredScopes": ["event:read"], "skills": ["inspect", "triage", "seer"], @@ -1533,6 +1497,7 @@ "name": "get_issue_tag_values", "description": "Get tag value distribution for a specific Sentry issue.\n\nUse this tool when you need to:\n- Understand how an issue is distributed across different tag values\n- Get aggregate counts of unique tag values (e.g., 'how many unique URLs are affected')\n- Analyze which browsers, environments, or URLs are most impacted by an issue\n- View the tag distributions page data programmatically\n\nCommon tag keys:\n- `url`: Request URLs affected by the issue\n- `browser`: Browser types and versions\n- `browser.name`: Browser names only\n- `os`: Operating systems\n- `environment`: Deployment environments (production, staging, etc.)\n- `release`: Software releases\n- `device`: Device types\n- `user`: Affected users\n\n\n### Get URL distribution for an issue\n```\nget_issue_tag_values(organizationSlug='my-organization', issueId='PROJECT-123', tagKey='url')\n```\n\n### Get browser distribution using issue URL\n```\nget_issue_tag_values(issueUrl='https://sentry.io/issues/PROJECT-123/', tagKey='browser')\n```\n\n### Get environment distribution\n```\nget_issue_tag_values(organizationSlug='my-organization', issueId='PROJECT-123', tagKey='environment')\n```\n\n\n\n- If user provides a Sentry URL, pass the ENTIRE URL to issueUrl parameter unchanged\n- Common tag keys: url, browser, browser.name, os, environment, release, device, user\n- Tag keys are case-sensitive\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1540,6 +1505,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -1548,9 +1514,7 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "issueId": { "type": "string", @@ -1567,9 +1531,7 @@ "description": "The tag key to get values for (e.g., 'url', 'browser', 'environment', 'release')." } }, - "required": ["tagKey"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["tagKey"] }, "requiredScopes": ["event:read"], "skills": ["inspect"], @@ -1579,6 +1541,7 @@ "name": "get_issue_user_reports", "description": "Get legacy User Reports or crash-report feedback attached to a Sentry issue.\n\nUse this tool when you need to:\n- See what a user said happened when an error occurred\n- Check if any legacy bug reports or crash-report feedback were submitted for this issue\n- Get the human-provided context behind a crash, beyond the stack trace\n\n\nget_issue_user_reports(organizationSlug='my-organization', issueId='PROJECT-123')\nget_issue_user_reports(issueUrl='https://my-organization.sentry.io/issues/PROJECT-123/')\n\n\n\n- For standalone User Feedback Widget submissions, use `search_issues(query='issue.category:feedback')`.\n- Reuse pagination cursors only with the same issue scope.\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1586,6 +1549,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -1594,9 +1558,7 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "issueId": { "type": "string", @@ -1608,6 +1570,7 @@ "description": "The URL of the issue. e.g. https://my-organization.sentry.io/issues/PROJECT-1Z43" }, "cursor": { + "default": null, "anyOf": [ { "type": "string", @@ -1616,20 +1579,16 @@ { "type": "null" } - ], - "description": "Optional pagination cursor from a previous response.", - "default": null + ] }, "limit": { + "default": 25, "type": "integer", "exclusiveMinimum": 0, "maximum": 100, - "description": "Maximum number of user reports to return.", - "default": 25 + "description": "Maximum number of user reports to return." } - }, - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + } }, "requiredScopes": ["event:read"], "skills": ["inspect", "triage"], @@ -1639,6 +1598,7 @@ "name": "get_latest_base_snapshot", "description": "Get the latest UI screenshots/images for an app from the preprod snapshot system.\n\nThis is the primary tool for retrieving app screenshots — not search_events or search_issues.\n\nUse this tool when you need to:\n- Get screenshots, screens, golden images, or reference images for an app\n- Find what the current UI looks like (latest screenshots from the main/default branch)\n- List available snapshots or browse images before requesting specific ones\n- Look up dark mode, light mode, or other variant screenshots\n- Understand what baseline images exist when investigating snapshot test or visual regression CI failures\n\nThe appId parameter is the app identifier (e.g. 'sentry-frontend', 'com.emergetools.hackernews').\nReturns compact image metadata (display_name, image_file_name, group, description) for every image.\n\n\n### Get the latest screenshots for an app\n\n```\nget_latest_base_snapshot(organizationSlug=\"sentry\", appId=\"sentry-frontend\", project=\"frontend\")\n```\n\n### Get the latest screenshots for a specific branch\n\n```\nget_latest_base_snapshot(organizationSlug=\"sentry\", appId=\"sentry-frontend\", project=\"frontend\", branch=\"main\")\n```\n\n\n\n- The response includes compact metadata per image. Scan the list to find images matching what you need (e.g. filter by group or name containing 'button').\n- To view a specific image, use get_sentry_resource(url='?selectedSnapshot=').\n- If you need to investigate a specific snapshot comparison, use get_sentry_resource with the snapshot URL.\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1650,6 +1610,7 @@ "description": "The app identifier (e.g. 'sentry-frontend', 'com.emergetools.hackernews'). Required." }, "branch": { + "default": null, "anyOf": [ { "type": "string", @@ -1658,11 +1619,10 @@ { "type": "null" } - ], - "description": "Filter by git branch (e.g. 'main'). Omit to use the app's default branch.", - "default": null + ] }, "project": { + "default": null, "anyOf": [ { "type": "string", @@ -1671,11 +1631,10 @@ { "type": "null" } - ], - "description": "Project slug or numeric ID for scoping (e.g. 'frontend').", - "default": null + ] }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -1684,14 +1643,10 @@ { "type": "null" } - ], - "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.", - "default": null + ] } }, - "required": ["organizationSlug", "appId"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug", "appId"] }, "requiredScopes": ["project:read"], "skills": ["inspect"], @@ -1701,6 +1656,7 @@ "name": "get_monitor_details", "description": "Get details for a Sentry cron monitor.\n\nUse this tool when you need to:\n- Inspect a monitor's schedule, status, owner, project, and environments\n- Review recent check-ins for missed, failed, timeout, or OK runs\n- Check monitor stats over a recent time range\n\n\nget_monitor_details(organizationSlug='my-organization', monitorSlug='nightly-import')\nget_monitor_details(organizationSlug='my-organization', monitorSlug='nightly-import', projectSlugOrId='backend', environment='production', period='7d')\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1708,6 +1664,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -1716,11 +1673,11 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "projectSlugOrId": { + "default": null, + "description": "Optional project slug or numeric ID. Use this to disambiguate monitors with the same slug or to scope a monitor URL that includes a project segment.", "anyOf": [ { "type": "string" @@ -1728,9 +1685,7 @@ { "type": "null" } - ], - "default": null, - "description": "Optional project slug or numeric ID. Use this to disambiguate monitors with the same slug or to scope a monitor URL that includes a project segment." + ] }, "monitorSlug": { "type": "string", @@ -1738,6 +1693,7 @@ "description": "Monitor slug or GUID." }, "environment": { + "default": null, "anyOf": [ { "type": "string", @@ -1746,11 +1702,10 @@ { "type": "null" } - ], - "description": "Optional environment name to filter monitor environments, recent check-ins, and stats.", - "default": null + ] }, "period": { + "default": null, "anyOf": [ { "type": "string", @@ -1760,68 +1715,64 @@ { "type": "null" } - ], - "description": "Relative time range. Defaults to `24h` when `start` and `end` are omitted.", - "default": null + ] }, "start": { + "default": null, "anyOf": [ { "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))$", "description": "Absolute start time. Must be provided with `end`; do not combine with `period`." }, { "type": "null" } - ], - "description": "Absolute start time. Must be provided with `end`; do not combine with `period`.", - "default": null + ] }, "end": { + "default": null, "anyOf": [ { "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))$", "description": "Absolute end time. Must be provided with `start`; do not combine with `period`." }, { "type": "null" } - ], - "description": "Absolute end time. Must be provided with `start`; do not combine with `period`.", - "default": null + ] }, "checkInLimit": { + "default": 10, "type": "integer", "exclusiveMinimum": 0, "maximum": 50, - "description": "Maximum number of recent check-ins to include.", - "default": 10 + "description": "Maximum number of recent check-ins to include." }, "includeStats": { + "default": true, "type": "boolean", - "description": "Include aggregate check-in stats for the selected time range.", - "default": true + "description": "Include aggregate check-in stats for the selected time range." }, "rollupSeconds": { + "default": null, "anyOf": [ { "type": "integer", "exclusiveMinimum": 0, + "maximum": 9007199254740991, "description": "Optional stats bucket size in seconds. Omit this to let Sentry choose an appropriate rollup." }, { "type": "null" } - ], - "description": "Optional stats bucket size in seconds. Omit this to let Sentry choose an appropriate rollup.", - "default": null + ] } }, - "required": ["organizationSlug", "monitorSlug"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug", "monitorSlug"] }, "requiredScopes": ["project:read"], "skills": ["inspect"], @@ -1831,18 +1782,20 @@ "name": "get_profile", "description": "Analyze CPU profiling data to identify performance bottlenecks and detect regressions.\n\nUSE THIS TOOL WHEN:\n- User asks why a specific endpoint/transaction is slow\n- User wants to understand where CPU time is spent\n- User asks about performance bottlenecks\n- User wants to compare performance between time periods\n- User shares a Sentry profile URL\n\nRETURNS:\n- Hot paths (call stacks consuming the most CPU time)\n- Performance percentiles (p75, p95, p99) for each function\n- User code vs library code breakdown\n- Actionable recommendations for optimization\n- Regression analysis when comparing periods\n\n\n### Analyze from URL (with transaction name)\n```\nget_profile(\n profileUrl='https://my-org.sentry.io/explore/profiling/profile/backend/flamegraph/?profilerId=abc123',\n transactionName='/api/users'\n)\n```\n\n### Analyze by transaction name\n```\nget_profile(\n organizationSlug='my-org',\n transactionName='/api/users',\n projectSlugOrId='backend'\n)\n```\n\n### Compare performance between periods\n```\nget_profile(\n organizationSlug='my-org',\n transactionName='/api/users',\n projectSlugOrId='backend',\n period='7d',\n compareAgainstPeriod='14d'\n)\n```\n\n\n\n- Use `focusOnUserCode: true` (default) to filter out library code\n- High p99 relative to p75 indicates inconsistent performance\n- Use compareAgainstPeriod to detect regressions over time\n- Transaction names are case-sensitive\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "profileUrl": { + "description": "Sentry profile URL. If provided, organization and project are extracted from URL. transactionName is still required.", "type": "string", - "format": "uri", - "description": "Sentry profile URL. If provided, organization and project are extracted from URL. transactionName is still required." + "format": "uri" }, "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." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -1851,44 +1804,47 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "projectSlugOrId": { - "type": ["string", "number"], - "description": "Project slug or numeric ID" + "description": "Project slug or numeric ID", + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] }, "transactionName": { - "type": "string", - "description": "Transaction name (e.g., '/api/users', 'POST /graphql')" + "description": "Transaction name (e.g., '/api/users', 'POST /graphql')", + "type": "string" }, "period": { - "type": "string", - "pattern": "^\\d+[hdw]$", + "default": "7d", "description": "Profiling time window (default: '7d'). Use '1h' for very recent profiling data.", - "default": "7d" + "type": "string", + "pattern": "^\\d+[hdw]$" }, "compareAgainstPeriod": { + "description": "Compare against this baseline profiling time window. Enables regression detection.", "type": "string", - "pattern": "^\\d+[hdw]$", - "description": "Compare against this baseline profiling time window. Enables regression detection." + "pattern": "^\\d+[hdw]$" }, "focusOnUserCode": { - "type": "boolean", "default": true, - "description": "Show only user code (is_application: true). Set to false to include library code." + "description": "Show only user code (is_application: true). Set to false to include library code.", + "type": "boolean" }, "maxHotPaths": { + "default": 10, + "description": "Number of hot paths to display (1-20, default: 10)", "type": "integer", "minimum": 1, - "maximum": 20, - "default": 10, - "description": "Number of hot paths to display (1-20, default: 10)" + "maximum": 20 } - }, - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + } }, "requiredScopes": ["event:read"], "skills": ["inspect"], @@ -1898,18 +1854,20 @@ "name": "get_profile_details", "description": "Inspect a specific Sentry profile in detail.\n\nUSE THIS TOOL WHEN:\n- User shares a transaction profile URL and wants the details\n- User has a profile ID and wants a concise summary plus raw sample structure\n- User needs to inspect a continuous profile session by profiler ID and time range\n\nRETURNS:\n- Transaction profile summary with profile URL, transaction, trace, release, and runtime details\n- Sample structure summaries such as frame count, sample count, stacks, and thread breakdown\n- Top frames by occurrence for a quick hotspot overview\n\nNOTE: This tool supports two profile modes.\n- Transaction profiles: pass `profileUrl` or `organizationSlug` + `projectSlugOrId` + `profileId`\n- Continuous profiles: pass `profileUrl` or `organizationSlug` + `projectSlugOrId` + `profilerId` + `start` + `end`\n\n\n### Transaction profile URL\n```\nget_profile_details(\n profileUrl='https://my-org.sentry.io/explore/profiling/profile/backend/cfe78a5c892d4a64a962d837673398d2/flamegraph/'\n)\n```\n\n### Transaction profile by ID\n```\nget_profile_details(\n organizationSlug='my-org',\n projectSlugOrId='backend',\n profileId='cfe78a5c892d4a64a962d837673398d2'\n)\n```\n\n### Continuous profile by session\n```\nget_profile_details(\n organizationSlug='my-org',\n projectSlugOrId='backend',\n profilerId='041bde57b9844e36b8b7e5734efae5f7',\n start='2024-01-01T00:00:00Z',\n end='2024-01-01T01:00:00Z'\n)\n```\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "profileUrl": { + "description": "Sentry transaction profile or continuous profile URL. If provided, organization, project, and profile identifiers are extracted from the URL.", "type": "string", - "format": "uri", - "description": "Sentry transaction profile or continuous profile URL. If provided, organization, project, and profile identifiers are extracted from the URL." + "format": "uri" }, "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." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -1918,38 +1876,41 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "projectSlugOrId": { - "type": ["string", "number"], - "description": "Project slug or numeric ID" + "description": "Project slug or numeric ID", + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] }, "profileId": { - "type": "string", - "description": "Transaction profile ID from a profile flamegraph URL" + "description": "Transaction profile ID from a profile flamegraph URL", + "type": "string" }, "profilerId": { - "type": "string", - "description": "Continuous profiler session ID" + "description": "Continuous profiler session ID", + "type": "string" }, "start": { - "type": "string", - "description": "Continuous profile start time in ISO 8601 format, for example '2024-01-01T00:00:00Z'" + "description": "Continuous profile start time in ISO 8601 format, for example '2024-01-01T00:00:00Z'", + "type": "string" }, "end": { - "type": "string", - "description": "Continuous profile end time in ISO 8601 format, for example '2024-01-01T01:00:00Z'" + "description": "Continuous profile end time in ISO 8601 format, for example '2024-01-01T01:00:00Z'", + "type": "string" }, "focusOnUserCode": { - "type": "boolean", "default": true, - "description": "Show only user code frames in the hotspot table. Set to false to include library frames." + "description": "Show only user code frames in the hotspot table. Set to false to include library frames.", + "type": "boolean" } - }, - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + } }, "requiredScopes": ["event:read"], "skills": ["inspect"], @@ -1959,6 +1920,7 @@ "name": "get_release_details", "description": "Get details for a Sentry release.\n\nUse this tool when you need to:\n- Inspect an exact release version\n- Scope a release lookup to a specific project\n- See deploys and environments for a release\n- See recent commits attached to a release\n- Gather release health metadata when a project is known\n\n\nget_release_details(organizationSlug='my-organization', releaseVersion='1.2.3')\nget_release_details(organizationSlug='my-organization', releaseVersion='1.2.3', projectSlugOrId='backend')\nget_release_details(organizationSlug='my-organization', releaseVersion='1.2.3', includeHealth=true, projectSlugOrId='backend')\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1966,6 +1928,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -1974,9 +1937,7 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "releaseVersion": { "type": "string", @@ -1984,6 +1945,7 @@ "description": "Exact release version." }, "projectSlugOrId": { + "default": null, "anyOf": [ { "type": "string", @@ -1992,36 +1954,32 @@ { "type": "null" } - ], - "description": "Optional project slug or numeric ID. Use this to scope release details, deploys, and commits to one project; required for health metadata unless the session is already project-constrained.", - "default": null + ] }, "includeHealth": { + "default": false, "type": "boolean", - "description": "Include project-specific release health metadata. Requires projectSlugOrId unless the session is already project-constrained.", - "default": false + "description": "Include project-specific release health metadata. Requires projectSlugOrId unless the session is already project-constrained." }, "includeDeploys": { + "default": true, "type": "boolean", - "description": "Include recent deploys for this release.", - "default": true + "description": "Include recent deploys for this release." }, "includeCommits": { + "default": true, "type": "boolean", - "description": "Include recent commits attached to this release.", - "default": true + "description": "Include recent commits attached to this release." }, "limit": { + "default": 10, "type": "integer", "exclusiveMinimum": 0, "maximum": 50, - "description": "Maximum number of deploys and commits to return, up to 50.", - "default": 10 + "description": "Maximum number of deploys and commits to return, up to 50." } }, - "required": ["organizationSlug", "releaseVersion"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug", "releaseVersion"] }, "requiredScopes": ["project:read"], "skills": ["inspect"], @@ -2031,6 +1989,7 @@ "name": "get_replay_details", "description": "Get high-level information about a specific Sentry replay by URL or replay ID.\n\nUSE THIS TOOL WHEN USERS:\n- Share a replay URL\n- Ask what happened in a specific replay\n- Want a concise replay summary plus the next issue or trace lookups to run\n\n\n### With replay URL\n```\nget_replay_details(replayUrl='https://my-organization.sentry.io/explore/replays/7e07485f-12f9-416b-8b14-26260799b51f/')\n```\n\n### With organization and replay ID\n```\nget_replay_details(organizationSlug='my-organization', replayId='7e07485f-12f9-416b-8b14-26260799b51f')\n```\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "replayUrl": { @@ -2055,12 +2014,9 @@ { "type": "null" } - ], - "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." + ] } - }, - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + } }, "requiredScopes": ["org:read", "project:read", "event:read"], "skills": ["inspect"], @@ -2070,14 +2026,16 @@ "name": "get_sentry_resource", "description": "Fetch a Sentry resource by URL, or by resourceType plus resourceId.\nPass a Sentry URL directly when possible; the resource type is auto-detected.\n\nSupports issues, events, traces, spans, AI conversations, breadcrumbs, replays, monitors, preprod snapshots, and snapshot images.\nTrace lookups return a condensed overview by default.\n\nAI Conversations: A conversation is a set of spans sharing the same gen_ai.conversation.id. Use resourceType='ai_conversation' with a conversation ID, or pass a Sentry conversation URL, to fetch the transcript/details. To discover or list conversations, use search_ai_conversations. Conversations are NOT issues — do not use search_issues for conversation queries.\n\nFor preprod snapshot URLs (matching 'sentry.io/preprod/snapshots/'):\n- Without ?selectedSnapshot=: returns the snapshot diff summary (changed, added, removed images)\n- With ?selectedSnapshot=: returns the image preview and metadata. Use the Sentry tool `get_snapshot_image` for full-resolution image bytes.\n\nResource IDs:\n- span: :\n- monitor: \n- snapshot: \n- snapshotImage: :\n\n\nget_sentry_resource(url='https://sentry.io/issues/PROJECT-123/')\nget_sentry_resource(resourceType='issue', organizationSlug='my-org', resourceId='PROJECT-123')\nget_sentry_resource(resourceType='span', organizationSlug='my-org', resourceId=':')\nget_sentry_resource(resourceType='ai_conversation', organizationSlug='my-org', resourceId='conversation-123')\nget_sentry_resource(url='https://sentry.sentry.io/preprod/snapshots/123/')\nget_sentry_resource(url='https://sentry.sentry.io/preprod/snapshots/123/?selectedSnapshot=login_screen.png')\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "url": { + "description": "Sentry URL. The resource type is auto-detected from the URL pattern.", "type": "string", - "format": "uri", - "description": "Sentry URL. The resource type is auto-detected from the URL pattern." + "format": "uri" }, "resourceType": { + "description": "Resource type. With a URL, can override the auto-detected type for breadcrumbs on an issue/event URL or for `trace` on a span-focused trace URL. Use `monitor` with a monitor slug only when inspect monitor tools are available, `snapshot` with a snapshot artifact ID, or `snapshotImage` with `:`.", "type": "string", "enum": [ "issue", @@ -2090,20 +2048,17 @@ "monitor", "snapshot", "snapshotImage" - ], - "description": "Resource type. With a URL, can override the auto-detected type for breadcrumbs on an issue/event URL or for `trace` on a span-focused trace URL. Use `monitor` with a monitor slug only when inspect monitor tools are available, `snapshot` with a snapshot artifact ID, or `snapshotImage` with `:`." + ] }, "resourceId": { - "type": "string", - "description": "Resource identifier: issue shortId (e.g., 'PROJECT-123'), event ID, trace ID, AI conversation ID, replay ID, monitor slug when inspect monitor tools are available, snapshot artifact ID, `:` for snapshot image resources, or `traceId:spanId` for span resources. Required when not using a URL." + "description": "Resource identifier: issue shortId (e.g., 'PROJECT-123'), event ID, trace ID, AI conversation ID, replay ID, monitor slug when inspect monitor tools are available, snapshot artifact ID, `:` for snapshot image resources, or `traceId:spanId` for span resources. Required when not using a URL.", + "type": "string" }, "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." } - }, - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + } }, "requiredScopes": ["event:read", "project:read"], "skills": ["inspect", "triage", "seer"], @@ -2113,6 +2068,7 @@ "name": "get_snapshot", "description": "Get a preprod snapshot comparison summary, including metadata, counts, and changed image sections.\n\nUse this tool when you need to:\n- Investigate a failed snapshot test from CI\n- Review what changed in a specific preprod snapshot\n- Browse snapshot image file names before viewing a specific image\n\nPass organizationSlug and snapshotId. Use get_sentry_resource for snapshot URLs.\nCompact output is returned by default. Set showUnmodified=true to list unchanged and skipped images separately.\n\n\n### Browse a snapshot\n\n```\nget_snapshot(organizationSlug=\"sentry\", snapshotId=\"231949\")\n```\n\n### Include unchanged and skipped images\n\n```\nget_snapshot(organizationSlug=\"sentry\", snapshotId=\"231949\", showUnmodified=true)\n```\n\n\n\n- Use the Sentry tool `get_snapshot_image` to view a specific image preview or full-resolution image bytes.\n- Use get_sentry_resource when starting from a Sentry snapshot URL.\n- The diff percent field shows what percentage of pixels changed (0-100).\n- showUnmodified=true is useful when a diff snapshot has no changed image sections.\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -2125,11 +2081,12 @@ "description": "The numeric snapshot artifact ID." }, "showUnmodified": { + "default": false, "type": "boolean", - "description": "When true, include unchanged and skipped image sections. This can substantially increase response size and token usage for large snapshots.", - "default": false + "description": "When true, include unchanged and skipped image sections. This can substantially increase response size and token usage for large snapshots." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -2138,14 +2095,10 @@ { "type": "null" } - ], - "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.", - "default": null + ] } }, - "required": ["organizationSlug", "snapshotId"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug", "snapshotId"] }, "requiredScopes": ["project:read"], "skills": ["inspect"], @@ -2155,6 +2108,7 @@ "name": "get_snapshot_image", "description": "Get metadata and image content for one image in a preprod snapshot.\n\nUse this tool when you need to:\n- View the current, previous, or diff image for a snapshot entry\n- Inspect metadata and context for a specific snapshot image\n- Fetch full-resolution image bytes when preview images are insufficient; full-resolution images can substantially increase response size and token usage\n\nPass organizationSlug, snapshotId, and imageIdentifier. Use get_sentry_resource for snapshot URLs.\nPreview images are returned by default; set imageResolution=full for original bytes when needed, but expect higher response size and token usage.\n\n\n### View a preview image\n\n```\nget_snapshot_image(organizationSlug=\"sentry\", snapshotId=\"231949\", imageIdentifier=\"login_screen.png\")\n```\n\n### Fetch original full-resolution bytes\n\n```\nget_snapshot_image(organizationSlug=\"sentry\", snapshotId=\"231949\", imageIdentifier=\"login_screen.png\", imageResolution=\"full\")\n```\n\n\n\n- Use get_snapshot first if you need to discover available image file names.\n- Use get_sentry_resource when starting from a Sentry snapshot URL.\n- imageIdentifier values may include slashes; pass the full image_file_name exactly as shown by get_snapshot.\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -2172,12 +2126,13 @@ "description": "The snapshot image file name or identifier to fetch." }, "imageResolution": { + "default": "preview", "type": "string", "enum": ["preview", "full"], - "description": "Return locally generated previews or original full-resolution bytes. Full-resolution images can substantially increase response size and token usage.", - "default": "preview" + "description": "Return locally generated previews or original full-resolution bytes. Full-resolution images can substantially increase response size and token usage." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -2186,14 +2141,10 @@ { "type": "null" } - ], - "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.", - "default": null + ] } }, - "required": ["organizationSlug", "snapshotId", "imageIdentifier"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug", "snapshotId", "imageIdentifier"] }, "requiredScopes": ["project:read"], "skills": ["inspect"], @@ -2203,6 +2154,7 @@ "name": "get_trace_details", "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\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\n\n\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", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -2210,6 +2162,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -2218,9 +2171,7 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "traceId": { "type": "string", @@ -2233,9 +2184,7 @@ "description": "The span ID within a trace. Use this with a trace resource to focus on a specific span." } }, - "required": ["organizationSlug", "traceId"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug", "traceId"] }, "requiredScopes": ["event:read"], "skills": ["inspect"], @@ -2245,6 +2194,7 @@ "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\nremove_team_from_project(organizationSlug='my-organization', projectSlug='my-project', teamSlug='my-team')\n\n\n\n- The team must already be assigned to the project.\n- This tool will not remove the last team assigned to a project.\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -2252,6 +2202,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -2260,9 +2211,7 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "projectSlug": { "type": "string", @@ -2273,9 +2222,7 @@ "description": "The team's slug. You can find a list of existing teams in an organization with the Sentry tool `find_teams`." } }, - "required": ["organizationSlug", "projectSlug", "teamSlug"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug", "projectSlug", "teamSlug"] }, "requiredScopes": ["project:write", "team:read", "org:read"], "skills": ["project-management"], @@ -2285,6 +2232,7 @@ "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\nsearch_ai_conversations(organizationSlug='my-org', query='failed conversations', period='7d')\nsearch_ai_conversations(organizationSlug='my-org', query='checkout', project='backend')\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -2292,77 +2240,76 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "query": { - "type": "string", - "description": "Conversation query/filter string." + "description": "Conversation query/filter string.", + "type": "string" }, "project": { + "description": "Project slug or numeric project ID, or an array of projects.", "anyOf": [ { "type": "string", "description": "The project's slug. You can find a list of existing projects in an organization using the `find_projects()` tool." }, { + "minItems": 1, "type": "array", "items": { "type": "string", "description": "The project's slug. You can find a list of existing projects in an organization using the `find_projects()` tool." - }, - "minItems": 1 + } } - ], - "description": "Project slug or numeric project ID, or an array of projects." + ] }, "environment": { + "description": "Environment name, or an array of environments.", "anyOf": [ { "type": "string", "minLength": 1 }, { + "minItems": 1, "type": "array", "items": { "type": "string", "minLength": 1 - }, - "minItems": 1 + } } - ], - "description": "Environment name, or an array of environments." + ] }, "period": { - "type": "string", - "pattern": "^\\d+[hdw]$", + "default": "30d", "description": "Relative time range. Defaults to 30d.", - "default": "30d" + "type": "string", + "pattern": "^\\d+[hdw]$" }, "start": { - "type": "string", - "description": "Explicit start time for the search window." + "description": "Explicit start time for the search window.", + "type": "string" }, "end": { - "type": "string", - "description": "Explicit end time for the search window." + "description": "Explicit end time for the search window.", + "type": "string" }, "cursor": { - "type": "string", - "description": "Pagination cursor from a previous response." + "description": "Pagination cursor from a previous response.", + "type": "string" }, "limit": { + "default": 10, "type": "integer", "minimum": 1, - "maximum": 100, - "default": 10 + "maximum": 100 }, "regionUrl": { "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." } }, - "required": ["organizationSlug"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug"] }, "outputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -2376,7 +2323,14 @@ "type": "number" }, "nextCursor": { - "type": ["string", "null"] + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] }, "conversations": { "type": "array", @@ -2427,10 +2381,24 @@ } }, "firstInputPreview": { - "type": ["string", "null"] + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] }, "lastOutputPreview": { - "type": ["string", "null"] + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] }, "flow": { "type": "array", @@ -2450,14 +2418,27 @@ "type": "object", "properties": { "email": { - "type": ["string", "null"] + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] }, "username": { - "type": ["string", "null"] + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] } }, - "required": ["email", "username"], - "additionalProperties": false + "required": ["email", "username"] }, { "type": "null" @@ -2484,8 +2465,7 @@ "flow", "toolNames", "user" - ], - "additionalProperties": false + ] } } }, @@ -2495,9 +2475,7 @@ "count", "nextCursor", "conversations" - ], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + ] }, "requiredScopes": ["event:read", "project:read"], "skills": ["inspect", "triage", "seer"], @@ -2507,6 +2485,7 @@ "name": "search_docs", "description": "Search Sentry documentation for SDK setup, instrumentation, and configuration guidance.\n\nUse this tool when you need to:\n- Set up Sentry SDK or framework integrations (Django, Flask, Express, Next.js, etc.)\n- Configure features like performance monitoring, error sampling, or release tracking\n- Implement custom instrumentation (spans, transactions, breadcrumbs)\n- Configure data scrubbing, filtering, or sampling rules\n\nReturns snippets only. Use the Sentry tool `get_doc` to fetch full documentation content.\n\n\n```\nsearch_docs(query='Django setup configuration SENTRY_DSN', guide='python/django')\nsearch_docs(query='source maps webpack upload', guide='javascript/nextjs')\n```\n\n\n\n- Use guide parameter to filter to specific technologies (e.g., 'javascript/nextjs')\n- Include specific feature names like 'beforeSend', 'tracesSampleRate', 'SENTRY_DSN'\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "query": { @@ -2516,11 +2495,11 @@ "description": "The search query in natural language. Be specific about what you're looking for." }, "maxResults": { + "default": 3, + "description": "Maximum number of results to return (1-10)", "type": "integer", "minimum": 1, - "maximum": 10, - "default": 3, - "description": "Maximum number of results to return (1-10)" + "maximum": 10 }, "guide": { "type": "string", @@ -2655,9 +2634,7 @@ "description": "Optional guide filter to limit search results to specific documentation sections. Use either a platform (e.g., 'javascript', 'python') or platform/guide combination (e.g., 'javascript/nextjs', 'python/django')." } }, - "required": ["query"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["query"] }, "requiredScopes": [], "skills": ["inspect", "docs"], @@ -2667,6 +2644,7 @@ "name": "search_events", "description": "Search Sentry events and replays. Use for event counts/statistics.\n\n`query` can be natural language or Sentry search syntax. With an agent configured, it fixes dataset, query, fields, and sort before running.\n\nSupports TWO query types:\n1. AGGREGATIONS (counts, sums, averages): 'how many errors', 'total tokens'\n2. Individual events with timestamps: 'error logs from last hour'\n\nDatasets:\n- errors: Exception/crash events with stack traces, usually grouped into issues\n- logs: Application log entries, including error-severity log messages\n- spans: Raw trace/span events for performance, AI/LLM calls, requests, and operations\n- metrics: Metric rows and aggregates: counters, gauges, distributions, values\n- profiles: Transaction/continuous profile results, profile IDs, profiled transactions\n- replays: Session replay results: rage clicks, dead clicks, visited pages, replay users\nIf the user says logs, log messages, error logs, or warning logs, choose logs instead of errors.\n\nReplay searches return replay lists only; replay count()/avg()/sum() are not supported.\n\nNOT for grouped issue lists (use search_issues) or app screenshots/images (use get_latest_base_snapshot).\n\n\nsearch_events(organizationSlug='my-org', query='how many errors today')\nsearch_events(organizationSlug='my-org', dataset='errors', query='level:error')\nsearch_events(organizationSlug='my-org', dataset='errors', fields=['issue', 'count()'], sort='-count()')\nsearch_events(organizationSlug='my-org', dataset='spans', query='span.op:db', sort='-span.duration')\nsearch_events(organizationSlug='my-org', dataset='replays', query='count_errors:>0', sort='-count_errors')\n\n\n\n- If the user passes a parameter in the form of name/otherName, it's likely in the format of /.\n- Parse org/project notation directly without calling find_organizations or find_projects.\n- Use fields with aggregate functions like count(), avg(), sum() for statistics\n- Sort by -count() for most common, -timestamp for newest\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -2674,15 +2652,16 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "dataset": { + "description": "Initial dataset hint: errors, logs, spans, metrics, profiles, or replays. The agent may correct this when configured.", "type": "string", - "enum": ["spans", "errors", "logs", "metrics", "profiles", "replays"], - "description": "Initial dataset hint: errors, logs, spans, metrics, profiles, or replays. The agent may correct this when configured." + "enum": ["spans", "errors", "logs", "metrics", "profiles", "replays"] }, "query": { - "type": "string", - "description": "Natural language or Sentry event search query syntax." + "description": "Natural language or Sentry event search query syntax.", + "type": "string" }, "fields": { + "description": "Fields to return for event datasets. If not specified, uses sensible defaults. Include aggregate functions like count(), avg() for statistics. Leave null for dataset='replays'.", "anyOf": [ { "type": "array", @@ -2693,10 +2672,10 @@ { "type": "null" } - ], - "description": "Fields to return for event datasets. If not specified, uses sensible defaults. Include aggregate functions like count(), avg() for statistics. Leave null for dataset='replays'." + ] }, "sort": { + "description": "Sort field (prefix with - for descending). If omitted, event datasets default to -timestamp and replays default to -started_at. Use -count() for event aggregations. For dataset='replays', use replay sorts like -started_at or -count_errors.", "anyOf": [ { "type": "string" @@ -2704,10 +2683,10 @@ { "type": "null" } - ], - "description": "Sort field (prefix with - for descending). If omitted, event datasets default to -timestamp and replays default to -started_at. Use -count() for event aggregations. For dataset='replays', use replay sorts like -started_at or -count_errors." + ] }, "projectSlug": { + "default": null, "anyOf": [ { "type": "string", @@ -2716,11 +2695,10 @@ { "type": "null" } - ], - "description": "The project's slug. You can find a list of existing projects in an organization using the `find_projects()` tool.", - "default": null + ] }, "environment": { + "description": "Optional environment filter for dataset='replays'. Use a string for one environment or an array for multiple. For other datasets, filter environment in the query string instead.", "anyOf": [ { "anyOf": [ @@ -2729,20 +2707,19 @@ "minLength": 1 }, { + "minItems": 1, "type": "array", "items": { "type": "string", "minLength": 1 - }, - "minItems": 1 + } } ] }, { "type": "null" } - ], - "description": "Optional environment filter for dataset='replays'. Use a string for one environment or an array for multiple. For other datasets, filter environment in the query string instead." + ] }, "period": { "type": "string", @@ -2750,6 +2727,7 @@ "description": "Relative time window, such as `24h`, `7d`, `14d`, `30d`, or `90d`. Controls which records fall within the search window." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -2758,26 +2736,22 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "limit": { + "default": 10, + "description": "Maximum number of results to return (1-100)", "type": "number", "minimum": 1, - "maximum": 100, - "default": 10, - "description": "Maximum number of results to return (1-100)" + "maximum": 100 }, "includeExplanation": { - "type": "boolean", "default": false, - "description": "Include explanation of how the query was translated or repaired" + "description": "Include explanation of how the query was translated or repaired", + "type": "boolean" } }, - "required": ["organizationSlug"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug"] }, "requiredScopes": ["event:read"], "skills": ["inspect", "triage", "seer"], @@ -2787,9 +2761,12 @@ "name": "search_issue_events", "description": "Search and filter events within a specific issue.\n\nProvide `query` as natural language or Sentry event search syntax. When an embedded agent is configured, it fixes filters, fields, sort, and time range before running.\n\nThe tool automatically constrains results to the specified issue.\n\nCommon Query Filters:\n- environment:production - Filter by environment\n- release:1.0.0 - Filter by release version\n- user.email:alice@example.com - Filter by user\n- trace:TRACE_ID - Filter by trace ID\n\nFor cross-issue searches use search_issues. For single issue or event details use get_sentry_resource.\n\n\nsearch_issue_events(issueId='MCP-41', organizationSlug='my-org', query='from last hour')\nsearch_issue_events(issueId='MCP-41', organizationSlug='my-org', query='environment:production')\nsearch_issue_events(issueUrl='https://sentry.io/.../issues/123/', query='release:v1.0.0', period='7d')\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { + "default": null, + "description": "Organization slug. Required when using issueId. Not needed when using issueUrl.", "anyOf": [ { "type": "string", @@ -2798,26 +2775,24 @@ { "type": "null" } - ], - "description": "Organization slug. Required when using issueId. Not needed when using issueUrl.", - "default": null + ] }, "issueId": { - "type": "string", - "description": "Issue ID (e.g., 'MCP-41', 'PROJECT-123'). Requires organizationSlug. Alternatively, use issueUrl." + "description": "Issue ID (e.g., 'MCP-41', 'PROJECT-123'). Requires organizationSlug. Alternatively, use issueUrl.", + "type": "string" }, "issueUrl": { + "description": "Full Sentry issue URL (e.g., 'https://sentry.io/organizations/my-org/issues/123/'). Includes both organization and issue ID.", "type": "string", - "format": "uri", - "description": "Full Sentry issue URL (e.g., 'https://sentry.io/organizations/my-org/issues/123/'). Includes both organization and issue ID." + "format": "uri" }, "query": { - "type": "string", - "description": "Natural language or Sentry event search query syntax for filtering within the issue." + "description": "Natural language or Sentry event search query syntax for filtering within the issue.", + "type": "string" }, "sort": { - "type": "string", - "description": "Sort field (prefix with - for descending). Default: -timestamp" + "description": "Sort field (prefix with - for descending). Default: -timestamp", + "type": "string" }, "period": { "type": "string", @@ -2825,6 +2800,8 @@ "description": "Relative time window, such as `24h`, `7d`, `14d`, `30d`, or `90d`. Controls which records fall within the search window." }, "projectSlug": { + "default": null, + "description": "Project slug for better tag discovery. Optional - helps find project-specific tags.", "anyOf": [ { "type": "string", @@ -2833,11 +2810,11 @@ { "type": "null" } - ], - "description": "Project slug for better tag discovery. Optional - helps find project-specific tags.", - "default": null + ] }, "regionUrl": { + "default": null, + "description": "Sentry region URL. Optional - defaults to main region.", "anyOf": [ { "type": "string", @@ -2846,25 +2823,21 @@ { "type": "null" } - ], - "description": "Sentry region URL. Optional - defaults to main region.", - "default": null + ] }, "limit": { + "default": 50, + "description": "Maximum number of events to return (1-100, default: 50)", "type": "number", "minimum": 1, - "maximum": 100, - "default": 50, - "description": "Maximum number of events to return (1-100, default: 50)" + "maximum": 100 }, "includeExplanation": { - "type": "boolean", "default": false, - "description": "Include explanation of how the query was translated or repaired" + "description": "Include explanation of how the query was translated or repaired", + "type": "boolean" } - }, - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + } }, "requiredScopes": ["event:read"], "skills": ["inspect", "triage"], @@ -2874,6 +2847,7 @@ "name": "search_issues", "description": "Search for grouped issues/problems in Sentry - returns a LIST of issues, NOT counts or aggregations.\n\nProvide `query` as natural language or Sentry issue search syntax. When an embedded agent is configured, it fixes query and sort before running while preserving explicit Sentry search syntax.\n\nReturns grouped issues with metadata like title, status, and user count.\n\nCommon Query Syntax:\n- is:unresolved / is:resolved / is:ignored / is:for_review / is:new / is:regressed / is:escalating\n- level:error / level:warning\n- firstSeen:-24h / lastSeen:-7d\n- assigned:me / assigned_or_suggested:me\n- release:latest\n- issue.category:feedback\n- issue.priority:high\n- environment:production\n- userCount:>100\n\nDO NOT USE FOR COUNTS/AGGREGATIONS → use search_events\nDO NOT USE FOR individual events with timestamps → use search_events\nDO NOT USE FOR details about a specific issue → use get_sentry_resource\n\n\nsearch_issues(organizationSlug='my-org', query='critical bugs from last week')\nsearch_issues(organizationSlug='my-org', query='is:unresolved is:unassigned', sort='freq')\nsearch_issues(organizationSlug='my-org', query='level:error firstSeen:-24h', projectSlugOrId='my-project')\n\n\n\n- If the user passes a parameter in the form of name/otherName, it's likely in the format of /.\n- Parse org/project notation directly without calling find_organizations or find_projects.\n- The projectSlugOrId parameter accepts both project slugs (e.g., 'my-project') and numeric IDs (e.g., '123456').\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -2881,17 +2855,19 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "query": { - "type": "string", "default": "is:unresolved", - "description": "Natural language or Sentry issue search query syntax." + "description": "Natural language or Sentry issue search query syntax.", + "type": "string" }, "sort": { - "type": "string", - "enum": ["date", "freq", "new", "user"], "default": "date", - "description": "Sort order: date (last seen), freq (frequency), new (first seen), user (user count)" + "description": "Sort order: date (last seen), freq (frequency), new (first seen), user (user count)", + "type": "string", + "enum": ["date", "freq", "new", "user"] }, "projectSlugOrId": { + "default": null, + "description": "The project's slug or numeric ID (optional)", "anyOf": [ { "type": "string" @@ -2899,11 +2875,10 @@ { "type": "null" } - ], - "default": null, - "description": "The project's slug or numeric ID (optional)" + ] }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -2912,32 +2887,28 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "limit": { + "default": 10, + "description": "Maximum number of issues to return (1-100)", "type": "number", "minimum": 1, - "maximum": 100, - "default": 10, - "description": "Maximum number of issues to return (1-100)" + "maximum": 100 }, "period": { - "type": "string", - "enum": ["24h", "7d", "14d", "30d", "90d"], "default": "30d", - "description": "Time window for issue search results. Controls which issues are returned based on when they had activity. Default 30d is a balance between coverage and query performance; use 24h for very recent issues or 90d for broader historical searches." + "description": "Time window for issue search results. Controls which issues are returned based on when they had activity. Default 30d is a balance between coverage and query performance; use 24h for very recent issues or 90d for broader historical searches.", + "type": "string", + "enum": ["24h", "7d", "14d", "30d", "90d"] }, "includeExplanation": { - "type": "boolean", "default": false, - "description": "Include explanation of how the query was translated or repaired" + "description": "Include explanation of how the query was translated or repaired", + "type": "boolean" } }, - "required": ["organizationSlug"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug"] }, "requiredScopes": ["event:read"], "skills": ["inspect", "triage", "seer"], @@ -2947,6 +2918,7 @@ "name": "search_sentry_tools", "description": "Search the available Sentry MCP tool catalog by name and description.\n\nMany Sentry operations are intentionally not exposed as top-level tools. Use this for any Sentry-related task when you do not see an obvious direct tool, including long-tail inspection, project management, documentation lookup, preprod snapshots, attachments, DSNs, releases, teams, and issue-specific pivots.\n\nUse this tool when you need to:\n- Find the right Sentry operation for a task\n- Discover catalog tools and their schemas for a task\n- Inspect the executable JSON input schema for an available tool\n\n\nsearch_sentry_tools(query='list projects')\nsearch_sentry_tools(query='issue details')\nsearch_sentry_tools(query='find dsn', limit=5)\nsearch_sentry_tools(query='snapshot image')\n\n\n\n- Results only include tools available in the current session.\n- If a Sentry operation is not listed as a direct tool, search here before deciding it is unavailable.\n- Returned schemas already account for active organization, project, and region constraints.\n- Use the returned name and schema when executing a catalog result.\n- This tool returns structured JSON. Do not parse markdown from its text content.\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "query": { @@ -2955,6 +2927,8 @@ "description": "Natural language keywords describing the Sentry operation, resource, or workflow to find." }, "limit": { + "default": 8, + "description": "Maximum number of matching tools to return, up to 20.", "anyOf": [ { "type": "integer", @@ -2964,16 +2938,13 @@ { "type": "null" } - ], - "default": 8, - "description": "Maximum number of matching tools to return, up to 20." + ] } }, - "required": ["query"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["query"] }, "outputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "query": { @@ -2992,6 +2963,9 @@ }, "inputSchema": { "type": "object", + "propertyNames": { + "type": "string" + }, "additionalProperties": {}, "description": "JSON Schema for the matching tool's arguments. Session-constrained parameters are omitted." }, @@ -3010,18 +2984,14 @@ "openWorldHint": { "type": "boolean" } - }, - "additionalProperties": false + } } }, - "required": ["name", "description", "inputSchema", "annotations"], - "additionalProperties": false + "required": ["name", "description", "inputSchema", "annotations"] } } }, - "required": ["query", "results"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["query", "results"] }, "requiredScopes": [], "skills": ["inspect", "seer", "docs", "triage", "project-management"], @@ -3031,6 +3001,7 @@ "name": "update_dsn", "description": "Update settings for an existing DSN (client key) in a project, such as name, active status, rate limit, and loader script options.\n\nUSE THIS TOOL WHEN:\n- Deactivating or activating a DSN/client key\n- Setting or removing DSN rate limits ('set rate limit of 1000 per hour on DSN X')\n- Renaming a DSN ('rename DSN X to Production')\n- Configuring Javascript SDK loader script options (session replay, performance, debug, feedback, etc.)\n\nBe careful when using this tool!\n\n\n### Rename DSN and set rate limit\n```\nupdate_dsn(organizationSlug='my-organization', projectSlug='my-project', keyId='d20df0a1ab5031c7f3c7edca9c02814d', name='Production Key', rateLimitWindow=3600, rateLimitCount=500)\n```\n\n### Deactivate a DSN\n```\nupdate_dsn(organizationSlug='my-organization', projectSlug='my-project', keyId='d20df0a1ab5031c7f3c7edca9c02814d', isActive=false)\n```\n\n### Disable rate limit entirely\n```\nupdate_dsn(organizationSlug='my-organization', projectSlug='my-project', keyId='d20df0a1ab5031c7f3c7edca9c02814d', disableRateLimit=true)\n```\n\n\n\n- Use `find_dsns()` first to find the `keyId` for the DSN you want to update.\n- Both `rateLimitWindow` (seconds) and `rateLimitCount` (error cap) must be provided together to set a rate limit.\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -3038,6 +3009,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -3046,9 +3018,7 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "projectSlug": { "type": "string", @@ -3076,6 +3046,7 @@ "rateLimitCount": { "type": "integer", "minimum": 0, + "maximum": 9007199254740991, "description": "The maximum number of errors allowed within the rate limit window." }, "disableRateLimit": { @@ -3107,9 +3078,7 @@ "description": "Configure Logs and Metrics for the Javascript Loader Script (requires SDK >= 10.0.0)." } }, - "required": ["organizationSlug", "projectSlug", "keyId"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug", "projectSlug", "keyId"] }, "requiredScopes": ["project:write"], "skills": ["project-management"], @@ -3119,6 +3088,7 @@ "name": "update_issue", "description": "Update a Sentry issue's status or assignment.\n\nUse this to resolve, reopen, assign, or ignore an issue.\n\n\n```\nupdate_issue(organizationSlug='my-org', issueId='PROJECT-123', status='resolved')\nupdate_issue(organizationSlug='my-org', issueId='PROJECT-123', assignedTo='user:123456')\nupdate_issue(organizationSlug='my-org', issueId='PROJECT-123', status='ignored')\nupdate_issue(organizationSlug='my-org', issueId='PROJECT-123', status='ignored', ignoreMode='forever')\nupdate_issue(organizationSlug='my-org', issueId='PROJECT-123', status='ignored', ignoreMode='untilOccurrenceCount', ignoreCount=100, ignoreWindowMinutes=60)\nupdate_issue(organizationSlug='my-org', issueId='PROJECT-123', status='ignored', reason='Ignoring because this is expected noise from the staging deploy')\n```\n\n\n\n- Provide `issueUrl` or `organizationSlug` + `issueId`.\n- At least one of `status` or `assignedTo` is required.\n- `assignedTo` format: `user:ID` or `team:ID_OR_SLUG`.\n- Use `execute_sentry_tool(name='whoami', arguments={})` to find your user ID for self-assignment.\n- Status values: `resolved`, `resolvedInNextRelease`, `unresolved`, `ignored`.\n- `status='ignored'` defaults to `ignoreMode='untilEscalating'`.\n- Ignore modes: `untilEscalating`, `forever`, `forDuration`, `untilOccurrenceCount`, `untilUserCount`.\n- Matching ignore inputs are `ignoreDurationMinutes`, `ignoreCount` + optional `ignoreWindowMinutes`, or `ignoreUserCount` + optional `ignoreUserWindowMinutes`.\n- To switch an already ignored issue between `untilEscalating`, `forever`, and condition-based ignore modes, first set `status='unresolved'`, then ignore it again with the new rule.\n- `reason` is optional. When provided, it will be posted as a comment on the issue's activity feed explaining why the action was taken.\n", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -3126,6 +3096,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -3134,9 +3105,7 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "issueId": { "type": "string", @@ -3175,11 +3144,13 @@ "ignoreDurationMinutes": { "type": "integer", "exclusiveMinimum": 0, + "maximum": 9007199254740991, "description": "How many minutes to ignore the issue when ignoreMode is 'forDuration'." }, "ignoreCount": { "type": "integer", "exclusiveMinimum": 0, + "maximum": 9007199254740991, "description": "How many times the issue must occur before it stops being ignored when ignoreMode is 'untilOccurrenceCount'." }, "ignoreWindowMinutes": { @@ -3191,6 +3162,7 @@ "ignoreUserCount": { "type": "integer", "exclusiveMinimum": 0, + "maximum": 9007199254740991, "description": "How many users must be affected before the issue stops being ignored when ignoreMode is 'untilUserCount'." }, "ignoreUserWindowMinutes": { @@ -3204,9 +3176,7 @@ "minLength": 1, "description": "Optional reason for taking this action. When provided, it will be posted as a comment on the issue's activity feed." } - }, - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + } }, "requiredScopes": ["event:write"], "skills": ["triage"], @@ -3216,6 +3186,7 @@ "name": "update_project", "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\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\n\n\n- If the user passes a parameter in the form of name/otherName, it's likely in the format of /.\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", "inputSchema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -3223,6 +3194,7 @@ "description": "The organization's slug. You can find a existing list of organizations you have access to using the `find_organizations()` tool." }, "regionUrl": { + "default": null, "anyOf": [ { "type": "string", @@ -3231,15 +3203,14 @@ { "type": "null" } - ], - "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.", - "default": null + ] }, "projectSlug": { "type": "string", "description": "The project's slug. You can find a list of existing projects in an organization using the `find_projects()` tool." }, "name": { + "default": null, "anyOf": [ { "type": "string", @@ -3248,11 +3219,10 @@ { "type": "null" } - ], - "description": "The new name for the project", - "default": null + ] }, "slug": { + "default": null, "anyOf": [ { "type": "string", @@ -3261,11 +3231,10 @@ { "type": "null" } - ], - "description": "The new slug for the project (must be unique)", - "default": null + ] }, "platform": { + "default": null, "anyOf": [ { "type": "string", @@ -3274,14 +3243,10 @@ { "type": "null" } - ], - "description": "The platform for the project. e.g., python, javascript, react, etc.", - "default": null + ] } }, - "required": ["organizationSlug", "projectSlug"], - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" + "required": ["organizationSlug", "projectSlug"] }, "requiredScopes": ["project:write"], "skills": ["project-management"], diff --git a/packages/mcp-core/src/tools/catalog-runtime/schema.ts b/packages/mcp-core/src/tools/catalog-runtime/schema.ts index 7da387357..4ea5060e2 100644 --- a/packages/mcp-core/src/tools/catalog-runtime/schema.ts +++ b/packages/mcp-core/src/tools/catalog-runtime/schema.ts @@ -1,5 +1,4 @@ import { z, type ZodTypeAny } from "zod"; -import { zodToJsonSchema } from "zod-to-json-schema"; export function zodFieldMapToJsonSchema( fieldMap: Record, @@ -7,9 +6,8 @@ export function zodFieldMapToJsonSchema( const zodObject = Object.keys(fieldMap).length > 0 ? z.object(fieldMap) : z.object({}); - return zodToJsonSchema(zodObject, { - $refStrategy: "none", - strictUnions: true, - pipeStrategy: "input", + return z.toJSONSchema(zodObject, { + io: "input", + unrepresentable: "any", }) as Record; } diff --git a/packages/mcp-core/src/tools/special/execute-tool.ts b/packages/mcp-core/src/tools/special/execute-tool.ts index 95108b273..6030ebb06 100644 --- a/packages/mcp-core/src/tools/special/execute-tool.ts +++ b/packages/mcp-core/src/tools/special/execute-tool.ts @@ -98,7 +98,7 @@ export function createExecuteTool(getTools: () => ToolRegistry) { .min(1) .describe("The name of the available tool to execute."), arguments: z - .record(z.unknown()) + .record(z.string(), z.unknown()) .default({}) .describe( "Arguments for the target tool, matching the schema returned by search_sentry_tools.", diff --git a/packages/mcp-core/src/tools/special/search-tools.ts b/packages/mcp-core/src/tools/special/search-tools.ts index ec291119e..a98e81982 100644 --- a/packages/mcp-core/src/tools/special/search-tools.ts +++ b/packages/mcp-core/src/tools/special/search-tools.ts @@ -24,7 +24,7 @@ export const searchToolsOutputSchema = z.object({ name: z.string(), description: z.string(), inputSchema: z - .record(z.unknown()) + .record(z.string(), z.unknown()) .describe( "JSON Schema for the matching tool's arguments. Session-constrained parameters are omitted.", ), diff --git a/packages/mcp-server-evals/src/evals/utils/toolPredictionScorer.ts b/packages/mcp-server-evals/src/evals/utils/toolPredictionScorer.ts index c1104787f..d199bebc7 100644 --- a/packages/mcp-server-evals/src/evals/utils/toolPredictionScorer.ts +++ b/packages/mcp-server-evals/src/evals/utils/toolPredictionScorer.ts @@ -73,7 +73,7 @@ const predictionSchema = z.object({ .array( z.object({ name: z.string(), - arguments: z.record(z.any()).optional().default({}), + arguments: z.record(z.string(), z.any()).optional().default({}), }), ) .describe("What tools the AI would likely call"), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2bb5fb86d..430657e6d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -169,11 +169,8 @@ catalogs: specifier: 0.1.0-3 version: 0.1.0-3 zod: - specifier: ^3.25.67 - version: 3.25.76 - zod-to-json-schema: - specifier: ^3.24.6 - version: 3.25.0 + specifier: ^4.4.3 + version: 4.4.3 overrides: '@modelcontextprotocol/sdk': ^1.26.0 @@ -257,19 +254,19 @@ importers: dependencies: '@ai-sdk/mcp': specifier: 'catalog:' - version: 1.0.16(zod@3.25.76) + version: 1.0.16(zod@4.4.3) '@ai-sdk/openai': specifier: 'catalog:' - version: 3.0.23(zod@3.25.76) + version: 3.0.23(zod@4.4.3) '@ai-sdk/react': specifier: 'catalog:' - version: 3.0.66(react@19.1.0)(zod@3.25.76) + version: 3.0.66(react@19.1.0)(zod@4.4.3) '@cloudflare/workers-oauth-provider': specifier: 'catalog:' version: 0.3.0 '@modelcontextprotocol/sdk': specifier: ^1.26.0 - version: 1.26.0(@cfworker/json-schema@4.1.1)(zod@3.25.76) + version: 1.26.0(@cfworker/json-schema@4.1.1)(zod@4.4.3) '@radix-ui/react-accordion': specifier: 'catalog:' version: 1.2.11(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -284,10 +281,10 @@ importers: version: 10.54.0(react@19.1.0) agents: specifier: 'catalog:' - version: 0.3.10(@ai-sdk/openai@3.0.23(zod@3.25.76))(@ai-sdk/react@3.0.66(react@19.1.0)(zod@3.25.76))(@cloudflare/ai-chat@0.0.4)(@cloudflare/codemode@0.3.4(@modelcontextprotocol/sdk@1.26.0(@cfworker/json-schema@4.1.1)(zod@3.25.76))(ai@6.0.64(zod@3.25.76))(zod@3.25.76))(@cloudflare/workers-types@4.20260405.1)(ai@6.0.64(zod@3.25.76))(react@19.1.0)(zod@3.25.76) + version: 0.3.10(@ai-sdk/openai@3.0.23(zod@4.4.3))(@ai-sdk/react@3.0.66(react@19.1.0)(zod@4.4.3))(@cloudflare/ai-chat@0.0.4)(@cloudflare/codemode@0.3.4(@modelcontextprotocol/sdk@1.26.0(@cfworker/json-schema@4.1.1)(zod@4.4.3))(ai@6.0.64(zod@4.4.3))(zod@4.4.3))(@cloudflare/workers-types@4.20260405.1)(ai@6.0.64(zod@4.4.3))(react@19.1.0)(zod@4.4.3) ai: specifier: 'catalog:' - version: 6.0.64(zod@3.25.76) + version: 6.0.64(zod@4.4.3) asciinema-player: specifier: ^3.10.0 version: 3.12.1 @@ -332,10 +329,10 @@ importers: version: 1.3.5 workers-mcp: specifier: 'catalog:' - version: 0.1.0-3(@cfworker/json-schema@4.1.1)(zod@3.25.76) + version: 0.1.0-3(@cfworker/json-schema@4.1.1)(zod@4.4.3) zod: specifier: 'catalog:' - version: 3.25.76 + version: 4.4.3 devDependencies: '@cloudflare/vite-plugin': specifier: ^1.13.15 @@ -399,13 +396,13 @@ importers: dependencies: '@ai-sdk/anthropic': specifier: 'catalog:' - version: 3.0.33(zod@3.25.76) + version: 3.0.33(zod@4.4.3) '@ai-sdk/mcp': specifier: 'catalog:' - version: 1.0.16(zod@3.25.76) + version: 1.0.16(zod@4.4.3) '@ai-sdk/openai': specifier: 'catalog:' - version: 3.0.23(zod@3.25.76) + version: 3.0.23(zod@4.4.3) '@logtape/logtape': specifier: ^1.1.1 version: 1.1.1 @@ -414,13 +411,13 @@ importers: version: 1.1.1(@logtape/logtape@1.1.1) '@modelcontextprotocol/sdk': specifier: ^1.26.0 - version: 1.26.0(@cfworker/json-schema@4.1.1)(zod@3.25.76) + version: 1.26.0(@cfworker/json-schema@4.1.1)(zod@4.4.3) '@sentry/core': specifier: 'catalog:' version: 10.54.0 ai: specifier: 'catalog:' - version: 6.0.64(zod@3.25.76) + version: 6.0.64(zod@4.4.3) dotenv: specifier: 'catalog:' version: 16.6.1 @@ -432,14 +429,14 @@ importers: version: 0.4.4 zod: specifier: 'catalog:' - version: 3.25.76 + version: 4.4.3 devDependencies: '@ai-sdk/provider': specifier: ^3.0.6 version: 3.0.6 '@ai-sdk/provider-utils': specifier: ^4.0.11 - version: 4.0.11(zod@3.25.76) + version: 4.0.11(zod@4.4.3) '@sentry/mcp-server-mocks': specifier: workspace:* version: link:../mcp-server-mocks @@ -455,15 +452,12 @@ importers: yaml: specifier: ^2.8.3 version: 2.8.3 - zod-to-json-schema: - specifier: 'catalog:' - version: 3.25.0(zod@3.25.76) packages/mcp-server: dependencies: '@modelcontextprotocol/sdk': specifier: ^1.26.0 - version: 1.26.0(@cfworker/json-schema@4.1.1)(zod@3.25.76) + version: 1.26.0(@cfworker/json-schema@4.1.1)(zod@4.4.3) '@sentry/core': specifier: 'catalog:' version: 10.54.0 @@ -475,7 +469,7 @@ importers: version: 16.6.1 zod: specifier: 'catalog:' - version: 3.25.76 + version: 4.4.3 devDependencies: '@sentry/mcp-core': specifier: workspace:* @@ -506,13 +500,13 @@ importers: dependencies: '@ai-sdk/mcp': specifier: 'catalog:' - version: 1.0.16(zod@3.25.76) + version: 1.0.16(zod@4.4.3) '@ai-sdk/openai': specifier: 'catalog:' - version: 3.0.23(zod@3.25.76) + version: 3.0.23(zod@4.4.3) '@modelcontextprotocol/sdk': specifier: ^1.26.0 - version: 1.26.0(@cfworker/json-schema@4.1.1)(zod@3.25.76) + version: 1.26.0(@cfworker/json-schema@4.1.1)(zod@4.4.3) '@sentry/mcp-core': specifier: workspace:* version: link:../mcp-core @@ -527,7 +521,7 @@ importers: version: link:../mcp-server-tsconfig ai: specifier: 'catalog:' - version: 6.0.64(zod@3.25.76) + version: 6.0.64(zod@4.4.3) dotenv: specifier: 'catalog:' version: 16.6.1 @@ -545,7 +539,7 @@ importers: version: 0.4.0(tinyrainbow@3.1.0)(vitest@4.1.2(@opentelemetry/api@1.9.1)(@types/node@24.0.10)(msw@2.10.2(@types/node@24.0.10)(typescript@5.8.3))(vite@6.3.5(@types/node@24.0.10)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.20.3)(yaml@2.8.3))) zod: specifier: 'catalog:' - version: 3.25.76 + version: 4.4.3 packages/mcp-server-mocks: dependencies: @@ -566,13 +560,13 @@ importers: dependencies: '@ai-sdk/mcp': specifier: 'catalog:' - version: 1.0.16(zod@3.25.76) + version: 1.0.16(zod@4.4.3) '@ai-sdk/openai': specifier: 'catalog:' - version: 3.0.23(zod@3.25.76) + version: 3.0.23(zod@4.4.3) '@modelcontextprotocol/sdk': specifier: ^1.26.0 - version: 1.26.0(@cfworker/json-schema@4.1.1)(zod@3.25.76) + version: 1.26.0(@cfworker/json-schema@4.1.1)(zod@4.4.3) '@sentry/core': specifier: 'catalog:' version: 10.54.0 @@ -584,7 +578,7 @@ importers: version: 10.54.0 ai: specifier: 'catalog:' - version: 6.0.64(zod@3.25.76) + version: 6.0.64(zod@4.4.3) chalk: specifier: 'catalog:' version: 5.4.1 @@ -599,7 +593,7 @@ importers: version: 10.1.2 zod: specifier: 'catalog:' - version: 3.25.76 + version: 4.4.3 devDependencies: tsdown: specifier: 'catalog:' @@ -690,12 +684,14 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] '@ast-grep/cli-linux-x64-gnu@0.43.0': resolution: {integrity: sha512-r/o9Mag6OZmGevY9OJjatuUKDOX1rSvgo29qSfxpMbIciiH3hkzEW/2w1xTPZI8xnM7iC+k+CkGoknmoXVTYGg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] '@ast-grep/cli-win32-arm64-msvc@0.43.0': resolution: {integrity: sha512-oHa4ruD87xccnqFuR+Pmx6F/suHV0YtibuyZ6SxUqgpNJAFZiUNAiFblzhEgQ5gp03e8B012P/Yy/7GYOvxOLg==} @@ -837,24 +833,28 @@ packages: engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] + libc: [musl] '@biomejs/cli-linux-arm64@1.9.4': resolution: {integrity: sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] + libc: [glibc] '@biomejs/cli-linux-x64-musl@1.9.4': resolution: {integrity: sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] + libc: [musl] '@biomejs/cli-linux-x64@1.9.4': resolution: {integrity: sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] + libc: [glibc] '@biomejs/cli-win32-arm64@1.9.4': resolution: {integrity: sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==} @@ -1427,155 +1427,183 @@ packages: resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-arm64@1.2.4': resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-arm@1.0.5': resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-arm@1.2.4': resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-ppc64@1.2.4': resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-riscv64@1.2.4': resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} cpu: [riscv64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-s390x@1.0.4': resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-s390x@1.2.4': resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-x64@1.0.4': resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-x64@1.2.4': resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linuxmusl-arm64@1.0.4': resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-libvips-linuxmusl-arm64@1.2.4': resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-libvips-linuxmusl-x64@1.0.4': resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-libvips-linuxmusl-x64@1.2.4': resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-linux-arm64@0.33.5': resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-linux-arm64@0.34.5': resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-linux-arm@0.33.5': resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-linux-arm@0.34.5': resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-linux-ppc64@0.34.5': resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ppc64] os: [linux] + libc: [glibc] '@img/sharp-linux-riscv64@0.34.5': resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [riscv64] os: [linux] + libc: [glibc] '@img/sharp-linux-s390x@0.33.5': resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-linux-s390x@0.34.5': resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-linux-x64@0.33.5': resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-linux-x64@0.34.5': resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-linuxmusl-arm64@0.33.5': resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-linuxmusl-arm64@0.34.5': resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-linuxmusl-x64@0.33.5': resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-linuxmusl-x64@0.34.5': resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-wasm32@0.33.5': resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} @@ -1959,21 +1987,25 @@ packages: resolution: {integrity: sha512-PFBBnj9JqLOL8gjZtoVGfOXe0PSpnPUXE+JuMcWz568K/p4Zzk7lDDHl7guD95wVtV89TmfaRwK2PWd9vKxHtg==} cpu: [arm64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-arm64-musl@1.0.0-beta.23': resolution: {integrity: sha512-KyQRLofVP78yUCXT90YmEzxK6I9VCBeOTSyOrs40Qx0Q0XwaGVwxo7sKj2SmnqxribdcouBA3CfNZC4ZNcyEnQ==} cpu: [arm64] os: [linux] + libc: [musl] '@rolldown/binding-linux-x64-gnu@1.0.0-beta.23': resolution: {integrity: sha512-EubfEsJyjQbKK9j3Ez1hhbIOsttABb07Z7PhMRcVYW0wrVr8SfKLew9pULIMfcSNnoz8QqzoI4lOSmezJ9bYWw==} cpu: [x64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-x64-musl@1.0.0-beta.23': resolution: {integrity: sha512-MUAthvl3I/+hySltZuj5ClKiq8fAMqExeBnxadLFShwWCbdHKFd+aRjBxxzarPcnqbDlTaOCUaAaYmQTOTOHSg==} cpu: [x64] os: [linux] + libc: [musl] '@rolldown/binding-wasm32-wasi@1.0.0-beta.23': resolution: {integrity: sha512-YI7QMQU01QFVNTEaQt3ysrq+wGBwLdFVFEGO64CoZ3gTsr/HulU8gvgR+67coQOlQC9iO/Hm1bvkBtceLxKrnA==} @@ -2035,56 +2067,67 @@ packages: resolution: {integrity: sha512-n0edDmSHlXFhrlmTK7XBuwKlG5MbS7yleS1cQ9nn4kIeW+dJH+ExqNgQ0RrFRew8Y+0V/x6C5IjsHrJmiHtkxQ==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.44.1': resolution: {integrity: sha512-8WVUPy3FtAsKSpyk21kV52HCxB+me6YkbkFHATzC2Yd3yuqHwy2lbFL4alJOLXKljoRw08Zk8/xEj89cLQ/4Nw==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.44.1': resolution: {integrity: sha512-yuktAOaeOgorWDeFJggjuCkMGeITfqvPgkIXhDqsfKX8J3jGyxdDZgBV/2kj/2DyPaLiX6bPdjJDTu9RB8lUPQ==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.44.1': resolution: {integrity: sha512-W+GBM4ifET1Plw8pdVaecwUgxmiH23CfAUj32u8knq0JPFyK4weRy6H7ooxYFD19YxBulL0Ktsflg5XS7+7u9g==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loongarch64-gnu@4.44.1': resolution: {integrity: sha512-1zqnUEMWp9WrGVuVak6jWTl4fEtrVKfZY7CvcBmUUpxAJ7WcSowPSAWIKa/0o5mBL/Ij50SIf9tuirGx63Ovew==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-powerpc64le-gnu@4.44.1': resolution: {integrity: sha512-Rl3JKaRu0LHIx7ExBAAnf0JcOQetQffaw34T8vLlg9b1IhzcBgaIdnvEbbsZq9uZp3uAH+JkHd20Nwn0h9zPjA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-gnu@4.44.1': resolution: {integrity: sha512-j5akelU3snyL6K3N/iX7otLBIl347fGwmd95U5gS/7z6T4ftK288jKq3A5lcFKcx7wwzb5rgNvAg3ZbV4BqUSw==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.44.1': resolution: {integrity: sha512-ppn5llVGgrZw7yxbIm8TTvtj1EoPgYUAbfw0uDjIOzzoqlZlZrLJ/KuiE7uf5EpTpCTrNt1EdtzF0naMm0wGYg==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.44.1': resolution: {integrity: sha512-Hu6hEdix0oxtUma99jSP7xbvjkUM/ycke/AQQ4EC5g7jNRLLIwjcNwaUy95ZKBJJwg1ZowsclNnjYqzN4zwkAw==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.44.1': resolution: {integrity: sha512-EtnsrmZGomz9WxK1bR5079zee3+7a+AdFlghyd6VbAjgRJDbTANJ9dcPIPAi76uG05micpEL+gPGmAKYTschQw==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.44.1': resolution: {integrity: sha512-iAS4p+J1az6Usn0f8xhgL4PaU878KEtutP4hqw52I4IO6AGoyOkHCxcc4bqufv1tQLdDWFx8lR9YlwxKuv3/3g==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-win32-arm64-msvc@4.44.1': resolution: {integrity: sha512-NtSJVKcXwcqozOl+FwI41OH3OApDyLk3kqTJgx8+gp6On9ZEt5mYhIsKNPGuaZr3p9T6NWPKGU/03Vw4CNU9qg==} @@ -2311,24 +2354,28 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-arm64-musl@4.1.11': resolution: {integrity: sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] '@tailwindcss/oxide-linux-x64-gnu@4.1.11': resolution: {integrity: sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-x64-musl@4.1.11': resolution: {integrity: sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] '@tailwindcss/oxide-wasm32-wasi@4.1.11': resolution: {integrity: sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==} @@ -3526,24 +3573,28 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-musl@1.30.1: resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-x64-gnu@1.30.1: resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-musl@1.30.1: resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-win32-arm64-msvc@1.30.1: resolution: {integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==} @@ -5005,11 +5056,6 @@ packages: youch@4.1.0-beta.10: resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==} - zod-to-json-schema@3.25.0: - resolution: {integrity: sha512-HvWtU2UG41LALjajJrML6uQejQhNJx+JBO9IflpSja4R03iNWfKXrj6W2h7ljuLyc1nKS+9yDyL/9tD1U/yBnQ==} - peerDependencies: - zod: ^3.25 || ^4 - zod-to-json-schema@3.25.1: resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} peerDependencies: @@ -5021,52 +5067,55 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod@4.4.3: + resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} + zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} snapshots: - '@ai-sdk/anthropic@3.0.33(zod@3.25.76)': + '@ai-sdk/anthropic@3.0.33(zod@4.4.3)': dependencies: '@ai-sdk/provider': 3.0.6 - '@ai-sdk/provider-utils': 4.0.11(zod@3.25.76) - zod: 3.25.76 + '@ai-sdk/provider-utils': 4.0.11(zod@4.4.3) + zod: 4.4.3 - '@ai-sdk/gateway@3.0.29(zod@3.25.76)': + '@ai-sdk/gateway@3.0.29(zod@4.4.3)': dependencies: '@ai-sdk/provider': 3.0.6 - '@ai-sdk/provider-utils': 4.0.11(zod@3.25.76) + '@ai-sdk/provider-utils': 4.0.11(zod@4.4.3) '@vercel/oidc': 3.1.0 - zod: 3.25.76 + zod: 4.4.3 - '@ai-sdk/mcp@1.0.16(zod@3.25.76)': + '@ai-sdk/mcp@1.0.16(zod@4.4.3)': dependencies: '@ai-sdk/provider': 3.0.6 - '@ai-sdk/provider-utils': 4.0.11(zod@3.25.76) + '@ai-sdk/provider-utils': 4.0.11(zod@4.4.3) pkce-challenge: 5.0.0 - zod: 3.25.76 + zod: 4.4.3 - '@ai-sdk/openai@3.0.23(zod@3.25.76)': + '@ai-sdk/openai@3.0.23(zod@4.4.3)': dependencies: '@ai-sdk/provider': 3.0.6 - '@ai-sdk/provider-utils': 4.0.11(zod@3.25.76) - zod: 3.25.76 + '@ai-sdk/provider-utils': 4.0.11(zod@4.4.3) + zod: 4.4.3 - '@ai-sdk/provider-utils@4.0.11(zod@3.25.76)': + '@ai-sdk/provider-utils@4.0.11(zod@4.4.3)': dependencies: '@ai-sdk/provider': 3.0.6 '@standard-schema/spec': 1.1.0 eventsource-parser: 3.0.6 - zod: 3.25.76 + zod: 4.4.3 '@ai-sdk/provider@3.0.6': dependencies: json-schema: 0.4.0 - '@ai-sdk/react@3.0.66(react@19.1.0)(zod@3.25.76)': + '@ai-sdk/react@3.0.66(react@19.1.0)(zod@4.4.3)': dependencies: - '@ai-sdk/provider-utils': 4.0.11(zod@3.25.76) - ai: 6.0.64(zod@3.25.76) + '@ai-sdk/provider-utils': 4.0.11(zod@4.4.3) + ai: 6.0.64(zod@4.4.3) react: 19.1.0 swr: 2.3.4(react@19.1.0) throttleit: 2.1.0 @@ -5138,7 +5187,7 @@ snapshots: '@babel/traverse': 7.28.0 '@babel/types': 7.28.0 convert-source-map: 2.0.0 - debug: 4.4.1 + debug: 4.4.3 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -5230,7 +5279,7 @@ snapshots: '@babel/parser': 7.28.0 '@babel/template': 7.27.2 '@babel/types': 7.28.0 - debug: 4.4.1 + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -5300,21 +5349,21 @@ snapshots: picocolors: 1.1.1 sisteransi: 1.0.5 - '@cloudflare/ai-chat@0.0.4(agents@0.3.10)(ai@6.0.64(zod@3.25.76))(react@19.1.0)(zod@3.25.76)': + '@cloudflare/ai-chat@0.0.4(agents@0.3.10)(ai@6.0.64(zod@4.4.3))(react@19.1.0)(zod@4.4.3)': dependencies: - agents: 0.3.10(@ai-sdk/openai@3.0.23(zod@3.25.76))(@ai-sdk/react@3.0.66(react@19.1.0)(zod@3.25.76))(@cloudflare/ai-chat@0.0.4)(@cloudflare/codemode@0.3.4(@modelcontextprotocol/sdk@1.26.0(@cfworker/json-schema@4.1.1)(zod@3.25.76))(ai@6.0.64(zod@3.25.76))(zod@3.25.76))(@cloudflare/workers-types@4.20260405.1)(ai@6.0.64(zod@3.25.76))(react@19.1.0)(zod@3.25.76) - ai: 6.0.64(zod@3.25.76) + agents: 0.3.10(@ai-sdk/openai@3.0.23(zod@4.4.3))(@ai-sdk/react@3.0.66(react@19.1.0)(zod@4.4.3))(@cloudflare/ai-chat@0.0.4)(@cloudflare/codemode@0.3.4(@modelcontextprotocol/sdk@1.26.0(@cfworker/json-schema@4.1.1)(zod@4.4.3))(ai@6.0.64(zod@4.4.3))(zod@4.4.3))(@cloudflare/workers-types@4.20260405.1)(ai@6.0.64(zod@4.4.3))(react@19.1.0)(zod@4.4.3) + ai: 6.0.64(zod@4.4.3) react: 19.1.0 - zod: 3.25.76 + zod: 4.4.3 - '@cloudflare/codemode@0.3.4(@modelcontextprotocol/sdk@1.26.0(@cfworker/json-schema@4.1.1)(zod@3.25.76))(ai@6.0.64(zod@3.25.76))(zod@3.25.76)': + '@cloudflare/codemode@0.3.4(@modelcontextprotocol/sdk@1.26.0(@cfworker/json-schema@4.1.1)(zod@4.4.3))(ai@6.0.64(zod@4.4.3))(zod@4.4.3)': dependencies: '@types/json-schema': 7.0.15 acorn: 8.16.0 optionalDependencies: - '@modelcontextprotocol/sdk': 1.26.0(@cfworker/json-schema@4.1.1)(zod@3.25.76) - ai: 6.0.64(zod@3.25.76) - zod: 3.25.76 + '@modelcontextprotocol/sdk': 1.26.0(@cfworker/json-schema@4.1.1)(zod@4.4.3) + ai: 6.0.64(zod@4.4.3) + zod: 4.4.3 '@cloudflare/kv-asset-handler@0.4.2': {} @@ -5873,7 +5922,7 @@ snapshots: '@jridgewell/gen-mapping@0.3.12': dependencies: - '@jridgewell/sourcemap-codec': 1.5.4 + '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping': 0.3.29 '@jridgewell/resolve-uri@3.1.2': {} @@ -5885,7 +5934,7 @@ snapshots: '@jridgewell/trace-mapping@0.3.29': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.4 + '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping@0.3.9': dependencies: @@ -5905,7 +5954,7 @@ snapshots: '@logtape/logtape': 1.1.1 '@sentry/core': 9.34.0 - '@modelcontextprotocol/sdk@1.26.0(@cfworker/json-schema@4.1.1)(zod@3.25.76)': + '@modelcontextprotocol/sdk@1.26.0(@cfworker/json-schema@4.1.1)(zod@4.4.3)': dependencies: '@hono/node-server': 1.19.9(hono@4.11.4) ajv: 8.17.1 @@ -5922,8 +5971,8 @@ snapshots: json-schema-typed: 8.0.2 pkce-challenge: 5.0.0 raw-body: 3.0.1 - zod: 3.25.76 - zod-to-json-schema: 3.25.1(zod@3.25.76) + zod: 4.4.3 + zod-to-json-schema: 3.25.1(zod@4.4.3) optionalDependencies: '@cfworker/json-schema': 4.1.1 transitivePeerDependencies: @@ -6701,13 +6750,13 @@ snapshots: transitivePeerDependencies: - supports-color - agents@0.3.10(@ai-sdk/openai@3.0.23(zod@3.25.76))(@ai-sdk/react@3.0.66(react@19.1.0)(zod@3.25.76))(@cloudflare/ai-chat@0.0.4)(@cloudflare/codemode@0.3.4(@modelcontextprotocol/sdk@1.26.0(@cfworker/json-schema@4.1.1)(zod@3.25.76))(ai@6.0.64(zod@3.25.76))(zod@3.25.76))(@cloudflare/workers-types@4.20260405.1)(ai@6.0.64(zod@3.25.76))(react@19.1.0)(zod@3.25.76): + agents@0.3.10(@ai-sdk/openai@3.0.23(zod@4.4.3))(@ai-sdk/react@3.0.66(react@19.1.0)(zod@4.4.3))(@cloudflare/ai-chat@0.0.4)(@cloudflare/codemode@0.3.4(@modelcontextprotocol/sdk@1.26.0(@cfworker/json-schema@4.1.1)(zod@4.4.3))(ai@6.0.64(zod@4.4.3))(zod@4.4.3))(@cloudflare/workers-types@4.20260405.1)(ai@6.0.64(zod@4.4.3))(react@19.1.0)(zod@4.4.3): dependencies: '@cfworker/json-schema': 4.1.1 - '@cloudflare/ai-chat': 0.0.4(agents@0.3.10)(ai@6.0.64(zod@3.25.76))(react@19.1.0)(zod@3.25.76) - '@cloudflare/codemode': 0.3.4(@modelcontextprotocol/sdk@1.26.0(@cfworker/json-schema@4.1.1)(zod@3.25.76))(ai@6.0.64(zod@3.25.76))(zod@3.25.76) - '@modelcontextprotocol/sdk': 1.26.0(@cfworker/json-schema@4.1.1)(zod@3.25.76) - ai: 6.0.64(zod@3.25.76) + '@cloudflare/ai-chat': 0.0.4(agents@0.3.10)(ai@6.0.64(zod@4.4.3))(react@19.1.0)(zod@4.4.3) + '@cloudflare/codemode': 0.3.4(@modelcontextprotocol/sdk@1.26.0(@cfworker/json-schema@4.1.1)(zod@4.4.3))(ai@6.0.64(zod@4.4.3))(zod@4.4.3) + '@modelcontextprotocol/sdk': 1.26.0(@cfworker/json-schema@4.1.1)(zod@4.4.3) + ai: 6.0.64(zod@4.4.3) cron-schedule: 6.0.0 escape-html: 1.0.3 json-schema: 0.4.0 @@ -6718,21 +6767,21 @@ snapshots: partysocket: 1.1.11 react: 19.1.0 yargs: 18.0.0 - zod: 3.25.76 + zod: 4.4.3 optionalDependencies: - '@ai-sdk/openai': 3.0.23(zod@3.25.76) - '@ai-sdk/react': 3.0.66(react@19.1.0)(zod@3.25.76) + '@ai-sdk/openai': 3.0.23(zod@4.4.3) + '@ai-sdk/react': 3.0.66(react@19.1.0)(zod@4.4.3) transitivePeerDependencies: - '@cloudflare/workers-types' - supports-color - ai@6.0.64(zod@3.25.76): + ai@6.0.64(zod@4.4.3): dependencies: - '@ai-sdk/gateway': 3.0.29(zod@3.25.76) + '@ai-sdk/gateway': 3.0.29(zod@4.4.3) '@ai-sdk/provider': 3.0.6 - '@ai-sdk/provider-utils': 4.0.11(zod@3.25.76) + '@ai-sdk/provider-utils': 4.0.11(zod@4.4.3) '@opentelemetry/api': 1.9.0 - zod: 3.25.76 + zod: 4.4.3 ajv-formats@3.0.1(ajv@8.17.1): optionalDependencies: @@ -7681,7 +7730,7 @@ snapshots: lightningcss@1.30.1: dependencies: - detect-libc: 2.0.4 + detect-libc: 2.1.2 optionalDependencies: lightningcss-darwin-arm64: 1.30.1 lightningcss-darwin-x64: 1.30.1 @@ -9553,10 +9602,10 @@ snapshots: '@cloudflare/workerd-linux-arm64': 1.20260401.1 '@cloudflare/workerd-windows-64': 1.20260401.1 - workers-mcp@0.1.0-3(@cfworker/json-schema@4.1.1)(zod@3.25.76): + workers-mcp@0.1.0-3(@cfworker/json-schema@4.1.1)(zod@4.4.3): dependencies: '@clack/prompts': 0.8.2 - '@modelcontextprotocol/sdk': 1.26.0(@cfworker/json-schema@4.1.1)(zod@3.25.76) + '@modelcontextprotocol/sdk': 1.26.0(@cfworker/json-schema@4.1.1)(zod@4.4.3) '@silvia-odwyer/photon-node': 0.3.4 chalk: 5.4.1 fs-extra: 11.3.0 @@ -9671,16 +9720,14 @@ snapshots: cookie: 1.0.2 youch-core: 0.3.3 - zod-to-json-schema@3.25.0(zod@3.25.76): + zod-to-json-schema@3.25.1(zod@4.4.3): dependencies: - zod: 3.25.76 - - zod-to-json-schema@3.25.1(zod@3.25.76): - dependencies: - zod: 3.25.76 + zod: 4.4.3 zod@3.22.3: {} zod@3.25.76: {} + zod@4.4.3: {} + zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 64a214fcb..6bb6fc242 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -80,5 +80,4 @@ catalog: vitest-evals: ^0.4.0 workers-mcp: 0.1.0-3 wrangler: 4.80.0 - zod: ^3.25.67 - zod-to-json-schema: ^3.24.6 + zod: ^4.4.3 From e639f1b1b4271081f6f5d304bc67d33e1a1b565c Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2026 19:34:32 +0000 Subject: [PATCH 2/3] fix(schema): Generate output schemas in output mode Co-Authored-By: OpenAI Codex --- .../mcp-core/scripts/generate-definitions.ts | 2 +- packages/mcp-core/src/toolDefinitions.json | 45 ++++++++++++------- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/packages/mcp-core/scripts/generate-definitions.ts b/packages/mcp-core/scripts/generate-definitions.ts index d77235d0e..9df81bdd5 100644 --- a/packages/mcp-core/scripts/generate-definitions.ts +++ b/packages/mcp-core/scripts/generate-definitions.ts @@ -161,7 +161,7 @@ function generateToolDefinitions({ inputSchema: jsonSchema, outputSchema: t.outputSchema ? z.toJSONSchema(t.outputSchema, { - io: "input", + io: "output", unrepresentable: "any", }) : undefined, diff --git a/packages/mcp-core/src/toolDefinitions.json b/packages/mcp-core/src/toolDefinitions.json index 7c3170b63..9fe0d9814 100644 --- a/packages/mcp-core/src/toolDefinitions.json +++ b/packages/mcp-core/src/toolDefinitions.json @@ -786,7 +786,8 @@ "end": { "type": "string" } - } + }, + "additionalProperties": false }, "startTimestamp": { "anyOf": [ @@ -950,7 +951,8 @@ "type": "string" } } - } + }, + "additionalProperties": false } }, "required": [ @@ -960,7 +962,8 @@ "projectId", "timestamp", "durationMs" - ] + ], + "additionalProperties": false } }, "timeline": { @@ -1012,7 +1015,8 @@ "type": "number" } }, - "required": ["totalTokens", "durationMs"] + "required": ["totalTokens", "durationMs"], + "additionalProperties": false }, "genAi": { "type": "object", @@ -1071,7 +1075,8 @@ "type": "string" } } - } + }, + "additionalProperties": false } }, "required": [ @@ -1081,7 +1086,8 @@ "timestamp", "spanId", "traceId" - ] + ], + "additionalProperties": false }, { "type": "object", @@ -1156,7 +1162,8 @@ "toolDefinitions": { "type": "string" } - } + }, + "additionalProperties": false } }, "required": [ @@ -1166,7 +1173,8 @@ "traceId", "timestamp", "durationMs" - ] + ], + "additionalProperties": false } ] } @@ -1188,7 +1196,8 @@ "totalTokens", "spanSummaries", "timeline" - ] + ], + "additionalProperties": false }, "requiredScopes": ["event:read", "project:read"], "skills": ["inspect", "triage", "seer"], @@ -2438,7 +2447,8 @@ ] } }, - "required": ["email", "username"] + "required": ["email", "username"], + "additionalProperties": false }, { "type": "null" @@ -2465,7 +2475,8 @@ "flow", "toolNames", "user" - ] + ], + "additionalProperties": false } } }, @@ -2475,7 +2486,8 @@ "count", "nextCursor", "conversations" - ] + ], + "additionalProperties": false }, "requiredScopes": ["event:read", "project:read"], "skills": ["inspect", "triage", "seer"], @@ -2984,14 +2996,17 @@ "openWorldHint": { "type": "boolean" } - } + }, + "additionalProperties": false } }, - "required": ["name", "description", "inputSchema", "annotations"] + "required": ["name", "description", "inputSchema", "annotations"], + "additionalProperties": false } } }, - "required": ["query", "results"] + "required": ["query", "results"], + "additionalProperties": false }, "requiredScopes": [], "skills": ["inspect", "seer", "docs", "triage", "project-management"], From 145104c6eeaa92ccae0312f26176d48b99a4b758 Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2026 19:52:02 +0000 Subject: [PATCH 3/3] fix(mcp-core): Preserve draft-7 tool schemas Co-Authored-By: OpenAI Codex Co-Authored-By: David Cramer --- .../mcp-core/scripts/generate-definitions.ts | 18 +++++-- packages/mcp-core/src/toolDefinitions.json | 48 ------------------- .../src/tools/catalog-runtime/schema.ts | 6 ++- 3 files changed, 17 insertions(+), 55 deletions(-) diff --git a/packages/mcp-core/scripts/generate-definitions.ts b/packages/mcp-core/scripts/generate-definitions.ts index 9df81bdd5..228d39eb3 100644 --- a/packages/mcp-core/scripts/generate-definitions.ts +++ b/packages/mcp-core/scripts/generate-definitions.ts @@ -32,7 +32,12 @@ function zodFieldMapToJsonSchema( ): unknown { if (!fieldMap || Object.keys(fieldMap).length === 0) return {}; const obj = z.object(fieldMap); - return z.toJSONSchema(obj, { io: "input", unrepresentable: "any" }); + const { $schema: _, ...jsonSchema } = z.toJSONSchema(obj, { + io: "input", + target: "draft-7", + unrepresentable: "any", + }); + return jsonSchema; } // Plugin variants whose agent frontmatter gets synced by this script. @@ -160,10 +165,13 @@ function generateToolDefinitions({ // Export full JSON Schema under inputSchema for external docs inputSchema: jsonSchema, outputSchema: t.outputSchema - ? z.toJSONSchema(t.outputSchema, { - io: "output", - unrepresentable: "any", - }) + ? (({ $schema: _, ...jsonSchema }) => jsonSchema)( + z.toJSONSchema(t.outputSchema, { + io: "output", + target: "draft-7", + unrepresentable: "any", + }), + ) : undefined, // Preserve tool access requirements for UIs/docs requiredScopes: t.requiredScopes, diff --git a/packages/mcp-core/src/toolDefinitions.json b/packages/mcp-core/src/toolDefinitions.json index 9fe0d9814..77fe4a4e8 100644 --- a/packages/mcp-core/src/toolDefinitions.json +++ b/packages/mcp-core/src/toolDefinitions.json @@ -3,7 +3,6 @@ "name": "add_issue_note", "description": "Add a human-visible comment to a Sentry issue's activity feed.\n\nUse this tool when the user explicitly asks to leave a note/comment, or when a triage workflow needs to record a user-approved explanation.\n\n\nadd_issue_note(organizationSlug='my-organization', issueId='PROJECT-123', text='Investigating with the payments team.')\nadd_issue_note(issueUrl='https://my-organization.sentry.io/issues/PROJECT-123/', text='Resolved by deploy 1.2.3.')\n\n\n\n- This mutates visible Sentry issue state by posting a comment.\n- Do not use this for private scratch notes, secrets, credentials, or unapproved content.\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -48,7 +47,6 @@ "name": "add_team_to_project", "description": "Grant a team access to an existing Sentry project.\n\nUse this tool when you need to:\n- Add another team to a project\n- Grant a team access without changing project metadata\n- Check whether a team already has project access before adding it\n\n\nadd_team_to_project(organizationSlug='my-organization', projectSlug='my-project', teamSlug='my-team')\n\n\n\n- Team access changes are separate from project metadata updates.\n- If the team is already assigned, this tool returns the current team list without making another change.\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -86,7 +84,6 @@ "name": "analyze_issue_with_seer", "description": "Use Seer to analyze production errors and get detailed root cause analysis with specific code fixes.\n\nUse this tool when:\n- The user explicitly asks for root cause analysis, Seer analysis, or help fixing/debugging an issue\n- You are unable to accurately determine the root cause from the issue details alone\n\nDo NOT call this tool as an automatic follow-up to get_sentry_resource.\n\nWhat this tool provides:\n- Root cause analysis with code-level explanations\n- Specific file locations and line numbers where errors occur\n- Concrete code fixes you can apply\n- Step-by-step implementation guidance\n\nThis tool automatically:\n1. Checks if analysis already exists (instant results)\n2. Starts new AI analysis if needed (~2-5 minutes)\n3. Returns complete fix recommendations\n\n\n### User: \"Run Seer on this issue\"\n\n```\nanalyze_issue_with_seer(issueUrl='https://my-org.sentry.io/issues/PROJECT-1Z43')\n```\n\n### User: \"Analyze this issue and suggest a fix\"\n\n```\nanalyze_issue_with_seer(organizationSlug='my-organization', issueId='ERROR-456')\n```\n\n\n\n- Only use when the user explicitly requests analysis or you cannot determine the root cause from issue details alone\n- Seer Autofix does not support metric alert issues (issueCategory: metric); use get_issue_details and search_events instead\n- If the user provides an issueUrl, extract it and use that parameter alone\n- The analysis includes actual code snippets and fixes, not just error descriptions\n- Results are cached - subsequent calls return instantly\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -128,7 +125,6 @@ "name": "create_dsn", "description": "Create an additional DSN for an EXISTING project.\n\nUSE THIS TOOL WHEN:\n- Project already exists and needs additional DSN\n- 'Create another DSN for project X'\n- 'I need a production DSN for existing project'\n\nDO NOT USE for new projects (use create_project instead)\n\nBe careful when using this tool!\n\n\n### Create additional DSN for existing project\n```\ncreate_dsn(organizationSlug='my-organization', projectSlug='my-project', name='Production')\n```\n\n\n\n- If the user passes a parameter in the form of name/otherName, its likely in the format of /.\n- If any parameter is ambiguous, you should clarify with the user what they meant.\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -166,7 +162,6 @@ "name": "create_project", "description": "Create a new project in Sentry (provisions DSN automatically).\n\nUSE THIS TOOL WHEN USERS WANT TO:\n- 'Create a new project'\n- 'Set up a project for [app/service] with team [X]'\n- 'I need a new Sentry project'\n- Create project AND need DSN in one step\n- Create project and link an existing repository\n\nReturns the created project slug and a usable SENTRY_DSN when key setup succeeds.\n\nBe careful when using this tool!\n\n\n### Create new project with team\n```\ncreate_project(organizationSlug='my-organization', teamSlug='my-team', name='my-project', platform='javascript')\n```\n### Create project with an explicit slug\n```\ncreate_project(organizationSlug='my-organization', teamSlug='my-team', name='My Project', slug='my-project', platform='javascript')\n```\n### Create project and link to a repository\n```\ncreate_project(organizationSlug='my-organization', teamSlug='my-team', name='my-project', platform='javascript', repository='getsentry/sentry')\n```\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -240,7 +235,6 @@ "name": "create_team", "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\n### Create a new team\n```\ncreate_team(organizationSlug='my-organization', name='the-goats')\n```\n\n\n\n- If any parameter is ambiguous, you should clarify with the user what they meant.\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -274,7 +268,6 @@ "name": "execute_sentry_tool", "description": "Execute an available Sentry MCP tool discovered through search_sentry_tools.\n\nUse this tool when you need to:\n- Call a Sentry operation returned by search_sentry_tools\n- Execute a tool by name using arguments that match its returned schema\n\n\nexecute_sentry_tool(name='find_projects', arguments={ organizationSlug: 'my-org' })\nexecute_sentry_tool(name='whoami', arguments={})\n\n\n\n- Use search_sentry_tools first if you are not sure which name or arguments to pass.\n- Arguments are validated against the target tool's schema before execution.\n- Active organization, project, and region constraints are injected automatically.\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "name": { @@ -302,7 +295,6 @@ "name": "find_alert_rules", "description": "Find Sentry alert rules.\n\nUse this tool when you need to:\n- List issue alert rules for a project\n- List metric alert rules for an organization or project\n- Find an alert rule ID by name before inspecting it\n- Check alert conditions, queries, triggers, actions, owner, or environment\n\n\nfind_alert_rules(organizationSlug='my-org')\nfind_alert_rules(organizationSlug='my-org', projectSlug='backend')\nfind_alert_rules(organizationSlug='my-org', kind='issue', projectSlug='backend', query='critical')\n\n\n\n- Issue alert rules are project-scoped, so `projectSlug` is required when `kind` is `issue`.\n- Metric alert rules can be listed organization-wide or project-scoped.\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -381,7 +373,6 @@ "name": "find_dashboards", "description": "Find Sentry dashboards in an organization.\n\nUse this tool when you need to:\n- List dashboards in an organization\n- Find a dashboard ID before calling get_dashboard_details\n- Search dashboards by title\n\n\nfind_dashboards(organizationSlug='my-organization')\nfind_dashboards(organizationSlug='my-organization', titleQuery='errors')\n\n\n\n- Dashboard IDs are organization-scoped.\n- Use `get_dashboard_details` after finding the correct dashboard ID.\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -448,7 +439,6 @@ "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\n- If the user passes a parameter in the form of name/otherName, its likely in the format of /.\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", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -482,7 +472,6 @@ "name": "find_monitors", "description": "Find Sentry cron monitors.\n\nUse this tool when you need to:\n- List cron monitors in an organization\n- Find a monitor by name or slug before getting details\n- Check monitor status, owner, project, schedule, or recent environment state\n\n\nfind_monitors(organizationSlug='my-organization')\nfind_monitors(organizationSlug='my-organization', projectSlug='backend', query='billing')\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -567,7 +556,6 @@ "name": "find_organizations", "description": "Find organizations that the user has access to in Sentry.\n\nUse this tool when you need to:\n- View organizations in Sentry\n- Find an organization's slug to aid other tool requests\n- Search for specific organizations by name or slug\n\nReturns up to 25 results. If you hit this limit, use the query parameter to narrow down results.", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "query": { @@ -592,7 +580,6 @@ "name": "find_projects", "description": "Find projects in Sentry.\n\nUse this tool when you need to:\n- View projects in a Sentry organization\n- Find a project's slug to aid other tool requests\n- Search for specific projects by name or slug\n\nReturns up to 25 results. If you hit this limit, use the query parameter to narrow down results.", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -634,7 +621,6 @@ "name": "find_releases", "description": "Find releases in Sentry.\n\nUse this tool when you need to:\n- Find recent releases in a Sentry organization\n- Find the most recent version released of a specific project\n- Determine when a release was deployed to an environment\n\n\n### Find the most recent releases in the 'my-organization' organization\n\n```\nfind_releases(organizationSlug='my-organization')\n```\n\n### Find releases matching '2ce6a27' in the 'my-organization' organization\n\n```\nfind_releases(organizationSlug='my-organization', query='2ce6a27')\n```\n\n\n\n- If the user passes a parameter in the form of name/otherName, its likely in the format of /.\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -688,7 +674,6 @@ "name": "find_teams", "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. If you hit this limit, use the query parameter to narrow down results.", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -730,7 +715,6 @@ "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.", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -761,7 +745,6 @@ "required": ["organizationSlug", "conversationId"] }, "outputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "conversationId": { @@ -1207,7 +1190,6 @@ "name": "get_alert_rule", "description": "Get details for a Sentry alert rule.\n\nUse this tool when you need to inspect an alert rule's exact conditions, query, triggers, and actions before explaining or planning changes.\n\n\nget_alert_rule(organizationSlug='my-org', kind='metric', ruleIdOrName='12345')\nget_alert_rule(organizationSlug='my-org', kind='issue', projectSlug='backend', ruleIdOrName='Notify backend team')\nget_alert_rule(organizationSlug='my-org', projectSlug='backend', ruleIdOrName='P95 latency')\n\n\n\n- Use `kind='issue'` or `kind='metric'` for numeric IDs because issue and metric alerts use separate endpoints.\n- With `kind='all'`, a digit-only `ruleIdOrName` is treated as an exact alert rule name.\n- Issue alert rules are project-scoped, so `projectSlug` is required when `kind` is `issue`.\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1260,7 +1242,6 @@ "name": "get_dashboard_details", "description": "Get detailed information about a specific Sentry dashboard.\n\nUse this tool when you need to:\n- Inspect a dashboard's widgets and saved query definitions\n- View dashboard projects, environments, filters, layout, and widget IDs\n- Resolve a dashboard by exact title or numeric ID\n\n\nget_dashboard_details(organizationSlug='my-organization', dashboardIdOrTitle='12345')\nget_dashboard_details(organizationSlug='my-organization', dashboardIdOrTitle='Errors Overview')\n\n\n\n- Numeric dashboard IDs are resolved directly.\n- Title lookups require one exact case-insensitive match. Use `find_dashboards` first if uncertain.\n- This returns saved widget query definitions, not live widget data.\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1295,7 +1276,6 @@ "name": "get_doc", "description": "Fetch the full markdown content of a Sentry documentation page.\n\nUse this tool when you need to:\n- Read the complete documentation for a specific topic\n- Get detailed implementation examples or code snippets\n- Access the full context of a documentation page\n- Extract specific sections from documentation\n\n\n### Get the Next.js integration guide\n\n```\nget_doc(path='/platforms/javascript/guides/nextjs.md')\n```\n\n\n\n- Use the path from search_docs results for accurate fetching\n- Paths should end with .md extension\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "path": { @@ -1313,7 +1293,6 @@ "name": "get_event_attachment", "description": "Download attachments from a Sentry event.\n\nUse this tool when you need to:\n- Download files attached to a specific event\n- Access screenshots, log files, or other attachments uploaded with an error report\n- Retrieve attachment metadata and download URLs\n\n\n### Download a specific attachment by ID\n\n```\nget_event_attachment(organizationSlug='my-organization', projectSlug='my-project', eventId='c49541c747cb4d8aa3efb70ca5aba243', attachmentId='12345')\n```\n\n### List all attachments for an event\n\n```\nget_event_attachment(organizationSlug='my-organization', projectSlug='my-project', eventId='c49541c747cb4d8aa3efb70ca5aba243')\n```\n\n\n\n\n- If `attachmentId` is provided, the specific attachment will be downloaded as an embedded resource\n- If `attachmentId` is omitted, all attachments for the event will be listed with download information\n- The `projectSlug` is required to identify which project the event belongs to\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1363,7 +1342,6 @@ "name": "get_event_stacktrace", "description": "Get a full thread stacktrace from a specific Sentry event.\n\nUse this tool when you need to:\n- Fetch the full stacktrace for a thread listed in issue details\n- Inspect a non-crashed thread from an event with multiple threads\n- Get Sentry's default selected thread stacktrace when no thread is specified\n\n\nget_event_stacktrace(organizationSlug='my-org', issueId='PROJECT-123')\nget_event_stacktrace(organizationSlug='my-org', issueId='PROJECT-123', eventId='abc123', thread=259)\nget_event_stacktrace(organizationSlug='my-org', issueId='PROJECT-123', thread='main')\n\n\n\n- `thread` is optional. If omitted, this returns the same default thread Sentry selects: first crashed thread, then first thread with a stacktrace, then first thread.\n- Pass `thread` as a numeric Thread ID or exact thread Name from the issue details thread list.\n- If the issue details show only one useful thread, omit `thread`.\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1416,7 +1394,6 @@ "name": "get_issue_activity", "description": "Get the activity feed and comments for a Sentry issue.\n\nUse this tool when you need to:\n- Review prior comments before triaging an issue\n- Understand who resolved, ignored, assigned, or commented on an issue\n- See recent issue activity that is not included in `get_issue_details`\n\n\nget_issue_activity(organizationSlug='my-organization', issueId='PROJECT-123')\nget_issue_activity(issueUrl='https://my-organization.sentry.io/issues/PROJECT-123/')\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1464,7 +1441,6 @@ "name": "get_issue_details", "description": "Get detailed information about a specific Sentry issue by ID.\n\nUSE THIS TOOL WHEN USERS:\n- Provide a specific issue ID (e.g., 'CLOUDFLARE-MCP-41', 'PROJECT-123')\n- Ask to 'explain [ISSUE-ID]', 'tell me about [ISSUE-ID]'\n- Want details/stacktrace/analysis for a known issue\n- Provide a Sentry issue URL\n\nDO NOT USE for:\n- General searching or listing issues (use search_issues)\n\nTRIGGER PATTERNS:\n- 'Explain ISSUE-123' → use get_issue_details\n- 'Tell me about PROJECT-456' → use get_issue_details\n- 'What happened in [issue URL]' → use get_issue_details\n\n\n### With Sentry URL (recommended - simplest approach)\n```\nget_issue_details(issueUrl='https://sentry.sentry.io/issues/6916805731/?project=4509062593708032&query=is%3Aunresolved')\n```\n\n### With issue ID and organization\n```\nget_issue_details(organizationSlug='my-organization', issueId='CLOUDFLARE-MCP-41')\n```\n\n### With event ID and organization\n```\nget_issue_details(organizationSlug='my-organization', eventId='c49541c747cb4d8aa3efb70ca5aba243')\n```\n\n\n\n- **IMPORTANT**: If user provides a Sentry URL, pass the ENTIRE URL to issueUrl parameter unchanged\n- When using issueUrl, all other parameters are automatically extracted - don't provide them separately\n- If using issueId (not URL), then organizationSlug is required\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1506,7 +1482,6 @@ "name": "get_issue_tag_values", "description": "Get tag value distribution for a specific Sentry issue.\n\nUse this tool when you need to:\n- Understand how an issue is distributed across different tag values\n- Get aggregate counts of unique tag values (e.g., 'how many unique URLs are affected')\n- Analyze which browsers, environments, or URLs are most impacted by an issue\n- View the tag distributions page data programmatically\n\nCommon tag keys:\n- `url`: Request URLs affected by the issue\n- `browser`: Browser types and versions\n- `browser.name`: Browser names only\n- `os`: Operating systems\n- `environment`: Deployment environments (production, staging, etc.)\n- `release`: Software releases\n- `device`: Device types\n- `user`: Affected users\n\n\n### Get URL distribution for an issue\n```\nget_issue_tag_values(organizationSlug='my-organization', issueId='PROJECT-123', tagKey='url')\n```\n\n### Get browser distribution using issue URL\n```\nget_issue_tag_values(issueUrl='https://sentry.io/issues/PROJECT-123/', tagKey='browser')\n```\n\n### Get environment distribution\n```\nget_issue_tag_values(organizationSlug='my-organization', issueId='PROJECT-123', tagKey='environment')\n```\n\n\n\n- If user provides a Sentry URL, pass the ENTIRE URL to issueUrl parameter unchanged\n- Common tag keys: url, browser, browser.name, os, environment, release, device, user\n- Tag keys are case-sensitive\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1550,7 +1525,6 @@ "name": "get_issue_user_reports", "description": "Get legacy User Reports or crash-report feedback attached to a Sentry issue.\n\nUse this tool when you need to:\n- See what a user said happened when an error occurred\n- Check if any legacy bug reports or crash-report feedback were submitted for this issue\n- Get the human-provided context behind a crash, beyond the stack trace\n\n\nget_issue_user_reports(organizationSlug='my-organization', issueId='PROJECT-123')\nget_issue_user_reports(issueUrl='https://my-organization.sentry.io/issues/PROJECT-123/')\n\n\n\n- For standalone User Feedback Widget submissions, use `search_issues(query='issue.category:feedback')`.\n- Reuse pagination cursors only with the same issue scope.\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1607,7 +1581,6 @@ "name": "get_latest_base_snapshot", "description": "Get the latest UI screenshots/images for an app from the preprod snapshot system.\n\nThis is the primary tool for retrieving app screenshots — not search_events or search_issues.\n\nUse this tool when you need to:\n- Get screenshots, screens, golden images, or reference images for an app\n- Find what the current UI looks like (latest screenshots from the main/default branch)\n- List available snapshots or browse images before requesting specific ones\n- Look up dark mode, light mode, or other variant screenshots\n- Understand what baseline images exist when investigating snapshot test or visual regression CI failures\n\nThe appId parameter is the app identifier (e.g. 'sentry-frontend', 'com.emergetools.hackernews').\nReturns compact image metadata (display_name, image_file_name, group, description) for every image.\n\n\n### Get the latest screenshots for an app\n\n```\nget_latest_base_snapshot(organizationSlug=\"sentry\", appId=\"sentry-frontend\", project=\"frontend\")\n```\n\n### Get the latest screenshots for a specific branch\n\n```\nget_latest_base_snapshot(organizationSlug=\"sentry\", appId=\"sentry-frontend\", project=\"frontend\", branch=\"main\")\n```\n\n\n\n- The response includes compact metadata per image. Scan the list to find images matching what you need (e.g. filter by group or name containing 'button').\n- To view a specific image, use get_sentry_resource(url='?selectedSnapshot=').\n- If you need to investigate a specific snapshot comparison, use get_sentry_resource with the snapshot URL.\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1665,7 +1638,6 @@ "name": "get_monitor_details", "description": "Get details for a Sentry cron monitor.\n\nUse this tool when you need to:\n- Inspect a monitor's schedule, status, owner, project, and environments\n- Review recent check-ins for missed, failed, timeout, or OK runs\n- Check monitor stats over a recent time range\n\n\nget_monitor_details(organizationSlug='my-organization', monitorSlug='nightly-import')\nget_monitor_details(organizationSlug='my-organization', monitorSlug='nightly-import', projectSlugOrId='backend', environment='production', period='7d')\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1791,7 +1763,6 @@ "name": "get_profile", "description": "Analyze CPU profiling data to identify performance bottlenecks and detect regressions.\n\nUSE THIS TOOL WHEN:\n- User asks why a specific endpoint/transaction is slow\n- User wants to understand where CPU time is spent\n- User asks about performance bottlenecks\n- User wants to compare performance between time periods\n- User shares a Sentry profile URL\n\nRETURNS:\n- Hot paths (call stacks consuming the most CPU time)\n- Performance percentiles (p75, p95, p99) for each function\n- User code vs library code breakdown\n- Actionable recommendations for optimization\n- Regression analysis when comparing periods\n\n\n### Analyze from URL (with transaction name)\n```\nget_profile(\n profileUrl='https://my-org.sentry.io/explore/profiling/profile/backend/flamegraph/?profilerId=abc123',\n transactionName='/api/users'\n)\n```\n\n### Analyze by transaction name\n```\nget_profile(\n organizationSlug='my-org',\n transactionName='/api/users',\n projectSlugOrId='backend'\n)\n```\n\n### Compare performance between periods\n```\nget_profile(\n organizationSlug='my-org',\n transactionName='/api/users',\n projectSlugOrId='backend',\n period='7d',\n compareAgainstPeriod='14d'\n)\n```\n\n\n\n- Use `focusOnUserCode: true` (default) to filter out library code\n- High p99 relative to p75 indicates inconsistent performance\n- Use compareAgainstPeriod to detect regressions over time\n- Transaction names are case-sensitive\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "profileUrl": { @@ -1863,7 +1834,6 @@ "name": "get_profile_details", "description": "Inspect a specific Sentry profile in detail.\n\nUSE THIS TOOL WHEN:\n- User shares a transaction profile URL and wants the details\n- User has a profile ID and wants a concise summary plus raw sample structure\n- User needs to inspect a continuous profile session by profiler ID and time range\n\nRETURNS:\n- Transaction profile summary with profile URL, transaction, trace, release, and runtime details\n- Sample structure summaries such as frame count, sample count, stacks, and thread breakdown\n- Top frames by occurrence for a quick hotspot overview\n\nNOTE: This tool supports two profile modes.\n- Transaction profiles: pass `profileUrl` or `organizationSlug` + `projectSlugOrId` + `profileId`\n- Continuous profiles: pass `profileUrl` or `organizationSlug` + `projectSlugOrId` + `profilerId` + `start` + `end`\n\n\n### Transaction profile URL\n```\nget_profile_details(\n profileUrl='https://my-org.sentry.io/explore/profiling/profile/backend/cfe78a5c892d4a64a962d837673398d2/flamegraph/'\n)\n```\n\n### Transaction profile by ID\n```\nget_profile_details(\n organizationSlug='my-org',\n projectSlugOrId='backend',\n profileId='cfe78a5c892d4a64a962d837673398d2'\n)\n```\n\n### Continuous profile by session\n```\nget_profile_details(\n organizationSlug='my-org',\n projectSlugOrId='backend',\n profilerId='041bde57b9844e36b8b7e5734efae5f7',\n start='2024-01-01T00:00:00Z',\n end='2024-01-01T01:00:00Z'\n)\n```\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "profileUrl": { @@ -1929,7 +1899,6 @@ "name": "get_release_details", "description": "Get details for a Sentry release.\n\nUse this tool when you need to:\n- Inspect an exact release version\n- Scope a release lookup to a specific project\n- See deploys and environments for a release\n- See recent commits attached to a release\n- Gather release health metadata when a project is known\n\n\nget_release_details(organizationSlug='my-organization', releaseVersion='1.2.3')\nget_release_details(organizationSlug='my-organization', releaseVersion='1.2.3', projectSlugOrId='backend')\nget_release_details(organizationSlug='my-organization', releaseVersion='1.2.3', includeHealth=true, projectSlugOrId='backend')\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -1998,7 +1967,6 @@ "name": "get_replay_details", "description": "Get high-level information about a specific Sentry replay by URL or replay ID.\n\nUSE THIS TOOL WHEN USERS:\n- Share a replay URL\n- Ask what happened in a specific replay\n- Want a concise replay summary plus the next issue or trace lookups to run\n\n\n### With replay URL\n```\nget_replay_details(replayUrl='https://my-organization.sentry.io/explore/replays/7e07485f-12f9-416b-8b14-26260799b51f/')\n```\n\n### With organization and replay ID\n```\nget_replay_details(organizationSlug='my-organization', replayId='7e07485f-12f9-416b-8b14-26260799b51f')\n```\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "replayUrl": { @@ -2035,7 +2003,6 @@ "name": "get_sentry_resource", "description": "Fetch a Sentry resource by URL, or by resourceType plus resourceId.\nPass a Sentry URL directly when possible; the resource type is auto-detected.\n\nSupports issues, events, traces, spans, AI conversations, breadcrumbs, replays, monitors, preprod snapshots, and snapshot images.\nTrace lookups return a condensed overview by default.\n\nAI Conversations: A conversation is a set of spans sharing the same gen_ai.conversation.id. Use resourceType='ai_conversation' with a conversation ID, or pass a Sentry conversation URL, to fetch the transcript/details. To discover or list conversations, use search_ai_conversations. Conversations are NOT issues — do not use search_issues for conversation queries.\n\nFor preprod snapshot URLs (matching 'sentry.io/preprod/snapshots/'):\n- Without ?selectedSnapshot=: returns the snapshot diff summary (changed, added, removed images)\n- With ?selectedSnapshot=: returns the image preview and metadata. Use the Sentry tool `get_snapshot_image` for full-resolution image bytes.\n\nResource IDs:\n- span: :\n- monitor: \n- snapshot: \n- snapshotImage: :\n\n\nget_sentry_resource(url='https://sentry.io/issues/PROJECT-123/')\nget_sentry_resource(resourceType='issue', organizationSlug='my-org', resourceId='PROJECT-123')\nget_sentry_resource(resourceType='span', organizationSlug='my-org', resourceId=':')\nget_sentry_resource(resourceType='ai_conversation', organizationSlug='my-org', resourceId='conversation-123')\nget_sentry_resource(url='https://sentry.sentry.io/preprod/snapshots/123/')\nget_sentry_resource(url='https://sentry.sentry.io/preprod/snapshots/123/?selectedSnapshot=login_screen.png')\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "url": { @@ -2077,7 +2044,6 @@ "name": "get_snapshot", "description": "Get a preprod snapshot comparison summary, including metadata, counts, and changed image sections.\n\nUse this tool when you need to:\n- Investigate a failed snapshot test from CI\n- Review what changed in a specific preprod snapshot\n- Browse snapshot image file names before viewing a specific image\n\nPass organizationSlug and snapshotId. Use get_sentry_resource for snapshot URLs.\nCompact output is returned by default. Set showUnmodified=true to list unchanged and skipped images separately.\n\n\n### Browse a snapshot\n\n```\nget_snapshot(organizationSlug=\"sentry\", snapshotId=\"231949\")\n```\n\n### Include unchanged and skipped images\n\n```\nget_snapshot(organizationSlug=\"sentry\", snapshotId=\"231949\", showUnmodified=true)\n```\n\n\n\n- Use the Sentry tool `get_snapshot_image` to view a specific image preview or full-resolution image bytes.\n- Use get_sentry_resource when starting from a Sentry snapshot URL.\n- The diff percent field shows what percentage of pixels changed (0-100).\n- showUnmodified=true is useful when a diff snapshot has no changed image sections.\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -2117,7 +2083,6 @@ "name": "get_snapshot_image", "description": "Get metadata and image content for one image in a preprod snapshot.\n\nUse this tool when you need to:\n- View the current, previous, or diff image for a snapshot entry\n- Inspect metadata and context for a specific snapshot image\n- Fetch full-resolution image bytes when preview images are insufficient; full-resolution images can substantially increase response size and token usage\n\nPass organizationSlug, snapshotId, and imageIdentifier. Use get_sentry_resource for snapshot URLs.\nPreview images are returned by default; set imageResolution=full for original bytes when needed, but expect higher response size and token usage.\n\n\n### View a preview image\n\n```\nget_snapshot_image(organizationSlug=\"sentry\", snapshotId=\"231949\", imageIdentifier=\"login_screen.png\")\n```\n\n### Fetch original full-resolution bytes\n\n```\nget_snapshot_image(organizationSlug=\"sentry\", snapshotId=\"231949\", imageIdentifier=\"login_screen.png\", imageResolution=\"full\")\n```\n\n\n\n- Use get_snapshot first if you need to discover available image file names.\n- Use get_sentry_resource when starting from a Sentry snapshot URL.\n- imageIdentifier values may include slashes; pass the full image_file_name exactly as shown by get_snapshot.\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -2163,7 +2128,6 @@ "name": "get_trace_details", "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\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\n\n\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", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -2203,7 +2167,6 @@ "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\nremove_team_from_project(organizationSlug='my-organization', projectSlug='my-project', teamSlug='my-team')\n\n\n\n- The team must already be assigned to the project.\n- This tool will not remove the last team assigned to a project.\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -2241,7 +2204,6 @@ "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\nsearch_ai_conversations(organizationSlug='my-org', query='failed conversations', period='7d')\nsearch_ai_conversations(organizationSlug='my-org', query='checkout', project='backend')\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -2318,7 +2280,6 @@ "required": ["organizationSlug"] }, "outputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -2497,7 +2458,6 @@ "name": "search_docs", "description": "Search Sentry documentation for SDK setup, instrumentation, and configuration guidance.\n\nUse this tool when you need to:\n- Set up Sentry SDK or framework integrations (Django, Flask, Express, Next.js, etc.)\n- Configure features like performance monitoring, error sampling, or release tracking\n- Implement custom instrumentation (spans, transactions, breadcrumbs)\n- Configure data scrubbing, filtering, or sampling rules\n\nReturns snippets only. Use the Sentry tool `get_doc` to fetch full documentation content.\n\n\n```\nsearch_docs(query='Django setup configuration SENTRY_DSN', guide='python/django')\nsearch_docs(query='source maps webpack upload', guide='javascript/nextjs')\n```\n\n\n\n- Use guide parameter to filter to specific technologies (e.g., 'javascript/nextjs')\n- Include specific feature names like 'beforeSend', 'tracesSampleRate', 'SENTRY_DSN'\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "query": { @@ -2656,7 +2616,6 @@ "name": "search_events", "description": "Search Sentry events and replays. Use for event counts/statistics.\n\n`query` can be natural language or Sentry search syntax. With an agent configured, it fixes dataset, query, fields, and sort before running.\n\nSupports TWO query types:\n1. AGGREGATIONS (counts, sums, averages): 'how many errors', 'total tokens'\n2. Individual events with timestamps: 'error logs from last hour'\n\nDatasets:\n- errors: Exception/crash events with stack traces, usually grouped into issues\n- logs: Application log entries, including error-severity log messages\n- spans: Raw trace/span events for performance, AI/LLM calls, requests, and operations\n- metrics: Metric rows and aggregates: counters, gauges, distributions, values\n- profiles: Transaction/continuous profile results, profile IDs, profiled transactions\n- replays: Session replay results: rage clicks, dead clicks, visited pages, replay users\nIf the user says logs, log messages, error logs, or warning logs, choose logs instead of errors.\n\nReplay searches return replay lists only; replay count()/avg()/sum() are not supported.\n\nNOT for grouped issue lists (use search_issues) or app screenshots/images (use get_latest_base_snapshot).\n\n\nsearch_events(organizationSlug='my-org', query='how many errors today')\nsearch_events(organizationSlug='my-org', dataset='errors', query='level:error')\nsearch_events(organizationSlug='my-org', dataset='errors', fields=['issue', 'count()'], sort='-count()')\nsearch_events(organizationSlug='my-org', dataset='spans', query='span.op:db', sort='-span.duration')\nsearch_events(organizationSlug='my-org', dataset='replays', query='count_errors:>0', sort='-count_errors')\n\n\n\n- If the user passes a parameter in the form of name/otherName, it's likely in the format of /.\n- Parse org/project notation directly without calling find_organizations or find_projects.\n- Use fields with aggregate functions like count(), avg(), sum() for statistics\n- Sort by -count() for most common, -timestamp for newest\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -2773,7 +2732,6 @@ "name": "search_issue_events", "description": "Search and filter events within a specific issue.\n\nProvide `query` as natural language or Sentry event search syntax. When an embedded agent is configured, it fixes filters, fields, sort, and time range before running.\n\nThe tool automatically constrains results to the specified issue.\n\nCommon Query Filters:\n- environment:production - Filter by environment\n- release:1.0.0 - Filter by release version\n- user.email:alice@example.com - Filter by user\n- trace:TRACE_ID - Filter by trace ID\n\nFor cross-issue searches use search_issues. For single issue or event details use get_sentry_resource.\n\n\nsearch_issue_events(issueId='MCP-41', organizationSlug='my-org', query='from last hour')\nsearch_issue_events(issueId='MCP-41', organizationSlug='my-org', query='environment:production')\nsearch_issue_events(issueUrl='https://sentry.io/.../issues/123/', query='release:v1.0.0', period='7d')\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -2859,7 +2817,6 @@ "name": "search_issues", "description": "Search for grouped issues/problems in Sentry - returns a LIST of issues, NOT counts or aggregations.\n\nProvide `query` as natural language or Sentry issue search syntax. When an embedded agent is configured, it fixes query and sort before running while preserving explicit Sentry search syntax.\n\nReturns grouped issues with metadata like title, status, and user count.\n\nCommon Query Syntax:\n- is:unresolved / is:resolved / is:ignored / is:for_review / is:new / is:regressed / is:escalating\n- level:error / level:warning\n- firstSeen:-24h / lastSeen:-7d\n- assigned:me / assigned_or_suggested:me\n- release:latest\n- issue.category:feedback\n- issue.priority:high\n- environment:production\n- userCount:>100\n\nDO NOT USE FOR COUNTS/AGGREGATIONS → use search_events\nDO NOT USE FOR individual events with timestamps → use search_events\nDO NOT USE FOR details about a specific issue → use get_sentry_resource\n\n\nsearch_issues(organizationSlug='my-org', query='critical bugs from last week')\nsearch_issues(organizationSlug='my-org', query='is:unresolved is:unassigned', sort='freq')\nsearch_issues(organizationSlug='my-org', query='level:error firstSeen:-24h', projectSlugOrId='my-project')\n\n\n\n- If the user passes a parameter in the form of name/otherName, it's likely in the format of /.\n- Parse org/project notation directly without calling find_organizations or find_projects.\n- The projectSlugOrId parameter accepts both project slugs (e.g., 'my-project') and numeric IDs (e.g., '123456').\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -2930,7 +2887,6 @@ "name": "search_sentry_tools", "description": "Search the available Sentry MCP tool catalog by name and description.\n\nMany Sentry operations are intentionally not exposed as top-level tools. Use this for any Sentry-related task when you do not see an obvious direct tool, including long-tail inspection, project management, documentation lookup, preprod snapshots, attachments, DSNs, releases, teams, and issue-specific pivots.\n\nUse this tool when you need to:\n- Find the right Sentry operation for a task\n- Discover catalog tools and their schemas for a task\n- Inspect the executable JSON input schema for an available tool\n\n\nsearch_sentry_tools(query='list projects')\nsearch_sentry_tools(query='issue details')\nsearch_sentry_tools(query='find dsn', limit=5)\nsearch_sentry_tools(query='snapshot image')\n\n\n\n- Results only include tools available in the current session.\n- If a Sentry operation is not listed as a direct tool, search here before deciding it is unavailable.\n- Returned schemas already account for active organization, project, and region constraints.\n- Use the returned name and schema when executing a catalog result.\n- This tool returns structured JSON. Do not parse markdown from its text content.\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "query": { @@ -2956,7 +2912,6 @@ "required": ["query"] }, "outputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "query": { @@ -3016,7 +2971,6 @@ "name": "update_dsn", "description": "Update settings for an existing DSN (client key) in a project, such as name, active status, rate limit, and loader script options.\n\nUSE THIS TOOL WHEN:\n- Deactivating or activating a DSN/client key\n- Setting or removing DSN rate limits ('set rate limit of 1000 per hour on DSN X')\n- Renaming a DSN ('rename DSN X to Production')\n- Configuring Javascript SDK loader script options (session replay, performance, debug, feedback, etc.)\n\nBe careful when using this tool!\n\n\n### Rename DSN and set rate limit\n```\nupdate_dsn(organizationSlug='my-organization', projectSlug='my-project', keyId='d20df0a1ab5031c7f3c7edca9c02814d', name='Production Key', rateLimitWindow=3600, rateLimitCount=500)\n```\n\n### Deactivate a DSN\n```\nupdate_dsn(organizationSlug='my-organization', projectSlug='my-project', keyId='d20df0a1ab5031c7f3c7edca9c02814d', isActive=false)\n```\n\n### Disable rate limit entirely\n```\nupdate_dsn(organizationSlug='my-organization', projectSlug='my-project', keyId='d20df0a1ab5031c7f3c7edca9c02814d', disableRateLimit=true)\n```\n\n\n\n- Use `find_dsns()` first to find the `keyId` for the DSN you want to update.\n- Both `rateLimitWindow` (seconds) and `rateLimitCount` (error cap) must be provided together to set a rate limit.\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -3103,7 +3057,6 @@ "name": "update_issue", "description": "Update a Sentry issue's status or assignment.\n\nUse this to resolve, reopen, assign, or ignore an issue.\n\n\n```\nupdate_issue(organizationSlug='my-org', issueId='PROJECT-123', status='resolved')\nupdate_issue(organizationSlug='my-org', issueId='PROJECT-123', assignedTo='user:123456')\nupdate_issue(organizationSlug='my-org', issueId='PROJECT-123', status='ignored')\nupdate_issue(organizationSlug='my-org', issueId='PROJECT-123', status='ignored', ignoreMode='forever')\nupdate_issue(organizationSlug='my-org', issueId='PROJECT-123', status='ignored', ignoreMode='untilOccurrenceCount', ignoreCount=100, ignoreWindowMinutes=60)\nupdate_issue(organizationSlug='my-org', issueId='PROJECT-123', status='ignored', reason='Ignoring because this is expected noise from the staging deploy')\n```\n\n\n\n- Provide `issueUrl` or `organizationSlug` + `issueId`.\n- At least one of `status` or `assignedTo` is required.\n- `assignedTo` format: `user:ID` or `team:ID_OR_SLUG`.\n- Use `execute_sentry_tool(name='whoami', arguments={})` to find your user ID for self-assignment.\n- Status values: `resolved`, `resolvedInNextRelease`, `unresolved`, `ignored`.\n- `status='ignored'` defaults to `ignoreMode='untilEscalating'`.\n- Ignore modes: `untilEscalating`, `forever`, `forDuration`, `untilOccurrenceCount`, `untilUserCount`.\n- Matching ignore inputs are `ignoreDurationMinutes`, `ignoreCount` + optional `ignoreWindowMinutes`, or `ignoreUserCount` + optional `ignoreUserWindowMinutes`.\n- To switch an already ignored issue between `untilEscalating`, `forever`, and condition-based ignore modes, first set `status='unresolved'`, then ignore it again with the new rule.\n- `reason` is optional. When provided, it will be posted as a comment on the issue's activity feed explaining why the action was taken.\n", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { @@ -3201,7 +3154,6 @@ "name": "update_project", "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\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\n\n\n- If the user passes a parameter in the form of name/otherName, it's likely in the format of /.\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", "inputSchema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "organizationSlug": { diff --git a/packages/mcp-core/src/tools/catalog-runtime/schema.ts b/packages/mcp-core/src/tools/catalog-runtime/schema.ts index 4ea5060e2..e9bddb9aa 100644 --- a/packages/mcp-core/src/tools/catalog-runtime/schema.ts +++ b/packages/mcp-core/src/tools/catalog-runtime/schema.ts @@ -6,8 +6,10 @@ export function zodFieldMapToJsonSchema( const zodObject = Object.keys(fieldMap).length > 0 ? z.object(fieldMap) : z.object({}); - return z.toJSONSchema(zodObject, { + const { $schema: _, ...jsonSchema } = z.toJSONSchema(zodObject, { io: "input", + target: "draft-7", unrepresentable: "any", - }) as Record; + }); + return jsonSchema; }