Writing style edits (#1024)

This commit is contained in:
Genevieve Warren 2025-11-25 13:27:39 -08:00 • committed by GitHub
commit e2a802ebdc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 54 additions and 46 deletions

View file

@ -15,21 +15,22 @@ Servers request structured data from users with the <xref:ModelContextProtocol.S
The C# SDK registers an instance of <xref:ModelContextProtocol.Server.McpServer> with the dependency injection container,
so tools can simply add a parameter of type <xref:ModelContextProtocol.Server.McpServer> to their method signature to access it.
The MCP Server must specify the schema of each input value it is requesting from the user.
Primitive types (string, number, boolean) and enum types are supported for elicitation requests.
The schema may include a description to help the user understand what is being requested.
The MCP Server must specify the schema of each input value it's requesting from the user.
Primitive types (string, number, Boolean) and enum types are supported for elicitation requests.
The schema might include a description to help the user understand what's being requested.
For enum types, the SDK supports several schema formats:
- **UntitledSingleSelectEnumSchema**: A single-select enum where the enum values serve as both the value and display text
- **TitledSingleSelectEnumSchema**: A single-select enum with separate display titles for each option (using JSON Schema `oneOf` with `const` and `title`)
- **UntitledMultiSelectEnumSchema**: A multi-select enum allowing multiple values to be selected
- **TitledMultiSelectEnumSchema**: A multi-select enum with display titles for each option
- **LegacyTitledEnumSchema** (deprecated): The legacy enum schema using `enumNames` for backward compatibility
- **UntitledSingleSelectEnumSchema**: A single-select enum where the enum values serve as both the value and display text.
- **TitledSingleSelectEnumSchema**: A single-select enum with separate display titles for each option (using JSON Schema `oneOf` with `const` and `title`).
- **UntitledMultiSelectEnumSchema**: A multi-select enum allowing multiple values to be selected.
- **TitledMultiSelectEnumSchema**: A multi-select enum with display titles for each option.
- **LegacyTitledEnumSchema** (deprecated): The legacy enum schema using `enumNames` for backward compatibility.
The server can request a single input or multiple inputs at once.
To help distinguish multiple inputs, each input has a unique name.
The following example demonstrates how a server could request a boolean response from the user.
The following example demonstrates how a server could request a Boolean response from the user.
[!code-csharp[](samples/server/Tools/InteractiveTools.cs?name=snippet_GuessTheNumber)]
@ -46,7 +47,6 @@ This will be highly dependent on the client application and how it interacts wit
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.
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.
Below is an example of how a console application might handle elicitation requests.
Here's an example implementation:
Here's an example implementation of how a console application might handle elicitation requests:
[!code-csharp[](samples/client/Program.cs?name=snippet_ElicitationHandler)]

View file

@ -66,6 +66,7 @@ Execution flow: `filter1 -> filter2 -> filter3 -> baseHandler -> filter3 -> filt
## Common Use Cases
### Logging
```csharp
.AddListToolsFilter(next => async (context, cancellationToken) =>
{
@ -79,6 +80,7 @@ Execution flow: `filter1 -> filter2 -> filter3 -> baseHandler -> filter3 -> filt
```
### Error Handling
```csharp
.AddCallToolFilter(next => async (context, cancellationToken) =>
{
@ -98,6 +100,7 @@ Execution flow: `filter1 -> filter2 -> filter3 -> baseHandler -> filter3 -> filt
```
### Performance Monitoring
```csharp
.AddListToolsFilter(next => async (context, cancellationToken) =>
{
@ -112,6 +115,7 @@ Execution flow: `filter1 -> filter2 -> filter3 -> baseHandler -> filter3 -> filt
```
### Caching
```csharp
.AddListResourcesFilter(next => async (context, cancellationToken) =>
{
@ -214,9 +218,11 @@ public class RestrictedTools
The authorization filters work differently for list operations versus individual operations:
#### List Operations (ListTools, ListPrompts, ListResources)
For list operations, the filters automatically remove unauthorized items from the results. Users only see tools, prompts, or resources they have permission to access.
#### Individual Operations (CallTool, GetPrompt, ReadResource)
For individual operations, the filters throw an `McpException` with "Access forbidden" message. These get turned into JSON-RPC errors if uncaught by middleware.
### Filter Execution Order and Authorization
@ -224,12 +230,14 @@ For individual operations, the filters throw an `McpException` with "Access forb
Authorization filters are applied automatically when you call `AddAuthorizationFilters()`. These filters run at a specific point in the filter pipeline, which means:
**Filters added before authorization filters** can see:
- Unauthorized requests for operations before they are rejected by the authorization filters
- Complete listings for unauthorized primitives before they are filtered out by the authorization filters
- Unauthorized requests for operations before they are rejected by the authorization filters.
- Complete listings for unauthorized primitives before they are filtered out by the authorization filters.
**Filters added after authorization filters** will only see:
- Authorized requests that passed authorization checks
- Filtered listings containing only authorized primitives
- Authorized requests that passed authorization checks.
- Filtered listings containing only authorized primitives.
This allows you to implement logging, metrics, or other cross-cutting concerns that need to see all requests, while still maintaining proper authorization:
@ -312,6 +320,6 @@ You can also create custom authorization filters using the filter methods:
Within filters, you have access to:
- `context.User` - The current user's `ClaimsPrincipal`
- `context.Services` - The request's service provider for resolving authorization services
- `context.MatchedPrimitive` - The matched tool/prompt/resource with its metadata including authorization attributes via `context.MatchedPrimitive.Metadata`
- `context.User` - The current user's `ClaimsPrincipal`.
- `context.Services` - The request's service provider for resolving authorization services.
- `context.MatchedPrimitive` - The matched tool/prompt/resource with its metadata including authorization attributes via `context.MatchedPrimitive.Metadata`.

View file

@ -7,11 +7,11 @@ uid: httpcontext
## HTTP Context
When using the Streamable HTTP transport, an MCP server may need to access the underlying [HttpContext] for a request.
When using the Streamable HTTP transport, an MCP server might need to access the underlying [HttpContext] for a request.
The [HttpContext] contains request metadata such as the HTTP headers, authorization context, and the actual path and query string for the request.
To access the [HttpContext], the MCP server should add the [IHttpContextAccessor] service to the application service collection (typically in Program.cs).
Then any classes, e.g. a class containing MCP tools, should accept an [IHttpContextAccessor] in their constructor and store this for use by its methods.
Then any classes, for example, a class containing MCP tools, should accept an [IHttpContextAccessor] in their constructor and store this for use by its methods.
Methods then use the [HttpContext property][IHttpContextAccessor.HttpContext] of the accessor to get the current context.
[HttpContext]: https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.http.httpcontext

View file

@ -7,7 +7,7 @@ uid: logging
## Logging
MCP servers may expose log messages to clients through the [Logging utility].
MCP servers can expose log messages to clients through the [Logging utility].
[Logging utility]: https://modelcontextprotocol.io/specification/2025-06-18/server/utilities/logging
@ -18,7 +18,7 @@ This document describes how to implement logging in MCP servers and how clients
MCP uses the logging levels defined in [RFC 5424](https://tools.ietf.org/html/rfc5424).
The MCP C# SDK uses the standard .NET [ILogger] and [ILoggerProvider] abstractions, which support a slightly
different set of logging levels. Here's the levels and how they map to standard .NET logging levels.
different set of logging levels. The following table shows the levels and how they map to standard .NET logging levels.
| Level | .NET | Description | Example Use Case |
|-----------|------|-----------------------------------|------------------------------|
@ -46,8 +46,8 @@ MCP servers that implement the Logging utility must declare this in the capabili
[Initialization]: https://modelcontextprotocol.io/specification/2025-06-18/basic/lifecycle#initialization
Servers built with the C# SDK always declare the logging capability. Doing so does not obligate the server
to send log messages -- only allows it. Note that stateless MCP servers may not be capable of sending log
messages as there may not be an open connection to the client on which the log messages could be sent.
to send log messages&mdash;only allows it. Note that stateless MCP servers might not be capable of sending log
messages as there might not be an open connection to the client on which the log messages could be sent.
The C# SDK provides an extension method <xref:Microsoft.Extensions.DependencyInjection.McpServerBuilderExtensions.WithSetLoggingLevelHandler*> on <xref:Microsoft.Extensions.DependencyInjection.IMcpServerBuilder> to allow the
server to perform any special logic it wants to perform when a client sets the logging level. However, the
@ -70,7 +70,7 @@ Clients should check if the server supports logging by checking the <xref:ModelC
If the server supports logging, the client should set the level of log messages it wishes to receive with
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
to send all log messages or none -- this is not specified in the protocol -- so it is important that the client
to send all log messages or none&mdash;this is not specified in the protocol. So it's important that the client
sets a logging level to ensure it receives the desired log messages and only those messages.
The `loggingLevel` set by the client is an MCP logging level.

View file

@ -12,7 +12,7 @@ The Model Context Protocol (MCP) supports [progress tracking] for long-running o
[progress tracking]: https://modelcontextprotocol.io/specification/2025-06-18/basic/utilities/progress
Typically progress tracking is supported by server tools that perform operations that take a significant amount of time to complete, such as image generation or complex calculations.
However, progress tracking is defined in the MCP specification as a general feature that can be implemented for any request that is handled by either a server or a client.
However, progress tracking is defined in the MCP specification as a general feature that can be implemented for any request that's handled by either a server or a client.
This project illustrates the common case of a server tool that performs a long-running operation and sends progress updates to the client.
### Server Implementation
@ -30,7 +30,7 @@ The server must verify that the caller provided a `progressToken` in the request
### Client Implementation
Clients request progress updates by including a `progressToken` in the parameters of a request.
Note that servers are not required to support progress tracking, so clients should not depend on receiving progress updates.
Note that servers aren't required to support progress tracking, so clients should not depend on receiving progress updates.
In the MCP C# SDK, clients can specify a `progressToken` in the request parameters when calling a tool method.
The client should also provide a notification handler to process "notifications/progress" notifications.