This repository was archived by the owner on Sep 4, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 357
Migrate Cloud Architect Tool from @azure to az mcp server #890
Merged
Merged
Changes from 42 commits
Commits
Show all changes
48 commits
Select commit
Hold shift + click to select a range
1960132
added cloud architect tool
msalaman abdb78b
updates
msalaman 5828a1e
updates
msalaman 2fbccb0
updates
msalaman 7520cca
updates
msalaman 05e15bd
update Tests
msalaman 629ece7
update documentation
msalaman 900bdea
update cspell
msalaman 951765e
updates
msalaman 46e6a5a
merged with master
msalaman d8331a2
added more prompt examples
msalaman f924482
removed unnecessary service classes
msalaman 986e3aa
fixed formatting, added unit tests for proper escape handling
msalaman 9a9dc76
update cspell value
msalaman 5ad85dd
Merge branch 'main' into masalama/cloudArchitectTool
msalaman 64912c6
update description
msalaman 91c5e90
Merge branch 'masalama/cloudArchitectTool' of https://github.com/Azur…
msalaman aac6b63
Merge branch 'main' into masalama/cloudArchitectTool
msalaman 586f010
updated unit test to use new description
msalaman f641248
Merge branch 'main' into masalama/cloudArchitectTool
msalaman d9bb62e
add e2e prompt for cloud architect tool
msalaman 9d115b3
Merge branch 'masalama/cloudArchitectTool' of https://github.com/Azur…
msalaman 33cadf5
Merge branch 'main' into masalama/cloudArchitectTool
msalaman 1040c02
cleaned up unused models
msalaman 77661e0
Merge branch 'main' into masalama/cloudArchitectTool
msalaman 032b0a4
Merge branch 'masalama/cloudArchitectTool' of https://github.com/Azur…
msalaman cec0e71
binded and used architectureTier and architectureDesignToolState options
msalaman e2287cc
added parameter validations and removed unnecessary classes
msalaman 25c2164
removed unnecessary base class and JsonPropertyNames
msalaman 7948170
fixed CHANGELOG link formatting
msalaman 2ecb1cd
removed unused json context
msalaman 8604fd4
fixed spelling error
msalaman 7f7320d
Merge branch 'main' into masalama/cloudArchitectTool
msalaman 0b26888
Include ResponseObject of parameters in response for design command
msalaman 7b5620f
Merge branch 'masalama/cloudArchitectTool' of https://github.com/Azur…
msalaman 24f2671
Merge branch 'main' into masalama/cloudArchitectTool
msalaman 2d29a97
merged with main
msalaman 7539670
Merge branch 'masalama/cloudArchitectTool' of https://github.com/Azur…
msalaman 532e25d
Merge branch 'main' into masalama/cloudArchitectTool
msalaman db31d3b
Merge branch 'main' into masalama/cloudArchitectTool
msalaman e5c0731
update description to be more concise to be under tool length limit
msalaman 3f5b6e1
Merge branch 'masalama/cloudArchitectTool' of https://github.com/Azur…
msalaman 041ce7f
Merge branch 'main' into masalama/cloudArchitectTool
msalaman cec4fb1
updated description to use multiline string
msalaman 57a8b50
Merge branch 'masalama/cloudArchitectTool' of https://github.com/Azur…
msalaman 07085da
added validation
msalaman 21768dd
update tests
msalaman 949c804
remove attribute
msalaman File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
msalaman marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
areas/cloudarchitect/src/AzureMcp.CloudArchitect/AssemblyInfo.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using System.Reflection; | ||
| using System.Runtime.CompilerServices; | ||
|
|
||
| [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Azure/azure-mcp")] | ||
msalaman marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| [assembly: InternalsVisibleTo("AzureMcp.CloudArchitect.UnitTests")] | ||
20 changes: 20 additions & 0 deletions
20
areas/cloudarchitect/src/AzureMcp.CloudArchitect/AzureMcp.CloudArchitect.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
| <PropertyGroup> | ||
| <IsAotCompatible>true</IsAotCompatible> | ||
| </PropertyGroup> | ||
| <ItemGroup> | ||
| <EmbeddedResource Include="**\Resources\*.txt" /> | ||
| <EmbeddedResource Include="**\Resources\*.json" /> | ||
| </ItemGroup> | ||
| <ItemGroup> | ||
| <ProjectReference Include="..\..\..\..\core\src\AzureMcp.Core\AzureMcp.Core.csproj" /> | ||
| </ItemGroup> | ||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.Extensions.DependencyInjection" /> | ||
| <PackageReference Include="ModelContextProtocol" /> | ||
| <PackageReference Include="System.CommandLine" /> | ||
| </ItemGroup> | ||
| <ItemGroup> | ||
| <Folder Include="Models\" /> | ||
| </ItemGroup> | ||
| </Project> |
25 changes: 25 additions & 0 deletions
25
areas/cloudarchitect/src/AzureMcp.CloudArchitect/CloudArchitectJsonContext.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using System.Text.Json.Serialization; | ||
| using AzureMcp.CloudArchitect.Commands.Design; | ||
| using AzureMcp.CloudArchitect.Models; | ||
| using AzureMcp.CloudArchitect.Options; | ||
|
|
||
| namespace AzureMcp.CloudArchitect; | ||
|
|
||
| [JsonSourceGenerationOptions( | ||
| WriteIndented = true, | ||
| PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, | ||
| PropertyNameCaseInsensitive = true)] | ||
| [JsonSerializable(typeof(CloudArchitectResponseObject))] | ||
| [JsonSerializable(typeof(CloudArchitectDesignResponse))] | ||
| [JsonSerializable(typeof(ArchitectureDesignToolState))] | ||
| [JsonSerializable(typeof(ArchitectureDesignTiers))] | ||
| [JsonSerializable(typeof(ArchitectureDesignRequirements))] | ||
| [JsonSerializable(typeof(ArchitectureDesignRequirement))] | ||
| [JsonSerializable(typeof(ArchitectureDesignConfidenceFactors))] | ||
| [JsonSerializable(typeof(RequirementImportance))] | ||
| public partial class CloudArchitectJsonContext : JsonSerializerContext | ||
| { | ||
| } |
28 changes: 28 additions & 0 deletions
28
areas/cloudarchitect/src/AzureMcp.CloudArchitect/CloudArchitectSetup.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using AzureMcp.CloudArchitect.Commands.Design; | ||
| using AzureMcp.Core.Areas; | ||
| using AzureMcp.Core.Commands; | ||
| using Microsoft.Extensions.DependencyInjection; | ||
| using Microsoft.Extensions.Logging; | ||
|
|
||
| namespace AzureMcp.CloudArchitect; | ||
|
|
||
| public class CloudArchitectSetup : IAreaSetup | ||
| { | ||
| public void ConfigureServices(IServiceCollection services) | ||
| { | ||
| } | ||
|
|
||
| public void RegisterCommands(CommandGroup rootGroup, ILoggerFactory loggerFactory) | ||
| { | ||
| // Create CloudArchitect command group | ||
| var cloudArchitect = new CommandGroup("cloudarchitect", "Cloud Architecture operations - Commands for generating Azure architecture designs and recommendations based on requirements."); | ||
| rootGroup.AddSubGroup(cloudArchitect); | ||
|
|
||
| // Register CloudArchitect commands | ||
| cloudArchitect.AddCommand("design", new DesignCommand( | ||
| loggerFactory.CreateLogger<DesignCommand>())); | ||
| } | ||
| } |
160 changes: 160 additions & 0 deletions
160
areas/cloudarchitect/src/AzureMcp.CloudArchitect/Commands/Design/DesignCommand.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,160 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using System.CommandLine; | ||
| using System.CommandLine.Parsing; | ||
| using System.Diagnostics.CodeAnalysis; | ||
| using System.Reflection; | ||
| using System.Text.Json; | ||
| using AzureMcp.CloudArchitect.Models; | ||
| using AzureMcp.CloudArchitect.Options; | ||
| using AzureMcp.Core.Commands; | ||
| using AzureMcp.Core.Helpers; | ||
| using AzureMcp.Core.Models; | ||
| using Microsoft.Extensions.Logging; | ||
|
|
||
| namespace AzureMcp.CloudArchitect.Commands.Design; | ||
|
|
||
| public sealed class DesignCommand(ILogger<DesignCommand> logger) : GlobalCommand<ArchitectureDesignToolOptions> | ||
| { | ||
| private const string CommandTitle = "Design Azure cloud architectures through guided questions"; | ||
| private readonly ILogger<DesignCommand> _logger = logger; | ||
|
|
||
| private readonly Option<string> _questionOption = CloudArchitectOptionDefinitions.Question; | ||
| private readonly Option<int> _questionNumberOption = CloudArchitectOptionDefinitions.QuestionNumber; | ||
| private readonly Option<int> _questionTotalQuestions = CloudArchitectOptionDefinitions.TotalQuestions; | ||
| private readonly Option<string> _answerOption = CloudArchitectOptionDefinitions.Answer; | ||
| private readonly Option<bool> _nextQuestionNeededOption = CloudArchitectOptionDefinitions.NextQuestionNeeded; | ||
| private readonly Option<double> _confidenceScoreOption = CloudArchitectOptionDefinitions.ConfidenceScore; | ||
|
|
||
| private readonly Option<string> _architectureDesignToolState = CloudArchitectOptionDefinitions.State; | ||
|
|
||
| private static readonly string s_designArchitectureText = LoadArchitectureDesignText(); | ||
|
|
||
| private static string GetArchitectureDesignText() => s_designArchitectureText; | ||
|
|
||
| public override string Name => "design"; | ||
|
|
||
| public override string Description => "Azure architecture design tool that gathers requirements through guided questions and recommends optimal solutions.\n\nKey parameters: question, questionNumber, confidenceScore (0.0-1.0, present architecture when ≥0.7), totalQuestions, answer, nextQuestionNeeded, architectureComponent, architectureTier, state.\n\nProcess:\n1. Ask about user role, business goals (1-2 questions at a time)\n2. Track confidence and update requirements (explicit/implicit/assumed)\n3. When confident enough, present architecture with table format, visual organization, ASCII diagrams\n4. Follow Azure Well-Architected Framework principles\n5. Cover all tiers: infrastructure, platform, application, data, security, operations\n6. Provide actionable advice and high-level overview\n\nState tracks components, requirements by category, and confidence factors. Be conservative with suggestions."; | ||
msalaman marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| public override string Title => CommandTitle; | ||
|
|
||
| public override ToolMetadata Metadata => new() | ||
| { | ||
| Destructive = false, | ||
| ReadOnly = true | ||
| }; | ||
|
|
||
| private static string LoadArchitectureDesignText() | ||
| { | ||
| Assembly assembly = typeof(DesignCommand).Assembly; | ||
msalaman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| string resourceName = EmbeddedResourceHelper.FindEmbeddedResource(assembly, "azure-architecture-design.txt"); | ||
| return EmbeddedResourceHelper.ReadEmbeddedResource(assembly, resourceName); | ||
| } | ||
|
|
||
| protected override void RegisterOptions(Command command) | ||
| { | ||
| base.RegisterOptions(command); | ||
| command.AddOption(_questionOption); | ||
| command.AddOption(_questionNumberOption); | ||
| command.AddOption(_questionTotalQuestions); | ||
| command.AddOption(_answerOption); | ||
| command.AddOption(_nextQuestionNeededOption); | ||
| command.AddOption(_confidenceScoreOption); | ||
| command.AddOption(_architectureDesignToolState); | ||
|
|
||
| command.AddValidator(result => | ||
| { | ||
| // Validate confidence score is between 0.0 and 1.0 | ||
| var confidenceScore = result.GetValueForOption(_confidenceScoreOption); | ||
| if (confidenceScore < 0.0 || confidenceScore > 1.0) | ||
| { | ||
| result.ErrorMessage = "Confidence score must be between 0.0 and 1.0"; | ||
| return; | ||
| } | ||
|
|
||
| // Validate question number is not negative | ||
| var questionNumber = result.GetValueForOption(_questionNumberOption); | ||
| if (questionNumber < 0) | ||
| { | ||
| result.ErrorMessage = "Question number cannot be negative"; | ||
| return; | ||
| } | ||
|
|
||
| // Validate total questions is not negative | ||
| var totalQuestions = result.GetValueForOption(_questionTotalQuestions); | ||
| if (totalQuestions < 0) | ||
| { | ||
| result.ErrorMessage = "Total questions cannot be negative"; | ||
| return; | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| protected override ArchitectureDesignToolOptions BindOptions(ParseResult parseResult) | ||
| { | ||
| var options = base.BindOptions(parseResult); | ||
| options.Question = parseResult.GetValueForOption(_questionOption) ?? string.Empty; | ||
| options.QuestionNumber = parseResult.GetValueForOption(_questionNumberOption); | ||
| options.TotalQuestions = parseResult.GetValueForOption(_questionTotalQuestions); | ||
| options.Answer = parseResult.GetValueForOption(_answerOption); | ||
| options.NextQuestionNeeded = parseResult.GetValueForOption(_nextQuestionNeededOption); | ||
| options.ConfidenceScore = parseResult.GetValueForOption(_confidenceScoreOption); | ||
| options.State = DeserializeState(parseResult.GetValueForOption(_architectureDesignToolState)); | ||
| return options; | ||
| } | ||
|
|
||
| private static ArchitectureDesignToolState DeserializeState(string? stateJson) | ||
| { | ||
| if (string.IsNullOrEmpty(stateJson)) | ||
| { | ||
| return new ArchitectureDesignToolState(); | ||
| } | ||
|
|
||
| try | ||
| { | ||
| var state = JsonSerializer.Deserialize<ArchitectureDesignToolState>(stateJson, CloudArchitectJsonContext.Default.ArchitectureDesignToolState); | ||
| return state ?? new ArchitectureDesignToolState(); | ||
| } | ||
| catch (JsonException ex) | ||
| { | ||
| throw new InvalidOperationException($"Failed to deserialize state JSON: {ex.Message}", ex); | ||
| } | ||
| } | ||
|
|
||
| public override Task<CommandResponse> ExecuteAsync(CommandContext context, ParseResult parseResult) | ||
| { | ||
| try | ||
| { | ||
| var options = BindOptions(parseResult); | ||
msalaman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| var designArchitecture = GetArchitectureDesignText(); | ||
| var responseObject = new CloudArchitectResponseObject | ||
| { | ||
| DisplayText = options.Question, | ||
| DisplayThought = options.State.Thought, | ||
| DisplayHint = options.State.SuggestedHint, | ||
| QuestionNumber = options.QuestionNumber, | ||
| TotalQuestions = options.TotalQuestions, | ||
| NextQuestionNeeded = options.NextQuestionNeeded, | ||
| State = options.State | ||
| }; | ||
|
|
||
| var result = new CloudArchitectDesignResponse | ||
| { | ||
| DesignArchitecture = designArchitecture, | ||
| ResponseObject = responseObject | ||
| }; | ||
|
|
||
| context.Response.Status = 200; | ||
| context.Response.Results = ResponseResult.Create(result, CloudArchitectJsonContext.Default.CloudArchitectDesignResponse); | ||
| context.Response.Message = string.Empty; | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| _logger.LogError(ex, "An exception occurred in cloud architect design command"); | ||
| HandleException(context, ex); | ||
| } | ||
| return Task.FromResult(context.Response); | ||
| } | ||
| } | ||
11 changes: 11 additions & 0 deletions
11
areas/cloudarchitect/src/AzureMcp.CloudArchitect/GlobalUsings.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| global using System.CommandLine; | ||
| global using System.CommandLine.Parsing; | ||
| global using System.Text.Json; | ||
| global using System.Text.Json.Serialization; | ||
| global using AzureMcp.Core.Extensions; | ||
| global using AzureMcp.Core.Models; | ||
| global using AzureMcp.Core.Models.Command; | ||
| global using ModelContextProtocol.Server; |
36 changes: 36 additions & 0 deletions
36
areas/cloudarchitect/src/AzureMcp.CloudArchitect/Models/CloudArchitectResponseObject.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT License. | ||
|
|
||
| using AzureMcp.CloudArchitect.Options; | ||
|
|
||
| namespace AzureMcp.CloudArchitect.Models; | ||
|
|
||
| /// <summary> | ||
| /// Response object for the cloud architect design command. | ||
| /// </summary> | ||
| public class CloudArchitectResponseObject | ||
| { | ||
| public string DisplayText { get; set; } = string.Empty; | ||
|
|
||
| public string DisplayThought { get; set; } = string.Empty; | ||
|
|
||
| public string DisplayHint { get; set; } = string.Empty; | ||
|
|
||
| public int QuestionNumber { get; set; } | ||
|
|
||
| public int TotalQuestions { get; set; } | ||
|
|
||
| public bool NextQuestionNeeded { get; set; } | ||
|
|
||
| public ArchitectureDesignToolState State { get; set; } = new(); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Complete response for the cloud architect design command including both response object and design architecture text. | ||
| /// </summary> | ||
| public class CloudArchitectDesignResponse | ||
| { | ||
| public string DesignArchitecture { get; set; } = string.Empty; | ||
|
|
||
| public CloudArchitectResponseObject ResponseObject { get; set; } = new(); | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.