- Package Name: azure-ai-projects, azure-identity, openai
- Package Version:
- azure-ai-projects version: 2.3.0
- azure-identity version: 1.25.3
- openai version: 2.44.0
- Operating System: Windows 11
- Python Version: Python 3.14.5
Describe the bug
When using Azure AI Foundry Agents with an MCP tool configured with require_approval="always" and the claude-sonnet-4-6 model, the first MCP approval succeeds, but a subsequent MCP approval request in the same response chain fails with HTTP 400.
The same workflow succeeds when require_approval="never" is used.
The issue appears when Claude performs a multi-step MCP interaction:
- Request MCP approval.
- Execute MCP tool call.
- Request approval for a second MCP tool call.
- Approval response for the second request returns HTTP 400.
The identical approval payload format works for the first approval request.
To Reproduce
I was following https://github.com/MicrosoftLearning/mslearn-ai-agents/tree/main/Labfiles/03-mcp-integration/Python and adjusted the code for agent.py slightly to handle multi-step approvals.
Steps to reproduce the behavior:
agent.py
import os
from dotenv import load_dotenv
import json
# Add references
import azure.identity as azure_identity
import azure.ai.projects as azure_ai_projects
import openai as openai
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import PromptAgentDefinition, MCPTool
from openai.types.responses.response_input_param import (
McpApprovalResponse,
ResponseInputParam,
)
from openai import BadRequestError
# Load environment variables from .env file
load_dotenv()
project_endpoint = os.getenv("PROJECT_ENDPOINT")
model_deployment = os.getenv("MODEL_DEPLOYMENT_NAME")
print("=" * 80)
print(f"azure-ai-projects version: {azure_ai_projects.__version__}")
print(f"azure-identity version: {azure_identity.__version__}")
print(f"openai version: {openai.__version__}")
print("=" * 80)
# Connect to the agents client
with (
DefaultAzureCredential() as credential,
AIProjectClient(endpoint=project_endpoint, credential=credential) as project_client,
project_client.get_openai_client() as openai_client,
):
# Initialize agent MCP tool
mcp_tool = MCPTool(
server_label="api-specs",
server_url="https://learn.microsoft.com/api/mcp",
require_approval="always",
)
# Create a new agent with the MCP tool
agent = project_client.agents.create_version(
agent_name="MyAgent",
definition=PromptAgentDefinition(
model=model_deployment,
instructions="You are a helpful agent that can use MCP tools to assist users. Use the available MCP tools to answer questions and perform tasks.",
tools=[mcp_tool],
),
)
print(
f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})"
)
# Create conversation thread
conversation = openai_client.conversations.create()
print(f"Created conversation (id: {conversation.id})")
# Send initial request that will trigger the MCP tool
response = openai_client.responses.create(
conversation=conversation.id,
input="Give me the Azure CLI commands to create an Azure Container App with a managed identity.",
extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}},
)
response_nr = 1
# Process any MCP approval requests that were generated
# The agent may issue several tool calls, each needing its own approval,
# so we loop until there are none left.
# # I had to change this from the instructions,
# # because my model iterated over tools instead of providing a list of tool calls.
while not response.output_text:
print("=" * 80)
print(
f"Response {response_nr}: {json.dumps(response.model_dump(), indent=2, sort_keys=True)}"
)
print("=" * 80)
# Collect any MCP approval requests from the latest response
input_list: ResponseInputParam = []
item_nr = 1
for item in response.output:
print(
f"Input Item {response_nr}.{item_nr}: {json.dumps(item.model_dump(), indent=2, sort_keys=True)}"
)
if item.type == "mcp_approval_request":
if item.server_label == "api-specs" and item.id:
# Automatically approve the MCP request to allow the agent to proceed
result = McpApprovalResponse(
type="mcp_approval_response",
approve=True,
approval_request_id=item.id,
)
print(
f"Output Item {response_nr}.{item_nr}: {json.dumps(result, indent=2, sort_keys=True)}"
)
input_list.append(result)
item_nr += 1
response_nr += 1
if not input_list:
break
try:
response = openai_client.responses.create(
input=input_list,
previous_response_id=response.id,
extra_body={
"agent_reference": {"name": agent.name, "type": "agent_reference"}
},
)
except BadRequestError as e:
print("Status:", e.status_code)
if hasattr(e, "response") and e.response:
print("Headers:", e.response.headers)
try:
print("JSON:", e.response.json())
except Exception:
print("TEXT:", e.response.text)
raise
print(f"\nAgent response: {response.output_text}")
# Clean up resources by deleting the agent version
project_client.agents.delete_version(
agent_name=agent.name, agent_version=agent.version
)
print("Agent deleted")
output structure
Response 1: {...}
Input Item 1.1: {type: mcp_list_tools}
Input Item 1.2: {type: mcp_approval_request}
Output Item 1.2: {type: mcp_approval_response}
Response 2: {...}
Input Item 2.1: {type: mcp_call}
Input Item 2.2: {type: mcp_approval_request}
Output Item 2.2: {type: mcp_approval_response}
...
openai.BadRequestError: Error code: 400 - {'error': {'message': 'There was an issue with your request. Please check your inputs and try again', 'type': 'invalid_request_error', 'param': None, 'code': None}}
Expected behavior
The second MCP approval should be accepted and the agent should continue execution, eventually producing a final response.
Describe the bug
When using Azure AI Foundry Agents with an MCP tool configured with
require_approval="always"and theclaude-sonnet-4-6model, the first MCP approval succeeds, but a subsequent MCP approval request in the same response chain fails with HTTP 400.The same workflow succeeds when
require_approval="never"is used.The issue appears when Claude performs a multi-step MCP interaction:
The identical approval payload format works for the first approval request.
To Reproduce
I was following https://github.com/MicrosoftLearning/mslearn-ai-agents/tree/main/Labfiles/03-mcp-integration/Python and adjusted the code for
agent.pyslightly to handle multi-step approvals.Steps to reproduce the behavior:
agent.py
output structure
Response 1: {...} Input Item 1.1: {type: mcp_list_tools} Input Item 1.2: {type: mcp_approval_request} Output Item 1.2: {type: mcp_approval_response} Response 2: {...} Input Item 2.1: {type: mcp_call} Input Item 2.2: {type: mcp_approval_request} Output Item 2.2: {type: mcp_approval_response} ... openai.BadRequestError: Error code: 400 - {'error': {'message': 'There was an issue with your request. Please check your inputs and try again', 'type': 'invalid_request_error', 'param': None, 'code': None}}Expected behavior
The second MCP approval should be accepted and the agent should continue execution, eventually producing a final response.