experimental-ext-interceptors/csharp/sdk/samples/InterceptorServerSample/SampleInterceptors.cs
Peder Holdgaard Pedersen d01a626b76
C# Re-implementation (#5)
Re-implementation of C# interceptors SDK with clearer focus on
server-side / gateway interceptors.
Fixes a lot of issues with the existing implementation.
Still more boilerplate than I'm happy with, but this is better than what
was there. Will refine further in later PRs.
2026-05-14 15:11:41 +02:00

95 lines
3.2 KiB
C#

using System.Text.Json.Nodes;
using ModelContextProtocol.Interceptors.Protocol;
using ModelContextProtocol.Interceptors.Server;
/// <summary>
/// Sample interceptors demonstrating validation, mutation, and sink types.
/// </summary>
[McpServerInterceptorType]
public class SampleInterceptors
{
/// <summary>
/// Validates that tool call arguments don't contain PII patterns.
/// </summary>
[McpServerInterceptor(
Name = "pii-validator",
Description = "Checks tool call arguments for PII patterns",
Type = InterceptorType.Validation,
Events = [InterceptionEvents.ToolsCall],
Phase = InterceptorPhase.Request)]
public static ValidationInterceptorResult ValidatePii(JsonNode payload)
{
var json = payload.ToJsonString();
// Simple pattern check for demonstration
if (json.Contains("ssn", StringComparison.OrdinalIgnoreCase) ||
json.Contains("social security", StringComparison.OrdinalIgnoreCase))
{
return ValidationInterceptorResult.Failure(
new ValidationMessage
{
Path = "$.arguments",
Message = "Payload may contain Social Security Number data",
Severity = ValidationSeverity.Error,
});
}
return ValidationInterceptorResult.Success();
}
/// <summary>
/// Redacts email addresses from tool call payloads.
/// </summary>
[McpServerInterceptor(
Name = "email-redactor",
Description = "Redacts email addresses from payloads",
Type = InterceptorType.Mutation,
Events = [InterceptionEvents.ToolsCall],
Phase = InterceptorPhase.Request,
PriorityHint = -1000)]
public static MutationInterceptorResult RedactEmails(JsonNode payload)
{
var json = payload.ToJsonString();
var redacted = System.Text.RegularExpressions.Regex.Replace(
json,
@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}",
"[EMAIL_REDACTED]");
if (redacted != json)
{
return new MutationInterceptorResult
{
Modified = true,
Payload = JsonNode.Parse(redacted),
};
}
return new MutationInterceptorResult { Modified = false, Payload = payload };
}
/// <summary>
/// Logs all intercepted events.
/// </summary>
[McpServerInterceptor(
Name = "request-logger",
Description = "Logs all requests",
Type = InterceptorType.Sink,
Events = [InterceptionEvents.All])]
public static SinkInterceptorResult LogRequest(
JsonNode payload,
string @event,
InterceptorPhase phase,
InvokeInterceptorContext? context)
{
Console.Error.WriteLine($"[interceptor] event={@event} phase={phase} traceId={context?.TraceId ?? "none"} payloadSize={payload.ToJsonString().Length}");
return new SinkInterceptorResult
{
Recorded = true,
Metrics = new Dictionary<string, double>
{
["payloadBytes"] = payload.ToJsonString().Length,
},
};
}
}