Summary
Implement MCP alert rule tools with parity to the Sentry CLI alert issues and alert metrics surfaces.
Existing related issue: #277 covers only issue alert rule management. This issue expands the scope to both issue alerts and metric alerts and maps the CLI implementation to MCP.
CLI surface to map
CLI route: /Users/dcramer/src/cli/src/commands/alert
Issue alerts (sentry alert issues):
list: list project-scoped issue alert rules.
view: resolve by ID or exact name and fetch details.
create: create project issue alert rule from name, conditions, actions, action match, frequency, optional environment, filters, filter match, owner.
edit: GET full rule document, merge partial fields, PUT full replacement.
delete: delete project issue alert rule.
Metric alerts (sentry alert metrics):
list: list org-scoped metric alert rules.
view: resolve by ID or exact name and fetch details.
create: create org metric alert rule from name, query, aggregate, dataset, time window, triggers, optional projects, environment, owner.
edit: GET full rule document, merge partial fields, PUT update.
delete: delete org metric alert rule.
Source-validated endpoints
Validated in ~/src/sentry:
- Routes:
src/sentry/api/urls.py
- Issue alert rules:
src/sentry/api/endpoints/project_rules.py and project_rule_details.py
- Metric alert rules:
src/sentry/incidents/endpoints/organization_alert_rule_index.py and organization_alert_rule_details.py
- Project metric alert routes exist but are deprecated in favor of organization metric alert routes.
Issue alert endpoints:
GET /api/0/projects/{org}/{project}/rules/
POST /api/0/projects/{org}/{project}/rules/
GET /api/0/projects/{org}/{project}/rules/{rule_id}/
PUT /api/0/projects/{org}/{project}/rules/{rule_id}/
DELETE /api/0/projects/{org}/{project}/rules/{rule_id}/
Source notes:
- Project rule endpoints are marked deprecated upstream, but they are still the CLI-backed issue-alert surface.
- PUT warns that it fully overwrites the issue alert rule. MCP update must fetch current state and submit a complete body after applying partial edits.
- DELETE returns
202 Accepted, not 204.
actionMatch and filterMatch support all, any, and none in source. The CLI only exposes all | any; decide whether MCP should preserve the CLI narrower enum or support source-complete none.
frequency source range is 5 to 43200 minutes. The CLI currently only checks positive values; MCP should enforce the source range.
Metric alert endpoints:
GET /api/0/organizations/{org}/alert-rules/
POST /api/0/organizations/{org}/alert-rules/
GET /api/0/organizations/{org}/alert-rules/{alert_rule_id}/
PUT /api/0/organizations/{org}/alert-rules/{alert_rule_id}/
DELETE /api/0/organizations/{org}/alert-rules/{alert_rule_id}/
- Optional helper:
GET /api/0/organizations/{org}/alert-rules/available-actions/
Source notes:
- Organization metric alert endpoints are the canonical route. Avoid the deprecated project metric alert endpoints unless there is a specific project-scoped need.
- PUT is partial in serializer usage, but the CLI fetches and merges a full document before PUT. For MCP, preserve that safer behavior unless tests prove partial PUT is sufficient for every field.
- DELETE returns
204 No Content.
- Metric alert create/update may return
202 with a uuid when async Slack channel lookup is required; MCP output should handle both async and created/updated rule responses.
Proposed MCP tools
Keep these catalog-only initially; do not add to TOP_LEVEL_TOOL_NAMES unless we intentionally expand the direct surface.
Use separate issue-alert and metric-alert tools rather than one giant discriminated union. The payloads, scopes, and endpoint semantics differ enough that separate schemas will be easier for agents to call correctly.
Issue alert tools
-
find_issue_alert_rules
- Read-only.
- Inputs:
organizationSlug, projectSlug, optional cursor, limit, regionUrl.
- Returns ID, name, status, action match, frequency, environment, owner, action/condition counts, next cursor.
-
get_issue_alert_rule
- Read-only.
- Inputs:
organizationSlug, projectSlug, ruleIdOrName, optional regionUrl.
- Numeric IDs fetch directly; names list and require exact unambiguous match. Return candidates on no/ambiguous match.
-
create_issue_alert_rule
- Write, non-destructive.
- Inputs:
organizationSlug, projectSlug, name, conditions, actions, actionMatch, optional frequency, environment, filters, filterMatch, owner, regionUrl.
- MCP should accept structured arrays of objects directly, not CLI JSON strings.
- Validate non-empty
conditions and actions.
-
update_issue_alert_rule
- Write, destructive/idempotent.
- Inputs:
organizationSlug, projectSlug, ruleIdOrName, optional editable fields.
- Must require at least one editable field.
- Must GET current rule document, merge updates, validate arrays/ranges, PUT full document.
- Support clearing nullable fields with
null for environment and owner.
-
delete_issue_alert_rule
- Destructive.
- Inputs:
organizationSlug, projectSlug, ruleIdOrName, regionUrl.
- Resolve by name/ID, DELETE, report accepted deletion.
Metric alert tools
-
find_metric_alert_rules
- Read-only.
- Inputs:
organizationSlug, optional projectSlug, cursor, limit, regionUrl.
- Use org route; filter/project params should match source behavior after validation.
- Returns ID, name, status, query, aggregate, dataset, time window, environment, projects, owner, next cursor.
-
get_metric_alert_rule
- Read-only.
- Inputs:
organizationSlug, ruleIdOrName, optional regionUrl.
- Numeric IDs fetch directly; names list and require exact unambiguous match.
-
create_metric_alert_rule
- Write, non-destructive.
- Inputs:
organizationSlug, name, query, aggregate, dataset, timeWindow, triggers, optional projects, environment, owner, regionUrl.
- MCP should accept structured trigger/action arrays directly.
- Validate dataset and time window against source. CLI allows
errors, transactions, sessions, events, spans, metrics; source docs also mention generic-metrics, so verify before final schema.
- Handle 201 rule response and 202 async
uuid response.
-
update_metric_alert_rule
- Write, destructive/idempotent.
- Inputs:
organizationSlug, ruleIdOrName, optional editable fields.
- Require at least one editable field.
- Status mapping:
active -> API value 0, disabled -> API value 1; active responses may omit status, so display omitted/0 as active.
- Fetch current document, merge updates, PUT.
- Support clearing nullable fields with
null for environment and owner; empty project list should clear project filters.
-
delete_metric_alert_rule
- Destructive.
- Inputs:
organizationSlug, ruleIdOrName, regionUrl.
- Resolve, DELETE, report deletion.
Optional helper:
get_alert_rule_action_options
- Read-only.
- Wrap
GET /organizations/{org}/alert-rules/available-actions/.
- This would make agent-driven create/update safer because alert action payloads are otherwise opaque structured JSON.
API client work
- Add schemas/types in
packages/mcp-core/src/api-client/schema.ts and types.ts:
- issue alert list/detail/document shape
- metric alert list/detail/document shape
- trigger/action object passthrough schemas where upstream payloads are plugin-dependent
- Add methods in
packages/mcp-core/src/api-client/client.ts:
listIssueAlertRules, getIssueAlertRule, createIssueAlertRule, updateIssueAlertRule, deleteIssueAlertRule
listMetricAlertRules, getMetricAlertRule, createMetricAlertRule, updateMetricAlertRule, deleteMetricAlertRule
- optional
getMetricAlertAvailableActions
- Respect
regionUrl via apiServiceFromContext.
- Add formatting helpers under
packages/mcp-core/src/tools/support/alerts/:
- name/ID resolution with candidates
- issue rule body merge/validation
- metric rule body merge/validation
- status formatting
Required scopes and annotations
Validate exact scopes against existing MCP auth and Sentry API behavior before landing.
Expected shape:
- list/get issue alerts: read-only, likely
project:read or event:read
- create/update/delete issue alerts: write, likely
project:write
- list/get metric alerts: read-only, likely
org:read plus project access
- create/update/delete metric alerts: write, likely
org:write
- all tools:
openWorldHint: true
- deletes:
destructiveHint: true
- updates:
destructiveHint: true, idempotentHint: true
- creates:
destructiveHint: false
Testing
- Unit tests for each tool with MSW-backed Sentry API responses and a full inline snapshot on at least one happy path per tool.
- Cover:
- list pagination and empty results
- direct ID resolution
- name resolution success, ambiguous match, no match with candidates
- issue alert create validation for empty conditions/actions
- issue alert update GET + merge + full PUT
- issue alert delete treats 202 as success
- metric alert create validation for dataset/timeWindow/triggers
- metric alert create/update handles 202 async
uuid
- metric alert status formatting when status is omitted,
0, 1, and "1"
- metric alert delete treats 204 as success
- upstream 400 validation errors are surfaced clearly
- Run:
pnpm run --filter @sentry/mcp-core generate-definitions
pnpm run tsc && pnpm run lint && pnpm run test
Open decisions
- Whether to support source-complete issue
actionMatch/filterMatch = none or stay CLI-compatible with all | any.
- Whether to include
get_alert_rule_action_options in the first pass to make action payload authoring discoverable.
- Whether to make metric alert project filtering a first-class
projectSlug parameter or keep only the org route and projects array.
Summary
Implement MCP alert rule tools with parity to the Sentry CLI
alert issuesandalert metricssurfaces.Existing related issue: #277 covers only issue alert rule management. This issue expands the scope to both issue alerts and metric alerts and maps the CLI implementation to MCP.
CLI surface to map
CLI route:
/Users/dcramer/src/cli/src/commands/alertIssue alerts (
sentry alert issues):list: list project-scoped issue alert rules.view: resolve by ID or exact name and fetch details.create: create project issue alert rule from name, conditions, actions, action match, frequency, optional environment, filters, filter match, owner.edit: GET full rule document, merge partial fields, PUT full replacement.delete: delete project issue alert rule.Metric alerts (
sentry alert metrics):list: list org-scoped metric alert rules.view: resolve by ID or exact name and fetch details.create: create org metric alert rule from name, query, aggregate, dataset, time window, triggers, optional projects, environment, owner.edit: GET full rule document, merge partial fields, PUT update.delete: delete org metric alert rule.Source-validated endpoints
Validated in
~/src/sentry:src/sentry/api/urls.pysrc/sentry/api/endpoints/project_rules.pyandproject_rule_details.pysrc/sentry/incidents/endpoints/organization_alert_rule_index.pyandorganization_alert_rule_details.pyIssue alert endpoints:
GET /api/0/projects/{org}/{project}/rules/POST /api/0/projects/{org}/{project}/rules/GET /api/0/projects/{org}/{project}/rules/{rule_id}/PUT /api/0/projects/{org}/{project}/rules/{rule_id}/DELETE /api/0/projects/{org}/{project}/rules/{rule_id}/Source notes:
202 Accepted, not 204.actionMatchandfilterMatchsupportall,any, andnonein source. The CLI only exposesall | any; decide whether MCP should preserve the CLI narrower enum or support source-completenone.frequencysource range is 5 to 43200 minutes. The CLI currently only checks positive values; MCP should enforce the source range.Metric alert endpoints:
GET /api/0/organizations/{org}/alert-rules/POST /api/0/organizations/{org}/alert-rules/GET /api/0/organizations/{org}/alert-rules/{alert_rule_id}/PUT /api/0/organizations/{org}/alert-rules/{alert_rule_id}/DELETE /api/0/organizations/{org}/alert-rules/{alert_rule_id}/GET /api/0/organizations/{org}/alert-rules/available-actions/Source notes:
204 No Content.202with auuidwhen async Slack channel lookup is required; MCP output should handle both async and created/updated rule responses.Proposed MCP tools
Keep these catalog-only initially; do not add to
TOP_LEVEL_TOOL_NAMESunless we intentionally expand the direct surface.Use separate issue-alert and metric-alert tools rather than one giant discriminated union. The payloads, scopes, and endpoint semantics differ enough that separate schemas will be easier for agents to call correctly.
Issue alert tools
find_issue_alert_rulesorganizationSlug,projectSlug, optionalcursor,limit,regionUrl.get_issue_alert_ruleorganizationSlug,projectSlug,ruleIdOrName, optionalregionUrl.create_issue_alert_ruleorganizationSlug,projectSlug,name,conditions,actions,actionMatch, optionalfrequency,environment,filters,filterMatch,owner,regionUrl.conditionsandactions.update_issue_alert_ruleorganizationSlug,projectSlug,ruleIdOrName, optional editable fields.nullforenvironmentandowner.delete_issue_alert_ruleorganizationSlug,projectSlug,ruleIdOrName,regionUrl.Metric alert tools
find_metric_alert_rulesorganizationSlug, optionalprojectSlug,cursor,limit,regionUrl.get_metric_alert_ruleorganizationSlug,ruleIdOrName, optionalregionUrl.create_metric_alert_ruleorganizationSlug,name,query,aggregate,dataset,timeWindow,triggers, optionalprojects,environment,owner,regionUrl.errors,transactions,sessions,events,spans,metrics; source docs also mentiongeneric-metrics, so verify before final schema.uuidresponse.update_metric_alert_ruleorganizationSlug,ruleIdOrName, optional editable fields.active-> API value0,disabled-> API value1; active responses may omit status, so display omitted/0 as active.nullforenvironmentandowner; empty project list should clear project filters.delete_metric_alert_ruleorganizationSlug,ruleIdOrName,regionUrl.Optional helper:
get_alert_rule_action_optionsGET /organizations/{org}/alert-rules/available-actions/.API client work
packages/mcp-core/src/api-client/schema.tsandtypes.ts:packages/mcp-core/src/api-client/client.ts:listIssueAlertRules,getIssueAlertRule,createIssueAlertRule,updateIssueAlertRule,deleteIssueAlertRulelistMetricAlertRules,getMetricAlertRule,createMetricAlertRule,updateMetricAlertRule,deleteMetricAlertRulegetMetricAlertAvailableActionsregionUrlviaapiServiceFromContext.packages/mcp-core/src/tools/support/alerts/:Required scopes and annotations
Validate exact scopes against existing MCP auth and Sentry API behavior before landing.
Expected shape:
project:readorevent:readproject:writeorg:readplus project accessorg:writeopenWorldHint: truedestructiveHint: truedestructiveHint: true,idempotentHint: truedestructiveHint: falseTesting
uuid0,1, and"1"pnpm run --filter @sentry/mcp-core generate-definitionspnpm run tsc && pnpm run lint && pnpm run testOpen decisions
actionMatch/filterMatch = noneor stay CLI-compatible withall | any.get_alert_rule_action_optionsin the first pass to make action payload authoring discoverable.projectSlugparameter or keep only the org route andprojectsarray.