registerAuditTool registers the audit tool with the MCP server. The audit tool requires write+ access and checks actor permissions. Returns an error if schema generation fails.
(server *mcp.Server, execCmd execCmdFunc, actor string, validateActor bool)
| 321 | // The audit tool requires write+ access and checks actor permissions. |
| 322 | // Returns an error if schema generation fails. |
| 323 | func registerAuditTool(server *mcp.Server, execCmd execCmdFunc, actor string, validateActor bool) error { |
| 324 | // Generate schema for audit tool |
| 325 | auditSchema, err := GenerateSchema[auditArgs]() |
| 326 | if err != nil { |
| 327 | mcpLog.Printf("Failed to generate audit tool schema: %v", err) |
| 328 | return err |
| 329 | } |
| 330 | |
| 331 | mcp.AddTool(server, &mcp.Tool{ |
| 332 | Name: "audit", |
| 333 | Annotations: &mcp.ToolAnnotations{ |
| 334 | ReadOnlyHint: true, |
| 335 | IdempotentHint: true, |
| 336 | OpenWorldHint: boolPtr(true), |
| 337 | }, |
| 338 | Description: `Investigate one or more workflow runs and generate a concise report. |
| 339 | |
| 340 | When a single run is provided, generates a detailed audit report. |
| 341 | When two or more runs are provided, the first is the base (reference) run and |
| 342 | the remaining runs are compared against it (diff mode), showing changes in |
| 343 | firewall domains, MCP tool usage, and run metrics. |
| 344 | |
| 345 | Each run accepts: |
| 346 | - Numeric run ID: 1234567890 |
| 347 | - Run URL: https://github.com/owner/repo/actions/runs/1234567890 |
| 348 | - Job URL: https://github.com/owner/repo/actions/runs/1234567890/job/9876543210 |
| 349 | - Job URL with step: https://github.com/owner/repo/actions/runs/1234567890/job/9876543210#step:7:1 |
| 350 | |
| 351 | When a job URL is provided (single-run mode only): |
| 352 | - If a step number is included (#step:7:1), extracts that specific step's output |
| 353 | - If no step number, finds and extracts the first failing step's output |
| 354 | - Saves job logs and step-specific logs to the output directory |
| 355 | |
| 356 | Use experiment/variant to filter runs by A/B experiment assignment (skips runs |
| 357 | that do not match). variant requires experiment. |
| 358 | |
| 359 | Single-run returns JSON with: |
| 360 | - overview: Basic run information (run_id, workflow_name, status, conclusion, created_at, started_at, updated_at, duration, event, branch, url, logs_path, experiment) |
| 361 | - metrics: Execution metrics (token_usage, estimated_cost, turns, error_count, warning_count) |
| 362 | - jobs: List of job details (name, status, conclusion, duration) |
| 363 | - downloaded_files: List of artifact files (path, size, size_formatted, description, is_directory) |
| 364 | - missing_tools: Tools that were requested but not available (tool, reason, alternatives, timestamp, workflow_name, run_id, experiment_name, variant) |
| 365 | - mcp_failures: MCP server failures (server_name, status, timestamp, workflow_name, run_id, experiment_name, variant) |
| 366 | - noop_reports: Noop signals from agents (message, timestamp, workflow_name, run_id, experiment_name, variant) |
| 367 | - missing_data: Missing data reports (data_type, reason, context, alternatives, timestamp, workflow_name, run_id, experiment_name, variant) |
| 368 | - errors: Error details (file, line, type, message) |
| 369 | - warnings: Warning details (file, line, type, message) |
| 370 | - tool_usage: Tool usage statistics (name, call_count, max_output_size, max_duration) |
| 371 | - firewall_analysis: Network firewall analysis if available (total_requests, allowed_requests, blocked_requests, allowed_domains, blocked_domains) |
| 372 | - experiments: A/B experiment assignments if present (assignments map, cumulative_counts map) |
| 373 | |
| 374 | Multi-run diff returns JSON describing changes between the base and each comparison run.`, |
| 375 | InputSchema: auditSchema, |
| 376 | Icons: []mcp.Icon{ |
| 377 | {Source: "🔍"}, |
| 378 | }, |
| 379 | }, func(ctx context.Context, req *mcp.CallToolRequest, args auditArgs) (*mcp.CallToolResult, any, error) { |
| 380 | // Check actor permissions first |