Data API builder 2.0 (currently in public preview) is a major release focused on MCP and AI integration. Among its headline features is the ability to expose stored procedures as custom MCP tools, making them discoverable and callable by AI agents. No glue code, no middleware, no extra plumbing.
In this post I'll walk through how the feature works, and show a practical example: wiring up a full-text search stored procedure as its own dedicated tool that any MCP client can discover and call by name.
The idea: a dedicated search tool
By default, DAB's SQL MCP Server exposes tables and views through generic DML tools — things like list_books, get_book, and so on. These are useful for straightforward CRUD, but they're not designed for complex operations like full-text search.
With custom-tool: true, you can go further. Set that flag on a stored-procedure entity and DAB dynamically registers the procedure as a named, purpose-built tool in tools/list. The AI agent discovers it by name, reads its description, and calls it directly — no SQL knowledge required.
Naming note: tool names are derived from the entity name, converted to snake_case. An entity called SearchProducts appears in the tool list as search_products. Use the snake_case name when calling the tool.
Step by step: adding a search command
Here's how to add a custom SearchProducts tool backed by a stored procedure that does full-text search across product names and descriptions.
1. Install the 2.0 preview CLI
dotnet tool install microsoft.dataapibuilder --prerelease
2. Enable MCP in your configuration
dotnet dab configure --runtime.mcp.enabled true
3. Add the stored procedure as a custom tool
dotnet dab add SearchProducts \ --source dbo.search_products \ --source.type "stored-procedure" \ --permissions "anonymous:execute" \ --mcp.custom-tool true \ --description "Full-text search across product names and descriptions"
This produces the following in your dab-config.json:
4. Start DAB and verify the tool is registered
dotnet dab start
When an MCP client calls tools/list, it sees your tool alongside the built-in DML tools:
tools/list response
{
"tools": [
{
"name": "search_products",
"description": "Full-text search across product names and descriptions",
"inputSchema": {
"type": "object",
"properties": {}
}
}
]
}
Why descriptions matter
The --description flag might look optional, but it's arguably the most important part of the setup. Without a description, an agent sees only the technical name. With a good description, it understands what the tool does, when to use it, and what kind of input it expects.
The inputSchema currently returns empty properties. Agents rely on the tool description and describe_entities to determine the correct parameters, so write descriptions that are specific and actionable.
A few things worth knowing
Only works on stored procedures
The custom-tool flag is only valid on entities with source.type: stored-procedure. Setting it on a table or view entity causes a configuration error at startup.
RBAC is respected
Custom tools honour the same role-based access control as every other DAB entity. If you restrict the entity to authenticated only, the tool won't appear in tools/list for anonymous agents, and any direct call returns a permission error.
You can register multiple tools
There's no limit. Run dab add for each procedure you want to expose. They all show up in the MCP tool list alongside each other.
You can disable without deleting
Set --mcp.custom-tool false via dab update to hide the tool from agents without removing the entity from your config. Re-enable it anytime by flipping the flag back to true.
More information
What's new for version 2.0 - Preview - Data API builder | Microsoft Learn
Data Manipulation Language Tools (DML) - SQL MCP Server | Microsoft Learn