Skip to content
Closed
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 @@ -21,12 +21,14 @@ public interface IMcpToolRegistrationService
/// This is the primary method that customers should use in orchestrators with full authentication context.
/// </summary>
/// <param name="agentClient">The PersistentAgentsClient instance.</param>
/// <param name="agentInstanceId">The ID of the agent instance.</param>
/// <param name="userAuthorization">User authorization context.</param>
/// <param name="authHandlerName">Authentication Handler Name for use with the UserAuthorization System</param>
/// <param name="turnContext">Turn context for the conversation.</param>
/// <param name="authToken">Optional auth token to access the MCP servers.</param>
Task AddToolServersToAgentAsync(
PersistentAgentsClient agentClient,
string agentInstanceId,
UserAuthorization userAuthorization,
string authHandlerName,
ITurnContext turnContext,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,19 @@ public void AddToolServersToAgent(
}
}

/// <inheritdoc />
/// <summary>
/// Add new MCP servers to the agent by updating the PersistentAgentsClient asynchronously.
/// </summary>
/// <param name="agentClient">PersistentAgentsClient instance for the agent.</param>
/// <param name="agentInstanceId">The ID of the agent instance.</param>
/// <param name="userAuthorization">User authorization information.</param>
/// <param name="authHandlerName">The name of the authentication handler.</param>
/// <param name="turnContext">Turn context for the current request.</param>
/// <param name="authToken">Authentication token for MCP server access.</param>
/// <exception cref="ArgumentNullException"></exception>
public async Task AddToolServersToAgentAsync(
PersistentAgentsClient agentClient,
string agentInstanceId,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have both TurnContext and auth token here, you should use this instead of adding another parameter and letting the caller handle it:

            // resolve agent identity from context or token. 
            string agenticAppId = Runtime.Utils.Utility.ResolveAgentIdentity(turnContext, authToken);

UserAuthorization userAuthorization,
string authHandlerName,
ITurnContext turnContext,
Expand All @@ -110,23 +120,21 @@ public async Task AddToolServersToAgentAsync(
authToken = await AgenticAuthenticationService.GetAgenticUserTokenAsync(userAuthorization, authHandlerName, turnContext, _configuration).ConfigureAwait(false);
}

var agenticAppId = turnContext.Activity.Recipient.AgenticAppId;

try
{
// Perform the (potentially async) work in a dedicated task to keep this synchronous signature.
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment states "keep this synchronous signature" but the method signature is actually async (AddToolServersToAgentAsync). This comment appears to be outdated or incorrect. Consider removing or updating the comment to accurately reflect that this is an async method that is calling GetAwaiter().GetResult() on another async operation.

Suggested change
// Perform the (potentially async) work in a dedicated task to keep this synchronous signature.

Copilot uses AI. Check for mistakes.
var (toolDefinitions, toolResources) = GetMcpToolDefinitionsAndResourcesAsync(agenticAppId, authToken ?? string.Empty, turnContext).GetAwaiter().GetResult();
var (toolDefinitions, toolResources) = GetMcpToolDefinitionsAndResourcesAsync(agentInstanceId, authToken ?? string.Empty, turnContext).GetAwaiter().GetResult();
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using GetAwaiter().GetResult() in an async method defeats the purpose of async/await and can lead to potential deadlocks. Since this method is already async, consider using await instead: var (toolDefinitions, toolResources) = await GetMcpToolDefinitionsAndResourcesAsync(agentInstanceId, authToken ?? string.Empty, turnContext).ConfigureAwait(false);

Suggested change
var (toolDefinitions, toolResources) = GetMcpToolDefinitionsAndResourcesAsync(agentInstanceId, authToken ?? string.Empty, turnContext).GetAwaiter().GetResult();
var (toolDefinitions, toolResources) = await GetMcpToolDefinitionsAndResourcesAsync(agentInstanceId, authToken ?? string.Empty, turnContext).ConfigureAwait(false);

Copilot uses AI. Check for mistakes.

agentClient.Administration.UpdateAgent(
agenticAppId,
agentInstanceId,
tools: toolDefinitions,
toolResources: toolResources);

_logger.LogInformation("Successfully configured {Count} MCP tool servers for agent", toolDefinitions.Count);
}
catch (Exception ex)
{
_logger.LogError(ex, "Unhandled failure during MCP tool registration workflow for agent user {agenticAppId}", agenticAppId);
_logger.LogError(ex, "Unhandled failure during MCP tool registration workflow for agent user {agentInstanceId}", agentInstanceId);
throw;
}
}
Expand Down