Currently as far as I'm aware of, I'm not able use function calling with OpenAI responses api.
My issue is I believe, that function calling calls response from tool as single response:
Using functionCalling:
[
{
"role": "system",
"contents": [
{
"$type": "text",
"text": "You are friendly assistant"
}
]
},
{
"role": "user",
"contents": [
{
"$type": "text",
"text": "Where is my package PKG00000012"
}
]
}
].
response contains call to mcp function and the call API:
[
{
"role": "tool",
"contents": [
{
"$type": "functionResult",
"result": {
"$type": "text",
"text": "{\"ok\":true,\"packageid\":\"PKG00000012\",\"status\":\"unknown\",\"message\":\"No tracking data available for this package.\"}"
},
"callId": "call_erfK17HEAyoHlboIri5R4l7L"
}
]
}
]
then server responds with bad gateway exception.
I need to use my custom implementation:
var response = await _chatClient.GetResponseAsync(input, chatOptions);
_logger.LogDebug("Hub response: {Text}", response);
input.AddRange(response.Messages);
var calls = response.Messages
.SelectMany(m => m.Contents)
.OfType<FunctionCallContent>()
.ToList();
if (calls.Count > 0)
{
var results = new List<AIContent>();
foreach (var call in calls)
{
_logger.LogInformation("Calling tool {Name} with args {Args}", call.Name, call.Arguments);
try
{
// Call MCP tool directly — no broken IChatClient translation involved
var mcpArgs = call.Arguments?
.ToDictionary(k => k.Key, v => v.Value)
?? [];
var mcpResult = await _mcpClient!.CallToolAsync(call.Name, mcpArgs);
var resultText = mcpResult.Content.FirstOrDefault()?.ToString() ?? "";
_logger.LogInformation("Tool {Name} result: {Result}", call.Name, resultText);
results.Add(new FunctionResultContent(call.CallId, mcpResult.Content));
}
catch (Exception ex)
{
_logger.LogError(ex, "Tool {Name} failed", call.Name);
results.Add(new FunctionResultContent(call.CallId, $"Error: {ex.Message}"));
}
}
// Add tool results as a single tool-role message
input.Add(new ChatMessage(ChatRole.Tool, results));
return await RunInternalAsync(input, tools);
which produces following input
[
{
"role": "system",
"contents": [
{
"$type": "text",
"text": "You are friendly assistant "
}
]
},
{
"role": "user",
"contents": [
{
"$type": "text",
"text": "Where is my package PKG00000012"
}
]
},
{
"createdAt": "2026-03-19T10:06:27+00:00",
"role": "assistant",
"contents": [
{
"$type": "reasoning",
"text": "...",
"protectedData": "..."
},
{
"$type": "functionCall",
"name": "get_package_status",
"arguments": {
"packageId": "PKG00000012"
},
"informationalOnly": false,
"callId": "call_EwvsSSC2mQXbRUTn68OZAGty"
}
]
},
{
"role": "tool",
"contents": [
{
"$type": "functionResult",
"result": [
{
"type": "text",
"text": "{\"ok\":true,\"packageid\":\"PKG00000012\",\"status\":\"unknown\",\"message\":\"No tracking data available for this package.\"}"
}
],
"callId": "call_EwvsSSC2mQXbRUTn68OZAGty"
}
]
}
]
and this one is properly consumed and gives success result:
I checked, package PKG00000012 shows status "unknown" - no tracking data available.
Is there any way to use build-in function calling without custom implementation?
Currently as far as I'm aware of, I'm not able use function calling with OpenAI responses api.
My issue is I believe, that function calling calls response from tool as single response:
Using functionCalling:
[ { "role": "system", "contents": [ { "$type": "text", "text": "You are friendly assistant" } ] }, { "role": "user", "contents": [ { "$type": "text", "text": "Where is my package PKG00000012" } ] } ].response contains call to mcp function and the call API:
[ { "role": "tool", "contents": [ { "$type": "functionResult", "result": { "$type": "text", "text": "{\"ok\":true,\"packageid\":\"PKG00000012\",\"status\":\"unknown\",\"message\":\"No tracking data available for this package.\"}" }, "callId": "call_erfK17HEAyoHlboIri5R4l7L" } ] } ]then server responds with bad gateway exception.
I need to use my custom implementation:
which produces following input
[ { "role": "system", "contents": [ { "$type": "text", "text": "You are friendly assistant " } ] }, { "role": "user", "contents": [ { "$type": "text", "text": "Where is my package PKG00000012" } ] }, { "createdAt": "2026-03-19T10:06:27+00:00", "role": "assistant", "contents": [ { "$type": "reasoning", "text": "...", "protectedData": "..." }, { "$type": "functionCall", "name": "get_package_status", "arguments": { "packageId": "PKG00000012" }, "informationalOnly": false, "callId": "call_EwvsSSC2mQXbRUTn68OZAGty" } ] }, { "role": "tool", "contents": [ { "$type": "functionResult", "result": [ { "type": "text", "text": "{\"ok\":true,\"packageid\":\"PKG00000012\",\"status\":\"unknown\",\"message\":\"No tracking data available for this package.\"}" } ], "callId": "call_EwvsSSC2mQXbRUTn68OZAGty" } ] } ]and this one is properly consumed and gives success result:
Is there any way to use build-in function calling without custom implementation?