Skip to content
Open
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 @@ -78,6 +78,25 @@ codeunit 8350 "MCP Config"
exit(MCPConfigImplementation.CopyConfiguration(SourceConfigId, NewName, NewDescription));
end;

/// <summary>
/// Sets the specified MCP configuration as the default configuration.
/// When no configuration is specified by a connection, the default configuration will be used.
/// Only active configurations can be set as default.
/// </summary>
/// <param name="ConfigId">The SystemId (GUID) of the configuration to set as default.</param>
procedure SetAsDefaultConfiguration(ConfigId: Guid)
begin
MCPConfigImplementation.SetAsDefaultConfiguration(ConfigId);
end;

/// <summary>
/// Clears the current default configuration designation and restores the system default.
/// </summary>
procedure ClearDefaultConfiguration()
begin
MCPConfigImplementation.ClearDefaultConfiguration();
end;

/// <summary>
/// Enables dynamic tool mode for the specified configuration.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ codeunit 8351 "MCP Config Implementation"
InvalidPageTypeErr: Label 'Only API pages are supported.';
InvalidAPIVersionErr: Label 'Only API v2.0 pages are supported.';
DefaultMCPConfigurationDescriptionLbl: Label 'Default MCP configuration';
DesignatedDefaultCannotBeDeactivatedErr: Label 'The designated default configuration cannot be deactivated. Clear the default designation first.';
ConfigurationMustBeActiveErr: Label 'Only active configurations can be set as the default.';
DynamicToolModeRequiredErr: Label 'Dynamic tool mode needs to be enabled to discover read-only objects.';
VersionNotValidErr: Label 'The API version is not valid for the selected tool.';
MCPConfigurationCreatedLbl: Label 'MCP Configuration created', Locked = true;
Expand All @@ -38,6 +40,7 @@ codeunit 8351 "MCP Config Implementation"
MCPConfigurationAuditDeletedLbl: Label 'MCP Configuration %1 deleted by user %2 in company %3', Comment = '%1 - configuration name, %2 - user security ID, %3 - company name', Locked = true;
InvalidConfigurationWarningLbl: Label 'The configuration is invalid and may not work as expected. Do you want to review warnings before activating?';
ConfigValidLbl: Label 'No warnings found. The configuration is valid.';
MCPDefaultConfigDesignatedLbl: Label 'MCP default configuration designated', Locked = true;
ConnectionStringLbl: Label '%1 Connection String', Comment = '%1 - configuration name';
MCPUrlProdLbl: Label 'https://mcp.businesscentral.dynamics.com', Locked = true;
MCPUrlTIELbl: Label 'https://mcp.businesscentral.dynamics-tie.com', Locked = true;
Expand All @@ -55,6 +58,7 @@ codeunit 8351 "MCP Config Implementation"
JsonFilterTxt: Label 'JSON Files (*.json)|*.json';
InvalidJsonErr: Label 'The selected file is not a valid configuration file.';
ConfigNameExistsMsg: Label 'A configuration with the name ''%1'' already exists. Please provide a different name.', Comment = '%1 = configuration name';
ConfigurationNotFoundErr: Label 'The MCP configuration was not found.';
MCPServerFeedbackConfirmQst: Label 'We noticed you no longer have any active configurations. Could you share what made you decide to stop using the MCP server? Your feedback helps us improve the experience.';
MCPServerFeedbackQst: Label 'What could we do to improve the MCP server experience?';
NoActiveConfigsFeedbackTxt: Label 'No active configs feedback triggered', Locked = true;
Expand Down Expand Up @@ -88,11 +92,14 @@ codeunit 8351 "MCP Config Implementation"
MCPConfiguration: Record "MCP Configuration";
begin
if not MCPConfiguration.GetBySystemId(ConfigId) then
exit;
Error(ConfigurationNotFoundErr);

if not Active and IsDefaultConfiguration(MCPConfiguration) then
Error(DefaultConfigCannotBeDeactivatedErr);

if not Active and IsDesignatedDefaultConfiguration(MCPConfiguration) then
Error(DesignatedDefaultCannotBeDeactivatedErr);

MCPConfiguration.Active := Active;
MCPConfiguration.Modify();

Expand All @@ -104,7 +111,7 @@ codeunit 8351 "MCP Config Implementation"
xMCPConfiguration: Record "MCP Configuration";
begin
if not MCPConfiguration.GetBySystemId(ConfigId) then
exit;
Error(ConfigurationNotFoundErr);

xMCPConfiguration := MCPConfiguration;

Expand Down Expand Up @@ -135,11 +142,14 @@ codeunit 8351 "MCP Config Implementation"
MCPConfiguration: Record "MCP Configuration";
begin
if not MCPConfiguration.GetBySystemId(ConfigId) then
exit;
Error(ConfigurationNotFoundErr);

if IsDefaultConfiguration(MCPConfiguration) then
Error(DefaultConfigCannotBeDeletedErr);

if IsDesignatedDefaultConfiguration(MCPConfiguration) then
MarkSystemDefaultAsDefault();

LogConfigurationDeleted(MCPConfiguration);
MCPConfiguration.Delete();
end;
Expand All @@ -166,11 +176,12 @@ codeunit 8351 "MCP Config Implementation"
NewMCPConfiguration: Record "MCP Configuration";
begin
if not SourceMCPConfiguration.GetBySystemId(SourceConfigId) then
exit;
Error(ConfigurationNotFoundErr);

NewMCPConfiguration.Copy(SourceMCPConfiguration);
NewMCPConfiguration.Name := NewName;
NewMCPConfiguration.Description := NewDescription;
NewMCPConfiguration.Default := false;
NewMCPConfiguration.Insert();

CopyTools(SourceMCPConfiguration, NewMCPConfiguration);
Expand Down Expand Up @@ -201,7 +212,7 @@ codeunit 8351 "MCP Config Implementation"
xMCPConfiguration: Record "MCP Configuration";
begin
if not MCPConfiguration.GetBySystemId(ConfigId) then
exit;
Error(ConfigurationNotFoundErr);

xMCPConfiguration := MCPConfiguration;

Expand All @@ -221,7 +232,7 @@ codeunit 8351 "MCP Config Implementation"
xMCPConfiguration: Record "MCP Configuration";
begin
if not MCPConfiguration.GetBySystemId(ConfigId) then
exit;
Error(ConfigurationNotFoundErr);

xMCPConfiguration := MCPConfiguration;

Expand All @@ -241,7 +252,7 @@ codeunit 8351 "MCP Config Implementation"
MCPConfiguration: Record "MCP Configuration";
begin
if not MCPConfiguration.GetBySystemId(ConfigId) then
exit;
Error(ConfigurationNotFoundErr);

if not MCPConfiguration.AllowProdChanges then
Error(CreateUpdateDeleteNotAllowedErr);
Expand All @@ -260,6 +271,7 @@ codeunit 8351 "MCP Config Implementation"
MCPConfiguration.EnableDynamicToolMode := true;
MCPConfiguration.DiscoverReadOnlyObjects := true;
MCPConfiguration.AllowProdChanges := true;
MCPConfiguration.Default := true;
MCPConfiguration.Insert();
end;

Expand All @@ -268,6 +280,57 @@ codeunit 8351 "MCP Config Implementation"
exit(MCPConfiguration.Name = '');
end;

internal procedure IsDesignatedDefaultConfiguration(MCPConfiguration: Record "MCP Configuration"): Boolean
begin
exit(MCPConfiguration.Default);
end;

internal procedure SetAsDefaultConfiguration(ConfigId: Guid)
var
MCPConfiguration: Record "MCP Configuration";
PreviousDefault: Record "MCP Configuration";
begin
if not MCPConfiguration.GetBySystemId(ConfigId) then
Error(ConfigurationNotFoundErr);

if not MCPConfiguration.Active then
Error(ConfigurationMustBeActiveErr);

PreviousDefault.SetRange(Default, true);
PreviousDefault.ModifyAll(Default, false);

MCPConfiguration.Default := true;
MCPConfiguration.Modify();

Session.LogMessage('0000R0R', MCPDefaultConfigDesignatedLbl, Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::All, GetDimensions(MCPConfiguration));
end;

internal procedure ClearDefaultConfiguration()
var
MCPConfiguration: Record "MCP Configuration";
SystemDefault: Record "MCP Configuration";
begin
MCPConfiguration.SetRange(Default, true);
MCPConfiguration.SetFilter(Name, '<>%1', '');
MCPConfiguration.ModifyAll(Default, false);

if SystemDefault.Get('') then begin
SystemDefault.Default := true;
SystemDefault.Modify();
end;
end;

local procedure MarkSystemDefaultAsDefault()
var
SystemDefault: Record "MCP Configuration";
begin
if not SystemDefault.Get('') then
exit;

SystemDefault.Default := true;
SystemDefault.Modify();
end;

internal procedure IsConfigurationActive(ConfigId: Guid): Boolean
var
MCPConfiguration: Record "MCP Configuration";
Expand Down Expand Up @@ -361,7 +424,7 @@ codeunit 8351 "MCP Config Implementation"
PageMetadata: Record "Page Metadata";
begin
if not MCPConfiguration.GetBySystemId(ConfigId) then
exit;
Error(ConfigurationNotFoundErr);

if IsDefaultConfiguration(MCPConfiguration) then
Error(ToolsCannotBeAddedToDefaultConfigErr);
Expand Down Expand Up @@ -917,7 +980,7 @@ codeunit 8351 "MCP Config Implementation"
OutputText: Text;
begin
if not MCPConfiguration.GetBySystemId(ConfigId) then
exit;
Error(ConfigurationNotFoundErr);

ConfigJson.Add('name', MCPConfiguration.Name);
ConfigJson.Add('description', MCPConfiguration.Description);
Expand Down Expand Up @@ -1081,6 +1144,7 @@ codeunit 8351 "MCP Config Implementation"
Dimensions.Add('Category', GetTelemetryCategory());
Dimensions.Add('MCPConfigurationName', MCPConfiguration.Name);
Dimensions.Add('Active', Format(MCPConfiguration.Active));
Dimensions.Add('IsDesignatedDefault', Format(MCPConfiguration.Default));
Dimensions.Add('UnblockEditTools', Format(MCPConfiguration.AllowProdChanges));
Dimensions.Add('DynamicToolMode', Format(MCPConfiguration.EnableDynamicToolMode));
Dimensions.Add('DiscoverReadOnlyObjects', Format(MCPConfiguration.DiscoverReadOnlyObjects));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ codeunit 8356 "MCP Upgrade"
trigger OnUpgradePerDatabase()
begin
UpgradeMCPAPIToolVersion();
UpgradeMCPSystemDefaultAsDefault();
end;

internal procedure UpgradeMCPAPIToolVersion()
Expand Down Expand Up @@ -45,14 +46,36 @@ codeunit 8356 "MCP Upgrade"
UpgradeTag.SetUpgradeTag(GetMCPAPIToolVersionUpgradeTag());
end;

internal procedure UpgradeMCPSystemDefaultAsDefault()
var
MCPConfiguration: Record "MCP Configuration";
UpgradeTag: Codeunit "Upgrade Tag";
begin
if UpgradeTag.HasDatabaseUpgradeTag(GetMCPSystemDefaultAsDefaultUpgradeTag()) then
exit;

if MCPConfiguration.Get('') then begin
MCPConfiguration.Default := true;
MCPConfiguration.Modify();
end;

UpgradeTag.SetUpgradeTag(GetMCPSystemDefaultAsDefaultUpgradeTag());
end;

[EventSubscriber(ObjectType::Codeunit, Codeunit::"Upgrade Tag", OnGetPerDatabaseUpgradeTags, '', false, false)]
local procedure RegisterUpgradeTags(var PerDatabaseUpgradeTags: List of [Code[250]])
begin
PerDatabaseUpgradeTags.Add(GetMCPAPIToolVersionUpgradeTag());
PerDatabaseUpgradeTags.Add(GetMCPSystemDefaultAsDefaultUpgradeTag());
end;

local procedure GetMCPAPIToolVersionUpgradeTag(): Text[250]
begin
exit('MS-619475-MCPAPIToolVersion-20260126');
end;

local procedure GetMCPSystemDefaultAsDefaultUpgradeTag(): Text[250]
begin
exit('MS-612454-MCPSystemDefaultAsDefault-20260216');
end;
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,18 @@ page 8351 "MCP Config Card"
trigger OnValidate()
begin
if Rec.Active then
MCPConfigImplementation.ValidateConfiguration(Rec, true);
MCPConfigImplementation.ValidateConfiguration(Rec, true)
else
if Rec.Default then
Error(DesignatedDefaultCannotBeDeactivatedErr);
end;
}
field(Default; Rec.Default)
{
Caption = 'Default';
ToolTip = 'Specifies whether this configuration is the default. The default configuration is used when no configuration is specified by a connection.';
Editable = false;
}
field(EnableDynamicToolMode; Rec.EnableDynamicToolMode)
{
ToolTip = 'Specifies whether to enable dynamic tool mode for this MCP configuration. When enabled, clients can search for tools within the configuration dynamically.';
Expand Down Expand Up @@ -156,11 +165,43 @@ page 8351 "MCP Config Card"
end;
}
}
action(SetAsDefault)
{
Caption = 'Set as Default';
ToolTip = 'Set this configuration as the default. It will be used when no configuration is specified by a connection.';
Image = Approve;
AccessByPermission = tabledata "MCP Configuration" = M;
Visible = not IsDefault;
Enabled = not Rec.Default;

trigger OnAction()
begin
MCPConfigImplementation.SetAsDefaultConfiguration(Rec.SystemId);
CurrPage.Update(false);
end;
}
action(ClearDefault)
{
Caption = 'Clear Default';
ToolTip = 'Remove the default designation from this configuration. The system will revert to built-in default settings.';
Image = Undo;
AccessByPermission = tabledata "MCP Configuration" = M;
Visible = not IsDefault;
Enabled = Rec.Default;

trigger OnAction()
begin
MCPConfigImplementation.ClearDefaultConfiguration();
CurrPage.Update(false);
end;
}
}
area(Promoted)
{
actionref(Promoted_Copy; Copy) { }
actionref(Promoted_Validate; Validate) { }
actionref(Promoted_SetAsDefault; SetAsDefault) { }
actionref(Promoted_ClearDefault; ClearDefault) { }
group(Promoted_Advanced)
{
Caption = 'Advanced';
Expand Down Expand Up @@ -202,6 +243,7 @@ page 8351 "MCP Config Card"
ToolModeLbl: Text;
StaticToolModeLbl: Label 'In Static Tool Mode, objects in the available tools will be directly exposed to clients. You can manage these tools by adding, modifying, or removing them from the configuration.';
DynamicToolModeLbl: Label 'In Dynamic Tool Mode, only system tools will be exposed to clients. Objects within the available tools can be discovered, described and invoked dynamically using system tools. You can enable dynamic discovery of any read-only object outside of the available tools using Discover Additional Objects setting.';
DesignatedDefaultCannotBeDeactivatedErr: Label 'The designated default configuration cannot be deactivated. Clear the default designation first.';

local procedure GetToolModeDescription(): Text
begin
Expand Down
Loading
Loading