diff --git a/src/Microsoft.Azure.Functions.Extensions.Mcp/Configuration/McpOptions.cs b/src/Microsoft.Azure.Functions.Extensions.Mcp/Configuration/McpOptions.cs
index 4306eefc..d1b0dd64 100644
--- a/src/Microsoft.Azure.Functions.Extensions.Mcp/Configuration/McpOptions.cs
+++ b/src/Microsoft.Azure.Functions.Extensions.Mcp/Configuration/McpOptions.cs
@@ -1,12 +1,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
+using Microsoft.Azure.WebJobs.Hosting;
+using Newtonsoft.Json.Linq;
+using System.ComponentModel;
+
namespace Microsoft.Azure.Functions.Extensions.Mcp.Configuration;
///
/// Options for configuring the Model Context Protocol (MCP) extension in Azure Functions.
///
-public sealed class McpOptions
+public sealed class McpOptions : IOptionsFormatter
{
private MessageOptions _messageOptions = new();
@@ -41,4 +45,20 @@ public MessageOptions MessageOptions
set => _messageOptions = value
?? throw new ArgumentNullException(nameof(value),"Message options cannot be null.");
}
+
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ string IOptionsFormatter.Format()
+ {
+ JObject options = new JObject
+ {
+ { nameof(ServerName), ServerName },
+ { nameof(ServerVersion), ServerVersion },
+ { nameof(Instructions), Instructions },
+ { nameof(EncryptClientState), EncryptClientState },
+ { nameof(MessageOptions) + "." + nameof(MessageOptions.UseAbsoluteUriForEndpoint), MessageOptions.UseAbsoluteUriForEndpoint }
+ };
+
+ return options.ToString(Newtonsoft.Json.Formatting.Indented);
+ }
}
\ No newline at end of file
diff --git a/test/Extensions.Mcp.Tests/McpOptionsTests.cs b/test/Extensions.Mcp.Tests/McpOptionsTests.cs
index 73ccd469..252a775b 100644
--- a/test/Extensions.Mcp.Tests/McpOptionsTests.cs
+++ b/test/Extensions.Mcp.Tests/McpOptionsTests.cs
@@ -2,6 +2,8 @@
// Licensed under the MIT License.
using Microsoft.Azure.Functions.Extensions.Mcp.Configuration;
+using Microsoft.Azure.WebJobs.Hosting;
+using Newtonsoft.Json.Linq;
using Xunit;
namespace Microsoft.Azure.Functions.Extensions.Mcp.Tests;
@@ -20,4 +22,45 @@ public void DefaultValues_AreSetCorrectly()
Assert.NotNull(options.MessageOptions);
Assert.False(options.MessageOptions.UseAbsoluteUriForEndpoint);
}
+
+ [Fact]
+ public void Format_ReturnsExpectedJson()
+ {
+ var options = new McpOptions
+ {
+ ServerName = "Test Server",
+ ServerVersion = "2.0.0",
+ Instructions = "Test instructions",
+ EncryptClientState = false
+ };
+ options.MessageOptions.UseAbsoluteUriForEndpoint = true;
+
+ var formatter = (IOptionsFormatter)options;
+ var formatted = formatter.Format();
+
+ Assert.NotNull(formatted);
+
+ var json = JObject.Parse(formatted);
+ Assert.Equal("Test Server", json[nameof(options.ServerName)]?.ToString());
+ Assert.Equal("2.0.0", json[nameof(options.ServerVersion)]?.ToString());
+ Assert.Equal("Test instructions", json[nameof(options.Instructions)]?.ToString());
+ Assert.Equal("False", json[nameof(options.EncryptClientState)]?.ToString());
+ Assert.Equal("True", json["MessageOptions.UseAbsoluteUriForEndpoint"]?.ToString());
+ }
+
+ [Fact]
+ public void Format_IncludesAllNonSensitiveProperties()
+ {
+ var options = new McpOptions();
+ var formatter = (IOptionsFormatter)options;
+ var formatted = formatter.Format();
+
+ var json = JObject.Parse(formatted);
+
+ Assert.Contains(nameof(options.ServerName), json.Properties().Select(p => p.Name));
+ Assert.Contains(nameof(options.ServerVersion), json.Properties().Select(p => p.Name));
+ Assert.Contains(nameof(options.Instructions), json.Properties().Select(p => p.Name));
+ Assert.Contains(nameof(options.EncryptClientState), json.Properties().Select(p => p.Name));
+ Assert.Contains("MessageOptions.UseAbsoluteUriForEndpoint", json.Properties().Select(p => p.Name));
+ }
}
\ No newline at end of file