mcp-chinookdb-server
Provides tools and resources to explore and query the Chinook sample SQLite database, including schema retrieval and read-only SQL query execution.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-chinookdb-serverShow the schema for the Track table."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-chinookdb-server
Example MCP Server to provide LLM MCP access to the example sqlite3 Chinook database
Overview
This project provides an MCP (Model Context Protocol) server for the Chinook SQLite database and a sample Agno agent client for interactive querying. It enables LLMs and other MCP-compatible clients to safely explore and query the Chinook database using a standardized protocol.
Related MCP server: sqlite-mcp-server
Key Features
Automatic Database Download:
Downloads and extracts the Chinook SQLite database if not present.
Resource Endpoints:
schema://chinook/tables: Returns the schema for all tables in the database.schema://chinook/table/{table_name}: Returns the schema for a specific table.
SQL Query Tool:
run_sql_query: Allows execution of read-only (SELECT) SQL queries. Only SELECT statements are permitted for safety.
Prompt Templates:
Provides prompt templates for common tasks, such as listing tables, showing table schemas, counting rows, and querying top artists.
Safe SQL Identifier Escaping:
Includes a local function to safely escape SQL identifiers for SQLite.
Agno Agent Integration:
Includes a sample client (
agno_test_client.py) that demonstrates how to connect to the MCP server and interact with it using an LLM agent.
How to Get Started
1. Installation
Clone the repository:
curl -LsSf https://astral.sh/uv/install.sh | sh git clone <your-repo-url> cd mcp-chinookdb-serverInstall Python dependencies using uv:
uv syncEnsure you have Python 3.8+ installed and uv available in your environment.
2. Running the MCP Server
Start the server:
uv run chinook_mcp_server.pyThe server will automatically download the Chinook database if needed and start listening for MCP requests (default: stdio transport).
3. Using the Agno Test Client
Start the interactive client:
uv run agno_test_client.pyThis will launch a REPL where you can type natural language queries about the Chinook database. The client will start the MCP server (if not already running) and use an LLM (e.g., OpenAI GPT-4) to interpret your queries and interact with the database via MCP tools.
Example queries:
List all tables.Show the schema for the Album table.How many tracks are there in the database?Who are the top 5 artists by number of tracks?
To exit: Type
q,quit, orexitat the prompt.
How the Programs Work
chinook_mcp_server.py
Implements an MCP server that exposes the Chinook database via resource endpoints, tools, and prompt templates.
Handles automatic download and extraction of the database.
Provides safe, read-only access to schema and data.
Designed to be used by LLMs or any MCP-compatible client.
agno_test_client.py
Demonstrates how to connect to the MCP server using the Agno agent framework.
Starts the MCP server as a subprocess (using
uv run chinook_mcp_server.pyfor fast startup).Uses an LLM (e.g., OpenAI GPT-4) to interpret user queries and call MCP tools/resources.
Provides a simple REPL for interactive exploration.
Security Notes
Only SELECT queries are allowed via the
run_sql_querytool.SQL identifiers are safely escaped to prevent injection.
Customization
You can add more MCP resources, tools, or prompts by following the patterns in
chinook_mcp_server.py.The client can be extended to use different LLMs or provide more advanced conversational features.
References
Chinook Database Overview
The Chinook SQLite database is a sample database that models a digital music store, similar to iTunes. It is widely used for SQL learning and demonstrations. The schema is designed to represent the core entities and relationships found in an online music store, including customers, employees, artists, albums, tracks, invoices, and more.
Concept Overview
Artists release albums.
Albums contain multiple tracks (songs or audio files).
Tracks are categorized by genre and media type.
Customers purchase tracks via invoices.
Employees represent staff, including sales support.
Invoice lines detail each track purchased in an invoice.
Playlists allow grouping of tracks for listening.
Main Tables and Columns
Artist
ArtistId(INTEGER, PK): Unique artist identifierName(NVARCHAR): Artist name
Album
AlbumId(INTEGER, PK): Unique album identifierTitle(NVARCHAR): Album titleArtistId(INTEGER, FK): Reference to the artist
Track
TrackId(INTEGER, PK): Unique track identifierName(NVARCHAR): Track nameAlbumId(INTEGER, FK): Reference to the albumMediaTypeId(INTEGER, FK): Reference to the media typeGenreId(INTEGER, FK): Reference to the genreComposer(NVARCHAR): Composer nameMilliseconds(INTEGER): Track lengthBytes(INTEGER): File sizeUnitPrice(NUMERIC): Price per track
Genre
GenreId(INTEGER, PK): Unique genre identifierName(NVARCHAR): Genre name
MediaType
MediaTypeId(INTEGER, PK): Unique media type identifierName(NVARCHAR): Media type name (e.g., MPEG audio, AAC audio)
Customer
CustomerId(INTEGER, PK): Unique customer identifierFirstName,LastName(NVARCHAR): Customer nameCompany,Address,City,State,Country,PostalCode(NVARCHAR): Contact infoPhone,Fax,Email(NVARCHAR): Contact infoSupportRepId(INTEGER, FK): Employee assigned to the customer
Employee
EmployeeId(INTEGER, PK): Unique employee identifierLastName,FirstName(NVARCHAR): Employee nameTitle(NVARCHAR): Job titleReportsTo(INTEGER, FK): ManagerBirthDate,HireDate(DATETIME): DatesAddress,City,State,Country,PostalCode,Phone,Fax,Email(NVARCHAR): Contact info
Invoice
InvoiceId(INTEGER, PK): Unique invoice identifierCustomerId(INTEGER, FK): Customer making the purchaseInvoiceDate(DATETIME): Date of invoiceBillingAddress,BillingCity,BillingState,BillingCountry,BillingPostalCode(NVARCHAR): Billing infoTotal(NUMERIC): Total amount
InvoiceLine
InvoiceLineId(INTEGER, PK): Unique line item identifierInvoiceId(INTEGER, FK): Reference to invoiceTrackId(INTEGER, FK): Reference to trackUnitPrice(NUMERIC): Price per trackQuantity(INTEGER): Number of tracks purchased
Playlist
PlaylistId(INTEGER, PK): Unique playlist identifierName(NVARCHAR): Playlist name
PlaylistTrack
PlaylistId(INTEGER, FK): Reference to playlistTrackId(INTEGER, FK): Reference to track
This schema enables a wide range of queries and analytics, such as finding top artists, most popular genres, customer purchase history, and more.
Available Tools
1 toolrun_sql_queryA
Executes a read-only (SELECT) SQL query against the Chinook database.
Only SELECT statements are allowed for safety.
Args:
sql_query: The SQL SELECT query to execute.
Returns:
Query results as a formatted string, or an error message.
| Name | Required | Description | Default |
|---|---|---|---|
| sql_query | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must disclose behavioral traits. It states the tool is read-only, only accepts SELECT queries, and returns a formatted string or error. This covers safety and output format but lacks details on authentication, rate limits, or error handling specifics. The information is adequate but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences: purpose/constraint, re-emphasis of constraint, and args/returns. It is brief and front-loads the key information. Minor redundancy ('read-only SQL query' and 'Only SELECT statements allowed') could be merged, but overall it is efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple tool (one parameter, no output schema), the description covers the essential: what it does, the constraint (SELECT only), and return format. It does not mention the database is a sample or any connection details, but for the tool's complexity, it is sufficiently complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% description coverage, so the description must compensate. The description explains the 'sql_query' parameter as 'The SQL SELECT query to execute,' which clarifies it must be a SELECT. However, it does not specify formatting, escaping, or length constraints. This adds some meaning but not comprehensive detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool executes read-only SQL SELECT queries against the Chinook database. It specifies the verb (executes), resource (Chinook database), and action type (SELECT only), which is specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states that only SELECT statements are allowed, which implies read-only usage. However, it does not provide explicit guidance on when to use this tool versus alternatives, nor does it mention when not to use it. Since no sibling tools exist, the lack of comparison is less critical, but the guideline is still minimal.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v0.1.0- First observed
run_sql_query
TDQS
Scored across 1 tool
Only one tool exists, so no ambiguity whatsoever.
Single tool uses clear snake_case verb_noun pattern, perfectly consistent.
One tool is on the low end; while it covers the core querying need, a few additional tools for schema discovery would improve utility.
Provides the essential SELECT query capability but lacks metadata tools (e.g., list tables, describe columns), which agents may need to form correct queries.
Maintenance
Related MCP Connectors
Read-only MCP server for ClassQuill, a tutoring-business-management platform.
An MCP server that provides an API to LLMs to manage their JumpCloud resources.
Read-only MCP server exposing a user ORANO library to their own AI agent.
Query, join, profile, clean and convert CSV/JSON/Parquet with server-side DuckDB over MCP.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAn MCP server that provides safe, read-only access to SQLite databases through MCP. This server is built with the FastMCP framework, which enables LLMs to explore and query SQLite databases with built-in safety features and query validation.107-
- AlicenseNot gradedqualityCmaintenanceA read-only MCP server that enables LLMs to safely explore and query any SQLite database via natural language. It exposes tools for listing tables, describing schemas, and executing SELECT/WITH queries with built-in safety guards like write prevention and row limits.MIT
- AlicenseNot gradedqualityCmaintenanceRead-only MCP server for SQLite databases, enabling AI assistants to safely query and inspect database schemas without write access.MIT
- AlicenseNot gradedqualityCmaintenanceRead-only MCP server for SQL databases (SQLite/PostgreSQL) that enables listing tables, describing schemas, and executing SELECT queries with safety guardrails.MIT