Skip to content

Commit 4223bf4

Browse files
authored
Merge branch 'modelcontextprotocol:main' into logging_capability_raw
2 parents 1ba3f54 + 0309dfc commit 4223bf4

25 files changed

+481
-65
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: Check Markdown links
2+
3+
on:
4+
push:
5+
branches: [ "main" ]
6+
pull_request:
7+
branches: [ "main" ]
8+
9+
jobs:
10+
markdown-link-check:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Checkout
14+
uses: actions/checkout@main
15+
- name: Markup Link Checker (mlc)
16+
uses: becheran/[email protected]

.github/workflows/release.yml

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# This workflow is triggered by new releases
2+
# It builds, tests, and publishes to the GitHub NuGet package registry
3+
name: Release package
4+
5+
on:
6+
release:
7+
types: [published]
8+
9+
jobs:
10+
build:
11+
12+
runs-on: windows-latest
13+
14+
steps:
15+
- uses: actions/checkout@v4
16+
with:
17+
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
18+
19+
- name: Setup .NET
20+
uses: actions/setup-dotnet@v2
21+
with:
22+
dotnet-version: |
23+
9.0.x
24+
8.0.x
25+
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+
43+
- name: Pack
44+
run: dotnet pack --configuration Release --output "${{ github.workspace }}/artifacts/packages"
45+
46+
- name: Upload artifact
47+
uses: actions/upload-artifact@v4
48+
if: ${{ !cancelled() }}
49+
with:
50+
name: build-artifacts
51+
path: ${{ github.workspace }}/artifacts
52+
53+
publish:
54+
name: Publish Package
55+
needs: build
56+
runs-on: ubuntu-latest
57+
steps:
58+
- name: Checkout code
59+
uses: actions/checkout@v2
60+
61+
- name: Setup .NET
62+
uses: actions/setup-dotnet@v2
63+
with:
64+
dotnet-version: |
65+
9.0.x
66+
8.0.x
67+
68+
- name: Download build artifacts
69+
uses: actions/download-artifact@v4
70+
71+
- name: Upload release asset
72+
if: github.event_name == 'release'
73+
run: gh release upload ${{ github.event.release.tag_name }}
74+
${{ github.workspace }}/build-artifacts/packages/*.*nupkg
75+
env:
76+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
77+
78+
- name: NuGet authentication for GitHub
79+
run: dotnet nuget add source
80+
"https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json"
81+
--name "github"
82+
--username ${{ github.actor }}
83+
--password ${{ secrets.GITHUB_TOKEN }}
84+
--store-password-in-clear-text
85+
86+
- name: Publish to GitHub NuGet package registry
87+
run: dotnet nuget push
88+
${{github.workspace}}/build-artifacts/packages/*.nupkg
89+
--source "github"
90+
--api-key ${{ secrets.GITHUB_TOKEN }}
91+
--skip-duplicate

Open.snk

596 Bytes
Binary file not shown.

README.MD

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ The official C# SDK for the [Model Context Protocol](https://modelcontextprotoco
1010
The Model Context Protocol (MCP) is an open protocol that standardizes how applications provide context to Large Language Models (LLMs). It enables secure integration between LLMs and various data sources and tools.
1111

1212
For more information about MCP:
13+
1314
- [Official Documentation](https://modelcontextprotocol.io/)
1415
- [Protocol Specification](https://spec.modelcontextprotocol.io/)
1516
- [GitHub Organization](https://github.com/modelcontextprotocol)
@@ -19,12 +20,13 @@ For more information about MCP:
1920
To get started writing a client, the `McpClientFactory.CreateAsync` method is used to instantiate and connect an `IMcpClient`
2021
to a server, with details about the client and server specified in `McpClientOptions` and `McpServerConfig` objects.
2122
Once you have an `IMcpClient`, you can interact with it, such as to enumerate all available tools and invoke tools.
23+
2224
```csharp
2325
McpClientOptions options = new()
2426
{
2527
ClientInfo = new() { Name = "TestClient", Version = "1.0.0" }
2628
};
27-
29+
2830
McpServerConfig config = new()
2931
{
3032
Id = "everything",
@@ -36,7 +38,7 @@ McpServerConfig config = new()
3638
["arguments"] = "-y @modelcontextprotocol/server-everything",
3739
}
3840
};
39-
41+
4042
var client = await McpClientFactory.CreateAsync(config, options);
4143

4244
// Print the list of tools available from the server.
@@ -55,11 +57,12 @@ var result = await client.CallToolAsync(
5557
Console.WriteLine(result.Content.First(c => c.Type == "text").Text);
5658
```
5759

58-
You can find samples demonstrating how to use ModelContextProtocol with an LLM SDK in the [samples](samples) directory, and also refer to the [IntegrationTests](test/ModelContextProtocol.IntegrationTests) project for more examples. Additional examples and documentation will be added as in the near future.
60+
You can find samples demonstrating how to use ModelContextProtocol with an LLM SDK in the [samples](samples) directory, and also refer to the [tests](tests/ModelContextProtocol.Tests) project for more examples. Additional examples and documentation will be added as in the near future.
5961

6062
Clients can connect to any MCP server, not just ones created using this library. The protocol is designed to be server-agnostic, so you can use this library to connect to any compliant server.
6163

6264
Tools can be exposed easily as `AIFunction` instances so that they are immediately usable with `IChatClient`s.
65+
6366
```csharp
6467
// Get available functions.
6568
IList<AIFunction> tools = await client.GetAIFunctionsAsync();
@@ -103,6 +106,7 @@ public static class EchoTool
103106
```
104107

105108
More control is also available, with fine-grained control over configuring the server and how it should handle client requests. For example:
109+
106110
```csharp
107111
using ModelContextProtocol.Protocol.Transport;
108112
using ModelContextProtocol.Protocol.Types;

src/Directory.Build.props

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
1313
<PackageOutputPath>$(RepoRoot)artifacts/</PackageOutputPath>
1414
<EmbedUntrackedSources>true</EmbedUntrackedSources>
15+
<AssemblyOriginatorKeyFile>$(RepoRoot)\Open.snk</AssemblyOriginatorKeyFile>
16+
<SignAssembly>true</SignAssembly>
1517
</PropertyGroup>
1618

1719
<ItemGroup>

src/ModelContextProtocol/Client/McpClientExtensions.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,44 @@ public static Task<GetPromptResult> GetPromptAsync(this IMcpClient client, strin
139139
cancellationToken);
140140
}
141141

142+
/// <summary>
143+
/// Retrieves a sequence of available resource templates from the server.
144+
/// </summary>
145+
/// <param name="client">The client.</param>
146+
/// <param name="cancellationToken">A token to cancel the operation.</param>
147+
/// <returns>An asynchronous sequence of resource template information.</returns>
148+
public static async IAsyncEnumerable<ResourceTemplate> ListResourceTemplatesAsync(
149+
this IMcpClient client, [EnumeratorCancellation] CancellationToken cancellationToken = default)
150+
{
151+
string? cursor = null;
152+
do
153+
{
154+
var resources = await ListResourceTemplatesAsync(client, cursor, cancellationToken).ConfigureAwait(false);
155+
foreach (var resource in resources.ResourceTemplates)
156+
{
157+
yield return resource;
158+
}
159+
160+
cursor = resources.NextCursor;
161+
}
162+
while (cursor is not null);
163+
}
164+
165+
/// <summary>
166+
/// Retrieves a list of available resources from the server.
167+
/// </summary>
168+
/// <param name="client">The client.</param>
169+
/// <param name="cursor">A cursor to paginate the results.</param>
170+
/// <param name="cancellationToken">A token to cancel the operation.</param>
171+
public static Task<ListResourceTemplatesResult> ListResourceTemplatesAsync(this IMcpClient client, string? cursor, CancellationToken cancellationToken = default)
172+
{
173+
Throw.IfNull(client);
174+
175+
return client.SendRequestAsync<ListResourceTemplatesResult>(
176+
CreateRequest("resources/templates/list", CreateCursorDictionary(cursor)),
177+
cancellationToken);
178+
}
179+
142180
/// <summary>
143181
/// Retrieves a sequence of available resources from the server.
144182
/// </summary>

src/ModelContextProtocol/Configuration/McpServerBuilderExtensions.Handler.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@ namespace ModelContextProtocol;
1111
/// </summary>
1212
public static partial class McpServerBuilderExtensions
1313
{
14+
/// <summary>
15+
/// Sets the handler for list resource templates requests.
16+
/// </summary>
17+
/// <param name="builder">The builder instance.</param>
18+
/// <param name="handler">The handler.</param>
19+
public static IMcpServerBuilder WithListResourceTemplatesHandler(this IMcpServerBuilder builder, Func<RequestContext<ListResourceTemplatesRequestParams>, CancellationToken, Task<ListResourceTemplatesResult>> handler)
20+
{
21+
Throw.IfNull(builder);
22+
23+
builder.Services.Configure<McpServerHandlers>(s => s.ListResourceTemplatesHandler = handler);
24+
return builder;
25+
}
26+
1427
/// <summary>
1528
/// Sets the handler for list tools requests.
1629
/// </summary>

src/ModelContextProtocol/ModelContextProtocol.csproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@
1313
<IsAotCompatible>true</IsAotCompatible>
1414
</PropertyGroup>
1515

16-
<ItemGroup>
17-
<InternalsVisibleTo Include="ModelContextProtocol.Tests" />
18-
</ItemGroup>
19-
2016
<ItemGroup>
2117
<PackageReference Include="Microsoft.Extensions.AI.Abstractions"/>
2218
<PackageReference Include="Microsoft.Extensions.AI" />
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace ModelContextProtocol.Protocol.Types;
4+
5+
/// <summary>
6+
/// Base for objects that include optional annotations for the client. The client can use annotations to inform how objects are used or displayed.
7+
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
8+
/// </summary>
9+
public abstract record Annotated
10+
{
11+
/// <summary>
12+
/// Optional annotations for the resource.
13+
/// </summary>
14+
[JsonPropertyName("annotations")]
15+
public Annotations? Annotations { get; init; }
16+
}

src/ModelContextProtocol/Protocol/Types/Capabilities.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ public record ResourcesCapability
117117
[JsonPropertyName("listChanged")]
118118
public bool? ListChanged { get; init; }
119119

120+
/// <summary>
121+
/// Gets or sets the handler for list resource templates requests.
122+
/// </summary>
123+
[JsonIgnore]
124+
public Func<RequestContext<ListResourceTemplatesRequestParams>, CancellationToken, Task<ListResourceTemplatesResult>>? ListResourceTemplatesHandler { get; init; }
125+
120126
/// <summary>
121127
/// Gets or sets the handler for list resources requests.
122128
/// </summary>

0 commit comments

Comments
 (0)