Skip to content

Commit fbf8217

Browse files
committed
update branch
1 parent 7b6a441 commit fbf8217

17 files changed

Lines changed: 1072 additions & 11 deletions

File tree

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88
workflow_dispatch:
99

1010
env:
11-
DOTNET_VERSION: '9.0.x'
11+
DOTNET_VERSION: '10.0.x'
1212
SOLUTION_FILE: 'DotNetDevMCP.sln'
1313

1414
jobs:

.github/workflows/codeql.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
- name: Setup .NET
3737
uses: actions/setup-dotnet@v4
3838
with:
39-
dotnet-version: '9.0.x'
39+
dotnet-version: '10.0.x'
4040

4141
- name: Restore dependencies
4242
run: dotnet restore DotNetDevMCP.sln

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ on:
1212
type: string
1313

1414
env:
15-
DOTNET_VERSION: '9.0.x'
15+
DOTNET_VERSION: '10.0.x'
1616
SOLUTION_FILE: 'DotNetDevMCP.sln'
1717

1818
jobs:

.gitignore

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,43 @@
1-
Nothing needs to be added to .gitignore since only a README.md file was modified and no build artifacts, dependencies, or temporary files were detected in the changes.
1+
```
2+
# Build artifacts
3+
**/bin/
4+
**/obj/
5+
**/out/
6+
*.dll
7+
*.exe
8+
*.pdb
9+
*.so
10+
*.dylib
11+
*.nupkg
12+
13+
# Dependencies
14+
packages/
15+
**/node_modules/
16+
17+
# Logs
18+
*.log
19+
20+
# Environment
21+
.env
22+
.env.local
23+
*.env.*
24+
25+
# Editors
26+
.vscode/
27+
.idea/
28+
*.swp
29+
*.swo
30+
31+
# OS generated files
32+
.DS_Store
33+
Thumbs.db
34+
35+
# Test and coverage
36+
coverage/
37+
**/TestResults/
38+
*.coverage
39+
40+
# Local config
41+
**/appsettings.Development.json
42+
**/appsettings.Local.json
43+
```

src/DotNetDevMCP.Analysis/DotNetDevMCP.Analysis.csproj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,13 @@
66
<Nullable>enable</Nullable>
77
</PropertyGroup>
88

9+
<ItemGroup>
10+
<PackageReference Include="ModelContextProtocol" Version="0.1.0-preview.4" />
11+
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" />
12+
<PackageReference Include="Microsoft.Build.Framework" Version="17.12.6" />
13+
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.12.6" />
14+
<PackageReference Include="NuGet.ProjectModel" Version="6.12.0" />
15+
<PackageReference Include="System.Text.Json" Version="10.0.0" />
16+
</ItemGroup>
17+
918
</Project>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using Microsoft.Extensions.DependencyInjection;
2+
using DotNetDevMCP.Analysis.Services;
3+
4+
namespace DotNetDevMCP.Analysis.Extensions;
5+
6+
/// <summary>
7+
/// Extension methods for registering Analysis services
8+
/// </summary>
9+
public static class ServiceCollectionExtensions
10+
{
11+
/// <summary>
12+
/// Adds Analysis services to the service collection
13+
/// </summary>
14+
public static IServiceCollection AddAnalysisServices(this IServiceCollection services)
15+
{
16+
services.AddSingleton<CodeAnalysisService>();
17+
return services;
18+
}
19+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
using ModelContextProtocol.Server;
2+
using DotNetDevMCP.Analysis.Services;
3+
using DotNetDevMCP.Analysis.Models;
4+
5+
namespace DotNetDevMCP.Analysis.Mcp.Tools;
6+
7+
/// <summary>
8+
/// MCP tools for code analysis and metrics
9+
/// </summary>
10+
[McpServerToolType]
11+
public sealed class AnalysisTools(
12+
CodeAnalysisService analysisService,
13+
ILogger<AnalysisTools> logger)
14+
{
15+
private readonly CodeAnalysisService _analysisService = analysisService;
16+
private readonly ILogger<AnalysisTools> _logger = logger;
17+
18+
/// <summary>
19+
/// Analyzes a .NET project or solution and returns comprehensive code metrics
20+
/// </summary>
21+
/// <param name="path">Path to the project file (.csproj), solution file (.sln), or directory</param>
22+
/// <param name="includeMetrics">Include detailed code metrics (default: true)</param>
23+
/// <param name="includeDependencies">Include dependency information (default: true)</param>
24+
[McpServerTool(Name = "dotnet_analyze_project")]
25+
public async Task<AnalysisResult> AnalyzeProjectAsync(
26+
string path,
27+
bool includeMetrics = true,
28+
bool includeDependencies = true,
29+
CancellationToken cancellationToken = default)
30+
{
31+
_logger.LogInformation("MCP: Analyzing project at {Path}", path);
32+
33+
if (!Directory.Exists(path) && !File.Exists(path))
34+
{
35+
throw new FileNotFoundException($"Path not found: {path}");
36+
}
37+
38+
return await _analysisService.AnalyzeAsync(path, cancellationToken);
39+
}
40+
41+
/// <summary>
42+
/// Gets dependency information for a .NET project
43+
/// </summary>
44+
/// <param name="projectPath">Path to the project file (.csproj)</param>
45+
[McpServerTool(Name = "dotnet_get_dependencies")]
46+
public async Task<DependencyInfo> GetDependenciesAsync(
47+
string projectPath,
48+
CancellationToken cancellationToken = default)
49+
{
50+
_logger.LogInformation("MCP: Getting dependencies for {Path}", projectPath);
51+
52+
if (!File.Exists(projectPath))
53+
{
54+
throw new FileNotFoundException($"Project file not found: {projectPath}");
55+
}
56+
57+
return await _analysisService.GetDependenciesAsync(projectPath, cancellationToken);
58+
}
59+
60+
/// <summary>
61+
/// Analyzes code quality and identifies potential issues
62+
/// </summary>
63+
/// <param name="path">Path to the project or directory to analyze</param>
64+
[McpServerTool(Name = "dotnet_analyze_quality")]
65+
public async Task<CodeQualityMetrics> AnalyzeQualityAsync(
66+
string path,
67+
CancellationToken cancellationToken = default)
68+
{
69+
_logger.LogInformation("MCP: Analyzing code quality at {Path}", path);
70+
71+
if (!Directory.Exists(path) && !File.Exists(path))
72+
{
73+
throw new FileNotFoundException($"Path not found: {path}");
74+
}
75+
76+
return await _analysisService.AnalyzeQualityAsync(path, cancellationToken);
77+
}
78+
79+
/// <summary>
80+
/// Scans for outdated NuGet packages in a project
81+
/// </summary>
82+
/// <param name="projectPath">Path to the project file (.csproj)</param>
83+
[McpServerTool(Name = "dotnet_scan_outdated_packages")]
84+
public async Task<IReadOnlyList<PackageDependency>> ScanOutdatedPackagesAsync(
85+
string projectPath,
86+
CancellationToken cancellationToken = default)
87+
{
88+
_logger.LogInformation("MCP: Scanning for outdated packages in {Path}", projectPath);
89+
90+
var deps = await _analysisService.GetDependenciesAsync(projectPath, cancellationToken);
91+
92+
// In a real implementation, this would check NuGet.org for latest versions
93+
// For now, return all direct dependencies as potentially outdated
94+
return deps.PackageDependencies
95+
.Where(d => d.IsDirect)
96+
.ToList()
97+
.AsReadOnly();
98+
}
99+
100+
/// <summary>
101+
/// Detects circular dependencies in a solution
102+
/// </summary>
103+
/// <param name="solutionPath">Path to the solution file (.sln)</param>
104+
[McpServerTool(Name = "dotnet_detect_circular_dependencies")]
105+
public async Task<bool> DetectCircularDependenciesAsync(
106+
string solutionPath,
107+
CancellationToken cancellationToken = default)
108+
{
109+
_logger.LogInformation("MCP: Detecting circular dependencies in {Path}", solutionPath);
110+
111+
// Simplified implementation - would need full graph analysis in production
112+
var deps = await _analysisService.GetDependenciesAsync(solutionPath, cancellationToken);
113+
return deps.HasCircularDependencies;
114+
}
115+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
namespace DotNetDevMCP.Analysis.Models;
2+
3+
/// <summary>
4+
/// Represents the result of a code analysis operation
5+
/// </summary>
6+
public sealed record AnalysisResult(
7+
string ProjectPath,
8+
int TotalFiles,
9+
int TotalLines,
10+
int CodeLines,
11+
int CommentLines,
12+
int BlankLines,
13+
int Classes,
14+
int Methods,
15+
double MaintainabilityIndex,
16+
double CyclomaticComplexity,
17+
DateTime AnalyzedAt
18+
);
19+
20+
/// <summary>
21+
/// Represents code quality metrics for a project
22+
/// </summary>
23+
public sealed record CodeQualityMetrics(
24+
string ProjectPath,
25+
double TechnicalDebtHours,
26+
int CodeSmells,
27+
int Bugs,
28+
int Vulnerabilities,
29+
double Coverage,
30+
double Duplication,
31+
IReadOnlyList<CodeIssue> Issues,
32+
DateTime AnalyzedAt
33+
);
34+
35+
/// <summary>
36+
/// Represents a single code issue
37+
/// </summary>
38+
public sealed record CodeIssue(
39+
string RuleId,
40+
string Message,
41+
string Severity,
42+
string FilePath,
43+
int LineNumber,
44+
int ColumnNumber,
45+
string? Suggestion = null
46+
);
47+
48+
/// <summary>
49+
/// Represents dependency information for a project
50+
/// </summary>
51+
public sealed record DependencyInfo(
52+
string ProjectPath,
53+
IReadOnlyList<PackageDependency> PackageDependencies,
54+
IReadOnlyList<ProjectReference> ProjectReferences,
55+
IReadOnlyList<string> FrameworkReferences,
56+
bool HasCircularDependencies,
57+
DateTime AnalyzedAt
58+
);
59+
60+
/// <summary>
61+
/// Represents a NuGet package dependency
62+
/// </summary>
63+
public sealed record PackageDependency(
64+
string Name,
65+
string Version,
66+
bool IsDirect,
67+
bool IsDevelopmentDependency,
68+
string? LicenseUrl = null,
69+
bool? HasKnownVulnerabilities = null
70+
);
71+
72+
/// <summary>
73+
/// Represents a project reference
74+
/// </summary>
75+
public sealed record ProjectReference(
76+
string Name,
77+
string Path,
78+
bool IsProjectReference
79+
);
80+
81+
/// <summary>
82+
/// Request model for code analysis
83+
/// </summary>
84+
public sealed record AnalysisRequest(
85+
string Path,
86+
bool IncludeMetrics = true,
87+
bool IncludeDependencies = true,
88+
bool IncludeIssues = true,
89+
string? Configuration = null,
90+
string? Platform = null
91+
);

0 commit comments

Comments
 (0)