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
9 changes: 5 additions & 4 deletions dotnet/agent-framework/sample-agent/Agent/MyAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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_<SERVER_NAME> (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)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
5 changes: 5 additions & 0 deletions dotnet/agent-framework/sample-agent/appsettings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
{
// V2 MCP per-server dev tokens: set BEARER_TOKEN_<UPPERCASE_SERVER_NAME> environment variables.
// Run: a365 develop get-token (writes these automatically for all configured servers)
// The SDK reads BEARER_TOKEN_<SERVER_NAME> for each V2 server and falls back to BEARER_TOKEN for V1.
// Example for a server named "MailTools": BEARER_TOKEN_MAILTOOLS=<token>

"AgentApplication": {
"StartTypingTimer": false,
"RemoveRecipientMention": false,
Expand Down
21 changes: 5 additions & 16 deletions dotnet/semantic-kernel/sample-agent/Agents/Agent365Agent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,6 @@ public static async Task<Agent365Agent> CreateA365AgentWrapper(Kernel kernel, IS
return _agent;
}

public static bool TryGetBearerTokenForDevelopment(out string? bearerToken)
{
bearerToken = Environment.GetEnvironmentVariable("BEARER_TOKEN");
return !string.IsNullOrEmpty(bearerToken);
}

/// <summary>
/// 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".
Expand Down Expand Up @@ -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_<SERVER_NAME> (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)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
}
5 changes: 5 additions & 0 deletions dotnet/semantic-kernel/sample-agent/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
"TenantId": "{{TenantId}}"
},

// V2 MCP per-server dev tokens: set BEARER_TOKEN_<UPPERCASE_SERVER_NAME> environment variables.
// Run: a365 develop get-token (writes these automatically for all configured servers)
// The SDK reads BEARER_TOKEN_<SERVER_NAME> for each V2 server and falls back to BEARER_TOKEN for V1.
// Example for a server named "MailTools": BEARER_TOKEN_MAILTOOLS=<token>

"AgentApplication": {
"StartTypingTimer": false,
"RemoveRecipientMention": false,
Expand Down
Loading