Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Use the file search tool to ground Microsoft Foundry agents in your own data. With file search, agents can retrieve relevant information from your documents and use it to generate more accurate, context-aware responses, augmenting agents with knowledge such as proprietary product information or user-provided documents.
In this article, you learn how to:
- Upload files and create a vector store
- Configure an agent with file search enabled
- Query your documents through the agent
By using the standard agent setup, the file search tool ensures your files remain in your own storage. Your Azure AI Search resource ingests the files, so you maintain complete control over your data.
Important
File search has additional charges beyond the token-based fees for model usage.
Prerequisites
The SDK package for your language:
- Python:
azure-ai-projects(latest) - .NET:
Azure.AI.Extensions.OpenAI - TypeScript:
@azure/ai-projects(latest) - Java:
azure-ai-agents
- Python:
Storage Blob Data Contributor role on your project's storage account (required for uploading files to your project's storage)
Foundry User role on the Foundry project to create and run agents.
Important
The Foundry RBAC roles were recently renamed. Foundry User, Foundry Owner, Foundry Account Owner, and Foundry Project Manager were previously named Azure AI User, Azure AI Owner, Azure AI Account Owner, and Azure AI Project Manager. You might still see the previous names in some places while the rename rolls out. The role IDs and core permissions are unchanged by the rename.
Azure credentials configured for authentication (such as
DefaultAzureCredential).Your Foundry project endpoint URL and model deployment name.
Upload and query a file
For the shortest path to a grounded response, complete these actions in order:
- Create or select a file that contains a fact you can test.
- Upload the file and add it to a vector store.
- Wait for ingestion to finish.
- Attach file search to an agent, and ask a question that only the file can answer.
- Verify that the response uses the uploaded content, and then delete the resources you created.
The Python and TypeScript examples show the upload-and-query flow in one program. Cleanup requirements vary by example, so follow the cleanup instructions in the selected language section.
Usage support
The following table shows SDK and setup support.
| Microsoft Foundry support | Python SDK | C# SDK | JavaScript SDK | Java SDK | REST API | Basic agent setup | Standard agent setup |
|---|---|---|---|---|---|---|---|
| ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
Code examples
The following examples show how to upload a file, create a vector store, configure an agent with file search enabled, and query the agent.
Prepare your sample
- Hosted C#: Install the packages and copy the
ToolboxMcpClient,ToolboxHandler, andAgentConfighelpers from Connect a hosted agent to a toolbox or the maintained hosted toolbox sample. The fragment in this article doesn't define these helpers. - REST: Use a Bash-compatible shell with Azure CLI, Azure Developer CLI, and
curl. SetFOUNDRY_PROJECT_ENDPOINTandFOUNDRY_MODEL_DEPLOYMENT_NAME, obtain anAGENT_TOKEN, and capture the returned file, vector store, and toolbox version IDs. The toolbox requests remain authenticated with the bearer token. - Java: Install JDK 17 or later and Maven 3.8 or later. Before running the Java code, use another language sample, REST, or the Foundry portal to upload the file, create the vector store and toolbox, and create the remote-tool project connection. For maintained Java client examples, see the Azure AI Agents Java SDK samples.
Tip
You can customize file search behavior at runtime, such as specifying which vector store to use per request, by using structured inputs.
Create an agent with the file search tool
The following code sample shows how to add the file search tool to a toolbox and attach the toolbox to an agent. You need to upload files and create a vector store before running this code. Select Prompt Agents to use the Azure AI Projects SDK to create a server-side prompt agent, or Hosted Agents to use the Agent Framework FoundryChatClient to build an ephemeral, in-process agent.
Prompt agents
from pathlib import Path
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import FileSearchTool, PromptAgentDefinition
from azure.identity import DefaultAzureCredential
# Format: "https://resource_name.ai.azure.com/api/projects/project_name"
PROJECT_ENDPOINT = "your_project_endpoint"
# Load the file to be indexed for search.
asset_file_path = (Path(__file__).parent / "../assets/product_info.md").resolve()
# Create clients to call Foundry API
project = AIProjectClient(
endpoint=PROJECT_ENDPOINT,
credential=DefaultAzureCredential(),
)
openai = project.get_openai_client()
# The openai client uses {PROJECT_ENDPOINT}/openai/v1 for file and vector store operations
# Create vector store and upload file
vector_store = openai.vector_stores.create(name="ProductInfoStore")
with asset_file_path.open("rb") as file_handle:
vector_store_file = openai.vector_stores.files.upload_and_poll(
vector_store_id=vector_store.id,
file=file_handle,
)
# Create agent with file search tool
agent = project.agents.create_version(
agent_name="MyAgent",
definition=PromptAgentDefinition(
model="gpt-5-mini",
instructions=(
"You are a helpful agent that can search through product information. "
"Use file search to answer questions from the uploaded files."
),
tools=[FileSearchTool(vector_store_ids=[vector_store.id])],
),
description="File search agent for product information queries.",
)
# Create conversation and generate response
conversation = openai.conversations.create()
response = openai.responses.create(
conversation=conversation.id,
input="Tell me about Contoso products",
extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}},
)
print(response.output_text)
# Clean up resources
project.agents.delete_version(
agent_name=agent.name,
agent_version=agent.version,
)
openai.vector_stores.delete(vector_store.id)
Expected output
The following output comes from the preceding code sample:
[Response text grounded in your uploaded document content]
References
- Reference: Azure SDK for Python sample: file search
- Reference: Microsoft Foundry REST API
Hosted agents
This sample creates the file-search toolbox with the Azure AI Projects SDK, then uses FoundryChatClient from the Microsoft Agent Framework and connects to the toolbox MCP endpoint using MCPStreamableHTTPTool. Set the FOUNDRY_PROJECT_ENDPOINT and FOUNDRY_MODEL environment variables, and sign in with az login.
import asyncio
from pathlib import Path
import httpx
from agent_framework import Agent, MCPStreamableHTTPTool
from agent_framework.foundry import FoundryChatClient
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import FileSearchToolboxTool
from azure.identity import AzureCliCredential, get_bearer_token_provider
PROJECT_ENDPOINT = "https://<account>.services.ai.azure.com/api/projects/<project>"
class _ToolboxAuth(httpx.Auth):
def __init__(self, token_provider):
self._token_provider = token_provider
def auth_flow(self, request):
request.headers["Authorization"] = f"Bearer {self._token_provider()}"
yield request
async def main() -> None:
credential = AzureCliCredential()
# Load the file to be indexed for search.
asset_file_path = (Path(__file__).parent / "../assets/product_info.md").resolve()
# Create vector store and upload file.
project = AIProjectClient(endpoint=PROJECT_ENDPOINT, credential=credential)
openai = project.get_openai_client()
vector_store = openai.vector_stores.create(name="ProductInfoStore")
with asset_file_path.open("rb") as file_handle:
vector_store_file = openai.vector_stores.files.upload_and_poll(
vector_store_id=vector_store.id,
file=file_handle,
)
# 1. Add the file search tool to a toolbox. Using a toolbox is the recommended way
# to give agents tools: you curate tools once and reuse the toolbox across agents.
# See /azure/foundry/agents/concepts/toolbox-overview
toolbox = project.toolboxes.create_version(
name="file-search-toolbox",
description="Toolbox with the file search tool",
tools=[FileSearchToolboxTool(vector_store_ids=[vector_store.id])],
)
# 2. The toolbox exposes an MCP-compatible endpoint.
TOOLBOX_MCP_URL = (
f"{PROJECT_ENDPOINT}/toolboxes/{toolbox.name}"
f"/versions/{toolbox.version}/mcp?api-version=v1"
)
# 3. Attach the toolbox to the hosted agent as an MCP tool.
token_provider = get_bearer_token_provider(credential, "https://ai.azure.com/.default")
http_client = httpx.AsyncClient(
auth=_ToolboxAuth(token_provider),
timeout=120.0,
)
mcp_tool = MCPStreamableHTTPTool(
name="toolbox",
url=TOOLBOX_MCP_URL,
http_client=http_client,
load_prompts=False,
)
agent = Agent(
client=FoundryChatClient(credential=credential),
instructions="You are a helpful assistant that can search through files to find information.",
tools=[mcp_tool],
)
result = await agent.run("What is the weather today? Do a file search to find the answer.")
print(f"Agent: {result.text}")
if __name__ == "__main__":
asyncio.run(main())
Expected output
The agent searches the indexed file content from the vector store and returns a grounded response. Console output shows the final response text containing the answer derived from the uploaded file.
Agent: The weather today is sunny with a high of 75F.
For the full sample, see foundry_chat_client_with_file_search.py.
File search sample with agent
In this example, you create a local file, upload it to Azure, and use it in the newly created VectorStore for file search. Select Prompt Agents to use the Azure AI Projects SDK to create a server-side prompt agent, or Hosted Agents to use the Microsoft Agent Framework to build an ephemeral, in-process agent.
Prompt agents
The code in this example is synchronous and streaming. For asynchronous usage, see the sample code in the Azure SDK for .NET repository on GitHub.
using System;
using System.IO;
using Azure.AI.Projects;
using Azure.AI.Extensions.OpenAI;
using Azure.Identity;
using OpenAI.Files;
using OpenAI.VectorStores;
// Format: "https://resource_name.ai.azure.com/api/projects/project_name"
var projectEndpoint = "your_project_endpoint";
// Create project client to call Foundry API
AIProjectClient projectClient = new(endpoint: new Uri(projectEndpoint), tokenProvider: new DefaultAzureCredential());
// Create a toy example file and upload it using OpenAI mechanism.
string filePath = "sample_file_for_upload.txt";
File.WriteAllText(
path: filePath,
contents: "The word 'apple' uses the code 442345, while the word 'banana' uses the code 673457.");
OpenAIFileClient fileClient = projectClient.ProjectOpenAIClient.GetOpenAIFileClient();
OpenAIFile uploadedFile = fileClient.UploadFile(filePath: filePath, purpose: FileUploadPurpose.Assistants);
File.Delete(filePath);
// Create the VectorStore and provide it with uploaded file ID.
VectorStoreClient vctStoreClient = projectClient.ProjectOpenAIClient.GetVectorStoreClient();
VectorStoreCreationOptions options = new()
{
Name = "MySampleStore",
FileIds = { uploadedFile.Id }
};
VectorStore vectorStore = vctStoreClient.CreateVectorStore(options: options);
// Create an Agent capable of using File search.
DeclarativeAgentDefinition agentDefinition = new(model: "gpt-5-mini")
{
Instructions = "You are a helpful agent that can help fetch data from files you know about.",
Tools = { ResponseTool.CreateFileSearchTool(vectorStoreIds: new[] { vectorStore.Id }), }
};
AgentVersion agentVersion = projectClient.AgentAdministrationClient.CreateAgentVersion(
agentName: "myAgent",
options: new(agentDefinition));
// Ask a question about the file's contents.
ProjectResponsesClient responseClient = projectClient.ProjectOpenAIClient.GetProjectResponsesClientForAgent(agentVersion.Name);
ResponseResult response = responseClient.CreateResponse("Can you give me the documented codes for 'banana' and 'orange'?");
Console.WriteLine(response.GetOutputText());
// Remove all the resources created in this sample.
projectClient.AgentAdministrationClient.DeleteAgentVersion(agentName: agentVersion.Name, agentVersion: agentVersion.Version);
vctStoreClient.DeleteVectorStore(vectorStoreId: vectorStore.Id);
fileClient.DeleteFile(uploadedFile.Id);
Expected output
The following output comes from the preceding code sample:
The code for 'banana' is 673457. I couldn't find any documented code for 'orange' in the files I have access to.
Hosted agents
The following code is an integration fragment. It creates the file-search toolbox with the Azure AI Projects SDK, then uses ResponsesServer from the Microsoft Agent Framework with custom ToolboxMcpClient, ToolboxHandler, and AgentConfig helpers that aren't defined in this article. For the required packages, imports, and maintained helper implementation, see Connect a hosted agent to a toolbox and the public hosted toolbox sample. Set the AZURE_AI_PROJECT_ENDPOINT, AZURE_OPENAI_ENDPOINT, and AZURE_AI_MODEL_DEPLOYMENT_NAME environment variables, and sign in with az login.
Helper-dependent integration fragment:
using System;
using System.IO;
using Azure.AI.AgentServer.Responses;
using Azure.AI.AgentServer.Responses.Models;
using Azure.AI.OpenAI;
using Azure.AI.Projects;
using Azure.AI.Extensions.OpenAI;
using Azure.Identity;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using OpenAI.Chat;
using OpenAI.Files;
using OpenAI.VectorStores;
const string AgentInstructions = "You are a helpful assistant that can search through uploaded files to answer questions.";
const string AgentName = "FileSearchAgent";
string projectEndpoint = Environment.GetEnvironmentVariable("AZURE_AI_PROJECT_ENDPOINT")
?? "https://<account>.services.ai.azure.com/api/projects/<project>";
string openAiEndpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
string deploymentName = Environment.GetEnvironmentVariable("AZURE_AI_MODEL_DEPLOYMENT_NAME") ?? "gpt-5-mini";
DefaultAzureCredential credential = new();
// 1. Create the file search tool and add it to a toolbox. Using a toolbox is the
// recommended way to give agents tools. See /azure/foundry/agents/concepts/toolbox-overview
AIProjectClient projectClient = new(endpoint: new Uri(projectEndpoint), tokenProvider: credential);
// Create a toy example file and upload it using OpenAI mechanism.
string filePath = "sample_file_for_upload.txt";
File.WriteAllText(
path: filePath,
contents: "The word 'apple' uses the code 442345, while the word 'banana' uses the code 673457.");
OpenAIFileClient fileClient = projectClient.ProjectOpenAIClient.GetOpenAIFileClient();
OpenAIFile uploadedFile = fileClient.UploadFile(filePath: filePath, purpose: FileUploadPurpose.Assistants);
File.Delete(filePath);
// Create the VectorStore and provide it with uploaded file ID.
VectorStoreClient vctStoreClient = projectClient.ProjectOpenAIClient.GetVectorStoreClient();
VectorStoreCreationOptions options = new()
{
Name = "MySampleStore",
FileIds = { uploadedFile.Id }
};
VectorStore vectorStore = vctStoreClient.CreateVectorStore(options: options);
ProjectsAgentTool fileSearchTool = ProjectsAgentTool.AsProjectTool(
ResponseTool.CreateFileSearchTool(vectorStoreIds: new[] { vectorStore.Id }));
ToolboxVersion toolboxVersion = projectClient.AgentAdministrationClient
.GetAgentToolboxes().CreateToolboxVersion(
toolboxName: "file-search-toolbox",
tools: [fileSearchTool],
description: "Toolbox with the file search tool");
// 2. The toolbox exposes an MCP-compatible endpoint.
string toolboxMcpEndpoint =
$"{projectEndpoint}/toolboxes/{toolboxVersion.Name}/versions/{toolboxVersion.Version}/mcp?api-version=v1";
// 3. Attach the toolbox to the hosted agent.
AzureOpenAIClient openAIClient = new(new Uri(openAiEndpoint), credential);
ChatClient chatClient = openAIClient.GetChatClient(deploymentName);
// ToolboxMcpClient discovers toolbox tools via MCP tools/list and calls them via tools/call.
ToolboxMcpClient toolboxClient = new(toolboxMcpEndpoint, credential);
ResponsesServer.Run<ToolboxHandler>(configure: builder =>
{
builder.Services.AddSingleton(new AgentConfig(
name: AgentName,
instructions: AgentInstructions,
chatClient: chatClient,
toolboxClient: toolboxClient));
});
Expected output
The hosted agent uses the toolbox MCP endpoint to search the vector store configured in the file-search toolbox and answers with grounded content.
Response: The youngest employee is Alice Johnson, who is 28 years old.
File Citation - File Id: file-abc123
For a maintained .NET Agent Framework integration, see Use a toolbox with a hosted agent.
File search sample with agent in streaming scenarios
In this example, you create a local file, upload it to Azure, and use it in the newly created VectorStore for file search. The code in this example is synchronous and streaming. For asynchronous usage, see the sample code in the Azure SDK for .NET repository on GitHub.
using System;
using System.IO;
using Azure.AI.Projects;
using Azure.AI.Extensions.OpenAI;
using Azure.Identity;
using OpenAI.Files;
using OpenAI.VectorStores;
class FileSearchStreamingDemo
{
// Create a helper method ParseResponse to format streaming response output.
// If the stream ends up in error state, it will throw an error.
private static void ParseResponse(StreamingResponseUpdate streamResponse)
{
if (streamResponse is StreamingResponseCreatedUpdate createUpdate)
{
Console.WriteLine($"Stream response created with ID: {createUpdate.Response.Id}");
}
else if (streamResponse is StreamingResponseOutputTextDeltaUpdate textDelta)
{
Console.WriteLine($"Delta: {textDelta.Delta}");
}
else if (streamResponse is StreamingResponseOutputTextDoneUpdate textDoneUpdate)
{
Console.WriteLine($"Response done with full message: {textDoneUpdate.Text}");
}
else if (streamResponse is StreamingResponseOutputItemDoneUpdate itemDoneUpdate)
{
if (itemDoneUpdate.Item is MessageResponseItem messageItem)
{
foreach (ResponseContentPart part in messageItem.Content)
{
foreach (ResponseMessageAnnotation annotation in part.OutputTextAnnotations)
{
if (annotation is FileCitationMessageAnnotation fileAnnotation)
{
// Note fileAnnotation.Filename will be available in OpenAI package versions
// greater then 2.6.0.
Console.WriteLine($"File Citation - File ID: {fileAnnotation.FileId}");
}
}
}
}
}
else if (streamResponse is StreamingResponseErrorUpdate errorUpdate)
{
throw new InvalidOperationException($"The stream has failed with the error: {errorUpdate.Message}");
}
}
public static void Main()
{
// Format: "https://resource_name.ai.azure.com/api/projects/project_name"
var projectEndpoint = "your_project_endpoint";
// Create project client to call Foundry API
AIProjectClient projectClient = new(endpoint: new Uri(projectEndpoint), tokenProvider: new DefaultAzureCredential());
// Create a toy example file and upload it using OpenAI mechanism.
string filePath = "sample_file_for_upload.txt";
File.WriteAllText(
path: filePath,
contents: "The word 'apple' uses the code 442345, while the word 'banana' uses the code 673457.");
OpenAIFile uploadedFile = projectClient.ProjectOpenAIClient.GetProjectFilesClient().UploadFile(filePath: filePath, purpose: FileUploadPurpose.Assistants);
File.Delete(filePath);
// Create the `VectorStore` and provide it with uploaded file ID.
VectorStoreCreationOptions options = new()
{
Name = "MySampleStore",
FileIds = { uploadedFile.Id }
};
VectorStore vectorStore = projectClient.ProjectOpenAIClient.GetProjectVectorStoresClient().CreateVectorStore(options);
// 1. Add the file search tool to a toolbox. Using a toolbox is the recommended
// way to give agents tools. See /azure/foundry/agents/concepts/toolbox-overview
AgentToolboxes toolboxClient = projectClient.AgentAdministrationClient.GetAgentToolboxes();
ProjectsAgentTool fileSearchTool = ProjectsAgentTool.AsProjectTool(
ResponseTool.CreateFileSearchTool(vectorStoreIds: new[] { vectorStore.Id }));
ToolboxVersion toolboxVersion = projectClient.AgentAdministrationClient
.GetAgentToolboxes().CreateToolboxVersion(
toolboxName: "file-search-toolbox",
tools: [fileSearchTool],
description: "Toolbox with the file search tool");
// 2. The toolbox exposes an MCP-compatible endpoint.
var toolboxMcpUrl = new Uri(
$"{projectEndpoint}/toolboxes/{toolboxVersion.Name}" +
$"/versions/{toolboxVersion.Version}/mcp?api-version=v1");
// 3. Create a remote-tool project connection that points at the toolbox endpoint.
// Use a user Entra token so the caller's identity is passed through
// (audience https://ai.azure.com). Create the connection once, for example
// with the Azure Developer CLI:
//
// azd ai connection create file-search-toolbox-conn \
// --kind remote-tool \
// --target "<toolboxMcpUrl>" \
// --auth-type user-entra-token \
// --audience https://ai.azure.com
var toolboxConnectionName = "file-search-toolbox-conn";
// 4. Attach the toolbox to the prompt agent as an MCP tool.
McpTool toolboxTool = ResponseTool.CreateMcpTool(
serverLabel: "toolbox",
serverUri: toolboxMcpUrl,
toolCallApprovalPolicy: new McpToolCallApprovalPolicy(
GlobalMcpToolCallApprovalPolicy.NeverRequireApproval));
toolboxTool.ProjectConnectionId = toolboxConnectionName;
DeclarativeAgentDefinition agentDefinition = new(model: "gpt-5-mini")
{
Instructions = "You are a helpful agent that can help fetch data from files you know about.",
Tools = { toolboxTool }
};
AgentVersion agentVersion = projectClient.AgentAdministrationClient.CreateAgentVersion(
agentName: "myAgent",
options: new(agentDefinition)
);
// Create the conversation to store responses.
ProjectConversation conversation = projectClient.ProjectOpenAIClient.GetProjectConversationsClient().CreateProjectConversation();
CreateResponseOptions responseOptions = new()
{
Agent = agentVersion,
AgentConversationId = conversation.Id,
StreamingEnabled = true,
};
// Wait for the stream to complete.
responseOptions.InputItems.Clear();
responseOptions.InputItems.Add(ResponseItem.CreateUserMessageItem("Can you give me the documented codes for 'banana' and 'orange'?"));
foreach (StreamingResponseUpdate streamResponse in projectClient.ProjectOpenAIClient.Responses.CreateResponseStreaming(responseOptions))
{
ParseResponse(streamResponse);
}
// Ask follow up question and start a new stream.
Console.WriteLine("Demonstrating follow-up query with streaming...");
responseOptions.InputItems.Clear();
responseOptions.InputItems.Add(ResponseItem.CreateUserMessageItem("What was my previous question about?"));
foreach (StreamingResponseUpdate streamResponse in projectClient.ProjectOpenAIClient.Responses.CreateResponseStreaming(responseOptions))
{
ParseResponse(streamResponse);
}
// Remove all the resources created in this sample.
projectClient.AgentAdministrationClient.DeleteAgentVersion(agentName: agentVersion.Name, agentVersion: agentVersion.Version);
projectClient.ProjectOpenAIClient.GetProjectVectorStoresClient().DeleteVectorStore(vectorStoreId: vectorStore.Id);
projectClient.ProjectOpenAIClient.GetProjectFilesClient().DeleteFile(uploadedFile.Id);
}
}
Expected output
The following output comes from the preceding code sample:
Stream response created with ID: <response-id>
Delta: The code for 'banana' is 673457. I couldn't find any documented code for 'orange' in the files I have access to.
Response done with full message: The code for 'banana' is 673457. I couldn't find any documented code for 'orange' in the files I have access to.
File Citation - File ID: <file-id>
Demonstrating follow-up query with streaming...
Stream response created with ID: <response-id>
Delta: Your previous question was about the documented codes for 'banana' and 'orange'.
Response done with full message: Your previous question was about the documented codes for 'banana' and
'orange'.
Sample file search with agent
The following TypeScript sample shows how to add the file search tool to a toolbox and attach the toolbox to an agent. You need to upload files and create a vector store before running this code. See the File search behavior by agent setup type section below for details. For a JavaScript example, see the sample code in the Azure SDK for JavaScript repository on GitHub.
import { DefaultAzureCredential } from "@azure/identity";
import { AIProjectClient } from "@azure/ai-projects";
import * as fs from "fs";
import * as path from "path";
import { fileURLToPath } from "url";
// Format: "https://resource_name.ai.azure.com/api/projects/project_name"
const PROJECT_ENDPOINT = "your_project_endpoint";
export async function main(): Promise<void> {
// Load the file to be indexed for search
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const assetFilePath = path.join(__dirname, "../assets/product_info.md");
// Create clients to call Foundry API
const project = new AIProjectClient(PROJECT_ENDPOINT, new DefaultAzureCredential());
// The openai client uses {PROJECT_ENDPOINT}/openai/v1 for file and vector store operations
const openai = project.getOpenAIClient();
// Create vector store and upload file
const vectorStore = await openai.vectorStores.create({
name: "ProductInfoStore",
});
const fileStream = fs.createReadStream(assetFilePath);
const file = await openai.vectorStores.files.uploadAndPoll(vectorStore.id, fileStream);
console.log("Creating a toolbox with the file search tool...");
// 1. Add the file search tool to a toolbox. Using a toolbox is the recommended
// way to give agents tools. See /azure/foundry/agents/concepts/toolbox-overview
const toolbox = await project.toolboxes.createVersion(
"file-search-toolbox",
[
{
type: "file_search",
file_search: {
vector_store_ids: [vectorStore.id],
},
},
],
{ description: "Toolbox with the file search tool" },
);
// 2. The toolbox exposes an MCP-compatible endpoint.
const toolboxMcpUrl =
`${PROJECT_ENDPOINT}/toolboxes/${toolbox.name}` +
`/versions/${toolbox.version}/mcp?api-version=v1`;
// 3. Create a remote-tool project connection that points at the toolbox endpoint.
// Use a user Entra token so the caller's identity is passed through
// (audience https://ai.azure.com). Create the connection once, for example
// with the Azure Developer CLI:
//
// azd ai connection create file-search-toolbox-conn \
// --kind remote-tool \
// --target "<toolboxMcpUrl>" \
// --auth-type user-entra-token \
// --audience https://ai.azure.com
const toolboxConnectionName = "file-search-toolbox-conn";
// 4. Attach the toolbox to a prompt agent as an MCP tool.
const agent = await project.agents.createVersion("agent-file-search", {
kind: "prompt",
model: "gpt-5-mini",
instructions: "You are a helpful assistant that can search through product information.",
tools: [
{
type: "mcp",
server_label: "toolbox",
server_url: toolboxMcpUrl,
require_approval: "never",
project_connection_id: toolboxConnectionName,
},
],
});
// Create conversation and generate response
const conversation = await openai.conversations.create();
const response = await openai.responses.create(
{
conversation: conversation.id,
input: "Tell me about Contoso products",
},
{
body: { agent_reference: { name: agent.name, type: "agent_reference" } },
},
);
console.log(response.output_text);
// Clean up resources
await project.agents.deleteVersion(agent.name, agent.version);
await openai.vectorStores.delete(vectorStore.id);
}
main().catch((err) => {
console.error("The sample encountered an error:", err);
});
Expected output
[Response text grounded in your uploaded document content]
References
- Reference: Azure SDK for JavaScript sample: file search
- Reference: Microsoft Foundry REST API
Use file search in a Java agent
Tip
Most agents use a toolbox to add the file search tool and attach the toolbox to your agent as an MCP tool. If you use the Java SDK, an API for creating toolboxes isn't yet available. Create a toolbox by using the Python, REST API, C#, TypeScript, or the Foundry portal, then reference its MCP endpoint from your Java agent as an McpTool.
Add the dependency to your pom.xml:
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-ai-agents</artifactId>
<version>2.2.0</version>
</dependency>
Create an agent with file search
Before running this sample, create a file and vector store using the {projectEndpoint}/openai/v1/files and {projectEndpoint}/openai/v1/vector_stores REST endpoints. Then create a file-search toolbox out of band by using the Python, REST, C#, or TypeScript example, or the Foundry portal. Create the remote-tool project connection for the toolbox MCP endpoint before you attach it to the Java agent.
import com.azure.ai.agents.AgentsClient;
import com.azure.ai.agents.AgentsClientBuilder;
import com.azure.ai.agents.ResponsesClient;
import com.azure.ai.agents.models.AgentReference;
import com.azure.ai.agents.models.AgentVersionDetails;
import com.azure.ai.agents.models.AzureCreateResponseOptions;
import com.azure.ai.agents.models.McpTool;
import com.azure.ai.agents.models.PromptAgentDefinition;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;
import java.util.Collections;
public class FileSearchExample {
public static void main(String[] args) {
// Format: "https://resource_name.ai.azure.com/api/projects/project_name"
String projectEndpoint = "your_project_endpoint";
String toolboxMcpUrl = projectEndpoint
+ "/toolboxes/file-search-toolbox/versions/1/mcp?api-version=v1";
String toolboxConnectionName = "file-search-toolbox-conn";
AgentsClientBuilder builder = new AgentsClientBuilder()
.credential(new DefaultAzureCredentialBuilder().build())
.endpoint(projectEndpoint);
AgentsClient agentsClient = builder.buildAgentsClient();
ResponsesClient responsesClient = builder.buildResponsesClient();
// The Java SDK doesn't yet expose a toolbox creation API. Create the
// toolbox with Python, REST, C#, TypeScript, or the Foundry portal, then
// attach its MCP endpoint as an MCP tool.
McpTool toolboxTool = new McpTool("toolbox")
.setServerUrl(toolboxMcpUrl)
.setProjectConnectionId(toolboxConnectionName)
.setRequireApproval("never");
// Create agent with the toolbox MCP tool
PromptAgentDefinition agentDefinition = new PromptAgentDefinition("gpt-5-mini")
.setInstructions("You are a helpful assistant that can search through files to answer questions.")
.setTools(Collections.singletonList(toolboxTool));
AgentVersionDetails agent = agentsClient.createAgentVersion("file-search-agent", agentDefinition);
System.out.printf("Agent created: %s (version %s)%n", agent.getName(), agent.getVersion());
// Create a response
AgentReference agentReference = new AgentReference(agent.getName())
.setVersion(agent.getVersion());
Response response = responsesClient.createAzureResponse(
new AzureCreateResponseOptions().setAgentReference(agentReference),
ResponseCreateParams.builder()
.input("What information is in the uploaded files?"));
System.out.println("Response: " + response.output());
// Clean up
agentsClient.deleteAgentVersion(agent.getName(), agent.getVersion());
}
}
Expected output
Agent created: file-search-agent (version 1)
Response: [ResponseOutputItem containing file search results ...]
For more examples including file upload and vector store creation, see the Azure AI Agents Java SDK samples.
Upload files and add them to a vector store
To access your files, the file search tool uses the vector store object. Upload your files and create a vector store. Then poll the store's status until all files are out of the in_progress state to ensure that all content is fully processed. The SDK provides helpers for uploading and polling.
Set the following environment variable before running the examples:
AGENT_TOKEN=$(az account get-access-token --scope https://ai.azure.com/.default --query accessToken -o tsv)
Upload a file
curl --request POST \
--url $FOUNDRY_PROJECT_ENDPOINT/openai/v1/files \
-H "Authorization: Bearer $AGENT_TOKEN" \
-F purpose="assistants" \
-F file="@c:\\path_to_file\\sample_file_for_upload.txt"
Create a vector store
curl --request POST \
--url $FOUNDRY_PROJECT_ENDPOINT/openai/v1/vector_stores \
-H "Authorization: Bearer $AGENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "my_vector_store",
"file_ids": ["'$FILE_ID'"]
}'
Add file search to a toolbox and create an agent
The recommended way to add file search is through a toolbox, then attach the toolbox to your agent as an MCP tool. See What is a toolbox?
Upload files for toolbox use
To create a file and vector store for use with a toolbox, upload the file at the resource-level Files endpoint with the x-aml-project-id header. Use the project GUID from properties.amlWorkspace.internalId.
- Upload your file:
POST {account_endpoint}/openai/v1/fileswithpurpose=assistantsand headerx-aml-project-id: {project-guid}. - Create a vector store:
POST {account_endpoint}/openai/v1/vector_storeswith the returned file ID and the samex-aml-project-idheader.
The resulting vector store ID is the value you supply as <VECTOR_STORE_ID>.
Create a toolbox that contains the file search tool:
curl --request POST \ --url "$FOUNDRY_PROJECT_ENDPOINT/toolboxes/file-search-toolbox/versions?api-version=v1" \ -H "Authorization: Bearer $AGENT_TOKEN" \ -H "Content-Type: application/json" \ --data '{ "description": "Toolbox with the file search tool", "tools": [ { "type": "file_search", "file_search": { "vector_store_ids": ["'$VECTOR_STORE_ID'"] }, "max_num_results": 20 } ] }'The toolbox exposes an MCP-compatible endpoint at
$FOUNDRY_PROJECT_ENDPOINT/toolboxes/file-search-toolbox/versions/<version>/mcp?api-version=v1, where<version>is the version returned by the previous call.Create a remote-tool project connection that points at the toolbox endpoint, using a user Entra token so the caller's identity is passed through (audience
https://ai.azure.com).azd ai connection create file-search-toolbox-conn \ --kind remote-tool \ --target "$FOUNDRY_PROJECT_ENDPOINT/toolboxes/file-search-toolbox/versions/<version>/mcp?api-version=v1" \ --auth-type user-entra-token \ --audience https://ai.azure.comCreate an agent that uses the toolbox by attaching it as an MCP tool.
curl -X POST "$FOUNDRY_PROJECT_ENDPOINT/agents?api-version=v1" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $AGENT_TOKEN" \ -d '{ "name": "<AGENT_NAME>-file-search", "description": "Agent with file search", "definition": { "kind": "prompt", "model": "'$FOUNDRY_MODEL_DEPLOYMENT_NAME'", "tools": [ { "type": "mcp", "server_label": "toolbox", "server_url": "'$FOUNDRY_PROJECT_ENDPOINT'/toolboxes/file-search-toolbox/versions/<version>/mcp?api-version=v1", "require_approval": "never", "project_connection_id": "file-search-toolbox-conn" } ], "instructions": "You are a customer support chatbot. Use file search results from the vector store to answer questions based on the uploaded files." } }'
Dynamic vector store selection (parameter override)
When you add file search to a toolbox, you can supply vector_store_ids in two ways:
- Pinned at toolbox creation — include
vector_store_idsin the tool configuration (as shown in the previous example). The vector store is fixed for every call and can't be overridden at runtime. - Dynamic at runtime (parameter override) — omit
vector_store_idsfrom the tool configuration. Callers supply it in thetools/callarguments, so each call can target a different vector store. This enables scenarios like multitenant document stores where every request searches a different set of files.
Create the toolbox without vector_store_ids:
curl --request POST \
--url "$FOUNDRY_PROJECT_ENDPOINT/toolboxes/file-search-toolbox/versions?api-version=v1" \
-H "Authorization: Bearer $AGENT_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"description": "File search with dynamic vector store",
"tools": [
{ "type": "file_search" }
]
}'
When you omit vector_store_ids, callers pass it in the tools/call arguments:
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"file_search","arguments":{"queries":["search text"],"vector_store_ids":["<VECTOR_STORE_ID>"]}}}
Note
The REST API, Python SDK, .NET SDK, JavaScript SDK, and Azure Developer CLI support dynamic vector_store_ids. The Foundry portal UI currently requires vector_store_ids when you add a File Search tool.
Important
When you use File Search through a toolbox in a hosted agent, user isolation isn't supported. All users in the same project share access to any vector stores referenced in the tool configuration or provided at runtime.
Create response with file search
curl --request POST \
--url $FOUNDRY_PROJECT_ENDPOINT/openai/v1/responses \
-H "Authorization: Bearer $AGENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"agent": {
"type": "agent_reference",
"name": "<AGENT_NAME>-file-search"
},
"metadata": {
"test_response": "file_search_enabled",
"vector_store_id": "'$VECTOR_STORE_ID'"
},
"input": [{
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "Can you search the uploaded file and tell me about Azure TV instructions?"
}
]
}],
"stream": true
}'
The response returns streaming output containing the agent's answer based on information retrieved from the vector store. The agent searches through your uploaded file to answer the query about Azure TV instructions.
Clean up
Delete the agent.
curl -X DELETE "$FOUNDRY_PROJECT_ENDPOINT/agents/<AGENT_NAME>-file-search?api-version=v1" \
-H "Authorization: Bearer $AGENT_TOKEN"
Delete the vector store.
curl --request DELETE \
--url $FOUNDRY_PROJECT_ENDPOINT/openai/v1/vector_stores/$VECTOR_STORE_ID \
-H "Authorization: Bearer $AGENT_TOKEN"
Delete the file.
curl --request DELETE \
--url $FOUNDRY_PROJECT_ENDPOINT/openai/v1/files/$FILE_ID \
-H "Authorization: Bearer $AGENT_TOKEN"
References
- Reference: Microsoft Foundry REST API
Verify file search results
After running a code sample in this article, verify that file search is working:
- Confirm that the vector store and file are created.
- In the Python and TypeScript samples, the upload-and-poll helpers complete only after ingestion finishes.
- Ask a question that you can answer only from your uploaded content.
- Confirm that the response is grounded in your documents.
File sources
- Upload local files (Basic and Standard agent setup)
- Azure Blob Storage (Standard setup only)
File search behavior by agent setup type
Basic agent setup
The file search tool has the same functionality as Azure OpenAI Responses API. The tool uses Microsoft managed search and storage resources.
- You store uploaded files in Microsoft managed storage.
- You create a vector store by using a Microsoft managed search resource.
Standard agent setup
The file search tool uses the Azure AI Search and Azure Blob Storage resources you connect to during agent setup.
- You store uploaded files in your connected Azure Blob Storage account.
- You create vector stores by using your connected Azure AI Search resource.
For both agent setups, the service handles the entire ingestion process, which includes:
- Automatically parsing and chunking documents.
- Generating and storing embeddings.
- Utilizing both vector and keyword searches to retrieve relevant content for user queries.
The code is identical for both setups. The only variation is where your files and vector stores are stored.
When to use file search
Choose file search when you need to:
- Search through documents you upload directly (PDFs, Word docs, code files)
- Enable agents to answer questions from proprietary or confidential content
- Process files up to 512 MB without managing external search infrastructure
Consider alternatives for these scenarios:
| Scenario | Recommended tool |
|---|---|
| Search existing Azure AI Search indexes | Azure AI Search tool |
| Search the public web for current information | Web search tool |
| Combine multiple data sources in one query | Use multiple tools together |
How file search works
The file search tool uses retrieval best practices to extract relevant data from your files and improve model responses.
Query processing
When you send a query, file search:
- Rewrites your query to optimize it for search.
- Breaks down complex queries into parallel searches.
- Runs hybrid search combining keyword and semantic matching across vector stores.
- Reranks results to select the most relevant content for the response.
Default chunking settings
| Setting | Default value |
|---|---|
| Chunk size | 800 tokens |
| Chunk overlap | 400 tokens |
| Embedding model | text-embedding-3-large (256 dimensions) |
| Max chunks in context | 20 |
Vector stores
Vector store objects give the file search tool the ability to search your files. When you add a file to a vector store, the process automatically parses, chunks, embeds, and stores the file in a vector database that supports both keyword and semantic search. Each vector store can hold up to 10,000 files. You can attach vector stores to both agents and conversations. Currently, you can attach at most one vector store to an agent and at most one vector store to a conversation.
For background concepts and lifecycle guidance (readiness, deletion behavior, and expiration policies), see Vector stores for file search.
Remove files from a vector store by:
- Deleting the vector store file object.
- Deleting the underlying file object. This action removes the file from all
vector_storeandcode_interpreterconfigurations across all agents and conversations in your organization.
The maximum file size is 512 MB. Each file should contain no more than 5,000,000 tokens (computed automatically when you attach a file).
Ensuring vector store readiness before creating runs
Ensure the system fully processes all files in a vector store before you create a run. This ensures all data in your vector store is searchable. Check for vector store readiness by using the polling helpers in the SDKs, or by manually polling the vector store object to ensure the status is completed.
As a fallback, the run object includes a 60-second maximum wait when the conversation's vector store contains files that are still processing. This wait ensures that any files your users upload in a conversation are fully searchable before the run proceeds. This fallback wait doesn't apply to the agent's vector store.
Conversation vector stores have default expiration policies
Vector stores that you create by using conversation helpers (like tool_resources.file_search.vector_stores in conversations or message.attachments in Messages) have a default expiration policy of seven days after they were last active (defined as the last time the vector store was part of a run).
When a vector store expires, the runs on that conversation fail. To fix this problem, recreate a new vector store with the same files and reattach it to the conversation.
Supported file types
Note
For text MIME types, the encoding must be UTF-8, UTF-16, or ASCII.
| File format | MIME Type |
|---|---|
.c |
text/x-c |
.cs |
text/x-csharp |
.cpp |
text/x-c++ |
.doc |
application/msword |
.docx |
application/vnd.openxmlformats-officedocument.wordprocessingml.document |
.html |
text/html |
.java |
text/x-java |
.json |
application/json |
.md |
text/markdown |
.pdf |
application/pdf |
.php |
text/x-php |
.pptx |
application/vnd.openxmlformats-officedocument.presentationml.presentation |
.py |
text/x-python |
.py |
text/x-script.python |
.rb |
text/x-ruby |
.tex |
text/x-tex |
.txt |
text/plain |
.css |
text/css |
.js |
text/javascript |
.sh |
application/x-sh |
.ts |
application/typescript |
Limitations
Keep these limits in mind when you plan your file search integration:
- File search supports specific file formats and encodings. See Supported file types.
- Each vector store can hold up to 10,000 files.
- You can attach at most one vector store to an agent and at most one vector store to a conversation.
- Features and availability vary by region. See Microsoft Foundry region support.
Troubleshooting
| Issue | Likely cause | Resolution |
|---|---|---|
| 401 Unauthorized | The access token is missing, expired, or scoped incorrectly. | Get a fresh token and retry the request. For REST calls, confirm you set AGENT_TOKEN correctly. |
| 403 Forbidden | The signed-in identity doesn't have the required roles. | Confirm the roles in Prerequisites and retry after role assignment finishes propagating. |
| 404 Not Found | The project endpoint or resource identifiers are incorrect. | Confirm FOUNDRY_PROJECT_ENDPOINT and IDs such as agent name, version, vector store ID, and file ID. |
| Responses ignore your files | The agent isn't configured with file_search, or the vector store isn't attached. |
Confirm the agent definition includes file_search and the vector_store_ids list contains your vector store ID. |
| File upload times out | Large file or slow network connection. | Use upload_and_poll to handle large files. Consider chunking very large documents. |
| Vector store creation fails | Quota exceeded or invalid file format. | Check vector store limits (10,000 files per store). Verify file format is supported. |
| Search returns irrelevant results | File content not properly indexed or query too broad. | Wait for indexing to complete (check vector_store.status). Use more specific queries. |
| No citations in response | Model didn't use file search or content not found. | Use tool_choice="required" to force file search. Verify the file content matches your query topic. |
Related content
- Azure AI Search tool - Search existing Azure AI Search indexes from your agents
- Web search tool - Enable agents to search the public web
- Vector stores for file search - Understand vector store lifecycle and expiration
- Structured inputs - Parameterize agent definitions at runtime