Skip to content
Draft
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
Expand Up @@ -48,7 +48,7 @@ public static IServiceCollection AddAzureMcpServer(this IServiceCollection servi
{
Namespace = serviceStartOptions.Namespace,
ReadOnly = serviceStartOptions.ReadOnly ?? false,
InsecureDisableElicitation = serviceStartOptions.InsecureDisableElicitation,
DangerouslyDisableElicitation = serviceStartOptions.DangerouslyDisableElicitation,
Tool = serviceStartOptions.Tool,
};

Expand Down Expand Up @@ -142,7 +142,7 @@ public static IServiceCollection AddAzureMcpServer(this IServiceCollection servi
var utilityToolLoaderOptions = new ToolLoaderOptions(
Namespace: Discovery.DiscoveryConstants.UtilityNamespaces,
ReadOnly: defaultToolLoaderOptions.ReadOnly,
InsecureDisableElicitation: defaultToolLoaderOptions.InsecureDisableElicitation,
DangerouslyDisableElicitation: defaultToolLoaderOptions.DangerouslyDisableElicitation,
Tool: defaultToolLoaderOptions.Tool
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ protected override void RegisterOptions(Command command)
command.Options.Add(ServiceOptionDefinitions.ReadOnly);
command.Options.Add(ServiceOptionDefinitions.Debug);
command.Options.Add(ServiceOptionDefinitions.DangerouslyDisableHttpIncomingAuth);
command.Options.Add(ServiceOptionDefinitions.InsecureDisableElicitation);
command.Options.Add(ServiceOptionDefinitions.DangerouslyDisableElicitation);
command.Options.Add(ServiceOptionDefinitions.OutgoingAuthStrategy);
command.Options.Add(ServiceOptionDefinitions.DangerouslyWriteSupportLogsToDir);
command.Validators.Add(commandResult =>
Expand Down Expand Up @@ -158,7 +158,7 @@ protected override ServiceStartOptions BindOptions(ParseResult parseResult)
ReadOnly = parseResult.GetValueOrDefault<bool?>(ServiceOptionDefinitions.ReadOnly.Name),
Debug = parseResult.GetValueOrDefault<bool>(ServiceOptionDefinitions.Debug.Name),
DangerouslyDisableHttpIncomingAuth = parseResult.GetValueOrDefault<bool>(ServiceOptionDefinitions.DangerouslyDisableHttpIncomingAuth.Name),
InsecureDisableElicitation = parseResult.GetValueOrDefault<bool>(ServiceOptionDefinitions.InsecureDisableElicitation.Name),
DangerouslyDisableElicitation = parseResult.GetValueOrDefault<bool>(ServiceOptionDefinitions.DangerouslyDisableElicitation.Name),
OutgoingAuthStrategy = outgoingAuthStrategy,
SupportLoggingFolder = parseResult.GetValueOrDefault<string?>(ServiceOptionDefinitions.DangerouslyWriteSupportLogsToDir.Name)
};
Expand Down Expand Up @@ -217,7 +217,7 @@ internal static void LogStartTelemetry(ITelemetryService telemetryService, Servi
activity.SetTag(TagName.Transport, options.Transport);
activity.SetTag(TagName.ServerMode, options.Mode);
activity.SetTag(TagName.IsReadOnly, options.ReadOnly);
activity.SetTag(TagName.InsecureDisableElicitation, options.InsecureDisableElicitation);
activity.SetTag(TagName.DangerouslyDisableElicitation, options.DangerouslyDisableElicitation);
activity.SetTag(TagName.DangerouslyDisableHttpIncomingAuth, options.DangerouslyDisableHttpIncomingAuth);
activity.SetTag(TagName.IsDebug, options.Debug);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ protected McpClientOptions CreateClientOptions(McpServer server)
/// </summary>
/// <param name="request">The request context containing the MCP server.</param>
/// <param name="toolName">The name of the tool being invoked.</param>
/// <param name="insecureDisableElicitation">Whether elicitation has been disabled via insecure option.</param>
/// <param name="dangerouslyDisableElicitation">Whether elicitation has been disabled via dangerous option.</param>
/// <param name="logger">Logger instance for recording elicitation events.</param>
/// <param name="cancellationToken">Cancellation token for the operation.</param>
/// <returns>
Expand All @@ -167,14 +167,14 @@ protected McpClientOptions CreateClientOptions(McpServer server)
protected static async Task<CallToolResult?> HandleSecretElicitationAsync(
RequestContext<CallToolRequestParams> request,
string toolName,
bool insecureDisableElicitation,
bool dangerouslyDisableElicitation,
ILogger logger,
CancellationToken cancellationToken)
{
// Check if elicitation is disabled by insecure option
if (insecureDisableElicitation)
// Check if elicitation is disabled by dangerous option
if (dangerouslyDisableElicitation)
{
logger.LogWarning("Tool '{Tool}' handles sensitive data but elicitation is disabled via --insecure-disable-elicitation. Proceeding without user consent (INSECURE).", toolName);
logger.LogWarning("Tool '{Tool}' handles sensitive data but elicitation is disabled via --dangerously-disable-elicitation. Proceeding without user consent.", toolName);
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ public override async ValueTask<CallToolResult> CallToolHandler(RequestContext<C
var elicitationResult = await HandleSecretElicitationAsync(
request,
toolName,
_options.Value.InsecureDisableElicitation,
_options.Value.DangerouslyDisableElicitation,
_logger,
cancellationToken);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ private async Task<CallToolResult> InvokeChildToolAsync(
var elicitationResult = await HandleSecretElicitationAsync(
request,
$"{namespaceName} {command}",
_options.Value.InsecureDisableElicitation,
_options.Value.DangerouslyDisableElicitation,
_logger,
cancellationToken);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ namespace Azure.Mcp.Core.Areas.Server.Commands.ToolLoading;
/// </summary>
/// <param name="Namespace">The namespaces to filter commands by. If null or empty, all commands will be included.</param>
/// <param name="ReadOnly">Whether the tool loader should operate in read-only mode. When true, only tools marked as read-only will be exposed.</param>
/// <param name="InsecureDisableElicitation">Whether elicitation is disabled (insecure mode). When true, elicitation will always be treated as accepted.</param>
/// <param name="DangerouslyDisableElicitation">Whether elicitation is disabled (dangerous mode). When true, elicitation will always be treated as accepted.</param>
/// <param name="Tool">The specific tool names to filter by. When specified, only these tools will be exposed.</param>
public sealed record ToolLoaderOptions(string[]? Namespace = null, bool ReadOnly = false, bool InsecureDisableElicitation = false, string[]? Tool = null);
public sealed record ToolLoaderOptions(string[]? Namespace = null, bool ReadOnly = false, bool DangerouslyDisableElicitation = false, string[]? Tool = null);
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public static class ServiceOptionDefinitions
public const string ReadOnlyName = "read-only";
public const string DebugName = "debug";
public const string DangerouslyDisableHttpIncomingAuthName = "dangerously-disable-http-incoming-auth";
public const string InsecureDisableElicitationName = "insecure-disable-elicitation";
public const string DangerouslyDisableElicitationName = "dangerously-disable-elicitation";
public const string OutgoingAuthStrategyName = "outgoing-auth-strategy";
public const string DangerouslyWriteSupportLogsToDirName = "dangerously-write-support-logs-to-dir";

Expand Down Expand Up @@ -77,8 +77,8 @@ public static class ServiceOptionDefinitions
DefaultValueFactory = _ => false
};

public static readonly Option<bool> InsecureDisableElicitation = new(
$"--{InsecureDisableElicitationName}")
public static readonly Option<bool> DangerouslyDisableElicitation = new(
$"--{DangerouslyDisableElicitationName}")
{
Required = false,
Description = "Disable elicitation (user confirmation) before allowing high risk commands to run, such as returning Secrets (passwords) from KeyVault.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ public class ServiceStartOptions
public bool DangerouslyDisableHttpIncomingAuth { get; set; } = false;

/// <summary>
/// Gets or sets whether elicitation (user confirmation for high-risk operations like accessing secrets) is disabled (insecure mode).
/// Gets or sets whether elicitation (user confirmation for high-risk operations like accessing secrets) is disabled (dangerous mode).
/// When true, elicitation will always be treated as accepted without user confirmation.
/// </summary>
[JsonPropertyName("insecureDisableElicitation")]
public bool InsecureDisableElicitation { get; set; } = false;
[JsonPropertyName("dangerouslyDisableElicitation")]
public bool DangerouslyDisableElicitation { get; set; } = false;

/// <summary>
/// Gets or sets the outgoing authentication strategy for Azure service requests.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -648,10 +648,10 @@ public async Task CallToolHandler_WithNonSecretTool_DoesNotTriggerElicitation()
}

[Fact]
public async Task CallToolHandler_WithSecretTool_WhenInsecureDisableElicitationEnabled_BypassesElicitation()
public async Task CallToolHandler_WithSecretTool_WhenDangerouslyDisableElicitationEnabled_BypassesElicitation()
{
// Create tool loader with insecure disable elicitation enabled
var options = new ToolLoaderOptions(InsecureDisableElicitation: true);
// Create tool loader with dangerously disable elicitation enabled
var options = new ToolLoaderOptions(DangerouslyDisableElicitation: true);
var (toolLoader, commandFactory) = CreateToolLoader(options);

// Add the fake secret command to the command factory
Expand Down Expand Up @@ -693,10 +693,10 @@ public async Task CallToolHandler_WithSecretTool_WhenInsecureDisableElicitationE
}

[Fact]
public async Task CallToolHandler_WithSecretTool_WhenInsecureDisableElicitationDisabled_StillRequiresElicitation()
public async Task CallToolHandler_WithSecretTool_WhenDangerouslyDisableElicitationDisabled_StillRequiresElicitation()
{
// Create tool loader with insecure disable elicitation disabled (default)
var options = new ToolLoaderOptions(InsecureDisableElicitation: false);
// Create tool loader with dangerously disable elicitation disabled (default)
var options = new ToolLoaderOptions(DangerouslyDisableElicitation: false);
var (toolLoader, commandFactory) = CreateToolLoader(options);

// Add the fake secret command to the command factory
Expand Down Expand Up @@ -735,23 +735,23 @@ public async Task CallToolHandler_WithSecretTool_WhenInsecureDisableElicitationD
}

[Fact]
public void ToolLoaderOptions_DefaultInsecureDisableElicitation_IsFalse()
public void ToolLoaderOptions_DefaultDangerouslyDisableElicitation_IsFalse()
{
// Arrange & Act
var options = new ToolLoaderOptions();

// Assert
Assert.False(options.InsecureDisableElicitation);
Assert.False(options.DangerouslyDisableElicitation);
}

[Fact]
public void ToolLoaderOptions_WithInsecureDisableElicitationTrue_IsSetCorrectly()
public void ToolLoaderOptions_WithDangerouslyDisableElicitationTrue_IsSetCorrectly()
{
// Arrange & Act
var options = new ToolLoaderOptions(InsecureDisableElicitation: true);
var options = new ToolLoaderOptions(DangerouslyDisableElicitation: true);

// Assert
Assert.True(options.InsecureDisableElicitation);
Assert.True(options.DangerouslyDisableElicitation);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,41 +56,41 @@ public void ServiceOption_ParsesCorrectly(string? inputService, string expectedS
[Theory]
[InlineData(true)]
[InlineData(false)]
public void InsecureDisableElicitationOption_ParsesCorrectly(bool expectedValue)
public void DangerouslyDisableElicitationOption_ParsesCorrectly(bool expectedValue)
{
// Arrange
var parseResult = CreateParseResultWithInsecureDisableElicitation(expectedValue);
var parseResult = CreateParseResultWithDangerouslyDisableElicitation(expectedValue);

// Act
var actualValue = parseResult.GetValue(ServiceOptionDefinitions.InsecureDisableElicitation);
var actualValue = parseResult.GetValue(ServiceOptionDefinitions.DangerouslyDisableElicitation);

// Assert
Assert.Equal(expectedValue, actualValue);
}

[Fact]
public void InsecureDisableElicitationOption_DefaultsToFalse()
public void DangerouslyDisableElicitationOption_DefaultsToFalse()
{
// Arrange
var parseResult = CreateParseResult(null);

// Act
var actualValue = parseResult.GetValue(ServiceOptionDefinitions.InsecureDisableElicitation);
var actualValue = parseResult.GetValue(ServiceOptionDefinitions.DangerouslyDisableElicitation);

// Assert
Assert.False(actualValue);
}

[Fact]
public void AllOptionsRegistered_IncludesInsecureDisableElicitation()
public void AllOptionsRegistered_IncludesDangerouslyDisableElicitation()
{
// Arrange & Act
var command = _command.GetCommand();

// Assert
var hasInsecureDisableElicitationOption = command.Options.Any(o =>
o.Name == ServiceOptionDefinitions.InsecureDisableElicitation.Name);
Assert.True(hasInsecureDisableElicitationOption, "InsecureDisableElicitation option should be registered");
var hasDangerouslyDisableElicitationOption = command.Options.Any(o =>
o.Name == ServiceOptionDefinitions.DangerouslyDisableElicitation.Name);
Assert.True(hasDangerouslyDisableElicitationOption, "DangerouslyDisableElicitation option should be registered");
}

[Fact]
Expand Down Expand Up @@ -224,7 +224,7 @@ public void BindOptions_WithAllOptions_ReturnsCorrectlyConfiguredOptions()
Assert.True(options.ReadOnly);
Assert.True(options.Debug);
Assert.False(options.DangerouslyDisableHttpIncomingAuth);
Assert.True(options.InsecureDisableElicitation);
Assert.True(options.DangerouslyDisableElicitation);
}

[Fact]
Expand Down Expand Up @@ -278,7 +278,7 @@ public void BindOptions_WithDefaults_ReturnsDefaultValues()
Assert.False(options.ReadOnly); // Default readonly
Assert.False(options.Debug);
Assert.False(options.DangerouslyDisableHttpIncomingAuth);
Assert.False(options.InsecureDisableElicitation);
Assert.False(options.DangerouslyDisableElicitation);
Assert.Null(options.SupportLoggingFolder);
}

Expand Down Expand Up @@ -630,7 +630,7 @@ public void InitializedHandler_SetsStartupInformation()
ReadOnly = false,
Debug = true,
Namespace = ["storage", "keyvault"],
InsecureDisableElicitation = false,
DangerouslyDisableElicitation = false,
DangerouslyDisableHttpIncomingAuth = true,
};
var activity = new Activity("test-activity");
Expand All @@ -647,8 +647,8 @@ public void InitializedHandler_SetsStartupInformation()
var dangerouslyDisableHttpIncomingAuth = GetAndAssertTagKeyValue(activity, TagName.DangerouslyDisableHttpIncomingAuth);
Assert.Equal(serviceStartOptions.DangerouslyDisableHttpIncomingAuth, dangerouslyDisableHttpIncomingAuth);

var insecureDisableElicitation = GetAndAssertTagKeyValue(activity, TagName.InsecureDisableElicitation);
Assert.Equal(serviceStartOptions.InsecureDisableElicitation, insecureDisableElicitation);
var dangerouslyDisableElicitation = GetAndAssertTagKeyValue(activity, TagName.DangerouslyDisableElicitation);
Assert.Equal(serviceStartOptions.DangerouslyDisableElicitation, dangerouslyDisableElicitation);

var transport = GetAndAssertTagKeyValue(activity, TagName.Transport);
Assert.Equal(serviceStartOptions.Transport, transport);
Expand Down Expand Up @@ -680,7 +680,7 @@ public void InitializedHandler_SetsCorrectInformationWhenNull()
Mode = null,
ReadOnly = true,
Debug = false,
InsecureDisableElicitation = true,
DangerouslyDisableElicitation = true,
DangerouslyDisableHttpIncomingAuth = false,
};
var activity = new Activity("test-activity");
Expand All @@ -699,8 +699,8 @@ public void InitializedHandler_SetsCorrectInformationWhenNull()
var dangerouslyDisableHttpIncomingAuth = GetAndAssertTagKeyValue(activity, TagName.DangerouslyDisableHttpIncomingAuth);
Assert.Equal(serviceStartOptions.DangerouslyDisableHttpIncomingAuth, dangerouslyDisableHttpIncomingAuth);

var insecureDisableElicitation = GetAndAssertTagKeyValue(activity, TagName.InsecureDisableElicitation);
Assert.Equal(serviceStartOptions.InsecureDisableElicitation, insecureDisableElicitation);
var dangerouslyDisableElicitation = GetAndAssertTagKeyValue(activity, TagName.DangerouslyDisableElicitation);
Assert.Equal(serviceStartOptions.DangerouslyDisableElicitation, dangerouslyDisableElicitation);

var transport = GetAndAssertTagKeyValue(activity, TagName.Transport);
Assert.Equal(serviceStartOptions.Transport, transport);
Expand Down Expand Up @@ -738,17 +738,17 @@ private static ParseResult CreateParseResult(string? serviceValue)
return root.Parse([.. args]);
}

private ParseResult CreateParseResultWithInsecureDisableElicitation(bool insecureDisableElicitation)
private ParseResult CreateParseResultWithDangerouslyDisableElicitation(bool dangerouslyDisableElicitation)
{
var args = new List<string>
{
"--transport",
"stdio"
};

if (insecureDisableElicitation)
if (dangerouslyDisableElicitation)
{
args.Add("--insecure-disable-elicitation");
args.Add("--dangerously-disable-elicitation");
}

return _command.GetCommand().Parse([.. args]);
Expand Down Expand Up @@ -807,7 +807,7 @@ private ParseResult CreateParseResultWithAllOptions()
"--mode", "all",
"--read-only",
"--debug",
"--insecure-disable-elicitation"
"--dangerously-disable-elicitation"
};

return _command.GetCommand().Parse([.. args]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class TagName
public const string IsReadOnly = "IsReadOnly";
public const string Namespace = "Namespace";
public const string ToolCount = "ToolCount";
public const string InsecureDisableElicitation = "InsecureDisableElicitation";
public const string DangerouslyDisableElicitation = "DangerouslyDisableElicitation";
public const string IsDebug = "IsDebug";
public const string DangerouslyDisableHttpIncomingAuth = "DangerouslyDisableHttpIncomingAuth";
public const string Tool = "Tool";
Expand Down
Loading