Tools: Built-in, Custom, OpenAPI & MCP
Give the agent hands: built-in tools (code interpreter, web search), your own function tools, an entire REST API via OpenAPI, and the 1,400+ tools available through MCP — all surfaced as ordinary, read-only tools.
Download starter repoOn this page▾
- Before you start: this is a billed Azure service
- About this series
- What you'll build
- Why this matters (the 5-minute business case)
- Concepts you'll use (2-minute primer)
- Prerequisites
- Step 1 — Built-in tools (no code)
- Step 2 — A custom function tool
- Step 3 — An OpenAPI tool (a whole REST API from its spec)
- Step 4 — MCP (the open tool ecosystem)
- Step 5 — Wire the tools onto the agent
- A note on governed access
- Cost & cleanup
- Verified against
- What's next
Before you start: this is a billed Azure service
- Cost and account. An Azure subscription, a Foundry project, and a model deployment. Tool calls (and any external services they reach) bill per use. Tear down test setups.
- Authored against the docs, not executed live. Code is written against the official docs and syntax-checked, not run during authoring. Tool class names and parameters move — pin your SDK version and verify.
- Two languages, hybrid. Python-primary with .NET noted; you'll use the portal (Add Tools catalog) and the SDK.
About this series
This is Part 4 of the twelve-part Microsoft Foundry series. Lab 3 gave the agent knowledge. This lab gives it hands — the ability to reach real systems and capabilities: built-in tools, your own functions, any REST API via OpenAPI, and the 1,400+ tools available through MCP.
What you'll build
You'll connect the Acme Orders assistant to capabilities through four kinds of tools, simplest to most powerful:
- Built-in tools — switch on capabilities like code interpreter and web search with no code.
- A custom function tool — your own Python function the agent can call.
- An OpenAPI tool — an entire REST API turned into tools from its spec.
- MCP — connect a remote Model Context Protocol server (from the Add Tools catalog or in code) and use its tools.
By the end the agent can run code, search the web, call your function, hit Acme's REST API, and use any MCP-served tool — through one consistent interface.
Why this matters (the 5-minute business case)
Read this before handing the lab to your team.
Tools are where an agent stops talking and starts doing. A grounded agent can tell a customer their return window; a tool-using agent can look up their actual order and start the return. Everything valuable an agent does in production runs through tools — and how you connect them is an architecture decision, not a detail.
Three reasons this is a leadership-level concern:
- It's M×N versus M+N integration economics. Without a standard, every agent needs a bespoke integration to every system — an M×N explosion of glue nobody maintains. OpenAPI and MCP turn that into M+N: build (or adopt) the connection once, any agent uses it. Foundry's 1,400+ MCP-enabled tools are that leverage off the shelf.
- It makes tool access governable. Routing tools through the platform's catalog and connectors — rather than API keys scattered in code — gives you one place to manage credentials, scope what each agent can reach, and audit what it did. Ungoverned tool access is how a helpful agent becomes a security incident.
- It meets your systems where they are. Most enterprise value is locked in existing APIs, databases, and SaaS. OpenAPI covers your own services; MCP covers the fast-growing external ecosystem; built-in tools cover the common cases — without a rewrite.
The honest caveats:
- A tool is a permission. The moment an agent can call an API, "what may it do, and on whose behalf?" is a live security question. Keep tools least-privilege and read-only until the safety and identity layers are in place (Labs 7–8). This lab keeps writes out.
- More tools, more surface. Each connected system can fail, leak, or be abused. Connect what the agent needs, not everything it might.
- MCP is powerful and open — vet what you connect. A remote MCP server is third-party code reaching your agent. Use trusted servers and scope them.
A framing for a non-technical stakeholder: "Tools are how the agent reaches our systems and the outside world — our APIs, our database, web search, and a large catalog of ready-made tools. We connect them through governed, reusable standards so any agent can use them safely."
Concepts you'll use (2-minute primer)
- Built-in tools — ready-to-use capabilities (code interpreter, web search, and Foundry-exclusive ones like SharePoint and Fabric) you enable without code.
- Function tool — your own Python function exposed to the agent; the SDK builds the schema from its signature and docstring.
- OpenAPI tool — point it at an OpenAPI (v3) spec and every operation becomes a callable tool. No hand-writing a function per endpoint.
- MCP — connect a remote MCP server (added from the portal's Add Tools catalog or in code); its tools become agent tools. Foundry exposes 1,400+ MCP-enabled tools this way.
One sentence: built-in for common cases, function tools for code you own, OpenAPI for your REST APIs, and MCP for the open tool ecosystem — all surfaced to the agent as ordinary tools.
Prerequisites
| You need | Notes |
|---|---|
| A Foundry project + model deployment | From Labs 1–2 |
| The SDK | pip install azure-ai-projects azure-identity — pin it |
| An OpenAPI spec | A sample Acme Orders API spec is in the starter repo |
az login | Code uses DefaultAzureCredential |
| Optional: an MCP server | A trusted remote MCP server for Step 4 |
Step 1 — Built-in tools (no code)
The fastest capability. In the portal's Add Tools catalog (or via the SDK), enable a built-in tool such as code interpreter (for calculations/data work) or web search (for current info). For Microsoft-centric shops, SharePoint and Fabric tools are built in too.
from azure.ai.agents.models import CodeInterpreterTool
code = CodeInterpreterTool()
# add code.definitions / code.resources to the agent definition (see Step 5)Reach for built-in tools first — they cover common needs with zero integration work.
Step 2 — A custom function tool
For logic you own, expose a plain Python function. The SDK reads its signature and docstring to build the schema the model sees:
def get_order_status(order_id: str) -> dict:
"""Look up the status of an Acme order by its ID.
Args:
order_id: The customer's order identifier, e.g. "AC-10231".
"""
return {"order_id": order_id, "status": "shipped", "eta": "2026-07-02"}Function tools are for capabilities only your code can provide; the next two steps are about not hand-writing a function for every external system.
Step 3 — An OpenAPI tool (a whole REST API from its spec)
If Acme has a REST API with an OpenAPI spec, hand the spec to an OpenAPI tool and get every operation as a callable tool:
from azure.ai.agents.models import OpenApiTool, OpenApiAnonymousAuthDetails
with open("acme_orders_api.yaml") as f:
spec = f.read()
api_tool = OpenApiTool(
name="acme_orders_api",
description="Acme Orders REST API.",
spec=spec,
auth=OpenApiAnonymousAuthDetails(), # use a real auth scheme in production
)Each operation becomes a tool named from its operationId — which is exactly why good API descriptions matter: they're now the agent's interface too.
Step 4 — MCP (the open tool ecosystem)
Connect a remote MCP server and its tools become agent tools. Add one from the portal's Add Tools catalog, or wire it in code:
from azure.ai.agents.models import McpTool
mcp = McpTool(
server_label="acme_orders_mcp",
server_url="https://mcp.acme.example.com/orders",
# scope which of the server's tools are allowed:
allowed_tools=["get_order", "list_orders"],
)This is the M+N payoff: a tool server built once — by you or a vendor — is usable by this agent and any other MCP-aware agent, no new glue. Foundry's catalog of 1,400+ MCP-enabled tools means a lot of that is already done.
Vet remote MCP servers. They're third-party code your agent will call. Use trusted servers, scope allowed_tools, and keep them read-only until Labs 7–8 add safety and identity.Step 5 — Wire the tools onto the agent
Combine the tool definitions/resources when you create the agent:
agent = project.agents.create_version(
agent_name="acme-orders-assistant",
definition={
"model": "gpt-5-mini",
"instructions": (
"You are the Acme Orders assistant. Use your tools to look up "
"orders, call the Acme API, run calculations, and use connected "
"services. Prefer the most specific tool. If no tool can answer, "
"say so — don't guess."
),
"tools": [*code.definitions, get_order_status, *api_tool.definitions, *mcp.definitions],
"tool_resources": api_tool.resources, # plus others that need resources
},
)The model picks the right tool per request — and because each tool's name and description is its interface, clear descriptions are what make that choice reliable.
Exact wiring (howdefinitions/resourcesand function tools combine in onecreate_versioncall) varies by SDK version. Pin your version and check the docs; the concept — definitions + resources attached to the agent — is stable.
.NET note: the same tools exist inAzure.AI.Agents(CodeInterpreterToolDefinition,OpenApiToolDefinition,McpToolDefinition, function tools). Names mirror Python.
A note on governed access
You just gave one agent several routes into real systems. Before production:
- Keep it read-only until the safety (Lab 7) and identity (Lab 8) layers are in place. Everything above is read-only on purpose.
- Scope at the tool/connection, not in the prompt.
allowed_tools, the API's auth scope, and connection permissions are real enforcement; an instruction is not. - Prefer the catalog, connectors, and MCP over raw keys in code. Centralized, auditable access beats scattered secrets.
Cost & cleanup
- Delete the test agent when done (
project.agents.delete_version(...)). - Remove any connections or MCP integrations created only for this lab.
- Stop any local MCP server you ran.
- Confirm in Cost Management that nothing is still accruing.
If a lab created it and you're done, delete it today.
Verified against
- Microsoft Foundry tool catalog docs (built-in tools, function tools, OpenApiTool, McpTool) and the `azure-ai-projects` /
azure-ai-agentsSDK, June 2026;.NETviaAzure.AI.Agents. - Tool class names and the wiring API vary by SDK version; code is syntax-checked against the docs but not executed during authoring. Pin your version.
What's next
Your agent can now reach the world. Next:
- Lab 5 — Threads & memory: give the agent durable context — short-term threads and managed memory, with the option to keep conversation data in your own store.
- Grounding (Lab 3) + tools (this lab) are what the agent knows and can do; memory (Lab 5) is what it remembers.
Written by Wes Goldwater, Director of Engineering at Prosigliere.
Hands-on cloud & pragmatic AI from Goldwater.dev.