git_iris/mcp/tools/
releasenotes.rs

1//! MCP release notes tool implementation
2//!
3//! This module provides the MCP tool for generating release notes.
4
5use crate::changes::ReleaseNotesGenerator;
6use crate::config::Config as GitIrisConfig;
7use crate::git::GitRepo;
8use crate::log_debug;
9use crate::mcp::tools::utils::{
10    GitIrisTool, apply_custom_instructions, create_text_result, parse_detail_level,
11    resolve_git_repo, validate_repository_parameter,
12};
13
14use rmcp::handler::server::tool::cached_schema_for_type;
15use rmcp::model::{CallToolResult, Tool};
16use rmcp::schemars;
17
18use serde::{Deserialize, Serialize};
19use std::borrow::Cow;
20use std::sync::Arc;
21
22/// Release notes tool for generating comprehensive release notes
23#[derive(Debug, Deserialize, Serialize, schemars::JsonSchema)]
24pub struct ReleaseNotesTool {
25    /// Starting reference (commit hash, tag, or branch name)
26    pub from: String,
27
28    /// Ending reference (commit hash, tag, or branch name). Defaults to HEAD if not specified.
29    #[serde(default)]
30    pub to: String,
31
32    /// Level of detail for the release notes
33    #[serde(default)]
34    pub detail_level: String,
35
36    /// Custom instructions for the AI
37    #[serde(default)]
38    pub custom_instructions: String,
39
40    /// Repository path (local) or URL (remote). Required.
41    pub repository: String,
42
43    /// Explicit version name to use (optional)
44    #[serde(default)]
45    pub version_name: String,
46}
47
48impl ReleaseNotesTool {
49    /// Returns the tool definition for the release notes tool
50    pub fn get_tool_definition() -> Tool {
51        Tool {
52            name: Cow::Borrowed("git_iris_release_notes"),
53            description: Cow::Borrowed(
54                "Generate comprehensive release notes between two Git references",
55            ),
56            input_schema: cached_schema_for_type::<Self>(),
57        }
58    }
59}
60
61#[async_trait::async_trait]
62impl GitIrisTool for ReleaseNotesTool {
63    /// Execute the release notes tool with the provided repository and configuration
64    async fn execute(
65        &self,
66        git_repo: Arc<GitRepo>,
67        config: GitIrisConfig,
68    ) -> Result<CallToolResult, anyhow::Error> {
69        log_debug!("Generating release notes with: {:?}", self);
70
71        // Validate repository parameter
72        validate_repository_parameter(&self.repository)?;
73        let git_repo = resolve_git_repo(Some(self.repository.as_str()), git_repo)?;
74        log_debug!("Using repository: {}", git_repo.repo_path().display());
75
76        // Parse detail level using shared utility
77        let detail_level = parse_detail_level(&self.detail_level);
78
79        // Set up config with custom instructions if provided
80        let mut config = config.clone();
81        apply_custom_instructions(&mut config, &self.custom_instructions);
82
83        // Default to HEAD if to is empty
84        let to = if self.to.trim().is_empty() {
85            "HEAD".to_string()
86        } else {
87            self.to.clone()
88        };
89
90        // Generate the release notes using the generator
91        let content = ReleaseNotesGenerator::generate(
92            git_repo.clone(),
93            &self.from,
94            &to,
95            &config,
96            detail_level,
97            if self.version_name.is_empty() {
98                None
99            } else {
100                Some(self.version_name.clone())
101            },
102        )
103        .await?;
104
105        // Create and return the result using shared utility
106        Ok(create_text_result(content))
107    }
108}