Skip to content

Commit 6d821b1

Browse files
authored
MCP Prompt tools (Azure#11066)
* Create new tools. One for validation and one to donwload prompts * Add response classes * Integrate new tools to be discoverable * Generalize prompt validation to file validation * skip files already downloaded * Variable declared twice * Check if working repo is same as repo we are targerting * remove unused variable * When in repository all is good
1 parent 8c5563d commit 6d821b1

File tree

6 files changed

+509
-0
lines changed

6 files changed

+509
-0
lines changed

tools/azsdk-cli/Azure.Sdk.Tools.Cli/Commands/SharedOptions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public static class SharedOptions
2323
typeof(SpecWorkflowTool),
2424
typeof(SpecValidationTools),
2525
typeof(ReleaseReadinessTool),
26+
typeof(FileValidationTool),
27+
typeof(DownloadPromptsTool),
2628
typeof(SdkReleaseTool),
2729
#if DEBUG
2830
// only add this tool in debug mode
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace Azure.Sdk.Tools.Cli.Models;
4+
5+
/// <summary>
6+
/// Response model for file download operations
7+
/// </summary>
8+
public class DownloadResponse : Response
9+
{
10+
[JsonPropertyName("message")]
11+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
12+
public string Message { get; set; } = string.Empty;
13+
14+
[JsonPropertyName("success")]
15+
public bool Success { get; set; }
16+
17+
[JsonPropertyName("downloaded_count")]
18+
public int DownloadedCount { get; set; }
19+
20+
[JsonPropertyName("total_files")]
21+
public int TotalFiles { get; set; }
22+
23+
public override string ToString()
24+
{
25+
return ToString(Message);
26+
}
27+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace Azure.Sdk.Tools.Cli.Models;
4+
5+
/// <summary>
6+
/// Response model for prompt validation operations
7+
/// </summary>
8+
public class ValidationResponse : Response
9+
{
10+
[JsonPropertyName("message")]
11+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
12+
public string Message { get; set; } = string.Empty;
13+
14+
[JsonPropertyName("is_valid")]
15+
public bool IsValid { get; set; }
16+
17+
[JsonPropertyName("missing_count")]
18+
public int MissingCount { get; set; }
19+
20+
[JsonPropertyName("total_source_files")]
21+
public int TotalSourceFiles { get; set; }
22+
23+
[JsonPropertyName("missing_files")]
24+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
25+
public List<string>? MissingFiles { get; set; }
26+
27+
public override string ToString()
28+
{
29+
return ToString(Message);
30+
}
31+
}

tools/azsdk-cli/Azure.Sdk.Tools.Cli/Services/GitHubService.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ public interface IGitHubService
7878
public Task<List<string>> GetPullRequestCommentsAsync(string repoOwner, string repoName, int pullRequestNumber);
7979
public Task<PullRequest?> GetPullRequestForBranchAsync(string repoOwner, string repoName, string remoteBranch);
8080
public Task<Issue> GetIssueAsync(string repoOwner, string repoName, int issueNumber);
81+
public Task<IReadOnlyList<RepositoryContent>?> GetContentsAsync(string owner, string repoName, string path);
8182
}
8283

8384
public class GitHubService : GitConnection, IGitHubService
@@ -274,5 +275,31 @@ public async Task<Issue> GetIssueAsync(string repoOwner, string repoName, int is
274275
{
275276
return await gitHubClient.Issue.Get(repoOwner, repoName, issueNumber);
276277
}
278+
279+
/// <summary>
280+
/// Helper method to get contents from a GitHub repository path.
281+
/// </summary>
282+
/// <param name="owner">Repository owner</param>
283+
/// <param name="repoName">Repository name</param>
284+
/// <param name="path">Directory or file path</param>
285+
/// <param name="expectSingleFile">If true, returns only the first file content; if false, returns all contents</param>
286+
/// <returns>List of repository contents or null if path doesn't exist</returns>
287+
public async Task<IReadOnlyList<RepositoryContent>?> GetContentsAsync(string owner, string repoName, string path)
288+
{
289+
try
290+
{
291+
return await gitHubClient.Repository.Content.GetAllContents(owner, repoName, path);
292+
}
293+
catch (NotFoundException)
294+
{
295+
logger.LogInformation($"Path {path} not found in {owner}/{repoName}");
296+
return null;
297+
}
298+
catch (Exception ex)
299+
{
300+
logger.LogError(ex, $"Error fetching contents from {owner}/{repoName}/{path}");
301+
throw;
302+
}
303+
}
277304
}
278305
}

0 commit comments

Comments
 (0)