Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 30, 2026

Summary

This PR consolidates MCP server tool approval flow by making McpServerToolCallContent and McpServerToolResultContent inherit from FunctionCallContent and FunctionResultContent respectively, instead of having separate approval types.

Changes

  • Extend function content types: Made McpServerToolCallContent extend FunctionCallContent and McpServerToolResultContent extend FunctionResultContent
  • Remove specialized approval types: Deleted McpServerToolApprovalRequestContent and McpServerToolApprovalResponseContent classes - MCP approvals now use the existing FunctionApprovalRequestContent and FunctionApprovalResponseContent
  • Add invocation flag: Added InvocationRequired property to FunctionCallContent (defaults to true). For McpServerToolCallContent, this defaults to false since MCP tool calls are informational
  • Update OpenAI integration: Modified OpenAIResponsesChatClient to work with the unified approval model
  • Add API compatibility suppressions: Documented breaking changes in CompatibilitySuppressions.xml

Impact

This reduces complexity by reusing existing function call/result abstractions rather than maintaining parallel MCP-specific approval types. The approval mechanism now works consistently for both regular function calls and MCP server tool calls.

Original prompt

Create a new pull request in dotnet/extensions with:

  • Base branch: main
  • Head branch: copilot/update-mcp-server-tool-invocation

User explicitly wants a new PR (do not attempt to update/retarget existing agent PR #7244).

Use an appropriate PR title/description derived from the branch name (update MCP server tool invocation). No additional code changes requested—just open the PR.

This pull request was created from Copilot chat.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Microsoft Reviewers: Open in CodeFlow

Copilot AI changed the title [WIP] Update MCP server tool invocation Simplify MCP server tool invocation approval mechanism Jan 30, 2026
Copilot AI requested a review from jozkee January 30, 2026 07:19
@jozkee jozkee marked this pull request as ready for review January 30, 2026 07:19
@jozkee jozkee requested a review from a team as a code owner January 30, 2026 07:19
Copilot AI review requested due to automatic review settings January 30, 2026 07:19
@jozkee jozkee changed the title Simplify MCP server tool invocation approval mechanism Update MCP contents to extend Function contents Jan 30, 2026
@jozkee jozkee requested a review from stephentoub January 30, 2026 07:21
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR simplifies the MCP server tool invocation approval mechanism by consolidating approval types. Instead of having separate McpServerToolApprovalRequestContent and McpServerToolApprovalResponseContent classes, it makes McpServerToolCallContent and McpServerToolResultContent inherit from FunctionCallContent and FunctionResultContent respectively, and reuses the existing FunctionApprovalRequestContent and FunctionApprovalResponseContent for MCP approvals.

Changes:

  • Removed McpServerToolApprovalRequestContent and McpServerToolApprovalResponseContent classes
  • Made McpServerToolCallContent extend FunctionCallContent and McpServerToolResultContent extend FunctionResultContent
  • Added InvocationRequired property to FunctionCallContent (defaults to true, set to false for MCP tools)
  • Updated OpenAI integration and tests to work with the unified approval model
  • Added API compatibility suppressions for breaking changes

Reviewed changes

Copilot reviewed 25 out of 25 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
McpServerToolApprovalRequestContent.cs Deleted - approval now handled through FunctionApprovalRequestContent
McpServerToolApprovalResponseContent.cs Deleted - approval now handled through FunctionApprovalResponseContent
McpServerToolCallContent.cs Now extends FunctionCallContent, inherits Name, CallId, and Arguments properties, sets InvocationRequired = false
McpServerToolResultContent.cs Now extends FunctionResultContent, simplified to only add CallId through base constructor
FunctionCallContent.cs Added InvocationRequired property and polymorphic JSON serialization for McpServerToolCallContent
FunctionResultContent.cs Added polymorphic JSON serialization for McpServerToolResultContent
UserInputRequestContent.cs Removed McpServerToolApprovalRequestContent from JSON derived types
UserInputResponseContent.cs Removed McpServerToolApprovalResponseContent from JSON derived types
AIContent.cs Updated comments to reflect removed types
OpenAIResponsesChatClient.cs Updated to create FunctionApprovalRequestContent wrapping McpServerToolCallContent instead of separate MCP approval types, updated error handling to use Result property
OpenAIJsonContext.cs Removed IReadOnlyDictionary<string, object?> serialization (now uses IDictionary)
AIJsonUtilities.Defaults.cs Removed MCP approval types from JSON serialization registration
FunctionInvokingChatClient.cs Updated approval filtering to check InvocationRequired property on function calls
CompatibilitySuppressions.xml Added suppressions for removed types and changed properties across all target frameworks
Test files Updated to use new API, added tests for mixed MCP/function approval scenarios, fixed namespace

@stephentoub
Copy link
Member

@copilot please revise the PR summary based on the current state of the PR

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 30, 2026

@copilot please revise the PR summary based on the current state of the PR

Updated the PR summary to accurately reflect the current state of the PR. The summary now correctly describes that McpServerToolCallContent and McpServerToolResultContent extend FunctionCallContent and FunctionResultContent respectively, and that InvocationRequired is only on FunctionCallContent (not FunctionResultContent).

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated no new comments.

Output = [mtci.Error is not null ?
new ErrorContent(mtci.Error.ToString()) :
new TextContent(mtci.ToolOutput)],
Result = mtci.Error ?? (object)mtci.ToolOutput,
Copy link
Member

Choose a reason for hiding this comment

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

I think this is not a big concern for McpServerToolResultContent because it's content intended for the LLM and just included in the messages for information reasons.

There's no clear way to identify results as errors. Using ErrorContent was also somewhat of a bug because OpenAI's McpToolCallItem.Error is BinaryData so we were turning that into string in order to pack it in ErrorContent.

Copy link
Member

Choose a reason for hiding this comment

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

Using ErrorContent was also somewhat of a bug

Can you elaborate? McpToolCallItem.Error for whatever reason is modeled in the client as BinaryData, but it's a string in OpenAI's docs:
https://platform.openai.com/docs/api-reference/responses/object#responses-object-output-mcp_tool_call-error
which just means the client library is choosing to represent it as bytes.

Copy link
Member

Choose a reason for hiding this comment

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

OpenAI docs are wrong, in my testing, error is returned as object. See also openai/openai-dotnet#596 (comment).

Copy link
Member

Choose a reason for hiding this comment

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

If it's a json object that can still be represented as a string. The binary data is effectively just a utf8 string.

Copy link
Member

@jozkee jozkee Jan 31, 2026

Choose a reason for hiding this comment

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

OK, that's fair. FICC sets Result as "Error: Function failed" when an AIFunction throws, do we want to

  1. align this with that and return $"Error: {mtci.Error.ToString()}" or
  2. Keep wrapping with ErrorContent to keep fidelity with previous behavior?

If we go with the second, I don't think we would want to change FICC to wrap errors in ErrorContent since it may be too disruptive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants