use rmcp::handler::server::wrapper::{Json, Parameters};
use rmcp::{schemars, tool, tool_router};
use serde::{Deserialize, Serialize};
use crate::mcp::query;
use crate::mcp::query::git::Diff;
use crate::mcp::server::GitPawMcpServer;
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct GetRecentCommitsParams {
pub branch: String,
#[serde(default = "default_limit")]
#[schemars(description = "Maximum number of commits to return (default 20)")]
pub limit: usize,
}
fn default_limit() -> usize {
20
}
#[derive(Debug, Deserialize, schemars::JsonSchema)]
pub struct GetDiffParams {
pub branch: String,
#[serde(default)]
pub base: Option<String>,
}
#[derive(Serialize, schemars::JsonSchema)]
pub struct BranchesResponse {
pub branches: Vec<query::git::Branch>,
}
#[derive(Serialize, schemars::JsonSchema)]
pub struct CommitsResponse {
pub commits: Vec<query::git::Commit>,
}
#[tool_router(router = git_router, vis = "pub(crate)")]
impl GitPawMcpServer {
#[tool(
description = "List local branches, each with name, head commit SHA, whether it is the \
currently checked-out branch, and whether it is checked out in a linked \
(git-paw managed) worktree."
)]
pub(crate) fn get_branches(&self) -> Json<BranchesResponse> {
Json(BranchesResponse {
branches: query::git::branches(&self.ctx.root),
})
}
#[tool(
description = "Return up to `limit` (default 20) recent commits on `branch`, newest first, \
each with sha, author, ISO timestamp, and subject."
)]
pub(crate) fn get_recent_commits(
&self,
Parameters(p): Parameters<GetRecentCommitsParams>,
) -> Json<CommitsResponse> {
Json(CommitsResponse {
commits: query::git::recent_commits(&self.ctx.root, &p.branch, p.limit),
})
}
#[tool(
description = "Return the diff of `branch` against `base` (default: the repo's default \
branch) with a files-changed / insertions / deletions summary."
)]
pub(crate) fn get_diff(&self, Parameters(p): Parameters<GetDiffParams>) -> Json<Diff> {
Json(query::git::diff(
&self.ctx.root,
&p.branch,
p.base.as_deref(),
))
}
}