get_commit MCP tool

Note

Before picking up this work: this issue adds an MCP tool. Please follow the Adding a new tool guidance first. That includes creating an MCP Tool Proposal, using verb_object naming (get_ / list_ / save_ / delete_), and the shared resource-identification input base classes.

Problem Statement / Use Case

Agents need commit details, and often the commit's diff and its comments, when reviewing history or understanding a change. Today the DAP surface splits this across three tools (get_commit + get_commit_diff + get_commit_comments). get_commit consolidates them into one facet reader: base metadata is always returned, and the caller opts into diff and/or comments via include.

This mirrors the facet-reader pattern used by get_merge_request and get_pipeline (facets scoped to one parent object → include on that object's get_).

Scope and Non-Goals

  • In scope: single-commit metadata; diff facet (with detail payload control); comments facet (paginated).
  • Non-goals: listing commits (list_commits), creating commits (create_commit), commit search (folds into unified search, scope=commits).
  • Follow-ups: none.

Data Shape and Context Engineering

Two saturation guards: the detail enum (none/stats/full_patch) bounds the diff facet, and facet-scoped pagination bounds comments. Pagination params apply only when comments is in include — documented explicitly so the model doesn't set them spuriously.

  • Input schema (example):
{
  "tool": "get_commit",
  "description": "Get a single commit's metadata, optionally including its diff and/or comments.",
  "parameters": {
    "url": "string (optional)",
    "project_id": "int | string (optional)",
    "commit_sha": "string",
    "include": "string (optional; one of: diff, comments)",
    "detail": "enum (optional; none | stats | full_patch — applies to diff facet only)",
    "comments_page": "integer (optional; applies only when 'comments' in include)",
    "comments_per_page": "integer (optional, 1-100; applies only when 'comments' in include)"
  }
}
  • Output schema (JSON example):
{
  "sha": "9a1b2c",
  "title": "Fix panic in cache",
  "author_name": "Jane Doe",
  "created_at": "2026-07-01T10:00:00Z",
  "diff": {
    "detail": "stats",
    "stats": { "additions": 12, "deletions": 3, "files_changed": 2 },
    "files": [ { "old_path": "cache.rb", "new_path": "cache.rb", "changes": 15 } ]
  },
  "comments": {
    "metadata": { "page": 1, "per_page": 20, "has_more": false },
    "items": [ { "author": "reviewer", "note": "Nice catch", "line": 42 } ]
  }
}

Backward compatibility

Consolidates the shipped Python get_commit, get_commit_diff, and get_commit_comments (duo_workflow_service/tools/commit.py) into this one facet reader. The base get_commit name is unchanged, but its stats: bool is replaced by a detail enum (detail=stats preserves the old behaviour) and the diff/comments reads move behind include. Keep get_commit_diff/get_commit_comments available during migration, and map the old stats boolean onto detail. Follow the tool-renaming guidance in doc/development/duo_agent_platform/mcp/_index.md.

Resources (already implemented similar tools etc.)

  • Shipped DAP tools get_commit (has a stats: bool, replaced here by detail on the diff facet), get_commit_diff, get_commit_comments.
  • MCP dev guidelines: doc/development/duo_agent_platform/mcp/_index.md (facet readers, detail knob for diffs, facet-scoped pagination).

Implementation Plan

  1. Map include to the underlying commit / diff / comments REST calls.
  2. Replace the shipped stats bool with detail; detail=stats preserves old behavior.
  3. Route comments_* pagination to the comments call only.
  4. Cross-validate url vs project_id + commit_sha.
Edited by 🤖 GitLab Bot 🤖