Skip to content

Commit b40f06c

Browse files
Fix markdown links in docs and add docfx CI validation (#862)
* Initial plan * Replace obsolete API references with xref tags in markdown docs Co-authored-by: eiriktsarpalis <2813363+eiriktsarpalis@users.noreply.github.com> * Add documentation guidelines for xref syntax Co-authored-by: eiriktsarpalis <2813363+eiriktsarpalis@users.noreply.github.com> * Fix: Only update link URLs, preserve document structure Co-authored-by: eiriktsarpalis <2813363+eiriktsarpalis@users.noreply.github.com> * Add --warningsAsErrors flag to docfx command in Makefile Co-authored-by: eiriktsarpalis <2813363+eiriktsarpalis@users.noreply.github.com> * Add CI validation for document generation * Fix broken link * Fix invalid xref cross-references in documentation Co-authored-by: eiriktsarpalis <2813363+eiriktsarpalis@users.noreply.github.com> * Apply suggestion from @eiriktsarpalis * Fix Progress link syntax and remove docs/README.md Co-authored-by: eiriktsarpalis <2813363+eiriktsarpalis@users.noreply.github.com> * Separate build & test targets * Apply suggestion from @eiriktsarpalis * tweak Makefile * Fix test results upload path * Add emojis to CI workflow step names Co-authored-by: eiriktsarpalis <2813363+eiriktsarpalis@users.noreply.github.com> * perform manual cleanups --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: eiriktsarpalis <2813363+eiriktsarpalis@users.noreply.github.com> Co-authored-by: Eirik Tsarpalis <eirik.tsarpalis@gmail.com>
1 parent c40effe commit b40f06c

File tree

5 files changed

+54
-91
lines changed

5 files changed

+54
-91
lines changed

.github/workflows/ci-build-test.yml

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -34,64 +34,57 @@ jobs:
3434
runs-on: ${{ matrix.os }}
3535

3636
steps:
37-
- name: Clone the repo
37+
- name: 📥 Clone the repo
3838
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
3939
with:
4040
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
4141

42-
- name: Set up .NET
42+
- name: 🔧 Set up .NET
4343
uses: actions/setup-dotnet@d4c94342e560b34958eacfc5d055d21461ed1c5d # v5.0.0
4444
with:
4545
dotnet-version: |
4646
10.0.x
4747
9.0.x
4848
4949
# NetFX testing on non-Windows requires mono
50-
- name: Setup Mono
50+
- name: 🔧 Setup Mono
5151
if: runner.os == 'Linux'
5252
run: sudo apt-get install -y mono-devel
5353

54-
- name: Setup Mono on macOS
54+
- name: 🔧 Setup Mono on macOS
5555
if: runner.os == 'macOS'
5656
run: brew install mono
5757

58-
- name: Set up Node.js
58+
- name: 🔧 Set up Node.js
5959
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
6060
with:
6161
node-version: '20'
6262

63-
- name: Install dependencies for tests
63+
- name: 📦 Install dependencies for tests
6464
run: npm install @modelcontextprotocol/server-everything
6565

66-
- name: Install dependencies for tests
66+
- name: 📦 Install dependencies for tests
6767
run: npm install @modelcontextprotocol/server-memory
6868

69-
- name: Build
70-
run: dotnet build --configuration ${{ matrix.configuration }}
71-
72-
- name: Pack
73-
run: dotnet pack --configuration ${{ matrix.configuration }}
74-
75-
- name: Test
76-
run: >-
77-
dotnet test
78-
--filter '(Execution!=Manual)'
79-
--no-build
80-
--configuration ${{ matrix.configuration }}
81-
--logger "trx"
82-
--logger "GitHubActions;summary.includePassedTests=true;summary.includeSkippedTests=true"
83-
--blame
84-
--blame-hang-timeout 7m
85-
--blame-crash
86-
--results-directory testresults
87-
--collect "XPlat Code Coverage" -- RunConfiguration.CollectSourceInformation=true
88-
89-
- name: Upload test results artifact
69+
- name: 🏗️ Build
70+
run: make build CONFIGURATION=${{ matrix.configuration }}
71+
72+
- name: 🧪 Test
73+
run: make test CONFIGURATION=${{ matrix.configuration }}
74+
75+
- name: 📦 Pack
76+
if: matrix.configuration == 'Release'
77+
run: make pack CONFIGURATION=${{ matrix.configuration }}
78+
79+
- name: 📚 Generate docs
80+
run: make generate-docs CONFIGURATION=${{ matrix.configuration }}
81+
82+
- name: 📤 Upload test results artifact
9083
if: always()
9184
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
9285
with:
9386
name: testresults-${{ matrix.os }}-${{ matrix.configuration }}
94-
path: testresults/**
87+
path: artifacts/testresults/**
9588

9689
publish-coverage:
9790
if: github.actor != 'dependabot[bot]'

Makefile

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,21 @@ test: build
2121
--configuration $(CONFIGURATION) \
2222
--filter '(Execution!=Manual)' \
2323
--blame \
24+
--blame-crash \
25+
--blame-hang-timeout 7m \
2426
--diag "$(ARTIFACT_PATH)/diag.txt" \
2527
--logger "trx" \
26-
--collect "Code Coverage;Format=cobertura" \
27-
--results-directory $(ARTIFACT_PATH)/test-results \
28+
--logger "GitHubActions;summary.includePassedTests=true;summary.includeSkippedTests=true" \
29+
--collect "XPlat Code Coverage" \
30+
--results-directory $(ARTIFACT_PATH)/testresults \
2831
-- \
2932
RunConfiguration.CollectSourceInformation=true
3033

31-
generate-docs: clean restore
32-
dotnet build --no-restore --configuration Release
33-
dotnet docfx $(DOCS_PATH)/docfx.json
34+
pack: restore
35+
dotnet pack --no-restore --configuration $(CONFIGURATION)
36+
37+
generate-docs: build
38+
dotnet docfx $(DOCS_PATH)/docfx.json --warningsAsErrors true
3439

3540
serve-docs: generate-docs
3641
dotnet docfx serve $(ARTIFACT_PATH)/_site --port 8080

docs/concepts/elicitation/elicitation.md

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,9 @@ The **elicitation** feature allows servers to request additional information fro
1111

1212
### Server Support for Elicitation
1313

14-
Servers request structured data from users with the [ElicitAsync] extension method on [IMcpServer].
15-
The C# SDK registers an instance of [IMcpServer] with the dependency injection container,
16-
so tools can simply add a parameter of type [IMcpServer] to their method signature to access it.
17-
18-
[ElicitAsync]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Server.McpServerExtensions.html#ModelContextProtocol_Server_McpServerExtensions_ElicitAsync_ModelContextProtocol_Server_IMcpServer_ModelContextProtocol_Protocol_ElicitRequestParams_System_Threading_CancellationToken_
19-
[IMcpServer]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Server.IMcpServer.html
14+
Servers request structured data from users with the <xref:ModelContextProtocol.Server.McpServer.ElicitAsync*> extension method on <xref:ModelContextProtocol.Server.McpServer>.
15+
The C# SDK registers an instance of <xref:ModelContextProtocol.Server.McpServer> with the dependency injection container,
16+
so tools can simply add a parameter of type <xref:ModelContextProtocol.Server.McpServer> to their method signature to access it.
2017

2118
The MCP Server must specify the schema of each input value it is requesting from the user.
2219
Only primitive types (string, number, boolean) are supported for elicitation requests.
@@ -31,21 +28,16 @@ The following example demonstrates how a server could request a boolean response
3128

3229
### Client Support for Elicitation
3330

34-
Elicitation is an optional feature so clients declare their support for it in their capabilities as part of the `initialize` request. In the MCP C# SDK, this is done by configuring an [ElicitationHandler] in the [McpClientOptions]:
35-
36-
[ElicitationHandler]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Protocol.ElicitationCapability.html#ModelContextProtocol_Protocol_ElicitationCapability_ElicitationHandler
37-
[McpClientOptions]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Client.McpClientOptions.html
31+
Elicitation is an optional feature so clients declare their support for it in their capabilities as part of the `initialize` request. In the MCP C# SDK, this is done by configuring an <xref:ModelContextProtocol.Client.McpClientHandlers.ElicitationHandler> in the <xref:ModelContextProtocol.Client.McpClientOptions>:
3832

3933
[!code-csharp[](samples/client/Program.cs?name=snippet_McpInitialize)]
4034

4135
The ElicitationHandler is an asynchronous method that will be called when the server requests additional information.
4236
The ElicitationHandler must request input from the user and return the data in a format that matches the requested schema.
4337
This will be highly dependent on the client application and how it interacts with the user.
4438

45-
If the user provides the requested information, the ElicitationHandler should return an [ElicitResult] with the action set to "accept" and the content containing the user's input.
46-
If the user does not provide the requested information, the ElicitationHandler should return an [ElicitResult] with the action set to "reject" and no content.
47-
48-
[ElicitResult]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Protocol.ElicitResult.html
39+
If the user provides the requested information, the ElicitationHandler should return an <xref:ModelContextProtocol.Protocol.ElicitResult> with the action set to "accept" and the content containing the user's input.
40+
If the user does not provide the requested information, the ElicitationHandler should return an [<xref:ModelContextProtocol.Protocol.ElicitResult> with the action set to "reject" and no content.
4941

5042
Below is an example of how a console application might handle elicitation requests.
5143
Here's an example implementation:

docs/concepts/logging/logging.md

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -49,53 +49,36 @@ Servers built with the C# SDK always declare the logging capability. Doing so do
4949
to send log messages -- only allows it. Note that stateless MCP servers may not be capable of sending log
5050
messages as there may not be an open connection to the client on which the log messages could be sent.
5151

52-
The C# SDK provides an extension method [WithSetLoggingLevelHandler] on [IMcpServerBuilder] to allow the
52+
The C# SDK provides an extension method <xref:Microsoft.Extensions.DependencyInjection.McpServerBuilderExtensions.WithSetLoggingLevelHandler*> on <xref:Microsoft.Extensions.DependencyInjection.IMcpServerBuilder> to allow the
5353
server to perform any special logic it wants to perform when a client sets the logging level. However, the
54-
SDK already takes care of setting the [LoggingLevel] in the [IMcpServer], so most servers will not need to
54+
SDK already takes care of setting the <xref:ModelContextProtocol.Server.McpServer.LoggingLevel> in the <xref:ModelContextProtocol.Server.McpServer>, so most servers will not need to
5555
implement this.
5656

57-
[IMcpServer]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Server.IMcpServer.html
58-
[IMcpServerBuilder]: https://modelcontextprotocol.github.io/csharp-sdk/api/Microsoft.Extensions.DependencyInjection.IMcpServerBuilder.html
59-
[WithSetLoggingLevelHandler]: https://modelcontextprotocol.github.io/csharp-sdk/api/Microsoft.Extensions.DependencyInjection.McpServerBuilderExtensions.html#Microsoft_Extensions_DependencyInjection_McpServerBuilderExtensions_WithSetLoggingLevelHandler_Microsoft_Extensions_DependencyInjection_IMcpServerBuilder_System_Func_ModelContextProtocol_Server_RequestContext_ModelContextProtocol_Protocol_SetLevelRequestParams__System_Threading_CancellationToken_System_Threading_Tasks_ValueTask_ModelContextProtocol_Protocol_EmptyResult___
60-
[LoggingLevel]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Server.IMcpServer.html#ModelContextProtocol_Server_IMcpServer_LoggingLevel
61-
62-
MCP Servers using the MCP C# SDK can obtain an [ILoggerProvider] from the IMcpServer [AsClientLoggerProvider] extension method,
63-
and from that can create an [ILogger] instance for logging messages that should be sent to the MCP client.
57+
MCP Servers using the MCP C# SDK can obtain an [ILoggerProvider](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.iloggerprovider) from the IMcpServer <xref:ModelContextProtocol.Server.McpServer.AsClientLoggerProvider> extension method,
58+
and from that can create an [ILogger](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.ilogger) instance for logging messages that should be sent to the MCP client.
6459

6560
[!code-csharp[](samples/server/Tools/LoggingTools.cs?name=snippet_LoggingConfiguration)]
6661

67-
[ILoggerProvider]: https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.iloggerprovider
68-
[AsClientLoggerProvider]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Server.McpServerExtensions.html#ModelContextProtocol_Server_McpServerExtensions_AsClientLoggerProvider_ModelContextProtocol_Server_IMcpServer_
69-
[ILogger]: https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.ilogger
70-
7162
### Client support for logging
7263

7364
When the server indicates that it supports logging, clients should configure
7465
the logging level to specify which messages the server should send to the client.
7566

76-
Clients should check if the server supports logging by checking the [Logging] property of the [ServerCapabilities] field of [IMcpClient].
77-
78-
[IMcpClient]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Client.IMcpClient.html
79-
[ServerCapabilities]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Client.IMcpClient.html#ModelContextProtocol_Client_IMcpClient_ServerCapabilities
80-
[Logging]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Protocol.ServerCapabilities.html#ModelContextProtocol_Protocol_ServerCapabilities_Logging
67+
Clients should check if the server supports logging by checking the <xref:ModelContextProtocol.Protocol.ServerCapabilities.Logging> property of the <xref:ModelContextProtocol.Client.McpClient.ServerCapabilities> field of <xref:ModelContextProtocol.Client.McpClient>.
8168

8269
[!code-csharp[](samples/client/Program.cs?name=snippet_LoggingCapabilities)]
8370

8471
If the server supports logging, the client should set the level of log messages it wishes to receive with
85-
the [SetLoggingLevel] method on [IMcpClient]. If the client does not set a logging level, the server might choose
72+
the <xref:ModelContextProtocol.Client.McpClient.SetLoggingLevel*> method on <xref:ModelContextProtocol.Client.McpClient>. If the client does not set a logging level, the server might choose
8673
to send all log messages or none -- this is not specified in the protocol -- so it is important that the client
8774
sets a logging level to ensure it receives the desired log messages and only those messages.
8875

8976
The `loggingLevel` set by the client is an MCP logging level.
9077
See the [Logging Levels](#logging-levels) section above for the mapping between MCP and .NET logging levels.
9178

92-
[SetLoggingLevel]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Client.McpClientExtensions.html#ModelContextProtocol_Client_McpClientExtensions_SetLoggingLevel_ModelContextProtocol_Client_IMcpClient_Microsoft_Extensions_Logging_LogLevel_System_Threading_CancellationToken_
93-
9479
[!code-csharp[](samples/client/Program.cs?name=snippet_LoggingLevel)]
9580

96-
Lastly, the client must configure a notification handler for [NotificationMethods.LoggingMessageNotification] notifications.
81+
Lastly, the client must configure a notification handler for <xref:ModelContextProtocol.Protocol.NotificationMethods.LoggingMessageNotification> notifications.
9782
The following example simply writes the log messages to the console.
9883

99-
[NotificationMethods.LoggingMessageNotification]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Protocol.NotificationMethods.html#ModelContextProtocol_Protocol_NotificationMethods_LoggingMessageNotification
100-
10184
[!code-csharp[](samples/client/Program.cs?name=snippet_LoggingHandler)]

docs/concepts/progress/progress.md

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,13 @@ This project illustrates the common case of a server tool that performs a long-r
1717

1818
### Server Implementation
1919

20-
When processing a request, the server can use the [sendNotificationAsync] extension method of [IMcpServer] to send progress updates,
20+
When processing a request, the server can use the <xref:ModelContextProtocol.McpSession.SendNotificationAsync*> extension method of <xref:ModelContextProtocol.Server.McpServer> to send progress updates,
2121
specifying `"notifications/progress"` as the notification method name.
22-
The C# SDK registers an instance of [IMcpServer] with the dependency injection container,
23-
so tools can simply add a parameter of type [IMcpServer] to their method signature to access it.
24-
The parameters passed to [sendNotificationAsync] should be an instance of [ProgressNotificationParams], which includes the current progress, total steps, and an optional message.
22+
The C# SDK registers an instance of <xref:ModelContextProtocol.Server.McpServer> with the dependency injection container,
23+
so tools can simply add a parameter of type <xref:ModelContextProtocol.Server.McpServer> to their method signature to access it.
24+
The parameters passed to <xref:ModelContextProtocol.McpSession.SendNotificationAsync*> should be an instance of <xref:ModelContextProtocol.Protocol.ProgressNotificationParams>, which includes the current progress, total steps, and an optional message.
2525

26-
[sendNotificationAsync]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.McpEndpointExtensions.html#ModelContextProtocol_McpEndpointExtensions_SendNotificationAsync_ModelContextProtocol_IMcpEndpoint_System_String_System_Threading_CancellationToken_
27-
[IMcpServer]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Server.IMcpServer.html
28-
[ProgressNotificationParams]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Protocol.ProgressNotificationParams.html
29-
30-
The server must verify that the caller provided a `progressToken` in the request and include it in the call to [sendNotificationAsync]. The following example demonstrates how a server can send a progress notification:
26+
The server must verify that the caller provided a `progressToken` in the request and include it in the call to <xref:ModelContextProtocol.McpSession.SendNotificationAsync*>. The following example demonstrates how a server can send a progress notification:
3127

3228
[!code-csharp[](samples/server/Tools/LongRunningTools.cs?name=snippet_SendProgress)]
3329

@@ -38,10 +34,7 @@ Note that servers are not required to support progress tracking, so clients shou
3834

3935
In the MCP C# SDK, clients can specify a `progressToken` in the request parameters when calling a tool method.
4036
The client should also provide a notification handler to process "notifications/progress" notifications.
41-
There are two way to do this. The first is to register a notification handler using the [RegisterNotificationHandler] method on the [IMcpClient] instance. A handler registered this way will receive all progress notifications sent by the server.
42-
43-
[IMcpClient]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.Client.IMcpClient.html
44-
[RegisterNotificationHandler]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.IMcpEndpoint.html#ModelContextProtocol_IMcpEndpoint_RegisterNotificationHandler_System_String_System_Func_ModelContextProtocol_Protocol_JsonRpcNotification_System_Threading_CancellationToken_System_Threading_Tasks_ValueTask__
37+
There are two way to do this. The first is to register a notification handler using the <xref:ModelContextProtocol.McpSession.RegisterNotificationHandler*> method on the <xref:ModelContextProtocol.Client.McpClient> instance. A handler registered this way will receive all progress notifications sent by the server.
4538

4639
```csharp
4740
mcpClient.RegisterNotificationHandler(NotificationMethods.ProgressNotification,
@@ -57,13 +50,10 @@ mcpClient.RegisterNotificationHandler(NotificationMethods.ProgressNotification,
5750
}).ConfigureAwait(false);
5851
```
5952

60-
The second way is to pass a [Progress`<T>`] instance to the tool method. [Progress`<T>`] is a standard .NET type that provides a way to receive progress updates.
61-
For the purposes of MCP progress notifications, `T` should be [ProgressNotificationValue].
62-
The MCP C# SDK will automatically handle progress notifications and report them through the [Progress`<T>`] instance.
53+
The second way is to pass a [`Progress<T>`](https://learn.microsoft.com/dotnet/api/system.progress-1) instance to the tool method. `Progress<T>` is a standard .NET type that provides a way to receive progress updates.
54+
For the purposes of MCP progress notifications, `T` should be <xref:ModelContextProtocol.ProgressNotificationValue>.
55+
The MCP C# SDK will automatically handle progress notifications and report them through the `Progress<T>` instance.
6356
This notification handler will only receive progress updates for the specific request that was made,
6457
rather than all progress notifications from the server.
6558

66-
[Progress`<T>`]: https://learn.microsoft.com/en-us/dotnet/api/system.progress-1
67-
[ProgressNotificationValue]: https://modelcontextprotocol.github.io/csharp-sdk/api/ModelContextProtocol.ProgressNotificationValue.html
68-
6959
[!code-csharp[](samples/client/Program.cs?name=snippet_ProgressHandler)]

0 commit comments

Comments
 (0)