SQL MCP for Dynamic SQL: I want my money back and I didn't even buy it

SQL MCP for Dynamic SQL: I want my money back and I didn't even buy it

July 13, 2026 • by Rob Taylor Connecting to Data

Naturally, I like to bring good news to people! Sometimes, bad news is good news if it is the best news available.

I went on a foray this weekend - more like a mission - to add SQL capabilities to my model, giving me deep, broad vision into my database. The strategy was to pull the SQL Model Context Protocol (MCP) container from the Microsoft Artifact Registry (MAR) and add it to my model. The assumption was that if I added a view to my SQL database and configured the Data API builder (DAB) to read it, I would harness all the power that an agentic model and a SQL database have to offer.

By the time the adventure was over, I was questioning why the SQL MCP container is even offered.

It's a lot of work; it "works," but it doesn't really work.
Make no mistake - it functions, but the things it is capable of doing are very limited and basic. Even within those limitations, it is still incredibly fragile. Furthermore, the length of the directions you need to provide to make it work is often longer than the results it spits out.

Take a look at these directions. This prompt actually returns data. Look at all the precise constraints you must provide just to get a clean data return. You would think that with all those corrections, the final list would be pristine. It gets the dates of the games right. It gets the teams the Sabres played correct. After that, there are errors all over the place.


Do not guess column names.

First use describe_entities to confirm the exact field names for TrendData. Then use only the MCP SQL tool read_records.

Query TrendData for all records where:
• NHLSeasonID = 37
• and (Home_Team_Name = 'Sabres' or Away_Team_Name = 'Sabres')
Important:
• Retrieve the complete result set, using paging if necessary.
• Do not stop after the first page of results.
• Use a stable sort order by Game_Date asc.
• Request only these columns: Game_Date, Home_Team_Name, Away_Team_Name, Home_Team_City, Outcome_Type, Outcome_Type_OT, Goals_Scored

After retrieval:
• deduplicate by Game_ID
• parse Game_Date locally
• return every game played on or between 01/01/2026 and 01/31/2026
• Put the results in a nicely formatted table
• Sum the Win/Loss record for all games returned and put it at the bottom


Results from API request to model using SQL CMP

Right off the bat, the Sabres lost on 01/03; they didn't win. The Sabres won on 01/08; they didn't lose. At the bottom, it says "7 Wins – 8 Losses." That is backwards. The list shows 8 wins and 7 losses, but that is irrelevant because they actually went 10-4-1 in the month of January—well over .500. No matter what I tried- and I tried mightily - I could never get consistent results, even for a query running against a view where you would think it would be very easy to pull back a list of games between two dates with everything correct.

Soldiering On
In searching for solutions - which pretty much means Copilot, Gemini, and Claude these days—I found suggestions that made things better. One thing Copilot recommended was putting column definitions in the DAB config file. This made it more consistent in returning data, but it did nothing for the accuracy of the data. After a few hours of playing with it, I think I wore Gemini and Copilot out. Gemini kept dropping hints that this approach would never produce what I want. Finally, Copilot laid it out clearly with this message:

copilot message regarding SQL MCP and DAB

And by that time, it didn't take much for me to agree.

Leaving this Race for Hugging Face
Determined to find a solution and learn as much as I can about raw data interoperability with agentic models, I already know my next move. The plan is to move over to Hugging Face and set up a Qwen Instruct model using the smolagents library. I like what I am reading.

A Qwen Instruct and smolagents solution will rely on text-to-SQL. That is a dangerous game, I know. However, those risks are minimized when the system is not public-facing and is properly locked down. Like I said, I have a plan, and I will post updates as I go.



← Back to Blog