1use rmcp::handler::server::wrapper::{Json, Parameters};
8use rmcp::{schemars, tool, tool_router};
9use serde::{Deserialize, Serialize};
10
11use crate::mcp::query;
12use crate::mcp::query::git::Diff;
13use crate::mcp::server::GitPawMcpServer;
14
15#[derive(Debug, Deserialize, schemars::JsonSchema)]
17pub struct GetRecentCommitsParams {
18 pub branch: String,
20 #[serde(default = "default_limit")]
22 #[schemars(description = "Maximum number of commits to return (default 20)")]
23 pub limit: usize,
24}
25
26fn default_limit() -> usize {
27 20
28}
29
30#[derive(Debug, Deserialize, schemars::JsonSchema)]
32pub struct GetDiffParams {
33 pub branch: String,
35 #[serde(default)]
37 pub base: Option<String>,
38}
39
40#[derive(Serialize, schemars::JsonSchema)]
42pub struct BranchesResponse {
43 pub branches: Vec<query::git::Branch>,
45}
46
47#[derive(Serialize, schemars::JsonSchema)]
49pub struct CommitsResponse {
50 pub commits: Vec<query::git::Commit>,
52}
53
54#[tool_router(router = git_router, vis = "pub(crate)")]
55impl GitPawMcpServer {
56 #[tool(
58 description = "List local branches, each with name, head commit SHA, whether it is the \
59 currently checked-out branch, and whether it is checked out in a linked \
60 (git-paw managed) worktree."
61 )]
62 pub(crate) fn get_branches(&self) -> Json<BranchesResponse> {
63 Json(BranchesResponse {
64 branches: query::git::branches(&self.ctx.root),
65 })
66 }
67
68 #[tool(
70 description = "Return up to `limit` (default 20) recent commits on `branch`, newest first, \
71 each with sha, author, ISO timestamp, and subject."
72 )]
73 pub(crate) fn get_recent_commits(
74 &self,
75 Parameters(p): Parameters<GetRecentCommitsParams>,
76 ) -> Json<CommitsResponse> {
77 Json(CommitsResponse {
78 commits: query::git::recent_commits(&self.ctx.root, &p.branch, p.limit),
79 })
80 }
81
82 #[tool(
84 description = "Return the diff of `branch` against `base` (default: the repo's default \
85 branch) with a files-changed / insertions / deletions summary."
86 )]
87 pub(crate) fn get_diff(&self, Parameters(p): Parameters<GetDiffParams>) -> Json<Diff> {
88 Json(query::git::diff(
89 &self.ctx.root,
90 &p.branch,
91 p.base.as_deref(),
92 ))
93 }
94}