| 2386 | } |
| 2387 | |
| 2388 | func GetFileBlame(t translations.TranslationHelperFunc) inventory.ServerTool { |
| 2389 | st := NewTool( |
| 2390 | ToolsetMetadataRepos, |
| 2391 | mcp.Tool{ |
| 2392 | Name: "get_file_blame", |
| 2393 | Description: t("TOOL_GET_FILE_BLAME_DESCRIPTION", |
| 2394 | "Get git blame information for a file, showing the commit that last modified each line. "+ |
| 2395 | "Ranges share commit metadata via the top-level 'commits' map keyed by SHA. "+ |
| 2396 | "Use 'start_line'/'end_line' to restrict the result to a window of the file, and "+ |
| 2397 | "'perPage'/'after' to cursor-page through returned ranges. Matching ranges are capped at "+ |
| 2398 | "1000; when the cap is hit 'truncated' is set to true and 'total_ranges' reports the pre-cap match count.", |
| 2399 | ), |
| 2400 | Annotations: &mcp.ToolAnnotations{ |
| 2401 | Title: t("TOOL_GET_FILE_BLAME_USER_TITLE", "Get file blame information"), |
| 2402 | ReadOnlyHint: true, |
| 2403 | }, |
| 2404 | InputSchema: WithCursorPagination(&jsonschema.Schema{ |
| 2405 | Type: "object", |
| 2406 | Properties: map[string]*jsonschema.Schema{ |
| 2407 | "owner": { |
| 2408 | Type: "string", |
| 2409 | Description: "Repository owner (username or organization)", |
| 2410 | }, |
| 2411 | "repo": { |
| 2412 | Type: "string", |
| 2413 | Description: "Repository name", |
| 2414 | }, |
| 2415 | "path": { |
| 2416 | Type: "string", |
| 2417 | Description: "Path to the file in the repository, relative to the repository root", |
| 2418 | }, |
| 2419 | "ref": { |
| 2420 | Type: "string", |
| 2421 | Description: "Git reference (branch, tag, or commit SHA). Defaults to the repository's default branch (HEAD).", |
| 2422 | }, |
| 2423 | "start_line": { |
| 2424 | Type: "number", |
| 2425 | Description: "Optional 1-based starting line of the window of interest. Only ranges overlapping [start_line, end_line] are returned, clamped to the window.", |
| 2426 | Minimum: jsonschema.Ptr(1.0), |
| 2427 | }, |
| 2428 | "end_line": { |
| 2429 | Type: "number", |
| 2430 | Description: "Optional 1-based ending line of the window of interest. Must be >= start_line when both are provided.", |
| 2431 | Minimum: jsonschema.Ptr(1.0), |
| 2432 | }, |
| 2433 | }, |
| 2434 | Required: []string{"owner", "repo", "path"}, |
| 2435 | }), |
| 2436 | }, |
| 2437 | []scopes.Scope{scopes.Repo}, |
| 2438 | func(ctx context.Context, deps ToolDependencies, _ *mcp.CallToolRequest, args map[string]any) (*mcp.CallToolResult, any, error) { |
| 2439 | owner, err := RequiredParam[string](args, "owner") |
| 2440 | if err != nil { |
| 2441 | return utils.NewToolResultError(err.Error()), nil, nil |
| 2442 | } |
| 2443 | repo, err := RequiredParam[string](args, "repo") |
| 2444 | if err != nil { |
| 2445 | return utils.NewToolResultError(err.Error()), nil, nil |