get_report_with_conversation
Retrieve HackerOne vulnerability reports with complete triage conversations to analyze questions, responses, and resolution processes for learning effective security reporting.
Instructions
Get a report with its full triage conversation. Useful for understanding what questions triage asked, how you responded, and what led to resolution. Great for learning what works.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| report_id | Yes | The HackerOne report ID |
Implementation Reference
- src/index.ts:122-139 (handler)The handler function for the get_report_with_conversation tool, which calls getReportSummary.
async ({ report_id }) => { try { const summary = await getReportSummary(report_id); return { content: [ { type: "text" as const, text: JSON.stringify(summary, null, 2), }, ], }; } catch (err: any) { return { content: [{ type: "text" as const, text: `Error: ${err.message}` }], isError: true, }; } } - src/index.ts:116-140 (registration)Registration of the get_report_with_conversation tool using the MCP server instance.
server.tool( "get_report_with_conversation", "Get a report with its full triage conversation. Useful for understanding what questions triage asked, how you responded, and what led to resolution. Great for learning what works.", { report_id: z.string().describe("The HackerOne report ID"), }, async ({ report_id }) => { try { const summary = await getReportSummary(report_id); return { content: [ { type: "text" as const, text: JSON.stringify(summary, null, 2), }, ], }; } catch (err: any) { return { content: [{ type: "text" as const, text: `Error: ${err.message}` }], isError: true, }; } } ); - src/h1client.ts:297-321 (helper)Implementation of getReportSummary, which fetches and processes the report details and conversation activities.
export async function getReportSummary(reportId: string) { const report = await getReport(reportId); const activities = await getReportActivities(reportId); // Filter to meaningful comments only (no automated, no internal) const comments = activities.filter( (a: any) => a.message && !a.automated_response && (a.type === "activity-comment" || a.type === "activity-bug-triaged" || a.type === "activity-bug-resolved" || a.type === "activity-bounty-awarded") ); return { ...report, conversation: comments.map((c: any) => ({ from: c.actor ?? c.actor_type, type: c.type.replace("activity-", ""), message: c.message, date: c.created_at, })), }; }