Skip to content

Commit bb82314

Browse files
authored
fix: add user settings for MCP in DA and localize strings (#14622)
1 parent 7d77523 commit bb82314

File tree

7 files changed

+62
-46
lines changed

7 files changed

+62
-46
lines changed

packages/vscode-extension/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1871,6 +1871,11 @@
18711871
"default": "Info",
18721872
"markdownDescription": "Set the log level of Microsoft 365 Agents Toolkit. The default value is `Info`. The available values are `Debug`, `Verbose`, `Info`. The definitions of the log levels are:\n\n`Debug`:\n\n- HTTP request and response details from Microsoft 365 Agents Toolkit to external services such as Azure, Microsoft 365, and Developer Portal.\n- Information related to Microsoft 365 and Azure accounts and access permissions.\n- Debugging information for each Microsoft 365 Agents Toolkit command execution, such as stack trace, ARM deployment information, etc.\n\n`Verbose`:\n\n- Progress information when executing lifecycle commands defined in the YAML file.\n- Execution details of each action that defined in the YAML file, including outcomes, result summaries, diagnostic information, etc.\n\n`Info`: Microsoft 365 Agents Toolkit command execution summaries.\n"
18731873
},
1874+
"M365AgentsToolkit.enableDeclarativeAgentMCPSupport": {
1875+
"type": "boolean",
1876+
"default": true,
1877+
"markdownDescription": "Enable MCP server support for Declarative Agent."
1878+
},
18741879
"M365AgentsToolkit.enableLaunchAgentForTeamsInCopilot": {
18751880
"type": "boolean",
18761881
"default": false,

packages/vscode-extension/package.nls.json

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -608,41 +608,30 @@
608608
"teamstoolkit.chatParticipants.officeAddIn.generateCode.hint": "Generating code...",
609609
"teamstoolkit.chatParticipants.officeAddIn.generateCode.complex": "This is a complex task and may take longer, please be patient.",
610610
"teamstoolkit.chatParticipants.officeAddIn.generateCode.simple": "One moment, please.",
611-
612611
"teamstoolkit.walkthroughs.select.placeholder": "Select an option",
613612
"teamstoolkit.walkthroughs.select.title": "Select a Tutorial to Get Started",
614-
615613
"teamstoolkit.walkthroughs.buildIntelligentApps.title": "Build a Declarative Agent",
616614
"teamstoolkit.walkthroughs.buildIntelligentApps.description": "Build a declarative agent with Microsoft 365 Agents Toolkit to simplify workflows and automate tasks.",
617-
618615
"teamstoolkit.walkthroughs.buildIntelligentApps.intelligentAppsIntroduction.title": "Introduction",
619616
"teamstoolkit.walkthroughs.buildIntelligentApps.intelligentAppsIntroduction.description": "Build a declarative agent to customize Microsoft 365 Copilot with specific instructions, actions, and knowledge. Follow this guide to get started.",
620617
"teamstoolkit.walkthroughs.buildIntelligentApps.intelligentAppsEnvironment.title": "Set up your environment",
621618
"teamstoolkit.walkthroughs.buildIntelligentApps.intelligentAppsEnvironment.description": "Set up your environment to build a declarative agent for Microsoft 365 Copilot. Ensure you have Node.js, NPM, and a valid Microsoft 365 Copilot license. [Learn how to get a developer environment.](https://learn.microsoft.com/en-us/microsoft-365-copilot/extensibility/prerequisites#prerequisites)\n[Check Copilot License](command:fx-extension.checkCopilotAccess?%5B%22WalkThrough%22%5D)",
622-
623619
"teamstoolkit.walkthroughs.buildIntelligentApps.intelligentAppsBuildApp.title": "Build a declarative agent",
624620
"teamstoolkit.walkthroughs.buildIntelligentApps.intelligentAppsBuildApp.description": "Follow these steps to build your declarative agent using Microsoft 365 Agents Toolkit.\n[Build Declarative Agent](command:fx-extension.create?%5B%22SideBar%22%5D)",
625621
"teamstoolkit.walkthroughs.buildIntelligentApps.intelligentAppsPreview.title": "Preview in Microsoft 365 Copilot",
626622
"teamstoolkit.walkthroughs.buildIntelligentApps.intelligentAppsPreview.description": "To preview your declarative agent, [Provision](command:fx-extension.provision) it for Microsoft 365 Copilot and Launch Microsoft 365 Copilot for [Preview](command:fx-extension.localdebug).\n[Provision](command:fx-extension.provision)\n[Preview](command:fx-extension.localdebug)\nTip: Use [Run and Debug](command:workbench.view.debug) panel on the activity bar to browse all debug options in Teams.",
627-
628623
"teamstoolkit.walkthroughs.buildIntelligentApps.intelligentAppsExplore.title": "Improve your declarative agent",
629624
"teamstoolkit.walkthroughs.buildIntelligentApps.intelligentAppsExplore.description": "Improve your declarative agent's user experience by adding capabilities.\n\nThe capabilities element in the manifest unlocks various features for your users.",
630-
631625
"teamstoolkit.walkthroughs.buildIntelligentApps.twoPathsToIntelligentApps.title": "Two Paths to Intelligent Apps",
632626
"teamstoolkit.walkthroughs.buildIntelligentApps.twoPathsToIntelligentApps.description": "Build your intelligent apps with Microsoft 365 in two ways:\n🎯 Extend Microsoft Copilot with a plugin, Or\n✨ Build your own Copilot in Teams using Teams AI Library and Azure services",
633-
634627
"teamstoolkit.walkthroughs.buildIntelligentApps.copilotPlugin.title": "API Plugin",
635628
"teamstoolkit.walkthroughs.buildIntelligentApps.copilotPlugin.description": "Transform your app into a plugin to enhance Copilot's skills and boost user productivity in daily tasks and workflows. Explore [Copilot Extensibility](https://learn.microsoft.com/en-us/microsoft-365-copilot/extensibility/)\n[Check Copilot Access](command:fx-extension.checkCopilotAccess?%5B%22WalkThrough%22%5D)",
636-
637629
"teamstoolkit.walkthroughs.buildIntelligentApps.buildPlugin.title": "Build a Plugin",
638630
"teamstoolkit.walkthroughs.buildIntelligentApps.buildPlugin.description": "Expand, enrich, and customize Copilot with plugins and Graph connectors in any of the following ways\n[OpenAPI Description Document](command:fx-extension.createFromWalkthrough?%5B%22WalkThrough%22%2C%20%7B%22project-type%22%3A%20%22copilot-agent-type%22%2C%20%22capabilities%22%3A%20%22api-plugin%22%7D%5D)\n[Teams Message Extension](command:fx-extension.createFromWalkthrough?%5B%22WalkThrough%22%2C%20%7B%22capabilities%22%3A%20%22search-app%22%2C%20%22project-type%22%3A%20%22me-type%22%2C%20%22me-architecture%22%3A%20%22bot-plugin%22%7D%5D)\n[Graph Connector](command:fx-extension.openSamples?%5B%22WalkThrough%22%2C%20%22gc-nodejs-typescript-food-catalog%22%5D)",
639-
640631
"teamstoolkit.walkthroughs.buildIntelligentApps.customCopilot.title": "Custom Engine Agent",
641632
"teamstoolkit.walkthroughs.buildIntelligentApps.customCopilot.description": "Build your intelligent, natural language-driven experiences in Teams, leveraging its vast user base for collaboration. \nMicrosoft 365 Agents Toolkit integrates with Azure OpenAI and Teams AI Library to streamline copilot development and offer unique Teams-based capabilities. \nExplore [Teams AI Library](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/teams%20conversational%20ai/teams-conversation-ai-overview) and [Azure OpenAI Service](https://learn.microsoft.com/en-us/azure/ai-services/openai/overview)",
642-
643633
"teamstoolkit.walkthroughs.buildIntelligentApps.buildCustomCopilot.title": "Build Custom Engine Agent",
644634
"teamstoolkit.walkthroughs.buildIntelligentApps.buildCustomCopilot.description": "Build an AI agent bot for common tasks or an intelligent chatbot to answer specific questions\n[Build a Basic AI Chatbot](command:fx-extension.createFromWalkthrough?%5B%22WalkThrough%22%2C%20%7B%22capabilities%22%3A%20%22custom-copilot-basic%22%2C%20%22project-type%22%3A%20%22custom-copilot-type%22%7D%5D)\n[Build an AI Agent](command:fx-extension.createFromWalkthrough?%5B%22WalkThrough%22%2C%20%7B%22capabilities%22%3A%20%22custom-copilot-agent%22%2C%20%22project-type%22%3A%20%22custom-copilot-type%22%7D%5D)\n[Build a Bot to Chat with Your Data](command:fx-extension.createFromWalkthrough?%5B%22WalkThrough%22%2C%20%7B%22capabilities%22%3A%20%22custom-copilot-rag%22%2C%20%22project-type%22%3A%20%22custom-copilot-type%22%7D%5D)",
645-
646635
"teamstoolkit.walkthroughs.buildIntelligentApps.intelligentAppResources.title": "Resources",
647636
"teamstoolkit.walkthroughs.buildIntelligentApps.intelligentAppResources.description": "Explore these resources to build intelligent apps and enhance your development projects\n🗒️ [Generative AI for Beginners](https://github.com/microsoft/generative-ai-for-beginners/tree/main)\n✨ [Retrieval Augmented Generation (RAG)](https://learn.microsoft.com/en-us/azure/search/retrieval-augmented-generation-overview)\n📚 [AI Learning and Community Hub](https://learn.microsoft.com/en-us/ai/)",
648637
"teamstoolkit.m365.needSignIn.message": "You need to sign in your Microsoft 365 account.",
@@ -654,5 +643,11 @@
654643
"teamstoolkit.mcpUtils.setupMcpServer.successMessage": "M365 Agents Toolkit MCP server configured successfully!",
655644
"teamstoolkit.mcpUtils.setupMcpServer.errorMessage": "Unable to configure M365 Agents Toolkit MCP server. Error: %s",
656645
"teamstoolkit.handlers.openWorkspaceMCPConfigNotification": "Declarative agent project successfully created with a MCP wrapped. You can now start the MCP server from CodeLens button \"Start\" or customize your MCP server in .vscode/mcp.json file.\nTo fetch tools from MCP server, click \"ATK: Update Action with MCP\" from the CodeLens or Command Palatte.",
657-
"teamstoolkit.commands.updateActionWithMCP.title": "Fetch action from MCP"
646+
"teamstoolkit.commands.updateActionWithMCP.title": "Fetch action from MCP",
647+
"teamstoolkit.MCP.FileNotFound": "MCP configuration file not found in .vscode/mcp.json. Please ensure you have set up the MCP server.",
648+
"teamstoolkit.MCP.ContentInvalid": "MCP configuration file content is invalid. Please ensure the content in .vscode/mcp.json is correct.",
649+
"teamstoolkit.MCP.ServerNotFound": "No MCP server found in the MCP file.",
650+
"teamstoolkit.MCP.NameOrServerUrlMissing": "MCP name or server URL is missing.",
651+
"teamstoolkit.MCP.ToolsNotFound": "No tools found for the MCP server. Please run the server first.",
652+
"teamstoolkit.MCP.SelectServerFailed": "Failed to select MCP server."
658653
}

packages/vscode-extension/src/config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ export class ConfigManager {
2929
ConfigurationKey.BicepEnvCheckerEnable,
3030
false
3131
).toString();
32+
process.env[FeatureFlags.MCPForDA.name] = this.getConfiguration(
33+
ConfigurationKey.EnableMCPforDA,
34+
true
35+
).toString();
3236
process.env[FeatureFlags.CEAEnabled.name] = this.getConfiguration(
3337
ConfigurationKey.EnableCEA,
3438
false

packages/vscode-extension/src/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export const CONFIGURATION_PREFIX = "M365AgentsToolkit";
44
export enum ConfigurationKey {
55
BicepEnvCheckerEnable = "prerequisiteCheck.bicep",
66
LogLevel = "logLevel",
7+
EnableMCPforDA = "enableDeclarativeAgentMCPSupport",
78
EnableCEA = "enableLaunchAgentForTeamsInCopilot",
89
EnableDAMetaOS = "enableDeclarativeAgentInOfficeAddIn",
910
EnableCFShortcutMetaOS = "enableCustomFunctionShortcutInOfficeAddIn",

packages/vscode-extension/src/error/error.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,9 @@ export enum ExtensionErrors {
5757
DefaultAppPackageNotExistsError = "DefaultAppPackageNotExistsError",
5858
DevTunnelStartError = "DevTunnelStartError",
5959
LaunchTeamsDesktopClientError = "LaunchTeamsDesktopClientError",
60+
MCPFileNotFound = "MCPFileNotFound",
61+
MCPContentInvalid = "MCPContentInvalid",
62+
MCPServerNotFound = "MCPServerNotFound",
63+
MCPNameOrServerUrlMissing = "MCPNameOrServerUrlMissing",
64+
MCPToolsNotFound = "MCPToolsNotFound",
6065
}

packages/vscode-extension/src/handlers/updateActionWithMCP.ts

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import axios from "axios";
1818
import { runCommand } from "./sharedOpts";
1919
import { VS_CODE_UI } from "../qm/vsc_ui";
2020
import * as parser from "jsonc-parser";
21+
import { getDefaultString, localize } from "../utils/localizeUtils";
22+
import { ExtensionErrors } from "../error/error";
2123

2224
function sanitizeMCPName(name: string): string {
2325
// Replace special characters except "-" with "_", but if two special characters are adjacent,
@@ -41,25 +43,42 @@ export async function updateActionWithMCP(args?: any[]): Promise<Result<any, FxE
4143
if (!mcpName && !server) {
4244
const mcpFile = path.join(inputs.projectPath!, ".vscode", "mcp.json");
4345
if (!fs.pathExistsSync(mcpFile)) {
44-
void vscode.window.showErrorMessage("MCP file not found.");
45-
return err(new UserError("da-mcp", "MCPFileNotFound", "MCP file not found"));
46+
void vscode.window.showErrorMessage(localize("teamstoolkit.MCP.FileNotFound"));
47+
return err(
48+
new UserError(
49+
"da-mcp",
50+
ExtensionErrors.MCPFileNotFound,
51+
getDefaultString("teamstoolkit.MCP.FileNotFound"),
52+
localize("teamstoolkit.MCP.FileNotFound")
53+
)
54+
);
4655
}
4756
// const mcpContent = await fs.readJSON(mcpFile);
4857
const mcpOriginalContent = fs.readFileSync(mcpFile, "utf-8");
4958
const mcpContent = parser.parse(mcpOriginalContent);
5059
if (!mcpContent || !mcpContent.servers) {
51-
void vscode.window.showErrorMessage(
52-
"MCP content is invalid. Please make sure url property exists in the MCP file."
60+
void vscode.window.showErrorMessage(localize("teamstoolkit.MCP.ContentInvalid"));
61+
return err(
62+
new UserError(
63+
"da-mcp",
64+
ExtensionErrors.MCPContentInvalid,
65+
getDefaultString("teamstoolkit.MCP.ContentInvalid"),
66+
localize("teamstoolkit.MCP.ContentInvalid")
67+
)
5368
);
54-
return err(new UserError("da-mcp", "MCPContentInvalid", "MCP content is invalid"));
5569
}
5670

5771
// TODO: support multiple MCP servers
5872
const mcpNames = Object.keys(mcpContent.servers);
5973
if (mcpNames.length === 0) {
60-
void vscode.window.showErrorMessage("No MCP server found in the MCP file.");
74+
void vscode.window.showErrorMessage(localize("teamstoolkit.MCP.ServerNotFound"));
6175
return err(
62-
new UserError("da-mcp", "MCPServerNotFound", "No MCP server found in the MCP file")
76+
new UserError(
77+
"da-mcp",
78+
ExtensionErrors.MCPServerNotFound,
79+
getDefaultString("teamstoolkit.MCP.ServerNotFound"),
80+
localize("teamstoolkit.MCP.ServerNotFound")
81+
)
6382
);
6483
}
6584
if (mcpNames.length === 1) {
@@ -77,17 +96,24 @@ export async function updateActionWithMCP(args?: any[]): Promise<Result<any, FxE
7796
};
7897
const result = await VS_CODE_UI.selectOption(mcpNameSelection);
7998
if (result.isErr()) {
80-
void vscode.window.showErrorMessage(result.error.message || "Failed to select MCP server");
99+
void vscode.window.showErrorMessage(
100+
result.error.message || localize("teamstoolkit.MCP.SelectServerFailed")
101+
);
81102
return err(result.error);
82103
}
83104
const originalMcpName = result.value.result as string;
84105
mcpName = originalMcpName.replace(/[^a-zA-Z0-9]/g, "").substring(0, 10);
85106
server = mcpContent.servers[originalMcpName].url;
86107
}
87108
} else if (!mcpName || !server) {
88-
void vscode.window.showErrorMessage("MCP name or server URL is missing");
109+
void vscode.window.showErrorMessage(localize("teamstoolkit.MCP.NameOrServerUrlMissing"));
89110
return err(
90-
new UserError("da-mcp", "MCPNameOrServerUrlMissing", "MCP name or server URL is missing")
111+
new UserError(
112+
"da-mcp",
113+
ExtensionErrors.MCPNameOrServerUrlMissing,
114+
getDefaultString("teamstoolkit.MCP.NameOrServerUrlMissing"),
115+
localize("teamstoolkit.MCP.NameOrServerUrlMissing")
116+
)
91117
);
92118
}
93119

@@ -109,15 +135,14 @@ export async function updateActionWithMCP(args?: any[]): Promise<Result<any, FxE
109135
};
110136
});
111137
if (tools.length === 0) {
112-
void vscode.window.showErrorMessage(
113-
"No tools found for the MCP server. Please run the server first."
114-
);
138+
void vscode.window.showErrorMessage(localize("teamstoolkit.MCP.ToolsNotFound"));
115139
// Return an error result
116140
return err(
117141
new UserError(
118142
"da-mcp",
119-
"MCPToolsNotFound",
120-
"No tools found for the MCP server. Please run the server first."
143+
ExtensionErrors.MCPToolsNotFound,
144+
getDefaultString("teamstoolkit.MCP.ToolsNotFound"),
145+
localize("teamstoolkit.MCP.ToolsNotFound")
121146
)
122147
);
123148
}

packages/vscode-extension/test/handlers/updateActionWithMCP.test.ts

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ describe("updateActionWithMCP", () => {
106106
const result = await updateActionWithMCP(args);
107107

108108
chai.assert.isTrue(result.isErr());
109-
chai.assert.equal(result._unsafeUnwrapErr().message, "MCP name or server URL is missing");
110109
});
111110

112111
it("should return error when URL is provided but server name is missing", async () => {
@@ -115,7 +114,6 @@ describe("updateActionWithMCP", () => {
115114
const result = await updateActionWithMCP(args);
116115

117116
chai.assert.isTrue(result.isErr());
118-
chai.assert.equal(result._unsafeUnwrapErr().message, "MCP name or server URL is missing");
119117
});
120118
});
121119

@@ -126,11 +124,6 @@ describe("updateActionWithMCP", () => {
126124
const result = await updateActionWithMCP();
127125

128126
chai.assert.isTrue(result.isErr());
129-
chai.assert.equal(result._unsafeUnwrapErr().message, "MCP file not found");
130-
sinon.assert.calledWithExactly(
131-
vscode.window.showErrorMessage as sinon.SinonStub,
132-
"MCP file not found."
133-
);
134127
});
135128

136129
it("should return error when MCP file has invalid content", async () => {
@@ -142,7 +135,6 @@ describe("updateActionWithMCP", () => {
142135
const result = await updateActionWithMCP();
143136

144137
chai.assert.isTrue(result.isErr());
145-
chai.assert.equal(result._unsafeUnwrapErr().message, "MCP content is invalid");
146138
});
147139

148140
it("should return error when no MCP servers found", async () => {
@@ -154,7 +146,6 @@ describe("updateActionWithMCP", () => {
154146
const result = await updateActionWithMCP();
155147

156148
chai.assert.isTrue(result.isErr());
157-
chai.assert.equal(result._unsafeUnwrapErr().message, "No MCP server found in the MCP file");
158149
});
159150

160151
it("should process single MCP server automatically", async () => {
@@ -261,14 +252,6 @@ describe("updateActionWithMCP", () => {
261252
const result = await updateActionWithMCP(args);
262253

263254
chai.assert.isTrue(result.isErr());
264-
chai.assert.equal(
265-
result._unsafeUnwrapErr().message,
266-
"No tools found for the MCP server. Please run the server first."
267-
);
268-
sinon.assert.calledWithExactly(
269-
vscode.window.showErrorMessage as sinon.SinonStub,
270-
"No tools found for the MCP server. Please run the server first."
271-
);
272255
});
273256

274257
it("should filter and transform tools correctly", async () => {
@@ -456,7 +439,6 @@ describe("updateActionWithMCP", () => {
456439
const result = await updateActionWithMCP(undefined);
457440

458441
chai.assert.isTrue(result.isErr());
459-
chai.assert.equal(result._unsafeUnwrapErr().message, "MCP file not found");
460442
});
461443

462444
it("should handle empty args array", async () => {
@@ -466,7 +448,6 @@ describe("updateActionWithMCP", () => {
466448
const result = await updateActionWithMCP([]);
467449

468450
chai.assert.isTrue(result.isErr());
469-
chai.assert.equal(result._unsafeUnwrapErr().message, "MCP file not found");
470451
});
471452

472453
it("should handle tools with missing name parts", async () => {

0 commit comments

Comments
 (0)