Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
416e1b9
Initial plan
Copilot Oct 19, 2025
031a51a
Add source generator project and initial implementation
Copilot Oct 19, 2025
721ce02
Complete source generator implementation with README and fix analyzer…
Copilot Oct 19, 2025
0424b0c
Add example documentation and update README with availability info
Copilot Oct 19, 2025
4f96860
Convert to incremental generator, add parameter/return docs support, …
Copilot Oct 20, 2025
5ade3c3
Apply ASP.NET Core OpenAPI generator patterns: struct for caching, ca…
Copilot Oct 20, 2025
c7898da
Add tests for ASP.NET Core OpenAPI generator improvements: string esc…
Copilot Oct 20, 2025
3cf7601
Address all review feedback: single file generation, nullable disable…
Copilot Oct 20, 2025
a7e54c7
Fix nested type indentation calculation
Copilot Oct 20, 2025
a5b8d2b
Address final review feedback: simplify attribute checks, use newline…
Copilot Oct 20, 2025
e04d9dd
Fix CI build failures by removing direct Analyzer reference that expe…
Copilot Oct 20, 2025
fe179cf
Remove Benefits section from README per review feedback
Copilot Oct 20, 2025
efc0626
Merge branch 'main' into copilot/scaffold-analyzer-source-generator
stephentoub Oct 23, 2025
288e1fe
Fix CI build failures by disabling parallel builds for Core project t…
Copilot Oct 25, 2025
7376e58
Fix packaging path for analyzer DLL - remove incorrect $(Configuratio…
Copilot Oct 25, 2025
4c01569
Fix analyzer packaging - use $(Configuration) in path as SourceGenera…
Copilot Oct 25, 2025
c337fd2
Fix analyzer reference and packaging - use SetTargetFramework to ensu…
Copilot Oct 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@
<!-- Build Infra & Packaging -->
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />

<!-- Source Generator & Analyzer dependencies -->
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />

<!-- Testing dependencies -->
<PackageVersion Include="Anthropic.SDK" Version="5.6.0" />
<PackageVersion Include="coverlet.collector" Version="6.0.4">
Expand Down
1 change: 1 addition & 0 deletions ModelContextProtocol.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
<File Path="src/Directory.Build.props" />
<Project Path="src/ModelContextProtocol.AspNetCore/ModelContextProtocol.AspNetCore.csproj" />
<Project Path="src/ModelContextProtocol.Core/ModelContextProtocol.Core.csproj" />
<Project Path="src/ModelContextProtocol.SourceGenerators/ModelContextProtocol.SourceGenerators.csproj" />
<Project Path="src/ModelContextProtocol/ModelContextProtocol.csproj" />
</Folder>
<Folder Name="/tests/">
Expand Down
20 changes: 20 additions & 0 deletions src/ModelContextProtocol.Core/ModelContextProtocol.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,24 @@
<None Include="README.md" pack="true" PackagePath="\" />
</ItemGroup>

<!-- Include source generator as an analyzer -->
<ItemGroup>
<ProjectReference Include="..\ModelContextProtocol.SourceGenerators\ModelContextProtocol.SourceGenerators.csproj"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false" />
</ItemGroup>

<!-- Direct analyzer reference for build-time source generation -->
<ItemGroup>
<Analyzer Include="$(ArtifactsDir)bin\ModelContextProtocol.SourceGenerators\netstandard2.0\ModelContextProtocol.SourceGenerators.dll" />
</ItemGroup>

<!-- Package the analyzer DLL into the NuGet package -->
<ItemGroup>
<None Include="$(ArtifactsDir)bin\ModelContextProtocol.SourceGenerators\netstandard2.0\ModelContextProtocol.SourceGenerators.dll"
Pack="true"
PackagePath="analyzers/dotnet/cs"
Visible="false" />
</ItemGroup>

</Project>
70 changes: 70 additions & 0 deletions src/ModelContextProtocol.SourceGenerators/EXAMPLE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Source Generator Example

This example demonstrates how to use the XmlToDescriptionGenerator source generator.

## Without Source Generator (Traditional Approach)

```csharp
using ModelContextProtocol.Server;
using System.ComponentModel;

[McpServerToolType]
public class WeatherTools
{
/// <summary>
/// Get the current weather for a location.
/// </summary>
[McpServerTool]
[Description("Get the current weather for a location.")] // Duplication!
public static string GetWeather(string location)
{
return $"Weather for {location}: Sunny, 72°F";
}
}
```

## With Source Generator (Recommended)

```csharp
using ModelContextProtocol.Server;

[McpServerToolType]
public partial class WeatherTools
{
/// <summary>
/// Get the current weather for a location.
/// </summary>
[McpServerTool]
public static partial string GetWeather(string location)
{
return $"Weather for {location}: Sunny, 72°F";
}
}
```

The source generator automatically creates a partial method declaration with the `[Description]` attribute:

```csharp
// <auto-generated/>
#nullable enable

using System.ComponentModel;
using ModelContextProtocol.Server;

namespace YourNamespace;

public partial class WeatherTools
{
[Description("Get the current weather for a location.")]
public static partial string GetWeather(string location);
}
```

## Key Changes Required

1. Make the class `partial`
2. Make the method `partial`
3. Remove any existing `[Description]` attribute
4. Keep your XML documentation comments

The Description attribute will be automatically generated from your XML `<summary>` element!
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
<IsRoslynComponent>true</IsRoslynComponent>
<IsPackable>false</IsPackable>
<IncludeBuildOutput>false</IncludeBuildOutput>
<GenerateDocumentationFile>false</GenerateDocumentationFile>
</PropertyGroup>

<!-- Remove auto-included polyfills from Directory.Build.props -->
<ItemGroup>
<Compile Remove="..\Common\Polyfills\**\*.cs" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" PrivateAssets="all" />
</ItemGroup>

</Project>
78 changes: 78 additions & 0 deletions src/ModelContextProtocol.SourceGenerators/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# ModelContextProtocol.SourceGenerators

This project contains source generators for the Model Context Protocol C# SDK.

## XmlToDescriptionGenerator

This source generator automatically creates `Description` attributes from XML documentation comments for partial methods tagged with `[McpServerTool]`.

### How it works

When you write a partial method with:
1. An `[McpServerTool]` attribute
2. XML documentation comments (specifically a `<summary>` tag)
3. NO existing `[Description]` attribute

The generator will create a partial method declaration with a `[Description]` attribute containing the text from the XML `<summary>` element.

### Example Usage

**Your code:**
```csharp
using ModelContextProtocol.Server;
using System.ComponentModel;

[McpServerToolType]
public partial class MyTools
{
/// <summary>
/// This tool echoes the input message back to the user.
/// </summary>
[McpServerTool]
public static partial string Echo(string message)
{
return $"Echo: {message}";
}
}
```

**Generated code:**
```csharp
// <auto-generated/>
#nullable enable

using System.ComponentModel;
using ModelContextProtocol.Server;

namespace YourNamespace;

public partial class MyTools
{
[Description("This tool echoes the input message back to the user.")]
public static partial string Echo(string message);
}
```

### Benefits

- **Reduces duplication**: You don't need to write both XML comments AND Description attributes
- **Single source of truth**: XML comments are used for both documentation and runtime tool descriptions
- **Automatic synchronization**: Changes to XML comments are automatically reflected in the Description attributes

### Requirements

- Your method must be marked as `partial`
- Your method must have the `[McpServerTool]` attribute
- Your method must have XML documentation comments with a `<summary>` tag
- Your method must NOT already have a `[Description]` attribute
- Your project must reference `ModelContextProtocol.Core` directly (the source generator is distributed with this package)

### Availability

The source generator is distributed as part of the `ModelContextProtocol.Core` NuGet package and will be automatically available when you reference that package in your project.

### Notes

- The generator only extracts text from the `<summary>` element
- Multi-line summaries are combined into a single line
- Only partial methods with implementations (method bodies) are supported
Loading