Skip to content

Commit 7a4e442

Browse files
gfraiteurclaude
andcommitted
Add AI-generated command description to MCP approval dialog
The AI risk analyzer now generates a concise description of what the command does, displayed prominently in the approval dialog to help users quickly understand the command's purpose. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 572a489 commit 7a4e442

File tree

4 files changed

+34
-12
lines changed

4 files changed

+34
-12
lines changed

src/PostSharp.Engineering.McpApprovalServer/Mcp/Models/RiskAssessment.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ public sealed class RiskAssessment
3636

3737
public required string Reason { get; init; }
3838

39+
/// <summary>
40+
/// Gets a description of what the command does (for AI-driven assessments).
41+
/// Null for regex-based assessments.
42+
/// </summary>
43+
public string? Description { get; init; }
44+
3945
/// <summary>
4046
/// Gets the name of the rule that triggered this assessment (for regex-based rules).
4147
/// Null for AI-driven assessments.
@@ -52,6 +58,7 @@ public static RiskAssessment Parse( string output )
5258
var level = RiskLevel.Medium;
5359
var recommendation = Recommendation.Approve;
5460
var reason = "Unable to parse risk assessment";
61+
string? description = null;
5562

5663
var lines = output.Split( '\n', StringSplitOptions.RemoveEmptyEntries );
5764

@@ -87,8 +94,12 @@ public static RiskAssessment Parse( string output )
8794
{
8895
reason = trimmedLine.Substring( 7 ).Trim();
8996
}
97+
else if ( trimmedLine.StartsWith( "DESCRIPTION:", StringComparison.OrdinalIgnoreCase ) )
98+
{
99+
description = trimmedLine.Substring( 12 ).Trim();
100+
}
90101
}
91102

92-
return new RiskAssessment { Level = level, Recommendation = recommendation, Reason = reason };
103+
return new RiskAssessment { Level = level, Recommendation = recommendation, Reason = reason, Description = description };
93104
}
94105
}

src/PostSharp.Engineering.McpApprovalServer/Mcp/Services/RiskAnalyzer.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,11 +336,12 @@ private static async Task<string> BuildAnalysisPromptAsync(
336336
// Response format
337337
sb.AppendLine( "## Response Format" );
338338
sb.AppendLine();
339-
sb.AppendLine( "Respond with EXACTLY these three lines (no additional text):" );
339+
sb.AppendLine( "Respond with EXACTLY these four lines (no additional text):" );
340340
sb.AppendLine( "```" );
341+
sb.AppendLine( "DESCRIPTION: <one concise sentence describing what the command does>" );
341342
sb.AppendLine( "RISK: LOW|MEDIUM|HIGH|CRITICAL" );
342343
sb.AppendLine( "RECOMMEND: APPROVE|REJECT" );
343-
sb.AppendLine( "REASON: <one concise sentence explaining your assessment>" );
344+
sb.AppendLine( "REASON: <one concise sentence explaining your risk assessment>" );
344345
sb.AppendLine( "```" );
345346

346347
return sb.ToString();

src/PostSharp.Engineering.McpApprovalServer/ViewModels/ApprovalViewModel.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ public ApprovalViewModel( ApprovalRequest request, ApprovalRequestQueue queue )
4646

4747
public RiskAssessment RegexAssessment => this._request.RegexAssessment;
4848

49+
/// <summary>
50+
/// Gets the AI-generated description of what the command does.
51+
/// </summary>
52+
public string CommandDescription => this._request.AiAssessment.Description ?? "No description available";
53+
4954
// UI helpers
5055
public bool HasRuleName => !string.IsNullOrEmpty( this._request.RegexAssessment.RuleName );
5156

src/PostSharp.Engineering.McpApprovalServer/Views/ApprovalWindow.xaml

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
<RowDefinition Height="Auto" />
5858
<RowDefinition Height="Auto" />
5959
<RowDefinition Height="Auto" />
60+
<RowDefinition Height="Auto" />
6061
</Grid.RowDefinitions>
6162
<Grid.ColumnDefinitions>
6263
<ColumnDefinition Width="120" />
@@ -90,16 +91,20 @@
9091
Foreground="#1976D2"
9192
Margin="0,5" />
9293

93-
<TextBlock Grid.Row="3" Grid.Column="0" Text="Purpose:" FontWeight="Bold" Margin="0,5" />
94-
<TextBox Grid.Row="3" Grid.Column="1"
95-
Text="{Binding ClaimedPurpose, Mode=OneWay}"
96-
IsReadOnly="True"
97-
TextWrapping="Wrap"
98-
Background="#F5F5F5"
99-
Margin="0,5" />
94+
<TextBlock Grid.Row="3" Grid.Column="0" Text="Description:" FontWeight="Bold" Margin="0,5" />
95+
<TextBlock Grid.Row="3" Grid.Column="1"
96+
Text="{Binding CommandDescription}"
97+
TextWrapping="Wrap"
98+
Margin="0,5" />
99+
100+
<TextBlock Grid.Row="4" Grid.Column="0" Text="Purpose:" FontWeight="Bold" Margin="0,5" />
101+
<TextBlock Grid.Row="4" Grid.Column="1"
102+
Text="{Binding ClaimedPurpose}"
103+
TextWrapping="Wrap"
104+
Margin="0,5" />
100105

101-
<TextBlock Grid.Row="4" Grid.Column="0" Text="Received:" FontWeight="Bold" Margin="0,5" />
102-
<TextBlock Grid.Row="4" Grid.Column="1" Text="{Binding ReceivedAt}" Margin="0,5" />
106+
<TextBlock Grid.Row="5" Grid.Column="0" Text="Received:" FontWeight="Bold" Margin="0,5" />
107+
<TextBlock Grid.Row="5" Grid.Column="1" Text="{Binding ReceivedAt}" Margin="0,5" />
103108
</Grid>
104109

105110
<!-- Risk assessments in tabs -->

0 commit comments

Comments
 (0)