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.
This commit is contained in:
parent
5bd7ab4d2a
commit
d01a626b76
1 changed files with 7887 additions and 12886 deletions
|
|
@ -0,0 +1,95 @@
|
|||
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,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue