Skip to content

Commit fb9c714

Browse files
committed
WIP
1 parent 90a19cd commit fb9c714

29 files changed

Lines changed: 2665 additions & 201 deletions

cli/azd/cmd/mcp.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,16 @@ func (a *mcpStartAction) Run(ctx context.Context) (*actions.ActionResult, error)
154154

155155
allTools := []server.ServerTool{
156156
tools.NewAzdPlanInitTool(),
157+
tools.NewAzdIdentifyUserIntentTool(),
158+
tools.NewAzdSelectStackTool(),
159+
tools.NewAzdListStackResourcesTool(),
160+
tools.NewAzdNewProjectTool(),
161+
tools.NewAzdModernizeProjectTool(),
157162
tools.NewAzdDiscoveryAnalysisTool(),
158163
tools.NewAzdArchitecturePlanningTool(),
164+
tools.NewAzdArtifactGenerationTool(),
165+
tools.NewAzdAppCodeGenerationTool(),
166+
tools.NewGenerateProjectSpecTemplateTool(),
159167
tools.NewAzdAzureYamlGenerationTool(),
160168
tools.NewAzdDockerGenerationTool(),
161169
tools.NewAzdInfrastructureGenerationTool(),
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package tools
5+
6+
import (
7+
"context"
8+
9+
"github.com/azure/azure-dev/cli/azd/internal/mcp/tools/prompts"
10+
"github.com/mark3labs/mcp-go/mcp"
11+
"github.com/mark3labs/mcp-go/server"
12+
)
13+
14+
// NewAzdAppCodeGenerationTool creates a new azd application code generation tool
15+
func NewAzdAppCodeGenerationTool() server.ServerTool {
16+
return server.ServerTool{
17+
Tool: mcp.NewTool(
18+
"azd_appcode_generation",
19+
mcp.WithReadOnlyHintAnnotation(false),
20+
mcp.WithIdempotentHintAnnotation(false),
21+
mcp.WithDestructiveHintAnnotation(false),
22+
mcp.WithOpenWorldHintAnnotation(false),
23+
mcp.WithDescription(
24+
`Returns instructions for generating application code scaffolding for all project components
25+
using preferred programming languages and frameworks in src/<component> structure.
26+
27+
The LLM agent should execute these instructions using available tools.
28+
29+
Use this tool when:
30+
- Project components have been defined and technology stack selected
31+
- Programming language and framework preferences are known
32+
- Need to generate application scaffolding for APIs, SPAs, workers, functions, etc.
33+
- Ready to create production-ready code templates with Azure integrations`,
34+
),
35+
),
36+
Handler: handleAzdAppCodeGeneration,
37+
}
38+
}
39+
40+
func handleAzdAppCodeGeneration(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
41+
return mcp.NewToolResultText(prompts.AzdAppCodeGenerationPrompt), nil
42+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package tools
5+
6+
import (
7+
"context"
8+
9+
"github.com/azure/azure-dev/cli/azd/internal/mcp/tools/prompts"
10+
"github.com/mark3labs/mcp-go/mcp"
11+
"github.com/mark3labs/mcp-go/server"
12+
)
13+
14+
// NewAzdArtifactGenerationTool creates a new azd artifact generation orchestration tool
15+
func NewAzdArtifactGenerationTool() server.ServerTool {
16+
return server.ServerTool{
17+
Tool: mcp.NewTool(
18+
"azd_artifact_generation",
19+
mcp.WithReadOnlyHintAnnotation(false),
20+
mcp.WithIdempotentHintAnnotation(false),
21+
mcp.WithDestructiveHintAnnotation(false),
22+
mcp.WithOpenWorldHintAnnotation(false),
23+
mcp.WithDescription(
24+
`Returns instructions for orchestrating complete AZD project artifact generation including
25+
application scaffolding, Docker configurations, infrastructure templates, and azure.yaml configuration.
26+
27+
The LLM agent should execute these instructions using available tools.
28+
29+
Use this tool when:
30+
- Project architecture and requirements have been defined in Application specification
31+
- Ready to generate all project artifacts and implementation files
32+
- Need to create application code, infrastructure templates, and deployment configurations
33+
- Moving from planning phase to implementation phase`,
34+
),
35+
),
36+
Handler: handleAzdArtifactGeneration,
37+
}
38+
}
39+
40+
func handleAzdArtifactGeneration(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
41+
return mcp.NewToolResultText(prompts.AzdArtifactGenerationPrompt), nil
42+
}

cli/azd/internal/mcp/tools/azd_discovery_analysis.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Use this tool when:
3030
- Starting Phase 1 of AZD migration process
3131
- Need to identify all application components and dependencies
3232
- Codebase analysis required before architecture planning
33-
- azd-arch-plan.md does not exist or needs updating`,
33+
- Application spec does not exist or needs updating`,
3434
),
3535
),
3636
Handler: handleAzdDiscoveryAnalysis,
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package tools
5+
6+
import (
7+
"context"
8+
_ "embed"
9+
"fmt"
10+
"os"
11+
"strings"
12+
"time"
13+
14+
"github.com/mark3labs/mcp-go/mcp"
15+
"github.com/mark3labs/mcp-go/server"
16+
)
17+
18+
//go:embed resources/app-spec-template.md
19+
var appSpecTemplateContent string
20+
21+
// NewGenerateProjectSpecTemplateTool creates a new MCP tool for generating project specification templates
22+
func NewGenerateProjectSpecTemplateTool() server.ServerTool {
23+
return server.ServerTool{
24+
Tool: mcp.NewTool(
25+
"azd_generate_project_spec_template",
26+
mcp.WithReadOnlyHintAnnotation(false),
27+
mcp.WithIdempotentHintAnnotation(true),
28+
mcp.WithDestructiveHintAnnotation(false),
29+
mcp.WithOpenWorldHintAnnotation(false),
30+
mcp.WithDescription(
31+
`Generate a project specification template file (app-spec.md) in the current workspace.
32+
This tool creates the initial template file that other tools will populate with actual
33+
project information during the planning and implementation process.
34+
35+
The template will be created at 'app-spec.md' in the current directory if it doesn't
36+
already exist. No parameters required.`,
37+
),
38+
),
39+
Handler: handleGenerateProjectSpecTemplate,
40+
}
41+
}
42+
43+
func handleGenerateProjectSpecTemplate(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
44+
const outputPath = "app-spec.md"
45+
46+
// Check if file already exists
47+
if _, err := os.Stat(outputPath); err == nil {
48+
return mcp.NewToolResultText(fmt.Sprintf("Template file '%s' already exists in the workspace. No action taken.", outputPath)), nil
49+
}
50+
51+
// Generate current timestamp
52+
currentTime := time.Now()
53+
generatedDate := currentTime.Format("2006-01-02 15:04:05 MST")
54+
55+
// Create the template with placeholder project name and current timestamp
56+
templateContent := strings.ReplaceAll(appSpecTemplateContent, "{{.ProjectName}}", "[PROJECT_NAME]")
57+
templateContent = strings.ReplaceAll(templateContent, "{{.GeneratedDate}}", generatedDate)
58+
templateContent = strings.ReplaceAll(templateContent, "{{.LastUpdated}}", generatedDate)
59+
60+
// Write the template file to the workspace
61+
if err := os.WriteFile(outputPath, []byte(templateContent), 0644); err != nil {
62+
return mcp.NewToolResultText(fmt.Sprintf("Error writing template file: %v", err)), nil
63+
}
64+
65+
// Create success response
66+
response := fmt.Sprintf(`# Project Specification Template Created
67+
68+
✅ **Template File Successfully Created**
69+
70+
**File Path**: %s
71+
**Generated**: %s
72+
73+
## Template Overview
74+
75+
A comprehensive project specification template has been created in your workspace with the following structure:
76+
77+
- **Project Overview**: Basic project information and classification
78+
- **Project Requirements**: Sections for requirements discovery findings
79+
- **Technology Stack Selection**: Documentation of stack decisions and rationale
80+
- **Application Architecture**: Component definitions and data architecture
81+
- **Azure Service Mapping**: Infrastructure and service configurations
82+
- **Implementation Plan**: Development approach and deployment strategy
83+
- **Security and Compliance**: Security architecture and requirements
84+
- **Monitoring and Operations**: Operational procedures and monitoring
85+
- **Project Status and Next Steps**: Implementation roadmap and success criteria
86+
87+
## Next Steps
88+
89+
The template is ready! Other tools will now populate the template sections as they discover and plan project details:
90+
91+
1. User intent discovery will fill the "Project Requirements" section
92+
2. Stack selection will complete the "Technology Stack Selection" section
93+
3. Architecture planning will populate the "Application Architecture" and "Azure Service Mapping" sections
94+
4. Implementation planning will complete the remaining sections
95+
96+
The template serves as the living documentation for your AZD project throughout the planning and implementation process.`, outputPath, generatedDate)
97+
98+
return mcp.NewToolResultText(response), nil
99+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package tools
5+
6+
import (
7+
"context"
8+
9+
"github.com/azure/azure-dev/cli/azd/internal/mcp/tools/prompts"
10+
"github.com/mark3labs/mcp-go/mcp"
11+
"github.com/mark3labs/mcp-go/server"
12+
)
13+
14+
// NewAzdIdentifyUserIntentTool creates a new azd identify user intent tool
15+
func NewAzdIdentifyUserIntentTool() server.ServerTool {
16+
return server.ServerTool{
17+
Tool: mcp.NewTool(
18+
"azd_identify_user_intent",
19+
mcp.WithReadOnlyHintAnnotation(true),
20+
mcp.WithIdempotentHintAnnotation(true),
21+
mcp.WithDestructiveHintAnnotation(false),
22+
mcp.WithOpenWorldHintAnnotation(false),
23+
mcp.WithDescription(
24+
`Returns instructions for discovering user project intent, requirements, and technology preferences
25+
through conversational questioning.
26+
27+
The LLM agent should execute these instructions using available tools.
28+
29+
Use this tool when:
30+
- Starting requirements discovery for new or existing projects
31+
- Need to understand project scale, budget constraints, and architectural preferences
32+
- Want to capture programming language and framework preferences
33+
- Beginning project planning phase to inform technology stack decisions`,
34+
),
35+
),
36+
Handler: handleAzdIdentifyUserIntent,
37+
}
38+
}
39+
40+
func handleAzdIdentifyUserIntent(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
41+
return mcp.NewToolResultText(prompts.AzdIdentifyUserIntentPrompt), nil
42+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package tools
5+
6+
import (
7+
"context"
8+
_ "embed"
9+
"fmt"
10+
11+
"github.com/mark3labs/mcp-go/mcp"
12+
"github.com/mark3labs/mcp-go/server"
13+
)
14+
15+
//go:embed prompts/azd_list_stack_resources.md
16+
var azdListStackResourcesPrompt string
17+
18+
//go:embed resources/baseline_resources.md
19+
var baselineResourcesDoc string
20+
21+
//go:embed resources/containers_stack_resources.md
22+
var containersStackResourcesDoc string
23+
24+
//go:embed resources/serverless_stack_resources.md
25+
var serverlessStackResourcesDoc string
26+
27+
//go:embed resources/logic_apps_stack_resources.md
28+
var logicAppsStackResourcesDoc string
29+
30+
func NewAzdListStackResourcesTool() server.ServerTool {
31+
return server.ServerTool{
32+
Tool: mcp.NewTool(
33+
"azd_list_stack_resources",
34+
mcp.WithReadOnlyHintAnnotation(true),
35+
mcp.WithIdempotentHintAnnotation(true),
36+
mcp.WithDestructiveHintAnnotation(false),
37+
mcp.WithOpenWorldHintAnnotation(false),
38+
mcp.WithDescription(
39+
`List Azure resources required for a specific technology stack.
40+
41+
Returns baseline resources (required for all stacks) plus stack-specific resources for the chosen technology approach.
42+
43+
Use this tool when:
44+
- A technology stack has been selected for a project (containers, serverless, or logic apps)
45+
- Need resource listing for the selected technology stack
46+
47+
The tool takes a stack parameter (containers, serverless, logic_apps) and returns the comprehensive resource list with Azure resource type identifiers.`,
48+
),
49+
mcp.WithString("stack",
50+
mcp.Description("The technology stack to list resources for"),
51+
mcp.Enum("containers", "serverless", "logic_apps"),
52+
mcp.Required(),
53+
),
54+
),
55+
Handler: handleAzdListStackResources,
56+
}
57+
}
58+
59+
func handleAzdListStackResources(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
60+
stack, err := request.RequireString("stack")
61+
if err != nil {
62+
return mcp.NewToolResultError(fmt.Sprintf("Invalid arguments: %v", err)), nil
63+
}
64+
65+
// Validate stack parameter
66+
validStacks := map[string]bool{
67+
"containers": true,
68+
"serverless": true,
69+
"logic_apps": true,
70+
}
71+
72+
if !validStacks[stack] {
73+
return mcp.NewToolResultError(fmt.Sprintf("Invalid stack '%s'. Must be one of: containers, serverless, logic_apps", stack)), nil
74+
}
75+
76+
// Build response with baseline resources and stack-specific resources
77+
var stackSpecificDoc string
78+
var stackDisplayName string
79+
80+
switch stack {
81+
case "containers":
82+
stackSpecificDoc = containersStackResourcesDoc
83+
stackDisplayName = "Containers"
84+
case "serverless":
85+
stackSpecificDoc = serverlessStackResourcesDoc
86+
stackDisplayName = "Serverless"
87+
case "logic_apps":
88+
stackSpecificDoc = logicAppsStackResourcesDoc
89+
stackDisplayName = "Logic Apps"
90+
}
91+
92+
response := fmt.Sprintf(`%s
93+
94+
# Azure Resources for %s Stack
95+
96+
## Baseline Resources (All Stacks)
97+
98+
%s
99+
100+
## %s Stack-Specific Resources
101+
102+
%s`,
103+
azdListStackResourcesPrompt,
104+
stackDisplayName,
105+
baselineResourcesDoc,
106+
stackDisplayName,
107+
stackSpecificDoc,
108+
)
109+
110+
return mcp.NewToolResultText(response), nil
111+
}

0 commit comments

Comments
 (0)