Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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;

/// <summary>
/// Options for configuring the Model Context Protocol (MCP) extension in Azure Functions.
/// </summary>
public sealed class McpOptions
public sealed class McpOptions : IOptionsFormatter
{
private MessageOptions _messageOptions = new();

Expand Down Expand Up @@ -41,4 +45,20 @@ public MessageOptions MessageOptions
set => _messageOptions = value
?? throw new ArgumentNullException(nameof(value),"Message options cannot be null.");
}

/// <inheritdoc/>
[EditorBrowsable(EditorBrowsableState.Never)]
string IOptionsFormatter.Format()
{
JObject options = new JObject
Copy link
Member

@mathewc mathewc Sep 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use System.Text.Json rather than Newtonsoft

{
{ nameof(ServerName), ServerName },
{ nameof(ServerVersion), ServerVersion },
{ nameof(Instructions), Instructions },
Copy link
Member

@mathewc mathewc Sep 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's omit Instructions, since this may contain customer sensitive info

{ nameof(EncryptClientState), EncryptClientState },
{ nameof(MessageOptions) + "." + nameof(MessageOptions.UseAbsoluteUriForEndpoint), MessageOptions.UseAbsoluteUriForEndpoint }
};

return options.ToString(Newtonsoft.Json.Formatting.Indented);
}
}
43 changes: 43 additions & 0 deletions test/Extensions.Mcp.Tests/McpOptionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Copy link
Member

@mathewc mathewc Sep 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also do an assertion on the number of properties to make the test stronger

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));
Copy link
Member

@mathewc mathewc Sep 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here - do an assertion on the number of properties logged

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));
}
}