Azure / Azure/azure-sdk-for-python
Python: [Bug]: Citation URLs Point to MCP Endpoint Instead of Actual Document Sources
- Dominant language
- Python
- Stars
- 5.6k
- Forks
- 3.4k
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 202
Description
### Description
When using Azure AI Search Knowledge Base with MCP (Model Context Protocol) integration, the citations returned in agent responses contain generic MCP endpoint URLs instead of actual document source URLs. This makes it impossible to trace which specific document was referenced.
Ref:
https://github.com/microsoft/agent-framework/blob/main/python/samples/02-agents/providers/azure_ai/azure_ai_with_existing_agent.py
https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/foundry-iq-connect?tabs=search%2Cpython
# Citation returned by agent:
{
'type': 'citation',
'title': 'doc_0',
'url': 'https://srch-XXXXXX.search.windows.net:443/knowledgebases/XXXXXX-kb/mcp',
'additional_properties': {
'annotation_index': 0
},
'raw_representation': {
'type': 'url_citation',
'end_index': 1065,
'start_index': 1053,
'title': 'doc_0',
'url': 'https://srch-XXXXXX.search.windows.net:443/knowledgebases/XXXXXX-kb/mcp'
},
'annotated_regions': [
{
'type': 'text_span',
'start_index': 1053,
'end_index': 1065
}
]
}
### Code Sample
```markdown
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import (
PromptAgentDefinition,
FunctionTool,
MCPTool,
)
# Configuration
ENDPOINT = "https://your-project.services.ai.azure.com/api/projects/project1"
AZURE_AI_SEARCH_ENDPOINT = "https://srch-xxxxx.search.windows.net"
KB_NAME = "demo-kb" # Knowledge Base name
KB_MCP_CONNECTION_NAME = "demo-kb-mcp-connection"
# Initialize client
credential = DefaultAzureCredential()
project_client = AIProjectClient(
endpoint=ENDPOINT,
credential=credential
)
# ============================================================================
# Define Knowledge Base MCP Tool
# ============================================================================
# MCP endpoint for Knowledge Base
MCP_ENDPOINT = f"{AZURE_AI_SEARCH_ENDPOINT}/knowledgebases/{KB_NAME}/mcp?api-version=2025-11-01-preview"
mcp_kb_tool = MCPTool(
server_label="knowledge-base",
server_url=MCP_ENDPOINT,
require_approval="never",
allowed_tools=["knowledge_base_retrieve"],
project_connection_id=KB_MCP_CONNECTION_NAME,
)
# ============================================================================
# Create MCP Project Connection (Required for MCP Tool)
# ============================================================================
def create_kb_mcp_connection():
"""Create RemoteTool project connection for Knowledge Base MCP"""
import requests
subscription_id = "your-subscription-id"
resource_group = "your-resource-group"
ai_service_name = "your-ai-service"
project_name = "your-project-name"
mcp_endpoint = f"{AZURE_AI_SEARCH_ENDPOINT}/knowledgebases/{KB_NAME}/mcp?api-version=2025-11-01-preview"
token = get_bearer_token_provider(credential, "https://management.azure.com/.default")()
headers = {"Authorization": f"Bearer {token}"}
# REST API endpoint for connection
url = (
f"https://management.azure.com/subscriptions/{subscription_id}"
f"/resourceGroups/{resource_group}"
f"/providers/Microsoft.CognitiveServices/accounts/{ai_service_name}"
f"/projects/{project_name}"
f"/connections/{KB_MCP_CONNECTION_NAME}?api-version=2025-04-01-preview"
)
body = {
"name": KB_MCP_CONNECTION_NAME,
"properties": {
"authType": "ProjectManagedIdentity",
"category": "RemoteTool",
"target": mcp_endpoint,
"isSharedToAll": True,
"audience": "https://search.azure.com/",
"metadata": {"ApiType": "Azure"}
}
}
response = requests.put(url, headers=headers, json=body)
return response.status_code in (200, 201)
# ============================================================================
# Create Agent with All Tools
# ============================================================================
CHAT_AGENT_NAME = "ChatAgent"
agent_tools = [
function_tool,
mcp_kb_tool
]
agent_definition = PromptAgentDefinition(
model=MODEL,
instructions=instructions,
tools=agent_tools
)
# Create new agent
chat_agent = project_client.agents.create(
name=CHAT_AGENT_NAME,
definition=agent_definition
)
# ============================================================================
# AGENT USAGE
# ============================================================================
async with (
AsyncDefaultAzureCredential() as async_credential,
AIProjectClient(endpoint=ENDPOINT, credential=async_credential) as project_client,
):
# Create agent provider
provider = AzureAIProjectAgentProvider(project_client=project_client)
# Get agent with SQL tool binding
agent = await provider.get_agent(
name=CHAT_AGENT_NAME,
tools=functiontool )
# Create conversation for context continuity
openai_client = project_client.get_openai_client()
conversation = await openai_client.conversations.create()
async for chunk in agent.run(user_message, stream=True, conversation_id=conversation_id):
# Extract citations from chunk contents
for content in getattr(chunk, "contents", []):
annotations = getattr(content, "annotations", [])
if annotations:
citations.extend(annotations)
# Accumulate text response
chunk_text = str(chunk.text) if chunk.text else ""
if chunk_text:
text_output += chunk_text
# Display response
if text_output:
print(f"\nAssistant: {text_output}")
```
### Error Messages / Stack Traces
```markdown
# Citation returned by agent:
{
'type': 'citation',
'title': 'doc_0',
'url': 'https://srch-XXXXXX.search.windows.net:443/knowledgebases/XXXXXX-kb/mcp',
'additional_properties': {
'annotation_index': 0
},
'raw_representation': {
'type': 'url_citation',
'end_index': 1065,
'start_index': 1053,
'title': 'doc_0',
'url': 'https://srch-XXXXXX.search.windows.net:443/knowledgebases/XXXXXX-kb/mcp'
},
'annotated_regions': [
{
'type': 'text_span',
'start_index': 1053,
'end_index': 1065
}
]
}
```
### Package Versions
azure-ai-projects==2.0.0b3 azure-ai-agents==1.2.0b5 agent-framework-core==1.0.0rc2 agent-framework-azure-ai==1.0.0rc2
### Python Version
Python 3.11+
### Additional Context
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.