Add get_check_suite_logs tools

This commit is contained in:
Colin McDonnell
2025-11-19 23:27:24 -08:00
parent fe35e9e274
commit 098df15764
9 changed files with 1630 additions and 1401 deletions
+1
View File
@@ -19,6 +19,7 @@ export const claude = agent({
process.env.ANTHROPIC_API_KEY = apiKey;
const prompt = addInstructions(payload);
console.log(prompt);
const queryInstance = query({
prompt,
+4 -1
View File
@@ -44,6 +44,9 @@ Do not try to handle github auth- treat ${ghPullfrogMcpName} as a black box that
When using ${ghPullfrogMcpName}, use the tools to comment and interact in a way that a real member of the team would.
Ensure after your edits are done, your final comments do not contain intermediate reasoning or context, e.g. "I'll respond to the question."
For CI failures:
- Use ${ghPullfrogMcpName}/get_check_suite_logs with check_suite.id to get all failed workflow logs
## Mode Selection
Before starting any work, you must first determine which mode to use by examining the request and calling ${ghPullfrogMcpName}/select_mode.
@@ -62,4 +65,4 @@ ${[...modes, ...payload.modes].map((w) => ` - "${w.name}": ${w.description}`)
${payload.prompt}
${JSON.stringify(payload.event, null, 2)}`;
${typeof payload.event === "string" ? payload.event : JSON.stringify(payload.event, null, 2)}`;
+429 -425
View File
File diff suppressed because one or more lines are too long
+2 -1
View File
@@ -48,8 +48,9 @@ export type Payload = {
/**
* Event data from webhook payload.
* Can be an object (will be JSON.stringify'd) or a string (used as-is).
*/
readonly event: object;
readonly event: object | string;
/**
* Execution mode configuration
+1054 -973
View File
File diff suppressed because one or more lines are too long
+45
View File
@@ -0,0 +1,45 @@
# gh-pullfrog MCP Tools
this directory contains the mcp (model context protocol) server tools for interacting with github.
## available tools
### check suite tools
#### `get_check_suite_logs`
get workflow run logs for a failed check suite.
**parameters:**
- `check_suite_id` (number): the id from check_suite.id in the webhook payload
**replaces:** `gh run list` and `gh run view --log`
**returns:**
all logs from all failed workflow runs in the check suite, including:
- workflow run details (id, name, html_url, conclusion)
- job details for each workflow run (id, name, status, conclusion, logs)
**example:**
```typescript
// when handling a check_suite_completed webhook
await mcp.call("gh-pullfrog/get_check_suite_logs", {
check_suite_id: check_suite.id
});
```
### other tools
see individual files for documentation on other tools:
- `comment.ts` - create, edit, and update comments
- `issue.ts` - create issues
- `pr.ts` - create pull requests
- `prInfo.ts` - get pull request information
- `review.ts` - create pull request reviews
- `selectMode.ts` - select execution mode
## usage in agents
agents should never use the `gh` cli. instead, they should use the mcp tools provided by this server.
the agent instructions automatically include guidance on using these tools.
+93
View File
@@ -0,0 +1,93 @@
import { type } from "arktype";
import { contextualize, tool } from "./shared.ts";
export const GetCheckSuiteLogs = type({
check_suite_id: type.number.describe("the id from check_suite.id"),
});
export const GetCheckSuiteLogsTool = tool({
name: "get_check_suite_logs",
description:
"get workflow run logs for a failed check suite. pass check_suite.id from the webhook payload.",
parameters: GetCheckSuiteLogs,
execute: contextualize(async ({ check_suite_id }, ctx) => {
// get workflow runs for this specific check suite
const runsResponse = await ctx.octokit.rest.actions.listWorkflowRunsForRepo({
owner: ctx.owner,
repo: ctx.name,
check_suite_id,
per_page: 100,
});
const failedRuns = runsResponse.data.workflow_runs.filter(
(run) => run.conclusion === "failure"
);
if (failedRuns.length === 0) {
return {
check_suite_id,
message: "no failed workflow runs found for this check suite",
workflow_runs: [],
};
}
// get logs for each failed run
const logsForRuns = await Promise.all(
failedRuns.map(async (run) => {
const jobsResponse = await ctx.octokit.rest.actions.listJobsForWorkflowRun({
owner: ctx.owner,
repo: ctx.name,
run_id: run.id,
});
const jobLogs = await Promise.all(
jobsResponse.data.jobs.map(async (job) => {
try {
const logsResponse = await ctx.octokit.rest.actions.downloadJobLogsForWorkflowRun({
owner: ctx.owner,
repo: ctx.name,
job_id: job.id,
});
const logsUrl = logsResponse.url;
const logsText = await fetch(logsUrl).then((r) => r.text());
return {
job_id: job.id,
job_name: job.name,
status: job.status,
conclusion: job.conclusion,
started_at: job.started_at,
completed_at: job.completed_at,
logs: logsText,
};
} catch (error) {
return {
job_id: job.id,
job_name: job.name,
status: job.status,
conclusion: job.conclusion,
started_at: job.started_at,
completed_at: job.completed_at,
error: `failed to fetch logs: ${error}`,
};
}
})
);
return {
workflow_run_id: run.id,
workflow_name: run.name,
html_url: run.html_url,
conclusion: run.conclusion,
jobs: jobLogs,
};
})
);
return {
check_suite_id,
workflow_runs: logsForRuns,
};
}),
});
+2
View File
@@ -1,4 +1,5 @@
import { FastMCP } from "fastmcp";
import { GetCheckSuiteLogsTool } from "./checkSuite.ts";
import {
CreateCommentTool,
CreateWorkingCommentTool,
@@ -27,6 +28,7 @@ addTools(server, [
PullRequestTool,
ReviewTool,
PullRequestInfoTool,
GetCheckSuiteLogsTool,
]);
server.start();
-1
View File
@@ -29,7 +29,6 @@ export const modes: Mode[] = [
"Implement, build, create, or develop code changes; make specific changes to files or features; execute a plan; or handle tasks with specific implementation details",
prompt: `Follow these steps:
1. ${initialCommentInstruction}
2. If the request requires understanding the codebase structure, dependencies, or conventions, gather relevant context (read AGENTS.md if it exists, understand how to install dependencies, run tests, run builds, and make changes according to best practices). Skip this step if the prompt is trivial and self-contained.
3. Understand the requirements and any existing plan
4. Make the necessary code changes