registerChecksTool registers the checks tool with the MCP server. The checks tool is read-only and idempotent.
(server *mcp.Server)
| 351 | // registerChecksTool registers the checks tool with the MCP server. |
| 352 | // The checks tool is read-only and idempotent. |
| 353 | func registerChecksTool(server *mcp.Server) { |
| 354 | mcp.AddTool(server, &mcp.Tool{ |
| 355 | Name: "checks", |
| 356 | Annotations: &mcp.ToolAnnotations{ |
| 357 | ReadOnlyHint: true, |
| 358 | IdempotentHint: true, |
| 359 | OpenWorldHint: boolPtr(true), |
| 360 | }, |
| 361 | Description: `Classify CI check state for a pull request and return a normalized result. |
| 362 | |
| 363 | Maps PR check rollups to one of the following normalized states: |
| 364 | success - all checks passed |
| 365 | failed - one or more checks failed |
| 366 | pending - checks are still running or queued |
| 367 | no_checks - no checks configured or triggered |
| 368 | policy_blocked - policy or account gates are blocking the PR |
| 369 | |
| 370 | Returns JSON with two state fields: |
| 371 | state - aggregate state across all check runs and commit statuses |
| 372 | required_state - state derived from check runs and policy commit statuses only; |
| 373 | ignores optional third-party commit statuses (e.g., Vercel, |
| 374 | Netlify deployments) but still surfaces policy_blocked when |
| 375 | branch-protection or account-gate statuses fail |
| 376 | |
| 377 | Use required_state as the authoritative CI verdict in repos that have optional |
| 378 | deployment integrations posting commit statuses alongside required CI checks. |
| 379 | |
| 380 | Also returns pr_number, head_sha, check_runs, statuses, and total_count.`, |
| 381 | Icons: []mcp.Icon{ |
| 382 | {Source: "✅"}, |
| 383 | }, |
| 384 | }, func(ctx context.Context, req *mcp.CallToolRequest, args checksArgs) (*mcp.CallToolResult, any, error) { |
| 385 | // Check for cancellation before starting |
| 386 | select { |
| 387 | case <-ctx.Done(): |
| 388 | return nil, nil, newMCPError(jsonrpc.CodeInternalError, "request cancelled", ctx.Err().Error()) |
| 389 | default: |
| 390 | } |
| 391 | |
| 392 | if args.PRNumber == "" { |
| 393 | return nil, nil, newMCPError(jsonrpc.CodeInvalidParams, "missing required parameter: pr_number", nil) |
| 394 | } |
| 395 | |
| 396 | mcpLog.Printf("Executing checks tool: pr_number=%s, repo=%s", args.PRNumber, args.Repo) |
| 397 | |
| 398 | result, err := FetchChecksResult(args.Repo, args.PRNumber) |
| 399 | if err != nil { |
| 400 | return nil, nil, newMCPError(jsonrpc.CodeInternalError, "failed to fetch checks", map[string]any{"error": err.Error()}) |
| 401 | } |
| 402 | |
| 403 | jsonBytes, err := json.Marshal(result) |
| 404 | if err != nil { |
| 405 | return nil, nil, newMCPError(jsonrpc.CodeInternalError, "failed to marshal checks result", map[string]any{"error": err.Error()}) |
| 406 | } |
| 407 | |
| 408 | return &mcp.CallToolResult{ |
| 409 | Content: []mcp.Content{ |
| 410 | &mcp.TextContent{Text: string(jsonBytes)}, |
no test coverage detected