langchain-azure-ai package to load tools and skills from a Foundry
Toolbox into your LangChain and LangGraph agents. A Foundry Toolbox is a
managed multi-MCP server that aggregates multiple configured tools behind a
single Model Context Protocol (MCP) endpoint.
You learn how to load tools,
identify tools that require approval, load toolbox skills as resources, and
prepare skills for deep agents.
Prerequisites
- An Azure subscription. Create one for free.
- A Foundry project.
- A deployed chat model (for example,
gpt-4.1) in your project. - A toolbox configured in your Foundry project. Note its name.
- Python 3.10 or later.
- Azure CLI signed in (
az login) soDefaultAzureCredentialcan authenticate.
langchain-mcp-adapters and httpx. To load
skills for deep agents, also install deepagents.
Configure your environment
The toolbox needs a project endpoint and a toolbox name. Provide them as constructor arguments or through environment variables. Set your environment variables:FOUNDRY_PROJECT_ENDPOINT environment
variable as a fallback for the project endpoint.
Import the common classes and initialize the model used throughout this
article:
Connect to a toolbox
UseAzureAIProjectToolbox from the namespace langchain_azure_ai.tools to
connect to a toolbox. The integration detects the project connection when you
set the FOUNDRY_PROJECT_ENDPOINT environment variable. Microsoft Entra ID
is the default authentication method.
Load tools from a toolbox
Callaget_tools() to open a session with the toolbox and load every tool it
exposes as LangChain BaseTool instances. Each call is stateless: it opens a
fresh MCP session, loads the tools, and returns them.
AzureAIProjectToolbox also supports the asynchronous context manager
protocol. The behavior is identical because each aget_tools() call manages
its own session:
Identify tools that require approval
Some toolbox tools are configured to require approval before they run. Callget_tools_requiring_approval() to retrieve the names of those tools so you
can add a human-in-the-loop step before execution.
require_approval to always. Use
this list to gate sensitive operations behind an approval workflow.
This capability is independent of OAuth consent handling. For more information
about human-in-the-loop approvals, see Use Foundry Agent Service with LangGraph.
Handle OAuth consent
Toolbox in Microsoft Foundry can handle on-behalf-of workflows. You can configure the authorization requirements when you add the tools to your toolbox.
get_tools()/aget_tools() returns a fallback tool that surfaces the consent URL so your
agent can present it to the user.
When you invoke an agent and the model calls the fallback tool, the response
contains a message similar to the following:
Load skills from a toolbox
A toolbox can expose skills. A toolbox exposes skills as MCP resources with URIs of the formskill://{name}. Use get_resources() to load them as LangChain Blob
objects. Each Blob carries the resource name in its source property and
its raw URI under metadata["uri"].
skill:// resource from the toolbox
as a Blob. The scheme="skills" filter restricts the results to skill
resources. The match is case-insensitive and accepts the singular or plural
form ("skill" or "skills").
To load specific resources, pass their URIs explicitly. When you provide
uris, the scheme filter is ignored:
aget_resources() for the asynchronous equivalent:
Load skills for deep agents
If you use thedeepagents package, call get_skills() to load toolbox
skills as a ready-to-use file mapping for create_deep_agent. This method
builds on get_resources() and removes the boilerplate of converting each
Blob into the file layout that deep agents expect.
Install the package:
StateBackend (the default). Leave the
backend argument unset and pass the returned mapping as the files payload
on invoke:
SKILL.md paths and seeds them into the agent state through the files
payload. The agent can then use the skills under the /skills/ base path.
To seed a backend with standalone storage, such as FilesystemBackend, pass
it as the backend argument. The skills are written into the backend, and the
same mapping is also returned:
/skills/ base path. Pass a
different base_path to change the location. The value must start and end with
a slash, and you pass the same value to the skills argument of
create_deep_agent.