C# SDK: align mode value and priorityHint with the SEP#17
Conversation
The SEP defines mode as "enforce" | "audit"; the C# SDK used "active" on the wire, making it incompatible with the TypeScript SDK. Renames the enum member and wire value, updates the attribute default and the default-skipping logic, and adds a deserialization test. Part of #15. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The SEP allows priorityHint to be either a single number or
{ request?, response? } with different priorities per phase; the C# SDK
only supported a plain int. Adds a PriorityHint type with a converter
that round-trips both wire forms, resolves effective priority per phase
in chain ordering, and exposes RequestPriorityHint/ResponsePriorityHint
on the interceptor attribute.
Attribute-discovered interceptors with no priority set now omit
priorityHint from the wire instead of emitting 0 (semantically identical
per the SEP default, and consistent with Mode/FailOpen default-skipping).
Part of #15.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Aligns the C# interceptors SDK with SEP-1763 by updating the mode wire value to match the spec and extending priorityHint to support both scalar and per-phase object forms, including phase-specific mutation ordering in the chain orchestrator.
Changes:
- Renames
InterceptorMode.Active→InterceptorMode.Enforceand updates default/serialization behavior accordingly. - Introduces
PriorityHintprotocol type + JSON converter to round-tripnumber | { request?, response? }faithfully. - Updates chain orchestration to sort mutations by phase-effective priority and adds/updates tests for new semantics and attribute behavior.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| csharp/sdk/src/ModelContextProtocol.Interceptors/Protocol/InterceptorMode.cs | Changes enum member/wire value from active to enforce. |
| csharp/sdk/src/ModelContextProtocol.Interceptors/Protocol/PriorityHint.cs | Adds new protocol type + converter supporting scalar/object priority hints. |
| csharp/sdk/src/ModelContextProtocol.Interceptors/Protocol/Interceptor.cs | Changes PriorityHint property type to PriorityHint? and updates docs. |
| csharp/sdk/src/ModelContextProtocol.Interceptors/InterceptorJsonContext.cs | Registers PriorityHint for source-generated JSON support. |
| csharp/sdk/src/ModelContextProtocol.Interceptors/Server/McpServerInterceptorAttribute.cs | Adds optional per-phase priority hint attribute properties with backing fields. |
| csharp/sdk/src/ModelContextProtocol.Interceptors/Server/ReflectionMcpServerInterceptor.cs | Omits default Enforce mode on the wire and resolves scalar vs per-phase priority hints (with conflict error). |
| csharp/sdk/src/ModelContextProtocol.Interceptors/Client/InterceptorChainOrchestrator.cs | Sorts mutations by phase-effective priority hint. |
| csharp/sdk/tests/ModelContextProtocol.Interceptors.Tests/ProtocolTypesSerializationTests.cs | Adds serialization/round-trip coverage for PriorityHint and updated InterceptorMode. |
| csharp/sdk/tests/ModelContextProtocol.Interceptors.Tests/ReflectionMcpServerInterceptorTests.cs | Adds tests for per-phase attribute hints, omission when unset, and conflict detection. |
| csharp/sdk/tests/ModelContextProtocol.Interceptors.Tests/InterceptorChainOrchestratorTests.cs | Adds tests for phase-dependent ordering, default-zero behavior, and tie-breaking. |
| csharp/sdk/README.md | Documents per-phase priority hint usage for mutation ordering. |
| csharp/sdk/CLAUDE.md | Updates test count and documents expanded PriorityHint semantics. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ExecuteChainRequestParams.Phase could be set to InterceptorPhase.Both, which is documented as attribute-only and invalid on the wire. The orchestrator would silently match no hooks while ordering and branching as if it were the response phase. Throw ArgumentException up front instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Good catch from Copilot — (Authored by Claude Fable 5) |
Addresses the first two items of #15 (the chain-orchestrator multi-server item follows in a separate PR).
mode:"active"→"enforce"The SEP defines
mode?: "enforce" | "audit"; the C# SDK serialized"active", making it incompatible with the TypeScript SDK.InterceptorMode.Activeis renamed toEnforcewith wire value"enforce". Clean break —"active"is no longer accepted on read (experimental extension; the old value was never spec-compliant).priorityHint: supportnumber | { request?, response? }The SDK only supported a plain
int. This adds aPriorityHintprotocol type whose converter accepts both wire forms and preserves them on round-trip (a number stays a number, an object stays an object). Chain ordering now resolves the effective priority per phase exactly as the SEP'sresolvePriorityalgorithm (unset → 0, alphabetical tie-break unchanged).Interceptor.PriorityHintis nowPriorityHint?; an implicit conversion fromintkeeps existing code compiling.[McpServerInterceptor]gainsRequestPriorityHint/ResponsePriorityHint(mutually exclusive with the scalarPriorityHint), following the official SDK's backing-field pattern for optional attribute values.priorityHintfrom the wire instead of emitting0— semantically identical per the SEP default, and consistent with the existing default-skipping forMode/FailOpen.Testing
dotnet testfromcsharp/sdk/: 87 passing (was 66), including new coverage for both wire forms, partial objects, unknown-key tolerance, phase-dependent mutation ordering (the SEP's pii-redactor/compressor example), and the attribute conflict error.Part of #15.
🤖 Generated with Claude Code