Skip to main content
Glama
rrvrs

jira-alerts-mcp

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
HOSTNoHost for HTTP transport. Defaults to 127.0.0.1.127.0.0.1
PORTNoPort for HTTP transport. Defaults to 3000.3000
JSM_EMAILNoYour Atlassian account email, used with JSM_API_TOKEN.
TRANSPORTNoTransport to use: 'stdio' (default) or 'http'.stdio
JSM_CLOUD_IDYesYour Atlassian site's cloud id (a UUID).
ALLOWED_HOSTSNoComma-separated Host allowlist. Required if HOST is set beyond loopback - see SECURITY.md.
JSM_API_TOKENNoYour Atlassian API token, created at https://id.atlassian.com/manage-profile/security/api-tokens.
JSM_OAUTH_TOKENNoOAuth 3LO bearer token; takes precedence if set.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
jsm_list_alertsA

Search and list alerts in Jira Service Management Operations.

This is the entry point for almost every alert workflow: use it to find open or unacknowledged alerts, filter by priority/team/tag, and to resolve a short tinyId (as shown in the JSM UI) into the full alert id that every other alert tool requires. It reads only — it never creates or modifies alerts.

Args:

  • query (string, optional): field:value search, e.g. "status:open AND priority:P1"

  • limit (number): 1-100, default 20

  • offset (number): records to skip, default 0

  • sort (string): field to sort by, default "createdAt"

  • order ('asc' | 'desc'): default "desc"

  • response_format ('markdown' | 'json'): default "markdown"

Returns (json format): { "alerts": [ { "id": string, // full alert id — pass this to other tools "tinyId": string, // short id shown in the JSM UI "message": string, "status": "open" | "closed", "acknowledged": boolean, "priority": "P1".."P5", "count": number, // dedupe count "tags": string[], "owner": string, "createdAt": string, // ISO 8601 "lastOccurredAt": string } ], "pagination": { "count": number, "offset": number, "has_more": boolean, "next_offset": number } }

Examples:

  • "What's on fire right now?" -> query="status:open AND acknowledged:false", sort="createdAt"

  • "Show P1s from the Payments team" -> query="priority:P1 AND teams:Payments"

  • "Find the alert about Redis latency" -> query="message:Redis"

Constraints and errors:

  • offset + limit must stay below 20000; the API refuses to page deeper.

  • A malformed query returns HTTP 400 — field names are case-sensitive.

jsm_get_alertA

Retrieve the full detail of a single JSM alert, including its description, custom details/extraProperties, responders, tags and dedupe count.

Use this after jsm_list_alerts when you need the payload an integration attached to the alert (host, service, metric values, runbook links) — the list endpoint returns a thinner record without the description or details map.

Args:

  • identifier (string): the full alert id, or an alias when identifier_type='alias'

  • identifier_type ('id' | 'alias'): default 'id'

  • response_format ('markdown' | 'json'): default 'markdown'

Returns (json format): a single alert object with id, tinyId, message, description, status, acknowledged, snoozed, priority, source, owner, tags, responders, details (custom key/value map), extraProperties, count, createdAt, updatedAt, lastOccurredAt, and a report block with acknowledgedBy/closedBy. Responder ids are resolved to names where the credentials allow it.

Examples:

  • "What does alert #4821 actually say?" -> resolve the id via jsm_list_alerts, then call with identifier=

  • "Look up the alert our pipeline created with alias 'redis-latency-prod'" -> identifier="redis-latency-prod", identifier_type="alias"

Error handling:

  • HTTP 404 usually means a tinyId was passed instead of the full id. Resolve it with jsm_list_alerts first.

  • Aliases only resolve against OPEN alerts; a closed alert must be fetched by id.

jsm_list_alert_notesA

List the notes (human comments) recorded on a JSM alert's activity timeline, newest first by default.

Notes are where responders write triage context, and where integrations append re-fire and resolution updates for a deduplicated alert. Read them before acting on an alert so you don't repeat work someone already did.

Args:

  • alert_id (string): the full alert id (not the tinyId)

  • limit (number): 1-100, default 20

  • order ('asc' | 'desc'): default 'desc'

  • offset (string, optional): opaque cursor from a previous response's next_cursor

  • response_format ('markdown' | 'json'): default 'markdown'

Returns (json format): { "notes": [{ "note": string, "owner": string, "createdAt": string, "offset": string }], "pagination": { "count": number, "has_more": boolean, "next_cursor": string } }

Examples:

  • "Has anyone looked at this alert yet?" -> alert_id=, limit=10

  • "Read the full triage history oldest first" -> order="asc", limit=100

Note: these endpoints page with opaque cursors, not numeric offsets — pass next_cursor back as 'offset'.

jsm_list_alert_logsA

List the system activity log for a JSM alert — every state transition, notification, escalation and automated action, newest first by default.

Use this to answer "why did nobody get paged?" or "when was this escalated and to whom?". Logs are system-generated; human comments live in jsm_list_alert_notes instead.

Args:

  • alert_id (string): the full alert id (not the tinyId)

  • limit (number): 1-100, default 20

  • order ('asc' | 'desc'): default 'desc'

  • offset (string, optional): opaque cursor from a previous response's next_cursor

  • response_format ('markdown' | 'json'): default 'markdown'

Returns (json format): { "logs": [{ "log": string, "owner": string, "createdAt": string, "type": string, "offset": string }], "pagination": { "count": number, "has_more": boolean, "next_cursor": string } }

Examples:

  • "Trace the escalation path for this alert" -> alert_id=, order="asc", limit=100

  • "Who acked this and when?" -> alert_id=, limit=20

jsm_get_request_statusA

Check whether an asynchronous alert action actually succeeded.

Every JSM alert write (acknowledge, close, add note, assign, snooze) returns immediately with a requestId and does NOT apply the change synchronously. Pass that requestId here to confirm the action landed — this is the correct way to verify a write, rather than immediately re-reading the alert and finding it unchanged.

Args:

  • request_id (string): the requestId returned by a write tool

  • response_format ('markdown' | 'json'): default 'markdown'

Returns (json format): { "action": string, // e.g. "Acknowledge" "isSuccess": boolean, "status": string, // human-readable outcome, e.g. "Alert acknowledged" "processedAt": string, // ISO 8601 "alertId": string, "alias": string }

Examples:

  • After jsm_acknowledge_alert returns requestId "d383c6e9-..." -> request_id="d383c6e9-..."

Error handling:

  • HTTP 404 shortly after a write usually means the request is still queued; wait a second and retry.

jsm_create_alertA

Create a new alert in Jira Service Management Operations.

This pages people. A created alert enters the team's routing and escalation rules exactly as one raised by a monitoring integration would, so someone's phone may ring. Create one when a human wants an incident tracked and escalated — not to leave a note, which is jsm_add_alert_note, and not to record something nobody needs to act on.

Args:

  • message (string): one-line summary. The ONLY required field.

  • alias (string, optional): de-duplication key — see below

  • description (string, optional): longer detail, impact, what to try

  • priority ('P1'..'P5', optional): P1 highest; omit to let routing rules decide

  • responders (array, optional): [{ id, type }] with type 'user' | 'team' | 'escalation' | 'schedule'

  • visible_to (array, optional): [{ id, type }] with type 'user' | 'team'; max 50

  • entity (string, optional): what the alert is about, e.g. 'payments-api'

  • tags (string[], optional)

  • actions (string[], optional): names of custom actions configured in your org

  • extra_properties (object, optional): arbitrary key/value context

  • note (string, optional): note recorded on the new alert's timeline

  • source (string, optional): where the alert came from, e.g. 'claude-mcp'

There is no 'user' argument, unlike the other write tools: this endpoint has no actor override, and the alert is created as the owner of the credentials.

Returns: { "requestId": string, "result": string, "alias": string }

IMPORTANT: this is asynchronous, and it does not return the new alert's id. The response confirms the request was accepted, not that an alert exists. Unusually for this API the status code is 200 rather than 202, which does not make it synchronous. To get the id: call jsm_get_request_status with the returned requestId, or — if you set an alias — jsm_get_alert with identifier_type='alias'.

Alias is the de-duplication key, and it is the difference between a safe retry and a silent no-op. Creating with an alias that already has an OPEN alert does not create a second alert; it increments the existing one's count and leaves everything else alone. That makes a retried create safe. It also means reusing an alias from an earlier, still-open incident quietly does nothing visible — so make aliases specific to the occurrence, not to the check.

Examples:

  • "Raise a P1 for the payments API being down" -> message="Payments API returning 503", priority="P1", entity="payments-api"

  • Retryable create -> alias="payments-api-503-2026-09-05T11:00"

Constraints and errors:

  • Needs write:ops-alert:jira-service-management alongside the read scope. A token with only read scopes gets 403.

  • Responders bypass the team's routing rules. Omit them unless you specifically want to route around routing.

  • HTTP 422 usually means a responder id doesn't exist or its type is wrong.

jsm_acknowledge_alertA

Acknowledge an open JSM alert, stopping further escalation notifications for it.

Acknowledging signals that a human has picked the alert up. It does not resolve the alert — use jsm_close_alert for that. Acknowledging an already-acknowledged alert is a no-op.

Args:

  • alert_id (string): the full alert id (not the tinyId)

Returns: { "requestId": string, "result": string, "alert_id": string }

IMPORTANT: this action is asynchronous. The response confirms the request was accepted, not that the alert changed. Verify with jsm_get_request_status using the returned requestId.

Examples:

  • "Ack the Redis latency alert, I'm on it" -> alert_id=, note="Investigating, RVS"

jsm_unacknowledge_alertA

Return an acknowledged JSM alert to unacknowledged, so escalation notifications resume.

Use this when someone acked an alert they cannot actually work — picked it up by mistake, or got pulled onto something else — and it needs to go back into the escalation path so the next responder is paged. It does not close, snooze or reassign the alert.

Args:

  • alert_id (string): the full alert id (not the tinyId)

Returns: { "requestId": string, "result": string, "alert_id": string }

IMPORTANT: this action is asynchronous. Verify with jsm_get_request_status using the returned requestId.

This restarts paging. Say so before doing it on someone's behalf — the practical effect is that a phone rings.

Examples:

  • "I can't take this one after all, put it back" -> alert_id=, note="Handing back, on another incident"

Constraints and errors:

  • Unacknowledging an alert that was never acknowledged is a no-op, not an error.

jsm_snooze_alertA

Silence a JSM alert's notifications until a specific instant, after which it resumes as if untouched.

Snoozing is the right tool for "we know, and there is nothing to do until the maintenance window ends" — it stops the paging without pretending the alert is resolved. Closing it would remove it from the open queue and lose the fact that it is still an open problem.

Args:

  • alert_id (string): the full alert id (not the tinyId)

  • end_time (string): ISO 8601 instant with an offset, e.g. "2026-09-05T18:30:00Z"

Returns: { "requestId": string, "result": string, "alert_id": string }

IMPORTANT: this action is asynchronous. Verify with jsm_get_request_status using the returned requestId.

Time handling is the sharp edge here. end_time is an absolute instant, not a duration — "snooze for two hours" means computing the instant yourself from the current time. A past instant is accepted, and the alert un-snoozes immediately, which looks exactly like the call having failed. Send an explicit offset ('Z' or '+05:30') rather than a bare local time.

Examples:

  • "Snooze this until the deploy finishes at 6pm UTC" -> end_time="2026-09-05T18:00:00Z"

  • "Give it an hour" -> compute now + 1h as an ISO instant, then pass it

Constraints and errors:

  • Snoozing a closed alert has no useful effect; close is terminal for notification purposes.

jsm_assign_alertA

Make one person the owner of a JSM alert, so it is clear who is working it.

Assigning names an owner; jsm_add_alert_responder adds people to notify without taking ownership away. Reach for this when triage has decided whose problem it is, and for that one alert rather than a class of them — routing rules, not assignment, are how a class of alerts finds its team.

Args:

  • alert_id (string): the full alert id (not the tinyId)

  • account_id (string): Atlassian account id of the assignee

Returns: { "requestId": string, "result": string, "alert_id": string }

IMPORTANT: this action is asynchronous. Verify with jsm_get_request_status using the returned requestId.

account_id is an Atlassian account id, not an email address and not a display name. It looks like '712020:9ae5385e-6a4c-4f0e-9c02-6f8a1e21d7b1'. Both other forms are rejected. To find one: jsm_get_on_call and jsm_get_alert both return account ids for the people they name, so read the id from there rather than guessing from a name.

Examples:

  • "Assign this to whoever is on call for payments" -> jsm_get_on_call first, take the account id from the result, then assign

Constraints and errors:

  • HTTP 422 or a failed request status usually means the account id is wrong, or the account has no JSM Operations access on that team.

jsm_escalate_alertA

Push a JSM alert into an escalation policy immediately, rather than waiting for it to escalate on its own.

Use this when an alert is not getting picked up and waiting out the escalation timer is not acceptable. It pages the next people in that policy now.

Args:

  • alert_id (string): the full alert id (not the tinyId)

  • escalation_id (string): id of the escalation policy to run

Returns: { "requestId": string, "result": string, "alert_id": string }

IMPORTANT: this action is asynchronous. Verify with jsm_get_request_status using the returned requestId.

This pages people out of band, ahead of the schedule they agreed to. Confirm with the user before escalating on their behalf.

escalation_id is an escalation policy id — not a team id and not a schedule id. The three are separate objects with separate ids, and passing the wrong one fails with 422 rather than escalating to something adjacent.

Examples:

  • "Nobody has picked this up, escalate it" -> get the escalation id for the team, then escalate

Constraints and errors:

  • HTTP 422 or a failed request status usually means escalation_id is not an escalation, or belongs to a different team than the alert.

jsm_close_alertA

Close a JSM alert, marking it resolved and ending all notifications for it.

Closing is how an alert leaves the open queue. Treat it as effectively one-way: a closed alert cannot be reopened through this API, and a recurring condition will create a fresh alert (or increment a deduplicated one) rather than reviving this record. Prefer jsm_acknowledge_alert while work is still in progress.

Args:

  • alert_id (string): the full alert id (not the tinyId)

Returns: { "requestId": string, "result": string, "alert_id": string }

IMPORTANT: this action is asynchronous. Verify with jsm_get_request_status using the returned requestId.

Examples:

  • "Close it, the deploy fixed it" -> alert_id=, note="Resolved by rollback of build 4412"

Don't use when: the alert is still being worked — acknowledge instead.

jsm_update_alert_fieldA

Overwrite one field on an existing JSM alert: its priority, its message, or its description.

This is how an alert gets corrected once triage knows more than the integration that raised it did — a P3 that turns out to be customer-facing, a message that says "check failed" when it should say which check, a description that should carry what has been tried.

Args:

  • alert_id (string): the full alert id (not the tinyId)

  • field ('priority' | 'message' | 'description'): which field to overwrite

  • value (string): the new value

There are no 'user' or 'source' arguments here, unlike the other write tools: these three endpoints take only the value.

Returns: { "requestId": string, "result": string, "alert_id": string }

IMPORTANT: this action is asynchronous. Verify with jsm_get_request_status using the returned requestId.

This overwrites, it does not append. Reading the current value first with jsm_get_alert is the difference between adding context to a description and destroying what someone else wrote in it. If you mean to add to the record without replacing anything, use jsm_add_alert_note instead — notes are additive and are what the activity timeline is for.

For field='priority', value must be exactly one of P1, P2, P3, P4, P5 — not "high", not "1", not "p1".

Examples:

  • "This is worse than we thought, make it a P1" -> field="priority", value="P1"

  • "Fix the alert title to name the failing endpoint" -> read it first, then field="message"

Constraints and errors:

  • Raising priority may change who is paged, since routing and escalation rules read it.

jsm_add_alert_noteA

Append a note to a JSM alert's activity timeline without changing its state.

Use this to record triage findings, link a runbook or dashboard, or leave context for the next responder. It does not acknowledge, close, or reassign the alert.

Args:

  • alert_id (string): the full alert id (not the tinyId)

  • note (string): the note text

  • user (string, optional): actor name/email; defaults to the credential owner

  • source (string, optional): source label for the activity log

Returns: { "requestId": string, "result": string, "alert_id": string }

IMPORTANT: this action is asynchronous. Verify with jsm_get_request_status using the returned requestId.

Examples:

  • "Note that this correlates with the 14:02 deploy" -> alert_id=, note="Correlates with deploy 4412 at 14:02 UTC"

jsm_update_alert_noteA

Replace the text of an existing note on a JSM alert.

Use it to correct a note you just wrote — a wrong hostname, a stale conclusion. Prefer adding a new note with jsm_add_alert_note for anything that reads as a development rather than a correction: the timeline is the record of what responders knew and when, and editing history out of it costs more than an extra line.

Args:

  • alert_id (string): the full alert id (not the tinyId)

  • note_id (string): id of the note to edit, from jsm_list_alert_notes

  • note (string): the replacement text

Returns the updated note: { "alert_id", "note_id", "note", "owner", "createdAt", "updatedAt" }

Unlike every other alert write, this one is synchronous. It answers with the note itself, so there is no requestId and nothing to verify with jsm_get_request_status.

This replaces the note's whole text. There is no append. Read the note first if you mean to add to it.

Examples:

  • "Fix my last note, the host is db-3 not db-2" -> jsm_list_alert_notes, take the id, then update with the corrected text

Constraints and errors:

  • HTTP 404 means the note id does not belong to that alert. Note ids come from jsm_list_alert_notes, not from the note's text.

jsm_delete_alert_noteA

Permanently remove a note from a JSM alert's timeline.

Reach for this only for a note that should never have been written — a pasted credential, someone's personal information, a note on the wrong alert. Not for a note that turned out to be wrong: that is what jsm_update_alert_note is for, and being able to see what a responder believed at the time is most of what the timeline is worth.

Args:

  • alert_id (string): the full alert id (not the tinyId)

  • note_id (string): id of the note to delete, from jsm_list_alert_notes

Returns: { "deleted": true, "note_id": string }

There is no undo, and no confirmation step at the API. The note is gone the moment this returns. Confirm with the user before calling it, and quote the note's text back to them first so they are deleting the thing they think they are.

Unlike most alert writes this is synchronous: the API answers 204 with no body, so there is no requestId to verify.

Constraints and errors:

  • Needs delete:ops-alert:jira-service-management, which is a separate grant from write:ops-alert. A token that can edit notes may still get 403 here.

jsm_add_alert_tagsA

Add one or more tags to a JSM alert. Tags are additive — existing ones stay.

Tags are how alerts get grouped and found later: jsm_list_alerts can filter on them (tag:"db"), and they are what turns a scattering of individual alerts into "the seventeen from last night's storage incident".

Args:

  • alert_id (string): the full alert id (not the tinyId)

  • tags (string[]): one or more tag names

Returns: { "requestId": string, "result": string, "alert_id": string }

IMPORTANT: this action is asynchronous. Verify with jsm_get_request_status using the returned requestId.

Tags are case-sensitive. 'DB' and 'db' are two tags, and searches will not find one by the other — so match whatever the team already uses rather than inventing a casing.

Examples:

  • "Tag this as part of the storage incident" -> tags=["incident-2026-09-05", "storage"]

jsm_remove_alert_tagsA

Remove one or more tags from a JSM alert.

Args:

  • alert_id (string): the full alert id (not the tinyId)

  • tags (string[]): the tag names to remove

Returns: { "requestId": string, "result": string, "alert_id": string }

IMPORTANT: this action is asynchronous. Verify with jsm_get_request_status using the returned requestId.

Removal matches exactly and is case-sensitive, so removing 'DB' leaves 'db' in place. Read the alert's current tags with jsm_get_alert first rather than guessing the casing — a removal that silently matches nothing still returns a successful receipt.

Constraints and errors:

  • Needs delete:ops-alert:jira-service-management, a separate grant from write:ops-alert. Adding tags can work where removing them returns 403.

jsm_add_alert_extra_propertiesA

Attach arbitrary key/value context to a JSM alert, or overwrite properties already on it.

Extra properties are the structured half of an alert, next to the prose in its description: a runbook link, the region, the deploy that preceded it, a trace id. Unlike a note they can be read back programmatically by whatever picks the alert up next.

Args:

  • alert_id (string): the full alert id (not the tinyId)

  • extra_properties (object): key/value pairs; values may be strings, numbers or booleans

Returns: { "requestId": string, "result": string, "alert_id": string }

IMPORTANT: this action is asynchronous. Verify with jsm_get_request_status using the returned requestId.

This merges by key: keys not mentioned are left alone, and a key that already exists is overwritten without warning. Read the alert first with jsm_get_alert if you need to know what a key currently holds.

Examples:

jsm_remove_alert_extra_propertiesA

Remove properties from a JSM alert by key.

Args:

  • alert_id (string): the full alert id (not the tinyId)

  • keys (string[]): the property keys to remove — keys, not values

Returns: { "requestId": string, "result": string, "alert_id": string }

IMPORTANT: this action is asynchronous. Verify with jsm_get_request_status using the returned requestId.

A key that is not present is not an error, so a receipt here does not prove anything was removed. Read the alert back if that matters.

Constraints and errors:

  • Needs delete:ops-alert:jira-service-management, a separate grant from write:ops-alert.

jsm_add_alert_responderA

Add a responder (user, team, escalation or schedule) to an existing JSM alert so they are notified and become accountable for it.

Use this to pull in another team once triage shows the alert belongs elsewhere. Responders are additive — this does not remove the existing ones.

Args:

  • alert_id (string): the full alert id (not the tinyId)

  • responder_id (string): id of the user/team/escalation/schedule to add

  • responder_type ('user' | 'team' | 'escalation' | 'schedule'): what responder_id refers to

Returns: { "requestId": string, "result": string, "alert_id": string }

IMPORTANT: this action is asynchronous. Verify with jsm_get_request_status using the returned requestId.

Examples:

  • "Page the database team on this" -> responder_id=, responder_type="team"

Error handling:

  • HTTP 422 or a failed request status usually means responder_id doesn't exist or its type is wrong. Team and schedule ids can be found with jsm_list_schedules or the JSM UI.

jsm_execute_alert_actionA

Run one of your organisation's own custom alert actions — the buttons a team wires up on an integration, like "Restart service" or "Roll back deploy".

What these do is entirely up to whoever configured them, and this server cannot see it. An action name is a request to run somebody's automation against production.

Args:

  • alert_id (string): the full alert id (not the tinyId)

  • action_name (string): the configured action's name, exactly as configured

Returns: { "requestId": string, "result": string, "alert_id": string }

IMPORTANT: this action is asynchronous. Verify with jsm_get_request_status using the returned requestId.

Do not guess an action name. There is no endpoint that lists them, so a plausible-sounding guess is exactly as likely to be a real destructive automation as it is to be nothing. An unrecognised name is accepted and silently does nothing, which means a successful receipt is not evidence that anything ran. Ask the user which action they mean, and confirm before running it.

Constraints and errors:

  • Names are configured per integration, so an action that exists for one alert's source may not exist for another's.

jsm_delete_alertA

Permanently delete a JSM alert and everything recorded on it.

This is almost never the right tool. Closing an alert with jsm_close_alert takes it out of the open queue and keeps the record: who was paged, what they tried, when it resolved. Deleting throws that away, for everyone, with no undo — the notes, the activity log, the attachments and the timing all go with it. A closed alert costs nothing to keep.

The cases that justify it are narrow: an alert containing credentials or personal data that must not persist, or a flood of alerts from a misconfigured integration that never represented anything real.

Args:

  • alert_id (string): the full alert id (not the tinyId)

Returns: { "requestId": string, "result": string, "alert_id": string }

IMPORTANT: this action is asynchronous. Verify with jsm_get_request_status using the returned requestId.

Before calling this, read the alert back with jsm_get_alert and show the user what they are about to lose — its message, its state and how many notes it carries — and get an explicit yes. Never call it to tidy up, to clear a queue, or in a loop over search results.

Constraints and errors:

  • Needs delete:ops-alert:jira-service-management, a separate grant from write:ops-alert. A token that can close alerts usually cannot delete them, and that is a deliberate configuration rather than a problem to work around.

jsm_list_schedulesA

List the on-call schedules configured in JSM Operations, with their ids, owning teams and timezones.

Start here when you need a schedule id for jsm_get_on_call or jsm_get_next_on_call, or when you want to know which rotations exist at all.

Args:

  • limit (number): 1-100, default 20

  • offset (number): records to skip, default 0

  • response_format ('markdown' | 'json'): default 'markdown'

Returns (json format): { "schedules": [ { "id": string, "name": string, "description": string, "timezone": string, "enabled": boolean, "ownerTeam": { "id": string, "name": string } } ], "pagination": { "count": number, "offset": number, "has_more": boolean, "next_offset": number } }

Examples:

  • "What on-call rotations do we have?" -> no args

  • "Find the schedule id for the platform rotation" -> then match on name

Error handling:

  • HTTP 401 here while alert tools work means the token is missing read:ops-config:jira-service-management — schedules and on-call sit behind a different scope from alerts, so this is a scope gap, not a bad credential.

jsm_get_on_callA

Return the responders currently on-call for a JSM schedule, optionally evaluated at a past or future timestamp.

This is the tool for "who do I wake up?" and, with the 'date' argument, for "who was on-call when this incident started?" — which is often the more useful question during a post-incident review.

Args:

  • schedule_id (string): schedule id, or name if schedule_identifier_type='name'

  • schedule_identifier_type ('id' | 'name'): default 'id'

  • date (string, optional): ISO 8601 timestamp to evaluate at; defaults to now

  • flat (boolean): default true — flat list of user identifiers; false shows rotation/escalation nesting

  • response_format ('markdown' | 'json'): default 'markdown'

Returns (json format): { "on_call": { ... }, // the API response, unmodified "participants": [ // resolved, and the field to read { "id": string, "type": string, "displayName": string, "emailAddress": string } ] }

Responders are Atlassian account ids; this tool resolves them to names for you, so there is no need to look an id up elsewhere. If the credentials lack the Jira user scope the ids are still returned, with a note saying so.

Examples:

  • "Who's on-call for platform right now?" -> schedule_id="platform", schedule_identifier_type="name"

  • "Who was on-call at 03:14 UTC yesterday?" -> date="2026-08-20T03:14:00Z"

Error handling:

  • An empty result means nobody is rostered at that moment — a real and important answer, not a failure.

  • HTTP 404 means the schedule id/name is wrong; list them with jsm_list_schedules.

  • HTTP 401 here while alert tools work means the token is missing read:ops-config:jira-service-management — schedules and on-call sit behind a different scope from alerts, so this is a scope gap, not a bad credential.

jsm_get_next_on_callA

Return the responders who take over the next shift on a JSM schedule, and when that shift begins.

Use this for handover messages and for deciding whether an alert can wait for the next rotation.

Args:

  • schedule_id (string): schedule id, or name if schedule_identifier_type='name'

  • schedule_identifier_type ('id' | 'name'): default 'id'

  • date (string, optional): ISO 8601 reference point; "next" is computed relative to it. Defaults to now

  • flat (boolean): default true — flat list of user identifiers; false shows rotation/escalation nesting

  • response_format ('markdown' | 'json'): default 'markdown'

Returns (json format): { "next_on_call": { ... }, // the API response, unmodified "participants": [ // resolved, and the field to read { "id": string, "type": string, "displayName": string, "emailAddress": string } ] }

Responders are Atlassian account ids; this tool resolves them to names for you. If the credentials lack the Jira user scope the ids are still returned, with a note saying so.

Examples:

  • "Who picks up after this shift?" -> schedule_id=

  • "Who is on after the shift that covers Thursday?" -> date="2026-08-27T12:00:00Z"

  • "Draft a handover note" -> combine with jsm_list_alerts query="status:open"

Error handling:

  • HTTP 401 here while alert tools work means the token is missing read:ops-config:jira-service-management — schedules and on-call sit behind a different scope from alerts, so this is a scope gap, not a bad credential.

jsm_get_schedule_timelineA

Return the on-call rotation periods for a JSM schedule — who covers each shift, and exactly when each shift starts and ends.

This is the tool for any question about shift boundaries rather than a single moment: "when does the current shift end?", "when is the handover?", "who covers the weekend?", "show me next week's rota". Answering those by calling jsm_get_on_call at guessed timestamps takes many calls and still cannot find a boundary exactly; this takes one.

Responders are resolved to names, so periods come back with people rather than bare account ids.

Args:

  • schedule_id (string): schedule id, or name if schedule_identifier_type='name'

  • schedule_identifier_type ('id' | 'name'): default 'id'

  • date (string, optional): ISO 8601 instant the window should cover; defaults to now

  • response_format ('markdown' | 'json'): default 'markdown'

Returns (json format): { "shifts": [ { "start": string, // ISO 8601 "end": string, // ISO 8601 "rotation_name": string, "type": "base" | "override" | "forwarding" | "historical", "responders": [ { "id": string, "displayName": string, "emailAddress": string } ] } ] }

The window spans roughly three weeks around the requested date, so both the shift in progress and the ones on either side of it are included.

Examples:

  • "When does the current on-call shift end?" -> schedule_id=

  • "Who has the rota next week?" -> date=

  • "When did the handover happen on Tuesday?" -> date="2026-08-25T00:00:00Z"

Error handling:

  • Periods of type 'historical' are in the past; 'override' means someone swapped in.

  • HTTP 401 here while alert tools work means the token is missing read:ops-config:jira-service-management — the same scope the other on-call tools need.

jsm_list_capabilitiesA

Report every toolset this server knows about, whether it is currently loaded, and how to load one that is not.

Call this before telling the user something is impossible. This server carries far more of the Jira Service Management Operations API than any one install registers — the operator chooses which families load, so an absent tool usually means "not enabled here", not "not supported". This tool tells you which of the two it is, and names the exact environment variable to change.

It takes no arguments, makes no API call, and needs no credentials, so it also answers when the token is missing or wrong.

Args: none beyond response_format.

  • response_format ('markdown' | 'json'): default "markdown"

Returns (json format): { "requested": string[], // the names this process was configured with "read_only": boolean, "tool_count": number, // tools actually registered "toolsets": [ { "name": string, "enabled": boolean, // whether any of its tools are registered "selected": boolean, // whether the selection asked for it; false enabled with true // selected means read-only mode withheld the tools "summary": string, "scopes": string[], // OAuth scopes this family needs "tool_count": number, "tools": string[], "unverified": string // present only when the family was never seen to work } ] }

A toolset carrying unverified ships but no profile loads it, 'all' included — it has to be named on its own, as JSM_TOOLSETS=all,. The string says what blocked it: a JSM plan that excludes the feature, or a permission no credential on the test site held. Enabling it is allowed and may well work on a different site, but say what the limit was before suggesting it.

Examples:

  • User asks for something no loaded tool covers -> call this, then tell them which toolset covers it and that JSM_TOOLSETS needs to include it.

  • Tool exists but its toolset is unverified -> say so plainly, quote the reason, and let the user decide whether their plan differs.

  • "What can you do here?" -> call this rather than guessing from your tool list.

Note: changing JSM_TOOLSETS requires restarting the server. You cannot enable a toolset from inside a conversation.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A4.4/5.0

Scored across 28 tools

Disambiguation5/5

Every tool maps to a distinct resource and action, and the descriptions actively call out neighboring tools to prevent confusion (e.g. logs vs notes, create vs add note, close vs delete, current vs next on-call). There is no pair of tools that appears to do the same thing.

Naming Consistency4/5

All tools share the jsm_ prefix and follow a snake_case verb_noun pattern, with consistent list/get/update/delete pairs throughout. Minor deviations exist between create_alert vs add_alert_* for creating versus attaching, and delete vs remove for notes versus tags/properties, but the conventions are still predictable.

Tool Count3/5

28 tools is on the high side, though the server covers two related domains—alert lifecycle and on-call schedules—plus async verification and capability discovery. The granularity is justified by distinct operations, but the surface is heavy for an agent to scan at a glance.

Completeness4/5

The alert lifecycle is thoroughly covered: create, read, list, update, acknowledge, snooze, close, delete, assign, escalate, responders, notes, tags, extra properties, and logs. Notable gaps are the lack of a remove-responder tool and no way to list escalation policies, teams, or custom action names, which sometimes forces the user to supply ids manually.

Maintenance

ActivityMaintained
ResponsivenessUnresponsive