This Claude Code plugin layers opinionated, developer-friendly workflows on top of Rootly's MCP server for the full incident lifecycle: prevent, respond, learn. The implementation is primarily prompt engineering and workflow orchestration. Incident data flows through the Rootly MCP server at mcp.rootly.com, while hooks use minimal direct REST API calls for low-latency checks.
rootly-claude-plugin/
├── .claude-plugin/
│ ├── plugin.json # Plugin manifest (required)
│ └── marketplace.json # Repo-hosted marketplace metadata
├── .mcp.json # Rootly MCP server reference
├── skills/
│ ├── setup/
│ │ └── SKILL.md # /rootly:setup (first-run experience)
│ ├── deploy-check/
│ │ └── SKILL.md # /rootly:deploy-check
│ ├── respond/
│ │ └── SKILL.md # /rootly:respond
│ ├── oncall/
│ │ └── SKILL.md # /rootly:oncall
│ ├── retro/
│ │ └── SKILL.md # /rootly:retro
│ ├── status/
│ │ └── SKILL.md # /rootly:status
│ ├── ask/
│ │ └── SKILL.md # /rootly:ask
│ ├── brief/
│ │ └── SKILL.md # /rootly:brief (stakeholder communication)
│ └── handoff/
│ └── SKILL.md # /rootly:handoff (shift transitions)
├── agents/
│ ├── incident-investigator.md # Deep incident investigation agent
│ ├── deploy-guardian.md # Deployment risk analysis agent
│ └── retro-analyst.md # Post-incident pattern analysis agent
├── hooks/
│ └── hooks.json # SessionStart + PreToolUse hooks
├── scripts/
│ ├── check-active-incidents.sh # Lightweight pre-commit check
│ ├── validate-token.sh # SessionStart token validation
│ └── register-deploy.sh # Optional: post-push deployment registration
├── README.md
└── LICENSE
{
"name": "rootly",
"version": "1.1.0",
"description": "Full-lifecycle incident management from your IDE. Prevent incidents before deploy, respond in real-time, and learn from post-mortems -- powered by Rootly.",
"author": {
"name": "Rootly AI Labs",
"email": "support@rootly.com",
"url": "https://rootly.com"
},
"homepage": "https://rootly.com/integrations/claude",
"repository": "https://github.com/Rootly-AI-Labs/rootly-claude-plugin",
"license": "Apache-2.0",
"userConfig": {
"ROOTLY_API_TOKEN": {
"description": "Rootly API token used for MCP access and incident workflow hooks",
"sensitive": true
}
},
"keywords": [
"incident-management",
"on-call",
"sre",
"devops",
"deploy-safety",
"retrospectives",
"rootly"
]
}This file provides the repo-hosted marketplace metadata for the plugin.
{
"name": "rootly-plugins",
"owner": {
"name": "Rootly AI Labs",
"email": "support@rootly.com"
},
"metadata": {
"description": "Official Rootly plugins for Claude Code",
"version": "1.1.0"
},
"plugins": [
{
"name": "rootly",
"source": "./",
"description": "Full-lifecycle incident management: deploy safety, incident response, on-call management, and retrospectives.",
"version": "1.1.0",
"author": {
"name": "Rootly AI Labs"
},
"license": "Apache-2.0",
"keywords": ["incident-management", "on-call", "sre", "devops", "rootly"]
}
]
}This file references Rootly's hosted MCP server. The plugin does not bundle a server binary.
{
"mcpServers": {
"rootly": {
"type": "http",
"url": "https://mcp.rootly.com/mcp",
"headers": {
"Authorization": "Bearer ${CLAUDE_PLUGIN_OPTION_ROOTLY_API_TOKEN}"
}
}
}
}Authentication: The plugin declares ROOTLY_API_TOKEN in userConfig, so Claude Code prompts for it when the plugin is enabled and automatically exports it as CLAUDE_PLUGIN_OPTION_ROOTLY_API_TOKEN. The MCP config and hook scripts both use this environment variable with fallback to ROOTLY_API_TOKEN for local development with --plugin-dir.
Alternative configurations (also documented in the README for advanced users):
- CLI setup:
claude mcp add rootly --transport http https://mcp.rootly.com/mcp --header "Authorization: Bearer YOUR_TOKEN" - Local MCP server (for self-hosted Rootly or offline use):
{ "mcpServers": { "rootly": { "command": "uvx", "args": ["--from", "rootly-mcp-server", "rootly-mcp-server"], "env": { "ROOTLY_API_TOKEN": "${user_config.ROOTLY_API_TOKEN}" } } } }
Each skill lives in skills/<name>/SKILL.md with YAML frontmatter.
skills/setup/SKILL.md
Purpose: Guide new users through plugin configuration.
Frontmatter:
name: setup
description: Set up the Rootly plugin. Checks for API token, verifies MCP server connection, and guides through configuration. Run this after installing the plugin.
disable-model-invocation: true
allowed-tools:
- Bash
- mcp__rootly__*Workflow:
- Check if a plugin-configured token or local
ROOTLY_API_TOKENfallback is available - If not set, provide step-by-step instructions:
- Where to get an API token in the Rootly dashboard (Settings > API Keys)
- How to update the plugin configuration with the token
- How to use
export ROOTLY_API_TOKEN=...only as a local development fallback
- If set, test the MCP connection by calling
get_server_version(lightweight read-only tool) - Confirm success or diagnose failure (invalid token, network issue, etc.)
- Check for
.claude/rootly-config.json-- if missing, help create one by listing Rootly services and letting the user pick which map to this repo - Show quick-start guide for available commands
skills/deploy-check/SKILL.md
Purpose: Evaluate deployment safety before pushing code.
Frontmatter:
name: deploy-check
description: Evaluate deployment risk by analyzing code changes against incident history, active incidents, and on-call readiness. Use when a developer is about to deploy, push, or merge code.
argument-hint: [branch-name]
disable-model-invocation: true
context: fork
agent: rootly:deploy-guardian
allowed-tools:
- Bash
- mcp__rootly__*Workflow (encoded in SKILL.md prompt):
- Get current git diff via dynamic context injection (
!git diff --stat HEAD``) - Identify affected services using the resolution chain:
- Read
.claude/rootly-config.jsonif present - Otherwise match git repo name against Rootly services via
search_incidents - Fall back to asking the user
- Read
- Call
search_incidentsfor those services (last 90 days) - Call
find_related_incidentswith the change summary - Check for active P1/P2 incidents on affected services
- Call
get_oncall_handoff_summaryto check on-call availability - Handle edge case: if git diff is empty, report "no changes to evaluate" and exit
- Synthesize into a structured deployment brief:
- Risk level (low/medium/high/critical)
- Active incidents on affected services
- On-call status and availability
- Similar past incidents and what resolved them
- Go/no-go recommendation with reasoning
Dynamic context (injected before Claude sees the prompt):
## Current changes
!`git diff --stat HEAD`
## Current branch
!`git branch --show-current`
## Recent commits
!`git log --oneline -5`skills/respond/SKILL.md
Purpose: Investigate and coordinate incident response from the IDE.
Frontmatter:
name: respond
description: Investigate and respond to a production incident. Pulls context, finds similar past incidents, suggests solutions, and enables coordination -- all from the terminal. Use when paged or when an incident needs attention.
argument-hint: [incident-id]
disable-model-invocation: true
context: fork
agent: rootly:incident-investigator
allowed-tools:
- Bash
- mcp__rootly__*Workflow:
- Accept incident ID from
$ARGUMENTS. If not provided, callsearch_incidentsfiltered to active and list for the user to choose. - If many active incidents, filter by severity (critical/high first) with pagination.
- Call
getIncidentfor full incident context - Call
get_alert_by_short_idor search alerts via OpenAPI tools for alert details - Call
find_related_incidentsfor historical matches - Call
suggest_solutionsfor resolution recommendations - Call
get_oncall_handoff_summaryfor team status - Present structured response brief:
- Incident summary and timeline
- Related historical incidents (with confidence scores)
- Suggested solutions (with confidence scores and sources)
- Current responders and on-call team
- Available actions (update severity, add responder, post status update)
- Human-in-the-loop: ALWAYS present write operations as recommendations. Require explicit user confirmation before executing any mutation (
updateIncident, escalate, add responder, etc.)
Error handling in prompt:
- If MCP tools return errors, report the specific error and suggest manual steps
- If
find_related_incidentsreturns low confidence (< 0.3), flag and suggest manual investigation - If no incidents are active, report "no active incidents" cleanly
Note: context: fork runs this in an isolated subagent to avoid polluting the main coding context with incident data, and agent: rootly:incident-investigator explicitly routes the workflow through the shipped specialist agent.
skills/oncall/SKILL.md
Purpose: Quick view of on-call status and health metrics.
Frontmatter:
name: oncall
description: Show current on-call status, shift metrics, and health indicators for your team. Use to check who's on-call, handoff context, or on-call workload.
argument-hint: [team-name]
disable-model-invocation: true
allowed-tools:
- mcp__rootly__*Workflow:
- Call
get_oncall_handoff_summaryfor current/next on-call - Call
get_oncall_shift_metricsfor workload data - Call
check_oncall_health_riskfor fatigue indicators - Present compact dashboard:
- Current on-call (name, since when, incidents handled this shift)
- Next on-call (name, handoff time)
- Shift health (hours worked, fatigue risk)
- Recent incidents during this shift
skills/retro/SKILL.md
Purpose: Generate a structured post-incident retrospective.
Frontmatter:
name: retro
description: Generate a structured post-incident retrospective from incident data. Use after an incident is resolved to document what happened, why, and action items.
argument-hint: [incident-id]
disable-model-invocation: true
context: fork
agent: rootly:retro-analyst
allowed-tools:
- mcp__rootly__*Workflow:
- Accept incident ID from
$ARGUMENTS - Call
getIncidentfor full incident record - Check incident status -- if still
started, warn user that retro is typically done post-resolution and ask to confirm - Call
get_alert_by_short_idor alert search tools for alert timeline - Call
find_related_incidentsfor pattern context - Generate structured retrospective:
- Summary (1-2 sentences)
- Impact (duration, affected users/services, severity)
- Timeline (key events from alert data)
- Root cause analysis
- Contributing factors
- What went well
- What could be improved
- Action items (with owners if identifiable)
- Pattern note (if similar incidents recur -- "This is the Nth incident of this type in the last 90 days")
- Output as markdown to terminal (copy-pasteable)
skills/status/SKILL.md
Purpose: Quick service health dashboard.
Frontmatter:
name: status
description: Show a compact service health overview including active incidents by severity. Use for a quick health check of your services.
argument-hint: [service-name]
disable-model-invocation: true
allowed-tools:
- mcp__rootly__*Workflow:
- Call
search_incidentsfiltered to active (started) status - Group by service and severity
- Present compact table:
- Services with active incidents
- Severity breakdown (critical/high/medium/low)
- Time-in-incident for each
skills/ask/SKILL.md
Purpose: Free-form questions against incident data.
Frontmatter:
name: ask
description: Ask natural language questions about incidents, on-call, services, and reliability data. Translates your question into Rootly API calls and returns structured answers.
argument-hint: [your question]
disable-model-invocation: true
allowed-tools:
- mcp__rootly__*Workflow:
- Parse the natural language question from
$ARGUMENTS - First, call
list_endpointsto discover available Rootly MCP tools - Select the most appropriate tools for the question
- Execute queries (may require multiple calls)
- Synthesize and present answer with supporting data
- If the question can't be answered with available tools, say so explicitly rather than hallucinating
skills/brief/SKILL.md
Purpose: Generate concise executive/stakeholder briefs for incidents.
Frontmatter:
name: brief
description: Generate a concise stakeholder brief for an incident. Creates executive summary with key details, impact, timeline, and current status.
argument-hint: [incident-id]
disable-model-invocation: true
allowed-tools:
- mcp__rootly__*Workflow:
- Parse incident ID from
$ARGUMENTS - Call
mcp__rootly__getIncidentfor full incident details - Call
mcp__rootly__listIncidentAlertsfor associated alerts - Generate structured brief with business-focused language:
- Executive summary with impact and current status
- Service impact and timeline
- Next steps and resolution approach
- Format for non-technical stakeholders (under 200 words)
Use Cases: CEO updates, customer communications, legal/compliance documentation, cross-team notifications.
skills/handoff/SKILL.md
Purpose: Prepare incident or on-call handoff documents for shift changes.
Frontmatter:
name: handoff
description: Prepare an incident or on-call handoff document. Creates structured summary for shift changes or incident commander transitions.
argument-hint: [incident-id]
disable-model-invocation: true
allowed-tools:
- mcp__rootly__*Workflow:
- Determine handoff type based on
$ARGUMENTS:- Incident handoff (with incident ID): Call
mcp__rootly__getIncidentandmcp__rootly__listIncidentAlerts - On-call handoff (no ID): Call
mcp__rootly__get_oncall_handoff_summaryandmcp__rootly__search_incidents
- Incident handoff (with incident ID): Call
- Generate structured handoff document with:
- Current situation summary
- Actions taken and next steps
- Key contacts and escalation paths
- Critical context and monitoring points
- Format for seamless knowledge transfer
Use Cases: Shift changes, incident commander transitions, on-call handoffs, team coordination.
Agent frontmatter uses comma-separated string format for tools field (matching documented examples).
agents/incident-investigator.md
Frontmatter:
name: incident-investigator
description: Deep production-incident investigator for root-cause analysis, evidence gathering, and remediation planning beyond the initial response brief.
model: sonnet
tools: Read, Grep, Glob, Bash, mcp__rootly__*System prompt responsibilities:
- Gather all alerts, responder actions, and timeline events via
getIncidentand alert tools - Search codebase for recent git commits in affected service directories (
git log --since="3 days ago" -- <paths>) - Find top 5 similar historical incidents via
find_related_incidents - Extract resolution patterns from each similar incident
- Build root cause hypothesis tree with evidence chains
- Rank hypotheses by confidence
- Recommend specific remediation steps
- Output structured investigation report
agents/deploy-guardian.md
Frontmatter:
name: deploy-guardian
description: Deployment safety specialist for blast-radius analysis, downstream dependency checks, and cross-team coordination planning.
model: sonnet
tools: Read, Grep, Glob, Bash, mcp__rootly__*System prompt responsibilities (differentiated from /rootly:deploy-check):
- Analyze full diff and identify all affected services
- Map downstream service dependencies (what else breaks if this service has issues)
- Check active incidents, deployment freezes, on-call gaps
- Evaluate blast radius across dependent services (not just the changed service)
- Cross-reference with incident history for ALL affected services (direct + downstream)
- Assess on-call readiness and fatigue for all impacted teams
- Identify cross-team coordination needs (do other teams need to be notified?)
- Produce go/no-go recommendation with full reasoning and a coordination checklist
agents/retro-analyst.md
Frontmatter:
name: retro-analyst
description: Reliability pattern analyst for retrospectives, recurring-incident clustering, and systemic improvement recommendations.
model: sonnet
tools: Read, Grep, Glob, mcp__rootly__*System prompt responsibilities:
- Pull incidents for the requested scope (service, team, time period) via
search_incidents - Identify recurring root causes and failure modes
- Cluster incidents by pattern (same service, same error type, same trigger)
- Calculate frequency trends (getting better or worse?)
- Identify systemic issues requiring architectural fixes
- Correlate with code changes where possible (via Read/Grep on the codebase)
- Produce structured report with prioritized recommendations
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/validate-token.sh"
}
]
}
],
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"if": "Bash(git commit *)",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/check-active-incidents.sh"
},
{
"type": "command",
"if": "Bash(git push *)",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/check-active-incidents.sh"
}
]
}
]
}
}Hook 1: SessionStart -- Token Validation
- Runs once when Claude Code starts
- Checks for a configured plugin token, then falls back to
ROOTLY_API_TOKENfor local development - If missing, outputs a brief setup message directing user to
/rootly:setup - If set, pings the API to validate (with 2s timeout)
- Never blocks -- informational only
Hook 2: PreToolUse on Bash -- Active Incident Warning
- Uses hook-level
ifconditions so the script only spawns forgit commitandgit push - If git commit/push, makes one REST API call to check active incidents (< 2s)
- Returns warning via stdout if active critical/high incidents found, empty otherwise
- Exit code 0 always (warn, never block)
Design trade-off: Hook scripts make direct REST calls to api.rootly.com rather than going through the MCP server. This is intentional -- hooks need to be fast (< 2 seconds) and cannot invoke MCP tools. The REST calls are simple, read-only checks. This means the plugin depends on both the MCP server (for skills/agents) and the REST API (for hooks).
Why conservative hook design: Hooks run on every matching event. A noisy or slow hook degrades the entire IDE experience. Only the session-start validation and pre-commit incident check are enabled by default. The post-push deployment registration is provided as an opt-in script.
Runtime dependencies: Scripts use curl for REST calls and either jq or python3 for lightweight JSON parsing. If no parser is available, they fail silently per the graceful degradation principle.
#!/bin/bash
# SessionStart hook: check if a Rootly API token is configured.
# Prefer plugin-managed configuration and fall back to the legacy env var
# for local development with --plugin-dir.
ROOTLY_TOKEN="${CLAUDE_PLUGIN_OPTION_ROOTLY_API_TOKEN:-${ROOTLY_API_TOKEN:-}}"
ROOTLY_URL="${ROOTLY_API_URL:-https://api.rootly.com}"
if [ -z "$ROOTLY_TOKEN" ]; then
echo "Rootly plugin: No API token found. Configure the plugin and then run /rootly:setup."
exit 0
fi
# Quick validation ping (with strict timeout)
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Bearer $ROOTLY_TOKEN" \
"$ROOTLY_URL/v1/users/me" \
--max-time 2 2>/dev/null)
if [ "$HTTP_CODE" = "401" ] || [ "$HTTP_CODE" = "403" ]; then
echo "Rootly plugin: API token appears invalid (HTTP $HTTP_CODE). Update the plugin config and run /rootly:setup again."
fi
exit 0#!/bin/bash
# PreToolUse hook: warn about active incidents before git commit/push.
# hooks/hooks.json filters to the relevant Bash commands, so this script
# only needs to perform the incident check.
ROOTLY_TOKEN="${CLAUDE_PLUGIN_OPTION_ROOTLY_API_TOKEN:-${ROOTLY_API_TOKEN:-}}"
if [ -z "$ROOTLY_TOKEN" ]; then
exit 0 # Silent if not configured
fi
# Check for active high-severity incidents
# Uses JSON:API filter syntax per Rootly REST API spec
# Configurable base URL via ROOTLY_API_URL for self-hosted instances
ROOTLY_URL="${ROOTLY_API_URL:-https://api.rootly.com}"
RESPONSE=$(curl -s \
-H "Authorization: Bearer $ROOTLY_TOKEN" \
-H "Content-Type: application/vnd.api+json" \
"$ROOTLY_URL/v1/incidents?filter[status]=started&filter[severity]=critical&page[size]=50" \
--max-time 2 2>/dev/null)
if [ $? -ne 0 ]; then
exit 0 # Silent on network failure
fi
# Count incidents from JSON:API response (data is an array)
if command -v jq &>/dev/null; then
COUNT=$(echo "$RESPONSE" | jq '.data | length' 2>/dev/null)
elif command -v python3 &>/dev/null; then
COUNT=$(echo "$RESPONSE" | python3 -c "
import sys, json
try:
data = json.load(sys.stdin)
print(len(data.get('data', [])))
except:
print('0')
" 2>/dev/null)
else
exit 0
fi
if [ "$COUNT" != "0" ] && [ "$COUNT" != "null" ] && [ -n "$COUNT" ]; then
echo "WARNING: $COUNT active critical incident(s) detected. Run /rootly:status for details before deploying."
fi#!/bin/bash
# Optional: Register a deployment event with Rootly
# NOT wired into hooks by default. Provided as a convenience script.
#
# To enable as a post-push hook, add to your .claude/hooks.json:
# {
# "hooks": {
# "PostToolUse": [{
# "matcher": "Bash",
# "hooks": [{
# "type": "command",
# "command": "<plugin-root>/scripts/register-deploy.sh"
# }]
# }]
# }
# }
# Read stdin (PostToolUse hook input) -- check if this was a git push
INPUT=$(cat)
if command -v jq &>/dev/null; then
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
else
COMMAND=$(echo "$INPUT" | python3 -c "
import sys, json
try: print(json.load(sys.stdin).get('tool_input',{}).get('command',''))
except: print('')
" 2>/dev/null)
fi
if [[ "$COMMAND" != *"git push"* ]]; then
exit 0
fi
ROOTLY_TOKEN="${CLAUDE_PLUGIN_OPTION_ROOTLY_API_TOKEN:-${ROOTLY_API_TOKEN:-}}"
if [ -z "$ROOTLY_TOKEN" ]; then
exit 0
fi
ROOTLY_URL="${ROOTLY_API_URL:-https://api.rootly.com}"
COMMIT_SHA=$(git rev-parse HEAD 2>/dev/null)
BRANCH=$(git branch --show-current 2>/dev/null)
REPO=$(basename "$(git rev-parse --show-toplevel 2>/dev/null)")
curl -s -X POST "$ROOTLY_URL/v1/deployments" \
-H "Authorization: Bearer $ROOTLY_TOKEN" \
-H "Content-Type: application/vnd.api+json" \
-d "{\"commit_sha\": \"$COMMIT_SHA\", \"branch\": \"$BRANCH\", \"repository\": \"$REPO\"}" \
--max-time 3 2>/dev/null
exit 0Skills like deploy-check need to know which Rootly services correspond to the current repo. Resolution chain (in priority order):
- Explicit config:
.claude/rootly-config.jsonin the project:{ "services": ["auth-service", "auth-worker"], "team": "platform-team" } - Repo name matching: Match the git repo name against Rootly service names
- User prompt: Ask the user which service(s) this repo maps to, then suggest they create the config file
The /rootly:setup skill helps create this config file.
The hosted Rootly MCP server exposes many tools, but this plugin depends on a focused subset. Skills and agents reference these by exact name:
| Tool Name | Used By | Purpose |
|---|---|---|
find_related_incidents |
deploy-check, respond, retro, incident-investigator | TF-IDF similarity matching against historical incidents |
suggest_solutions |
respond, incident-investigator | Mine past resolutions for actionable recommendations |
search_incidents |
deploy-check, status, ask, retro-analyst | Search/filter incidents by status, severity, service |
getIncident |
respond, retro, incident-investigator | Get full details of a specific incident (camelCase) |
updateIncident |
respond (with human approval) | Update incident fields (camelCase) |
get_oncall_handoff_summary |
deploy-check, respond, oncall | Current/next on-call with shift context |
get_oncall_shift_metrics |
oncall | Shift hours, counts, grouped by user/team |
check_oncall_health_risk |
oncall, deploy-guardian | Fatigue and workload risk indicators |
get_alert_by_short_id |
respond, retro | Get alert details by short ID |
get_shift_incidents |
oncall | Incidents during a specific shift window |
get_oncall_schedule_summary |
deploy-guardian | Schedule overview for coordination |
check_responder_availability |
deploy-guardian | Whether responders are available |
list_endpoints |
ask | Discover available API endpoints |
get_server_version |
setup | Lightweight connectivity test |
list_shifts |
oncall | List on-call shifts |
create_override_recommendation |
oncall (optional) | Suggest schedule overrides |
Note: getIncident and updateIncident use camelCase (exceptions to the snake_case convention). All other tools use snake_case.
Skills and agents access incident data through the MCP server. Hook scripts make direct REST calls for simple, time-sensitive checks such as active-incident warnings. This is a pragmatic split: MCP is the primary data channel, and REST is used only where hooks need sub-2-second responses.
- Hooks (automatic): Ambient awareness, zero effort
- Skills (one command): Quick answers for specific questions
- Agents (deep): Multi-step investigation when you need thoroughness
All skills that modify Rootly data (updateIncident, change severity, add responder) require explicit user approval. The prompt instructions enforce this -- recommendations are presented, but actions require confirmation.
- No configured token? SessionStart hook guides to
/rootly:setup, skills explain how to configure, and local development can still useROOTLY_API_TOKENas a fallback. - MCP server unreachable? Skills report the specific error and suggest manual steps.
- Low-confidence results from
find_related_incidentsorsuggest_solutions? Flag explicitly, suggest manual investigation. - Hooks fail silently on error -- never block the developer's workflow.
- No
jqorpython3? Hook scripts exit 0 silently.
Only the session-start validation and pre-commit incident check are enabled by default. Both are fast, high-value, and fail silent. Everything else is opt-in.
- User loads the plugin in Claude Code, either from a marketplace install or locally with
claude --plugin-dir - Claude Code prompts for
ROOTLY_API_TOKENfrom the plugin'suserConfig - SessionStart hook validates the configured token and points the user to
/rootly:setupif it is missing or invalid /rootly:setupverifies the MCP connection withget_server_versionand helps with service mapping- Plugin
.mcp.jsonpasses${user_config.ROOTLY_API_TOKEN}to the hosted MCP server - Hook scripts read
CLAUDE_PLUGIN_OPTION_ROOTLY_API_TOKEN, withROOTLY_API_TOKENkept only as a local development fallback - Users can still set
ROOTLY_API_URLfor self-hosted REST endpoints (defaults tohttps://api.rootly.com)
No credentials stored in plugin files. No interactive OAuth flow.
- Bundle or run the MCP server -- points to hosted endpoint
- Store persistent state -- no databases, no caches
- Auto-execute write operations -- always requires user confirmation
- Block developer workflow -- hooks fail silent, skills are on-demand
- Assume specific Rootly deployment -- supports self-hosted via
ROOTLY_API_URL
- Schema validation: Run
claude plugin validatewhen the Claude CLI is available. - Local loading: From the repo root, run
claude --plugin-dir .during development. - Reload loop: Use
/reload-pluginsafter manifest, skill, agent, or hook changes. - Functional checks: Exercise each skill against a test Rootly organization with a valid token.
- Edge cases: Validate missing token, invalid token, network timeout, empty incident history, no on-call configured, self-hosted
ROOTLY_API_URL, active incident during retro generation, and clean git working tree on deploy-check.