4 Connecting Databases
The first three chapters worked with individual files — a CSV placed in a folder, a memo pasted into a conversation. Most real business data does not live in spreadsheets. It lives in databases: structured collections of related tables, hosted on servers, queried with SQL.
This chapter connects AI to those databases. By the end, you will understand how your organization can create tools so that everyone can query a database in plain English — no SQL required. As throughout this book, the examples use Claude Code, but the same workflows apply to Gemini CLI and OpenAI Codex.
4.1 The dashboard trap
Organizations spend millions building dashboards that answer yesterday’s questions. The cycle is familiar: a user requests a report, an analyst builds it, IT deploys it to Tableau or Power BI, and then the user asks a follow-up question — which starts the cycle over.
The cost is measured in three dimensions. Time: weeks to months per dashboard. Rigidity: fixed views of fixed data that cannot adapt to a new question. Adoption: according to Gartner (2023), fewer than half of data and analytics teams effectively provide value to their organizations.
The dashboard was a workaround for the fact that databases do not speak English. Now they do. With natural language AI, you skip the entire build cycle and go straight from question to answer. Ask in plain English instead of writing SQL and ask whatever you want instead of being limited to dashboard views. Get answers in seconds instead of weeks. Follow-up questions are free — just type the next sentence.
4.2 From spreadsheets to databases
In Chapter 2 you analyzed a spreadsheet — a single table of rows and columns living in a file on your machine. Most real business data lives in databases: many related tables linked by keys, hosted on a server, queried with SQL.
SQL is the language databases understand. You do not need to learn it. AI writes the SQL for you. But you do need to tell the AI what is in the database — which tables exist, what the columns mean, and how the tables relate to each other.
4.3 How AI connects to a database
There are several ways to give AI access to your data, ranging from simple to sophisticated.
Skill files. The simplest approach: write a markdown file that describes your database schema and hand it to a coding agent. The agent reads the description, writes SQL, and executes it. No special infrastructure is needed — just a file and a coding agent that can run code. This is what we build in this chapter.
Direct API calls. A lightweight application — even fifty lines of Python — can send a user’s question and a schema description to an LLM, get back SQL, run it, and display the results. This is the pattern behind the demo app at the end of this chapter. It works for prototypes and internal tools where you control the deployment.
MCP (Model Context Protocol). An open standard that lets AI connect to external tools — databases, CRMs, calendars, anything with an API. Think of it as USB for AI. The AI assistant acts as an MCP client and connects to MCP servers that wrap external systems. MCP is most useful when you need to connect to many different tools in a single conversation or when IT wants a standardized way to manage AI’s access to corporate systems.
Vendor platforms. Salesforce, Snowflake, Databricks, and others are embedding natural-language query directly into their products. If your data already lives in one of these platforms, you may not need to build anything — just enable the feature.
All of these approaches share the same core idea: give the AI a description of your data and let it write the query. The differences are in how the description is delivered, who runs the query, and how much infrastructure is involved. We start with skill files because they require no setup and teach the underlying pattern that every other approach builds on.
4.4 The sample database: Chinook
The exercises in this chapter use the Chinook sample database, which you can download here: chinook.db. It represents a music retailer’s operations and contains 11 related tables.
The key tables are employees (8 staff members), customers (59 customers across 24 countries), invoices and invoice_items (412 transactions), and tracks, albums, artists, and genres (a product catalog of more than 3,500 tracks). It is a publicly available SQLite file that requires no setup — just place it in a folder and point your coding agent at it. The same skill pattern you learn here works with any database.
4.5 What is a skill?
A skill is a set of instructions that specializes a general-purpose AI for a specific task. Every AI customization works the same way: additional text is added to the prompt. A skill provides three things: domain knowledge (what the data means), workflow instructions (how to do the task), and output format specifications (how to present results).
Skills are not limited to databases. You could build a skill for weekly report generation, customer support analysis, or any recurring task where AI benefits from domain context.
4.6 The SKILL.md file
The skill is a markdown file that the coding agent reads when you invoke it. The structure has three parts.
The first part is the description and location: what the skill does and the path to the database file.
The second part is the schema and relationships: every table, its columns, data types, and how tables link to each other. This is the most important part. The more precisely you describe the schema, the better the AI’s queries will be. Include column descriptions (“status is one of: active, completed, on-hold”), explain join paths (“invoices link to customers via CustomerId”), and note any business logic (“revenue means invoice_items.UnitPrice times Quantity”).
The third part is the instructions: query style, output format, and chart preferences. For example: “Always show the SQL query before showing results. Use Plotly for interactive charts. Annotate the highest and lowest values.”
The skill file is just text. Anyone can edit it. No programming is required — just clear descriptions of your data.
4.7 Creating the skill step by step
Create a project folder with the SQLite database file and a file called SKILL.md. Write the schema, describing each table, its columns, and its relationships. Then test by asking questions and refining based on what Claude gets wrong.
Your first draft will not be perfect, and that is fine. The skill improves through iteration. Every time Claude misinterprets a question or uses the wrong join path, you add a clarification to the SKILL.md. After a few rounds of testing, the skill handles the most common questions reliably.
You do not have to write the skill from scratch. Point your coding agent at the database and ask it to generate the SKILL.md for you. It will inspect the tables, columns, and foreign keys and produce a first draft. Your job is to read the result, verify that the descriptions match your understanding of the data, and add any business context the agent could not infer on its own.
4.8 Building the Chinook skill
To make this concrete, consider a scenario. You are an operations director at a music retailer. The CEO wants a recommendation by Friday: which markets to invest in, which product lines to promote, and how to improve per-customer revenue.
The data lives in the Chinook database. The answer requires joining customer, invoice, and catalog data across multiple tables. There is no time to wait for an analyst.
The solution: build a skill that knows the Chinook schema, then ask questions in plain English. The agent writes SQL, runs it, and returns charts.
4.9 Decision-driven queries
With the skill active, every question should connect to the CEO’s decision.
“Top five countries by revenue, bar chart, sorted” produces a bar chart comparing categories. “Monthly revenue trend line — is the business growing?” produces a line chart showing trends over time. “Plot average order value versus number of orders by country” produces a scatter plot that reveals clusters of high-value versus high-frequency markets.
You can go deeper. “Correlation heatmap of all numeric columns” shows which metrics move together. “Make that chart interactive so I can hover for details” switches from matplotlib to Plotly, saving the result as an HTML file. “Annotate the outlier country on the scatter plot” adds context to the visualization.
Each question is a different lens on the same decision. The skill ensures that every query uses the correct tables, joins, and business logic.
4.10 SQL transparency
One of the most important features of this workflow is that you can always see the SQL. When you ask “Which country generates the most revenue? Show a bar chart of the top 10,” Claude generates a SQL query that selects country and summed revenue from the invoices and customers tables, groups by country, orders by revenue descending, and limits to ten results.
You can read the SQL and verify that the joins are correct, the filters make sense, and the aggregation matches your intent. Analysts can review the logic. This builds trust: AI is not a black box.
If you ask a follow-up — “Break down the US revenue by state” — Claude writes a new query with a WHERE clause and additional grouping. The SQL is always available for inspection.
4.11 Iterating on the skill
Common refinements include adding column descriptions, specifying default sorting and format rules, and setting chart preferences. You can specify whether charts should be static (matplotlib, good for reports and slides) or interactive (Plotly, with hover, zoom, and filter, saved as HTML files and shareable via email). The same prompt works for both — just add “interactive” or “Plotly.”
Skills turn institutional knowledge into executable instructions. Instead of a procedures manual that sits on a shelf, you have a prompt that AI follows every time. The knowledge is not just documented; it is operationalized.
4.12 Behind the firewall
Understanding the data flow matters for security. When you use a coding agent, the flow works like this: you type a question, the agent sends your question and the schema description to the LLM (hosted in the cloud), the LLM returns SQL, and the agent executes that SQL against your database locally. The raw data never leaves your network — only your question and the schema travel to the cloud. The query results stay on your machine.
In a deployed app (like the Streamlit demo), the app replaces the coding agent: the app sends the question to the LLM, receives SQL back, runs it against the database, and displays results to the user. Again, the LLM never sees the actual data — only the question and the schema.
IT controls which databases the agent or app can access and can restrict connections to read-only credentials.
For organizations that need to connect AI to multiple systems — databases, CRMs, ticketing tools — MCP provides a standardized way to manage those connections. MCP connectors exist for Salesforce, Jira, Slack, internal databases, and anything else with an API.
Claude Code has native MCP support, and Gemini CLI also supports MCP servers. Codex uses a different tool-integration mechanism but can connect to the same databases through its own plugin system. The skill-file pattern described in this chapter works with any agent that can read a markdown file and execute SQL.
In this chapter we connect to a local SQLite file. In your organization, the same pattern connects to PostgreSQL, Snowflake, or any database your team uses.
4.13 The skill as deployment artifact
A polished skill is what gets deployed on your intranet. The skill file encodes which tables matter, how they relate, and what the business terminology means. IT adds the infrastructure: SSO authentication, read-only database credentials, and query logging for audit. Chapter 5 shows how to chain this skill into an automated reporting pipeline.
4.14 A natural-language query app
The skill-file approach works well with a coding agent, but what about the rest of your organization? Not everyone will use a terminal. The same pattern — send a question and schema to an LLM, get SQL back, run it — can be wrapped in a simple web app that anyone can use from a browser.
In production, this app would be deployed on the corporate intranet, the database would be a PostgreSQL or Snowflake instance on the company’s servers, and the LLM would be an enterprise-licensed model (more on licensing and compliance in Chapter 7). For this demo, we run everything locally: a small Streamlit app on your laptop, the Chinook SQLite file in the same folder, and a free LLM API from OpenRouter.
Setting up the demo
You need a free OpenRouter API key. Go to openrouter.ai, create an account, and generate an API key from your dashboard. Set it as an environment variable:
export OPENROUTER_API_KEY="sk-or-..."Download the app files here: app.py and requirements.txt. Copy chinook.db into the same folder, install the dependencies, and run:
pip install -r requirements.txt
streamlit run app.pyWhat the app sends to the LLM
When you type a question, the app sends two things to the LLM: a system prompt containing the database schema, and your question. Here is the system prompt (abbreviated):
You are a SQL assistant. Given the schema below and a user
question, return ONLY a single SQLite SELECT statement.
The Chinook database has these tables:
artists(ArtistId, Name)
albums(AlbumId, Title, ArtistId) → artists
tracks(TrackId, Name, AlbumId, GenreId, UnitPrice) → albums, genres
invoices(InvoiceId, CustomerId, InvoiceDate, Total) → customers
invoice_items(InvoiceLineId, InvoiceId, TrackId, UnitPrice, Quantity)
...
Revenue = SUM(invoice_items.UnitPrice * invoice_items.Quantity).
Notice what is not in this prompt: no actual data. The LLM sees only the table and column names — the same schema description you would put in a skill file.
What comes back
If you ask “What are the top 5 countries by revenue?”, the LLM returns pure SQL:
SELECT c.Country, SUM(ii.UnitPrice * ii.Quantity) AS Revenue
FROM invoice_items ii
JOIN invoices i ON ii.InvoiceId = i.InvoiceId
JOIN customers c ON i.CustomerId = c.CustomerId
GROUP BY c.Country
ORDER BY Revenue DESC
LIMIT 5;The app runs this query against the local chinook.db file and displays the results in a table. The generated SQL is shown above the results — the same transparency principle discussed in the “SQL transparency” section. The LLM never sees the query results; it only writes the SQL.
The data flow
The complete round trip looks like this:
- You type a question in the browser.
- The app sends your question + the schema description to the LLM (cloud).
- The LLM returns a SQL query (cloud → your machine).
- The app executes the SQL against the database (entirely local).
- The app displays the results in your browser (entirely local).
The only things that leave your machine are the question and the schema. The actual data — customer names, revenue figures, transaction records — never goes to the cloud.
From demo to production
This is a demo, not a production application. There is no authentication, no guardrails on the SQL, and no sandboxing of query execution. In a production deployment, IT would add SSO login, restrict the database connection to read-only credentials, log every query for audit, and use an enterprise LLM with a data-processing agreement. Chapter 7 covers these considerations in detail. But as a prototype that proves the concept, fifty lines of Python is all it takes.
4.15 Exercises
Download chinook.db and place it in a new project folder. Create a SKILL.md file in the same folder with three sections: a description and database path, at least three table descriptions with columns and relationships, and three example questions.
Open your coding agent in the folder and test three decision-relevant queries. For each, ask Claude to show the SQL and verify that the joins and filters are correct. Then ask for an interactive Plotly chart and iterate on it at least once — change colors, add annotations, or improve the layout.
You should end up with a working SKILL.md and at least one interactive chart.
Connect your coding agent to the Chinook database without any SKILL.md — no documentation at all.
Ask: “What tables are in this database? How are they related?” Let Claude discover the schema on its own. Then ask: “If I were the CEO of this music company, what three questions should I be asking?”
Follow up with two questions that require joining at least two tables (for example, “Revenue by artist” requires joining invoices, invoice_items, tracks, albums, and artists).
Compare the agent’s schema discovery to what you know from the chapter. Did it miss anything?
You are the Chinook CEO. The board wants you to cut two of the five lowest-performing genres from the catalog to reduce licensing costs.
Using your Chinook skill (or a bare connection to chinook.db), answer these questions in sequence: Which genres contribute the least revenue? For those two genres, how many unique customers would be affected? Are any of those customers high-value customers who also buy other genres?
Write one sentence stating which two genres you would cut and why.
Take a CSV from your work (anonymize if needed) or a public dataset you care about. Ask the agent to convert it to a SQLite database. Then write a SKILL.md describing the tables, columns, relationships, and five example questions.
If you do not have a work dataset, try one of these public sources:
- Kaggle Datasets — thousands of downloadable CSVs across business, finance, healthcare, sports, and more.
- UCI Machine Learning Repository — classic datasets for analysis, including census, retail, and banking data.
- data.gov — U.S. government open data on economics, education, health, and public safety.
- World Bank Open Data — country-level economic and development indicators.
Test five queries and refine the skill until all five return correct results.
Identify a recurring report your team produces — weekly sales summary, monthly KPIs, pipeline report. Write a SKILL.md that includes the database schema, the specific queries needed, and the output format.
Add an instruction to the skill: “When I say ‘Monday report,’ run these three queries and format the results as a one-page summary.” Test it. Does one command produce your entire report?
Ask your coding agent to build a natural-language query app similar to the chinook-query demo, either from scratch or by improving the demo. Possible extensions: add chart generation for numeric results, show query history in a sidebar, add error handling that suggests corrections when the SQL fails, or let the user choose between different databases.