HarborHarbor
DocumentationGuidesPlugins
Recipes

Incident Triage

Sentry → GitHub → Linear → Slack. End-to-end working example.

A real working pipeline: when Sentry surfaces an unresolved issue, find the likely-bad commit, file a Linear ticket with context, post a Slack summary. Total round-trip: one hrbr exec call, fully traced.

What you need

PluginUsed for
sentry-mcpFetch the issue
github-mcpSearch code for the culprit string
linear-mcpCreate the ticket
slack-mcpPost the summary

All four installed and in ready state — see Install your first plugin if needed.

The exec

triage.ts
const issue = await sentryMcp.getIssue({ id: input.issueId });

const matches = await githubMcp.searchCode({
  query: issue.culprit,
  repo: input.repo ?? "acme/api",
});
const owner = matches[0]?.path ?? "unknown";

const ticket = await linearMcp.createIssue({
  teamId: input.teamId,
  title: issue.title,
  description: [
    `**Sentry:** ${issue.url}`,
    `**Suspect file:** \`${owner}\``,
    "",
    `\`\`\``,
    issue.message.slice(0, 1_200),
    `\`\`\``,
  ].join("\n"),
});

await slackMcp.postMessage({
  channel: input.channel ?? "#incidents",
  text: `Triage ready: ${ticket.url} (suspect: ${owner})`,
});

return { ticket: ticket.url, suspect: owner };

Run it:

hrbr exec -f triage.ts \
  --input '{ "issueId": "SENTRY-1234", "repo": "acme/api", "teamId": "ENG", "channel": "#incidents" }'

Promote to a Function

Once it works, wrap in defineJob so anyone (or a scheduled cron) can invoke it:

triage-function.ts

defineJob({
  name: "triage-sentry-issue",
  description: "Sentry alert → Linear ticket → Slack summary.",
  handler: async (ctx, input: TriageInput) => {
    /* … same body, ctx.plugins.<namespace>.<tool>(...) … */
  },
});
hrbr inspect -f ./triage-function.job.ts
hrbr inspect 'return await hrbr.jobs.inspect({ name: "triage-sentry-issue" })'

Promote to a Skill

Wire it as a workflow-backed skill so the agent picks it up automatically when the user says "triage SENTRY-1234":

triage-skill.md
---
name: triage-sentry-issue
description: |
  Use when the user references a Sentry issue (SENTRY-XXXX) and wants
  it triaged into a Linear ticket.
harbor_workflow:
                              # See Authoring → Skills
---

See Your first Skill for the full walkthrough.

Why this is one trace, not four

Without Harbor, that's four tool calls, four model round-trips, four network handshakes the agent had to babysit. With Harbor, the whole thing is one exec run:

  • One run, one trace, four child spans (one per plugin call)
  • One agent decision: "here's the code; run it"
  • Credentials never leave Harbor; the agent never sees a Sentry token
  • Replayable from the Traces page

For multi-step pipelines that take longer than 30 s or need retries, write step.do inside the handler — see Multi-step with retries.