Skip to content

Commit 07dcebb

Browse files
committed
Merge branch 'improving-resources' into dotnet-everything
2 parents e5227b2 + 59dadaa commit 07dcebb

File tree

130 files changed

+3172
-2599
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

130 files changed

+3172
-2599
lines changed

.github/workflows/ci.yml

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,28 @@ on:
88

99
jobs:
1010
build:
11-
12-
runs-on: ${{ matrix.os }}
13-
1411
strategy:
1512
matrix:
1613
os: [ubuntu-latest, windows-latest, macos-latest]
1714
configuration: [Debug, Release]
1815
fail-fast: false
1916

20-
steps:
21-
- uses: actions/checkout@v4
17+
runs-on: ${{ matrix.os }}
18+
19+
steps:
20+
- name: Clone the repo
21+
uses: actions/checkout@v4
2222
with:
2323
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
24-
25-
- name: Setup .NET
24+
25+
- name: Set up .NET
2626
uses: actions/setup-dotnet@v4
2727
with:
28-
dotnet-version: |
28+
dotnet-version: |
2929
9.0.x
3030
8.0.x
3131
32-
# Netfx testing on non-Windows requires mono
32+
# NetFX testing on non-Windows requires mono
3333
- name: Setup Mono
3434
if: runner.os == 'Linux'
3535
run: sudo apt-get install -y mono-devel
@@ -38,7 +38,7 @@ jobs:
3838
uses: actions/setup-node@v3
3939
with:
4040
node-version: '20'
41-
41+
4242
- name: Install dependencies for tests
4343
run: npm install @modelcontextprotocol/server-everything
4444

@@ -48,6 +48,9 @@ jobs:
4848
- name: Build
4949
run: dotnet build --configuration ${{ matrix.configuration }}
5050

51+
- name: Pack
52+
run: dotnet pack --configuration ${{ matrix.configuration }}
53+
5154
- name: Test
5255
run: >-
5356
dotnet test

.github/workflows/docs.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ permissions:
1616
concurrency:
1717
group: "pages"
1818
cancel-in-progress: false
19-
19+
2020
jobs:
2121
publish-docs:
22+
# Only publish from the modelcontextprotocol/csharp-sdk repository
23+
if: ${{ github.repository == 'modelcontextprotocol/csharp-sdk' }}
2224
environment:
2325
name: github-pages
2426
url: ${{ steps.deployment.outputs.page_url }}
@@ -42,4 +44,4 @@ jobs:
4244

4345
- name: Deploy to GitHub Pages
4446
id: deployment
45-
uses: actions/deploy-pages@v4
47+
uses: actions/deploy-pages@v4

.github/workflows/release.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Release Process
2+
3+
The following process is used when publishing new releases to NuGet.org:
4+
5+
1. **Ensure the CI workflow is fully green**
6+
- Some of the integration tests are flaky and require re-running
7+
- Once the state of the branch is known to be good, a release can proceed
8+
- **The release workflow _does not_ run tests**
9+
10+
2. **Create a new Release in GitHub**
11+
- Use the link on the repo home page to [Create a new release](https://github.com/modelcontextprotocol/csharp-sdk/releases/new)
12+
- Click the 'Choose a tag' dropdown button
13+
- Type the name using the `v{major}.{minor}.{patch}-{suffix}` pattern
14+
- Click 'Create new tag: ... on publish'
15+
- Click the 'Target' dropdown button
16+
- Choose the 'Recent Commits' tab
17+
- Select the commit to use for the release, ensuring it's one from above where CI is known to be green
18+
- Click the 'Previous tag' dropdown button
19+
- Choose the previous release to use for generating release notes
20+
- Click the 'Generate release notes button'
21+
- This will add release notes into the Release description
22+
- The generated release notes include what has changed and the list of new contributors
23+
- Verify the Release title
24+
- It will be populated to match the tag name to be created
25+
- This should be retained, using the release title format matching the `v{major}.{minor}.{patch}-{suffix}` format
26+
- Augment the Release description as desired
27+
- This content is presented used on GitHub and is not persisted into any artifacts
28+
- Check the 'Set as a pre-release' button under the release description if appropriate
29+
- Click 'Public release'
30+
31+
3. **Monitor the Release workflow**
32+
- After publishing the release, a workflow will begin for producing the release's build artifacts and publishing the NuGet package to NuGet.org
33+
- If the job fails, troubleshoot and re-run the workflow as needed
34+
- Verify the package version becomes listed on at [https://nuget.org/packages/ModelContextProtocol](https://nuget.org/packages/ModelContextProtocol)
35+
36+
4. **Update the source to increment the version number**
37+
- Immediately after publishing a new release, the [`/src/Directory.Build.Props`](../../src/Directory.Build.props) file needs to be updated to bump the version to the next expected release version

.github/workflows/release.yml

Lines changed: 75 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,71 @@
1-
# This workflow is triggered by new releases
2-
# It builds, tests, and publishes to the GitHub NuGet package registry
3-
name: Release package
1+
# Publish new package versions of ModelContextProtocol
2+
#
3+
# Daily and Manual Runs
4+
# - Triggered automatically at 07:00 UTC daily
5+
# - Triggered manually using GitHub Actions workflow_dispatch event
6+
# - Version prefix applied from /src/Directory.Build.props
7+
# - Version suffix set to `ci.{github.run_number}`
8+
# - Package published to GitHub package registry
9+
#
10+
# Official Releases
11+
# - Triggered after a GitHub Release is created
12+
# - Version prefix applied from /src/Directory.Build.props
13+
# - Version suffix applied from /src/Directory.Build.props
14+
# - Package published to GitHub package registry
15+
# - Package published to NuGet.org
16+
# - Version prefix and/or suffix should be updated after each release
17+
18+
name: Release Publishing
419

520
on:
21+
schedule:
22+
- cron: '0 7 * * *'
23+
24+
workflow_dispatch:
25+
inputs:
26+
version_suffix_override:
27+
description: Version suffix override
28+
type: string
29+
630
release:
731
types: [published]
832

933
jobs:
10-
build:
34+
build-all-configs:
35+
strategy:
36+
matrix:
37+
os: [ubuntu-latest, windows-latest, macos-latest]
38+
configuration: [Debug, Release]
39+
fail-fast: false
40+
41+
runs-on: ${{ matrix.os }}
42+
43+
steps:
44+
- name: Clone the repo
45+
uses: actions/checkout@v4
46+
with:
47+
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
48+
49+
- name: Set up .NET
50+
uses: actions/setup-dotnet@v4
51+
with:
52+
dotnet-version: 9.0.x
1153

54+
- name: Build
55+
run: dotnet build --configuration ${{ matrix.configuration }}
56+
57+
- name: Pack
58+
run: dotnet pack --configuration ${{ matrix.configuration }}
59+
60+
build-package:
1261
runs-on: windows-latest
62+
needs: build-all-configs
63+
64+
env:
65+
version_suffix_args: ${{ github.event_name != 'release' && format('--version-suffix "{0}"', inputs.version_suffix_override || format('ci.{0}', github.run_number)) || '' }}
1366

1467
steps:
1568
- uses: actions/checkout@v4
16-
with:
17-
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
1869

1970
- name: Setup .NET
2071
uses: actions/setup-dotnet@v2
@@ -23,25 +74,11 @@ jobs:
2374
9.0.x
2475
8.0.x
2576
26-
- name: Set up Node.js
27-
uses: actions/setup-node@v3
28-
with:
29-
node-version: '20'
30-
31-
- name: Install dependencies for tests
32-
run: npm install @modelcontextprotocol/server-everything
33-
34-
- name: Install dependencies for tests
35-
run: npm install @modelcontextprotocol/server-memory
36-
37-
- name: Build
38-
run: dotnet build --configuration Release
39-
40-
- name: Test
41-
run: dotnet test --configuration Release --no-build --filter '(Execution!=Manual)'
42-
4377
- name: Pack
44-
run: dotnet pack --configuration Release --output "${{ github.workspace }}/artifacts/packages"
78+
run: dotnet pack
79+
${{ env.version_suffix_args }}
80+
--configuration Release
81+
--output "${{ github.workspace }}/artifacts/packages"
4582

4683
- name: Upload artifact
4784
uses: actions/upload-artifact@v4
@@ -50,20 +87,16 @@ jobs:
5087
name: build-artifacts
5188
path: ${{ github.workspace }}/artifacts
5289

53-
publish:
54-
name: Publish Package
55-
needs: build
90+
publish-package:
91+
needs: build-package
5692
runs-on: ubuntu-latest
5793
steps:
58-
- name: Checkout code
59-
uses: actions/checkout@v2
94+
- uses: actions/checkout@v4
6095

6196
- name: Setup .NET
6297
uses: actions/setup-dotnet@v2
6398
with:
64-
dotnet-version: |
65-
9.0.x
66-
8.0.x
99+
dotnet-version: 9.0.x
67100

68101
- name: Download build artifacts
69102
uses: actions/download-artifact@v4
@@ -75,7 +108,7 @@ jobs:
75108
env:
76109
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
77110

78-
- name: NuGet authentication for GitHub
111+
- name: Authenticate to GitHub registry
79112
run: dotnet nuget add source
80113
"https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json"
81114
--name "github"
@@ -89,3 +122,12 @@ jobs:
89122
--source "github"
90123
--api-key ${{ secrets.GITHUB_TOKEN }}
91124
--skip-duplicate
125+
126+
- name: Publish to NuGet.org (Releases only)
127+
# Only publish to NuGet.org from the modelcontextprotocol/csharp-sdk repository
128+
if: ${{ github.event_name == 'release' && github.repository == 'modelcontextprotocol/csharp-sdk' }}
129+
run: dotnet nuget push
130+
${{github.workspace}}/build-artifacts/packages/*.nupkg
131+
--source https://api.nuget.org/v3/index.json
132+
--api-key ${{ secrets.NUGET_KEY_MODELCONTEXTPROTOCOL }}
133+
--skip-duplicate

Directory.Build.props

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,32 @@
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77
<IsPackable>false</IsPackable>
8-
<PackageVersion>0.1.0-preview</PackageVersion>
9-
<Authors>Microsoft</Authors>
10-
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
11-
<RepoRoot>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)'))</RepoRoot>
12-
<VSTestLogger>trx%3bLogFileName=$(MSBuildProjectName).$(TargetFramework).$(OS).trx</VSTestLogger>
13-
<VSTestResultsDirectory>$(RepoRoot)/artifacts/TestResults</VSTestResultsDirectory>
148
<WarnOnPackingNonPackableProject>false</WarnOnPackingNonPackableProject>
159
</PropertyGroup>
1610

11+
<PropertyGroup>
12+
<RepoRoot>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)'))</RepoRoot>
13+
<ArtifactsDir Condition="'$(ArtifactsDir)' == ''">$([MSBuild]::NormalizeDirectory('$(RepoRoot)', 'artifacts'))</ArtifactsDir>
14+
<ArtifactsObjDir>$([MSBuild]::NormalizeDirectory('$(ArtifactsDir)', 'obj'))</ArtifactsObjDir>
15+
<ArtifactsBinDir>$([MSBuild]::NormalizeDirectory('$(ArtifactsDir)', 'bin'))</ArtifactsBinDir>
16+
<ArtifactsTestResultsDir>$([MSBuild]::NormalizeDirectory('$(ArtifactsDir)', 'TestResults', '$(Configuration)'))</ArtifactsTestResultsDir>
17+
<ArtifactsPackagesDir>$([MSBuild]::NormalizeDirectory('$(ArtifactsDir)', 'packages', '$(Configuration)'))</ArtifactsPackagesDir>
18+
<OutDirName>$(MSBuildProjectName)</OutDirName>
19+
20+
<BaseIntermediateOutputPath>$([System.IO.Path]::GetFullPath('$(ArtifactsObjDir)$(OutDirName)\'))</BaseIntermediateOutputPath>
21+
<IntermediateOutputPath>$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
22+
23+
<BaseOutputPath>$([System.IO.Path]::GetFullPath('$(ArtifactsBinDir)$(OutDirName)\'))</BaseOutputPath>
24+
<OutputPath>$(BaseOutputPath)$(Configuration)\</OutputPath>
25+
26+
<PackageOutputPath>$(ArtifactsPackagesDir)</PackageOutputPath>
27+
</PropertyGroup>
28+
29+
<PropertyGroup>
30+
<VSTestLogger Condition="'$(VSTestLogger)' == ''">trx%3bLogFileName=$(MSBuildProjectName).$(TargetFramework).$(OS).trx</VSTestLogger>
31+
<VSTestResultsDirectory Condition="'$(VSTestResultsDirectory)' == ''">$(ArtifactsTestResultsDir)</VSTestResultsDirectory>
32+
</PropertyGroup>
33+
1734
<PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">
1835
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
1936
</PropertyGroup>

README.MD renamed to README.md

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
The official C# SDK for the [Model Context Protocol](https://modelcontextprotocol.io/), enabling .NET applications, services, and libraries to implement and interact with MCP clients and servers. Please visit our [API documentation](https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.html) for more details on available functionality.
66

77
> [!NOTE]
8-
> This repo is still in preview, breaking changes can be introduced without prior notice.
8+
> This project is in preview; breaking changes can be introduced without prior notice.
99
1010
## About MCP
1111

@@ -44,7 +44,7 @@ var client = await McpClientFactory.CreateAsync(new()
4444
});
4545

4646
// Print the list of tools available from the server.
47-
await foreach (var tool in client.ListToolsAsync())
47+
foreach (var tool in await client.ListToolsAsync())
4848
{
4949
Console.WriteLine($"{tool.Name} ({tool.Description})");
5050
}
@@ -80,7 +80,7 @@ var response = await chatClient.GetResponseAsync(
8080

8181
Here is an example of how to create an MCP server and register all tools from the current application.
8282
It includes a simple echo tool as an example (this is included in the same file here for easy of copy and paste, but it needn't be in the same file...
83-
the employed overload of `WithTools` examines the current assembly for classes with the `McpToolType` attribute, and registers all methods with the
83+
the employed overload of `WithTools` examines the current assembly for classes with the `McpServerToolType` attribute, and registers all methods with the
8484
`McpTool` attribute as tools.)
8585

8686
```csharp
@@ -198,11 +198,7 @@ McpServerOptions options = new()
198198
};
199199

200200
await using IMcpServer server = McpServerFactory.Create(new StdioServerTransport("MyServer"), options);
201-
202-
await server.StartAsync();
203-
204-
// Run until process is stopped by the client (parent process)
205-
await Task.Delay(Timeout.Infinite);
201+
await server.RunAsync();
206202
```
207203

208204
## Acknowledgements

samples/AspNetCoreSseServer/McpEndpointRouteBuilderExtensions.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ public static class McpEndpointRouteBuilderExtensions
1010
{
1111
public static IEndpointConventionBuilder MapMcpSse(this IEndpointRouteBuilder endpoints)
1212
{
13-
IMcpServer? server = null;
1413
SseResponseStreamTransport? transport = null;
1514
var loggerFactory = endpoints.ServiceProvider.GetRequiredService<ILoggerFactory>();
1615
var mcpServerOptions = endpoints.ServiceProvider.GetRequiredService<IOptions<McpServerOptions>>();
@@ -19,17 +18,17 @@ public static IEndpointConventionBuilder MapMcpSse(this IEndpointRouteBuilder en
1918

2019
routeGroup.MapGet("/sse", async (HttpResponse response, CancellationToken requestAborted) =>
2120
{
22-
await using var localTransport = transport = new SseResponseStreamTransport(response.Body);
23-
await using var localServer = server = McpServerFactory.Create(transport, mcpServerOptions.Value, loggerFactory, endpoints.ServiceProvider);
24-
25-
await localServer.StartAsync(requestAborted);
26-
2721
response.Headers.ContentType = "text/event-stream";
2822
response.Headers.CacheControl = "no-cache";
2923

24+
await using var localTransport = transport = new SseResponseStreamTransport(response.Body);
25+
await using var server = McpServerFactory.Create(transport, mcpServerOptions.Value, loggerFactory, endpoints.ServiceProvider);
26+
3027
try
3128
{
32-
await transport.RunAsync(requestAborted);
29+
var transportTask = transport.RunAsync(cancellationToken: requestAborted);
30+
await server.RunAsync(cancellationToken: requestAborted);
31+
await transportTask;
3332
}
3433
catch (OperationCanceledException) when (requestAborted.IsCancellationRequested)
3534
{

samples/AspNetCoreSseServer/Tools/SampleLlmTool.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace TestServerWithHosting.Tools;
1010
[McpServerToolType]
1111
public static class SampleLlmTool
1212
{
13-
[McpServerTool("sampleLLM"), Description("Samples from an LLM using MCP's sampling feature")]
13+
[McpServerTool(Name = "sampleLLM"), Description("Samples from an LLM using MCP's sampling feature")]
1414
public static async Task<string> SampleLLM(
1515
IMcpServer thisServer,
1616
[Description("The prompt to send to the LLM")] string prompt,

0 commit comments

Comments
 (0)