Skip to content

Commit d79aa0f

Browse files
jeffhandleyCopilot
andcommitted
Address PR feedback on conceptual docs
- Add bulleted lists of all definition methods for tools, prompts, resources (attribute, Create factory, deriving, custom handler, request filter) - Note DataContent from M.E.AI mapping to content blocks in tools and prompts - Simplify roots example by removing unnecessary explicit capability config - Add special parameter types note (McpServer, IProgress, ClaimsPrincipal, DI) - Mention message filters for cancellation notification interception - Use tool.CallAsync pattern in client tool consumption example - Merge redundant intro in capabilities.md - Simplify elicitation EnumSchemaOption syntax and remove auto-fill claim - Simplify prompts intro text Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent edd348a commit d79aa0f

File tree

7 files changed

+46
-32
lines changed

7 files changed

+46
-32
lines changed

docs/concepts/cancellation/cancellation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ The cancellation notification includes:
4444
- **RequestId**: The ID of the request to cancel, allowing the receiver to correlate the cancellation with the correct in-flight request.
4545
- **Reason**: An optional human-readable reason for the cancellation.
4646

47-
Cancellation notifications can be observed by registering a handler:
47+
Cancellation notifications can be observed by registering a handler. For broader interception of notifications and other messages, <xref:ModelContextProtocol.Server.McpMessageFilter> delegates can be added to the <xref:ModelContextProtocol.Server.McpMessageFilters.IncomingFilters> collection in <xref:ModelContextProtocol.Server.McpServerOptions.Filters>.
4848

4949
```csharp
5050
mcpClient.RegisterNotificationHandler(

docs/concepts/capabilities/capabilities.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,10 @@ uid: capabilities
77

88
## Capabilities
99

10-
MCP uses a [capability negotiation] mechanism during connection initialization. Clients and servers exchange their supported capabilities, allowing each side to understand what features the other supports and adapt behavior accordingly.
10+
MCP uses a [capability negotiation] mechanism during connection setup. Clients and servers exchange their supported capabilities so each side can adapt its behavior accordingly. Both sides should check the other's capabilities before using optional features.
1111

1212
[capability negotiation]: https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle#initialization
1313

14-
### Overview
15-
16-
During connection setup, clients and servers exchange their supported capabilities so each side can adapt its behavior accordingly. After initialization, both sides should check the other's capabilities before using optional features.
17-
1814
### Client capabilities
1915

2016
<xref:ModelContextProtocol.Protocol.ClientCapabilities> declares what features the client supports:

docs/concepts/elicitation/elicitation.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ var result = await server.ElicitAsync(new ElicitRequestParams
7373
}, cancellationToken);
7474
```
7575

76-
If the client returns accepted content with missing fields, the server automatically fills those fields with their schema defaults. This ensures tools always receive complete data regardless of client behavior.
77-
7876
#### Enum schema formats
7977

8078
Enum schemas allow the server to present a set of choices to the user.
@@ -91,9 +89,9 @@ Enum schemas allow the server to present a set of choices to the user.
9189
Description = "Task priority",
9290
OneOf =
9391
[
94-
new ElicitRequestParams.EnumSchemaOption { Const = "p0", Title = "Critical (P0)" },
95-
new ElicitRequestParams.EnumSchemaOption { Const = "p1", Title = "High (P1)" },
96-
new ElicitRequestParams.EnumSchemaOption { Const = "p2", Title = "Normal (P2)" },
92+
new() { Const = "p0", Title = "Critical (P0)" },
93+
new() { Const = "p1", Title = "High (P1)" },
94+
new() { Const = "p2", Title = "Normal (P2)" },
9795
],
9896
Default = "p2"
9997
},

docs/concepts/prompts/prompts.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,19 @@ This document covers implementing prompts on the server, consuming them from the
1515

1616
### Defining prompts on the server
1717

18-
Prompts are defined as methods marked with the <xref:ModelContextProtocol.Server.McpServerPromptAttribute> attribute within a class marked with <xref:ModelContextProtocol.Server.McpServerPromptTypeAttribute>. Prompts can return `ChatMessage` instances for simple text/image content, or <xref:ModelContextProtocol.Protocol.PromptMessage> instances when protocol-specific content types like <xref:ModelContextProtocol.Protocol.EmbeddedResourceBlock> are needed.
18+
Prompts can be defined in several ways:
19+
20+
- Using the <xref:ModelContextProtocol.Server.McpServerPromptAttribute> attribute on methods within a class marked with <xref:ModelContextProtocol.Server.McpServerPromptTypeAttribute>
21+
- Using <xref:ModelContextProtocol.Server.McpServerPrompt.Create*> factory methods from a delegate, `MethodInfo`, or `AIFunction`
22+
- Deriving from <xref:ModelContextProtocol.Server.McpServerPrompt> or <xref:ModelContextProtocol.Server.DelegatingMcpServerPrompt>
23+
- Implementing a custom <xref:ModelContextProtocol.Server.McpRequestHandler`2> via <xref:ModelContextProtocol.Server.McpServerHandlers>
24+
- Implementing a low-level <xref:ModelContextProtocol.Server.McpRequestFilter`2>
25+
26+
The attribute-based approach is the most common and is shown throughout this document. Prompts can return `ChatMessage` instances for simple text/image content, or <xref:ModelContextProtocol.Protocol.PromptMessage> instances when protocol-specific content types like <xref:ModelContextProtocol.Protocol.EmbeddedResourceBlock> are needed.
1927

2028
#### Simple prompts
2129

22-
A prompt without arguments returns a fixed message:
30+
A prompt without arguments:
2331

2432
```csharp
2533
[McpServerPromptType]
@@ -33,7 +41,7 @@ public class MyPrompts
3341

3442
#### Prompts with arguments
3543

36-
Prompts can accept parameters to customize the generated messages. Use `[Description]` attributes to document each parameter:
44+
Prompts can accept parameters to customize the generated messages. Use `[Description]` attributes to document each parameter. In addition to prompt arguments, methods can accept special parameter types that are resolved automatically: <xref:ModelContextProtocol.Server.McpServer>, `IProgress<ProgressNotificationValue>`, `ClaimsPrincipal`, and any service registered through dependency injection.
3745

3846
```csharp
3947
[McpServerPromptType]
@@ -66,7 +74,7 @@ builder.Services.AddMcpServer()
6674

6775
### Rich content in prompts
6876

69-
Prompt messages can contain more than just text. For text and image content, use `ChatMessage` from Microsoft.Extensions.AI. For protocol-specific content types like embedded resources, use <xref:ModelContextProtocol.Protocol.PromptMessage> instead.
77+
Prompt messages can contain more than just text. For text and image content, use `ChatMessage` from Microsoft.Extensions.AI. `DataContent` is automatically mapped to the appropriate MCP content block: image MIME types become <xref:ModelContextProtocol.Protocol.ImageContentBlock>, audio MIME types become <xref:ModelContextProtocol.Protocol.AudioContentBlock>, and all other MIME types become <xref:ModelContextProtocol.Protocol.EmbeddedResourceBlock> with binary resource contents. For text embedded resources specifically, use <xref:ModelContextProtocol.Protocol.PromptMessage> directly.
7078

7179
#### Image content
7280

docs/concepts/resources/resources.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,15 @@ This document covers implementing resources on the server, consuming them from t
1515

1616
### Defining resources on the server
1717

18-
Resources are defined as methods marked with the <xref:ModelContextProtocol.Server.McpServerResourceAttribute> attribute within a class marked with <xref:ModelContextProtocol.Server.McpServerResourceTypeAttribute>. The attribute specifies the URI template that identifies the resource.
18+
Resources can be defined in several ways:
19+
20+
- Using the <xref:ModelContextProtocol.Server.McpServerResourceAttribute> attribute on methods within a class marked with <xref:ModelContextProtocol.Server.McpServerResourceTypeAttribute>
21+
- Using <xref:ModelContextProtocol.Server.McpServerResource.Create*> factory methods from a delegate, `MethodInfo`, or `AIFunction`
22+
- Deriving from <xref:ModelContextProtocol.Server.McpServerResource> or <xref:ModelContextProtocol.Server.DelegatingMcpServerResource>
23+
- Implementing a custom <xref:ModelContextProtocol.Server.McpRequestHandler`2> via <xref:ModelContextProtocol.Server.McpServerHandlers>
24+
- Implementing a low-level <xref:ModelContextProtocol.Server.McpRequestFilter`2>
25+
26+
The attribute-based approach is the most common and is shown throughout this document.
1927

2028
#### Direct resources
2129

docs/concepts/roots/roots.md

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,11 @@ Each root is represented by a <xref:ModelContextProtocol.Protocol.Root> with a U
2323

2424
### Declaring roots capability on the client
2525

26-
Clients advertise their support for roots in the capabilities sent during initialization. To enable roots, configure the <xref:ModelContextProtocol.Protocol.ClientCapabilities.Roots> property and provide a handler that returns the root list:
26+
Clients advertise their support for roots in the capabilities sent during initialization. The roots capability is created automatically when a roots handler is provided. Configure the handler through <xref:ModelContextProtocol.McpClientHandlers.RootsHandler>:
2727

2828
```csharp
2929
var options = new McpClientOptions
3030
{
31-
Capabilities = new ClientCapabilities
32-
{
33-
Roots = new RootsCapability
34-
{
35-
ListChanged = true // Notify server when roots change
36-
}
37-
},
3831
Handlers = new McpClientHandlers
3932
{
4033
RootsHandler = (request, cancellationToken) =>

docs/concepts/tools/tools.md

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,15 @@ This document covers tool content types, change notifications, and schema genera
1515

1616
### Defining tools on the server
1717

18-
Tools are defined as methods marked with the <xref:ModelContextProtocol.Server.McpServerToolAttribute> attribute within a class marked with <xref:ModelContextProtocol.Server.McpServerToolTypeAttribute>. Parameters are automatically deserialized from JSON and documented using `[Description]` attributes.
18+
Tools can be defined in several ways:
19+
20+
- Using the <xref:ModelContextProtocol.Server.McpServerToolAttribute> attribute on methods within a class marked with <xref:ModelContextProtocol.Server.McpServerToolTypeAttribute>
21+
- Using <xref:ModelContextProtocol.Server.McpServerTool.Create*> factory methods from a delegate, `MethodInfo`, or `AIFunction`
22+
- Deriving from <xref:ModelContextProtocol.Server.McpServerTool> or <xref:ModelContextProtocol.Server.DelegatingMcpServerTool>
23+
- Implementing a custom <xref:ModelContextProtocol.Server.McpRequestHandler`2> via <xref:ModelContextProtocol.Server.McpServerHandlers>
24+
- Implementing a low-level <xref:ModelContextProtocol.Server.McpRequestFilter`2>
25+
26+
The attribute-based approach is the most common and is shown throughout this document. Parameters are automatically deserialized from JSON and documented using `[Description]` attributes. In addition to tool arguments, methods can accept special parameter types that are resolved automatically: <xref:ModelContextProtocol.Server.McpServer>, `IProgress<ProgressNotificationValue>`, `ClaimsPrincipal`, and any service registered through dependency injection.
1927

2028
```csharp
2129
[McpServerToolType]
@@ -37,7 +45,7 @@ builder.Services.AddMcpServer()
3745

3846
### Content types
3947

40-
Tools can return various content types. The simplest is a `string`, which is automatically wrapped in a <xref:ModelContextProtocol.Protocol.TextContentBlock>. For richer content, tools can return one or more <xref:ModelContextProtocol.Protocol.ContentBlock> instances.
48+
Tools can return various content types. The simplest is a `string`, which is automatically wrapped in a <xref:ModelContextProtocol.Protocol.TextContentBlock>. For richer content, tools can return one or more <xref:ModelContextProtocol.Protocol.ContentBlock> instances. Tools can also return `DataContent` from Microsoft.Extensions.AI, which is automatically mapped to the appropriate MCP content block: image MIME types become <xref:ModelContextProtocol.Protocol.ImageContentBlock>, audio MIME types become <xref:ModelContextProtocol.Protocol.AudioContentBlock>, and all other MIME types become <xref:ModelContextProtocol.Protocol.EmbeddedResourceBlock> with binary resource contents.
4149

4250
#### Text content
4351

@@ -160,9 +168,9 @@ foreach (var tool in tools)
160168
Console.WriteLine($"{tool.Name}: {tool.Description}");
161169
}
162170

163-
// Call a tool
164-
CallToolResult result = await client.CallToolAsync(
165-
"echo",
171+
// Call a tool by finding it in the list
172+
McpClientTool echoTool = tools.First(t => t.Name == "echo");
173+
CallToolResult result = await echoTool.CallAsync(
166174
new Dictionary<string, object?> { ["message"] = "Hello!" });
167175

168176
// Process the result content blocks
@@ -174,11 +182,9 @@ foreach (var content in result.Content)
174182
Console.WriteLine(text.Text);
175183
break;
176184
case ImageContentBlock image:
177-
// image.DecodedData contains the raw bytes
178185
File.WriteAllBytes("output.png", image.DecodedData.ToArray());
179186
break;
180187
case AudioContentBlock audio:
181-
// audio.DecodedData contains the raw bytes
182188
File.WriteAllBytes("output.wav", audio.DecodedData.ToArray());
183189
break;
184190
case EmbeddedResourceBlock resource:
@@ -195,7 +201,12 @@ Tool errors in MCP are distinct from protocol errors. When a tool encounters an
195201

196202
#### Automatic exception handling
197203

198-
When a tool method throws an exception, the server automatically catches it and returns a `CallToolResult` with `IsError = true`. <xref:ModelContextProtocol.McpProtocolException> is re-thrown as a JSON-RPC error, and `OperationCanceledException` is re-thrown when the cancellation token was triggered. All other exceptions are returned as tool error results. For <xref:ModelContextProtocol.McpException> subclasses, the exception message is included in the error text; for other exceptions, a generic message is returned to avoid leaking internal details.
204+
When a tool method throws an exception, the server catches it and returns a `CallToolResult` with `IsError = true`, with the following exceptions:
205+
206+
- <xref:ModelContextProtocol.McpProtocolException> is re-thrown as a JSON-RPC error response (not a tool error result).
207+
- `OperationCanceledException` is re-thrown when the cancellation token was triggered.
208+
209+
For all other exceptions, the error is returned as a tool result. If the exception derives from <xref:ModelContextProtocol.McpException> (excluding `McpProtocolException`, which is re-thrown above), its message is included in the error text; otherwise, a generic message is returned to avoid leaking internal details.
199210

200211
```csharp
201212
[McpServerTool, Description("Divides two numbers")]

0 commit comments

Comments
 (0)