diff --git a/dotnet/agent-framework/sample-agent/Agent/MyAgent.cs b/dotnet/agent-framework/sample-agent/Agent/MyAgent.cs index dbc9feec..5196708e 100644 --- a/dotnet/agent-framework/sample-agent/Agent/MyAgent.cs +++ b/dotnet/agent-framework/sample-agent/Agent/MyAgent.cs @@ -361,14 +361,15 @@ await A365OtelWrapper.InvokeObservedAgentOperation( { await context.StreamingResponse.QueueInformativeUpdateAsync("Loading tools..."); - // For the bearer token (development) flow, pass the token as an override and - // use OboAuthHandlerName (or fall back to AgenticAuthHandlerName) as the handler. + // The SDK's token provider (AgenticMcpTokenProvider in production, + // DevMcpTokenProvider in dev) resolves per-server tokens automatically: + // - Dev: reads BEARER_TOKEN_ (V2) or BEARER_TOKEN (V1 fallback) + // - Prod: performs per-audience OBO exchange for each V2 server var handlerForMcp = !string.IsNullOrEmpty(authHandlerName) ? authHandlerName : OboAuthHandlerName ?? AgenticAuthHandlerName ?? string.Empty; - var tokenOverride = string.IsNullOrEmpty(authHandlerName) ? accessToken : null; - var a365Tools = await toolService.GetMcpToolsAsync(agentId, UserAuthorization, handlerForMcp, context, tokenOverride).ConfigureAwait(false); + var a365Tools = await toolService.GetMcpToolsAsync(agentId, UserAuthorization, handlerForMcp, context).ConfigureAwait(false); if (a365Tools != null && a365Tools.Count > 0) { diff --git a/dotnet/agent-framework/sample-agent/Properties/launchSettings.json b/dotnet/agent-framework/sample-agent/Properties/launchSettings.json new file mode 100644 index 00000000..7fc3ce75 --- /dev/null +++ b/dotnet/agent-framework/sample-agent/Properties/launchSettings.json @@ -0,0 +1,33 @@ +{ + "profiles": { + "Sample Agent": { + "commandName": "Project", + "launchBrowser": false, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "SKIP_TOOLING_ON_ERRORS": "true" + }, + "applicationUrl": "http://localhost:3978" + }, + "Sample Agent with Bearer Token Support": { + "commandName": "Project", + "launchBrowser": false, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "BEARER_TOKEN": "", + "SKIP_TOOLING_ON_ERRORS": "true" + }, + "applicationUrl": "http://localhost:3978" + }, + "Sample Agent with V2 Bearer Token Support": { + "commandName": "Project", + "launchBrowser": false, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "BEARER_TOKEN": "", + "SKIP_TOOLING_ON_ERRORS": "true" + }, + "applicationUrl": "http://localhost:3978" + } + } +} diff --git a/dotnet/agent-framework/sample-agent/appsettings.json b/dotnet/agent-framework/sample-agent/appsettings.json index ea668f2d..e935f1bf 100644 --- a/dotnet/agent-framework/sample-agent/appsettings.json +++ b/dotnet/agent-framework/sample-agent/appsettings.json @@ -1,4 +1,9 @@ { + // V2 MCP per-server dev tokens: set BEARER_TOKEN_ environment variables. + // Run: a365 develop get-token (writes these automatically for all configured servers) + // The SDK reads BEARER_TOKEN_ for each V2 server and falls back to BEARER_TOKEN for V1. + // Example for a server named "MailTools": BEARER_TOKEN_MAILTOOLS= + "AgentApplication": { "StartTypingTimer": false, "RemoveRecipientMention": false, diff --git a/dotnet/semantic-kernel/sample-agent/Agents/Agent365Agent.cs b/dotnet/semantic-kernel/sample-agent/Agents/Agent365Agent.cs index 49532d38..4032369b 100644 --- a/dotnet/semantic-kernel/sample-agent/Agents/Agent365Agent.cs +++ b/dotnet/semantic-kernel/sample-agent/Agents/Agent365Agent.cs @@ -56,12 +56,6 @@ public static async Task CreateA365AgentWrapper(Kernel kernel, IS return _agent; } - public static bool TryGetBearerTokenForDevelopment(out string? bearerToken) - { - bearerToken = Environment.GetEnvironmentVariable("BEARER_TOKEN"); - return !string.IsNullOrEmpty(bearerToken); - } - /// /// Checks if graceful fallback to bare LLM mode is enabled when MCP tools fail to load. /// This is only allowed in Development environment AND when SKIP_TOOLING_ON_ERRORS is explicitly set to "true". @@ -103,16 +97,11 @@ public async Task InitializeAgent365Agent(Kernel kernel, IServiceProvider servic try { - if (TryGetBearerTokenForDevelopment(out var bearerToken)) - { - // Development mode: Use bearer token from environment variable for simplified local testing - await toolService.AddToolServersToAgentAsync(kernel, userAuthorization, authHandlerName, turnContext, bearerToken); - } - else - { - // Production mode: Use standard authentication flow (Client Credentials, Managed Identity, or Federated Credentials) - await toolService.AddToolServersToAgentAsync(kernel, userAuthorization, authHandlerName, turnContext); - } + // The SDK's token provider (AgenticMcpTokenProvider in production, + // DevMcpTokenProvider in dev) resolves per-server tokens automatically: + // - Dev: reads BEARER_TOKEN_ (V2) or BEARER_TOKEN (V1 fallback) + // - Prod: performs per-audience OBO exchange for each V2 server + await toolService.AddToolServersToAgentAsync(kernel, userAuthorization, authHandlerName, turnContext); } catch (Exception ex) { diff --git a/dotnet/semantic-kernel/sample-agent/Properties/launchSettings.json b/dotnet/semantic-kernel/sample-agent/Properties/launchSettings.json index b8aa31d3..e88f6cd3 100644 --- a/dotnet/semantic-kernel/sample-agent/Properties/launchSettings.json +++ b/dotnet/semantic-kernel/sample-agent/Properties/launchSettings.json @@ -18,6 +18,16 @@ "SKIP_TOOLING_ON_ERRORS": "true" }, "applicationUrl": "https://localhost:64896;http://localhost:64897" + }, + "Sample Agent with V2 Bearer Token Support": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "BEARER_TOKEN": "", + "SKIP_TOOLING_ON_ERRORS": "true" + }, + "applicationUrl": "https://localhost:64896;http://localhost:64897" } } } \ No newline at end of file diff --git a/dotnet/semantic-kernel/sample-agent/appsettings.json b/dotnet/semantic-kernel/sample-agent/appsettings.json index e7d06efc..069677d5 100644 --- a/dotnet/semantic-kernel/sample-agent/appsettings.json +++ b/dotnet/semantic-kernel/sample-agent/appsettings.json @@ -14,6 +14,11 @@ "TenantId": "{{TenantId}}" }, + // V2 MCP per-server dev tokens: set BEARER_TOKEN_ environment variables. + // Run: a365 develop get-token (writes these automatically for all configured servers) + // The SDK reads BEARER_TOKEN_ for each V2 server and falls back to BEARER_TOKEN for V1. + // Example for a server named "MailTools": BEARER_TOKEN_MAILTOOLS= + "AgentApplication": { "StartTypingTimer": false, "RemoveRecipientMention": false,