Skip to content

Conversation

@echapmanFromBunnings
Copy link

@echapmanFromBunnings echapmanFromBunnings commented Nov 18, 2025

Introduces a Headers property to HostedMcpServerTool for specifying additional request headers. Updates OpenAIResponsesChatClient to pass these headers when creating MCP tools and adds unit tests to verify header roundtripping.

Microsoft Reviewers: Open in CodeFlow

Introduces a Headers property to HostedMcpServerTool for specifying additional request headers. Updates OpenAIResponsesChatClient to pass these headers when creating MCP tools and adds unit tests to verify header roundtripping.
Copilot AI review requested due to automatic review settings November 18, 2025 15:13
@echapmanFromBunnings echapmanFromBunnings requested a review from a team as a code owner November 18, 2025 15:13
@github-actions github-actions bot added the area-ai Microsoft.Extensions.AI libraries label Nov 18, 2025
Copilot finished reviewing on behalf of echapmanFromBunnings November 18, 2025 15:16
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 adds support for custom HTTP headers in HostedMcpServerTool, enabling users to specify additional request headers when communicating with remote MCP servers.

  • Introduces a Headers property of type IDictionary<string, string>? to the HostedMcpServerTool class
  • Updates OpenAIResponsesChatClient to pass these headers to both variants of ResponseTool.CreateMcpTool()
  • Adds roundtrip tests to verify the Headers property can be set, retrieved, and cleared

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/Libraries/Microsoft.Extensions.AI.Abstractions/Tools/HostedMcpServerTool.cs Adds the nullable Headers property with XML documentation
src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIResponsesChatClient.cs Passes mcpTool.Headers parameter to both CreateMcpTool overloads (URI-based and connector ID-based)
test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Tools/HostedMcpServerToolTests.cs Adds assertions to verify Headers can be set to a dictionary, retrieved, and reset to null

@echapmanFromBunnings
Copy link
Author

@stephentoub any chance I can get an assignee on this one to help with getting it through? This is #7049 with the reverts.

@stephentoub stephentoub requested a review from jozkee November 25, 2025 15:54
@jozkee
Copy link
Member

jozkee commented Dec 1, 2025

Thanks for your PR @echapmanFromBunnings.

We originally pursued this API shape because OpenAI supported headers in the request, while Anthropic only supported passing an auth token. I initially took the broader approach and used a dictionary in HostedMcpServerTool since it could work with both providers.

Later, OpenAI added support for passing the token in the same way Anthropic does, which suggested to me that there might not be many use cases for headers beyond auth and that we don't need a headers dictionary in the class.

For the sake of doing an informed decision, could you share more about what kinds of headers you need to pass to your MCP server? If we bring the headers dictionary back, we need to reconsider if we want to keep AuthorizationToken, and if we do, verify how it interacts with the dictionary.

@echapmanFromBunnings
Copy link
Author

echapmanFromBunnings commented Dec 1, 2025

Hi @jozkee
We provide contextual headers to the MCP server, which are configured during agent registration. These headers play a key role in defining the structure of the MCP server we use, as outlined in the following resource:
https://github.com/echapmanFromBunnings/mcp.extensions

Since the MCP server essentially operates as an HTTP client, couldn’t we simply allow these headers to leverage the underlying protocol? In this context, headers are not being used for authentication, so encountering a header should not imply it is solely for that purpose. These are two distinct concerns and should be treated as such.

public HostedMcpServerToolApprovalMode? ApprovalMode { get; set; }

/// <summary>
/// Gets or sets additional headers to include in requests to the remote MCP server.
Copy link
Member

@jozkee jozkee Dec 2, 2025

Choose a reason for hiding this comment

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

From the previous version of this:

Suggested change
/// Gets or sets additional headers to include in requests to the remote MCP server.
/// Gets or sets the HTTP headers that the AI service should use when calling the remote MCP server.

Copy link
Member

Choose a reason for hiding this comment

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

Do we want to add <remarks> mentioning that some providers may return an error if both AuthorizationToken and an "authorization" header are specified? This is the case for OpenAI.

$ curl https://api.openai.com/v1/responses \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
  "model": "gpt-4o-mini",
  "tools": [
    {
      "type": "mcp",
      "server_label": "gh",
      "server_url": "https://api.githubcopilot.com/mcp",
      "authorization": "github_pat_123",
      "headers": { "Authorization": "Bearer github_pat_123" }
    }
  ],
  "input": "What tools are available?"
}'
{
  "error": {
    "message": "Cannot specify both 'authorization' parameter and 'Authorization' header.",
    "type": "invalid_request_error",
    "param": "headers",
    "code": null
  }
}

url,
mcpTool.AuthorizationToken,
mcpTool.ServerDescription) :
mcpTool.ServerDescription, mcpTool.Headers) :
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
mcpTool.ServerDescription, mcpTool.Headers) :
mcpTool.ServerDescription,
mcpTool.Headers) :

new McpToolConnectorId(mcpTool.ServerAddress),
mcpTool.AuthorizationToken,
mcpTool.ServerDescription);
mcpTool.ServerDescription, mcpTool.Headers);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
mcpTool.ServerDescription, mcpTool.Headers);
mcpTool.ServerDescription,
mcpTool.Headers);

@jozkee
Copy link
Member

jozkee commented Dec 2, 2025

CI errors are about CompatibilitySuppression.xml since we are bringing the property back.

.dotnet\sdk\10.0.100\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.ApiCompat.ValidatePackage.targets(39,5): error : (NETCORE_ENGINEERING_TELEMETRY=Build) [Baseline] CP0002 (Target: 'M:Microsoft.Extensions.AI.HostedMcpServerTool.get_Headers', Left: 'lib/net462/Microsoft.Extensions.AI.Abstractions.dll', Right: 'lib/net462/Microsoft.Extensions.AI.Abstractions.dll')
.dotnet\sdk\10.0.100\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.ApiCompat.ValidatePackage.targets(39,5): error : (NETCORE_ENGINEERING_TELEMETRY=Build) [Baseline] CP0002 (Target: 'M:Microsoft.Extensions.AI.HostedMcpServerTool.set_Headers(System.Collections.Generic.IDictionary{System.String,System.String})', Left: 'lib/net462/Microsoft.Extensions.AI.Abstractions.dll', Right: 'lib/net462/Microsoft.Extensions.AI.Abstractions.dll')

I suspect we need to remove them from:

<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Extensions.AI.HostedMcpServerTool.get_Headers</Target>
<Left>lib/net462/Microsoft.Extensions.AI.Abstractions.dll</Left>
<Right>lib/net462/Microsoft.Extensions.AI.Abstractions.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Extensions.AI.HostedMcpServerTool.get_Url</Target>
<Left>lib/net462/Microsoft.Extensions.AI.Abstractions.dll</Left>
<Right>lib/net462/Microsoft.Extensions.AI.Abstractions.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Microsoft.Extensions.AI.HostedMcpServerTool.set_Headers(System.Collections.Generic.IDictionary{System.String,System.String})</Target>
<Left>lib/net462/Microsoft.Extensions.AI.Abstractions.dll</Left>
<Right>lib/net462/Microsoft.Extensions.AI.Abstractions.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>

cc @joperezr

Deleted baseline suppressions for the Headers property and its setter in HostedMcpServerTool from CompatibilitySuppressions.xml.
Expanded XML documentation for the Headers property in HostedMcpServerTool to clarify usage and behavior. Minor formatting adjustments in OpenAIResponsesChatClient for MCP tool creation calls.
@echapmanFromBunnings
Copy link
Author

Addressed all PR comments, and added extensive documents on that headers prop @jozkee
I went with could, instead of should, as it's an optional implementation.

Deleted baseline suppressions for get_Headers and set_Headers members of HostedMcpServerTool across net8.0, net9.0, and netstandard2.0. This likely reflects removal or resolution of related compatibility issues.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-ai Microsoft.Extensions.AI libraries

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants