Skip to main content
Glama
rajacsp

Text2SQL MCP Server

by rajacsp

Text2SQL MCP Server - Natural Language Database Queries

License: MIT

Convert natural language questions into SQL queries and execute them against SQLite database. Get results in table or string format.

Overview

Text2SQL is an MCP (Model Context Protocol) server that enables natural language querying of SQLite databases. Ask questions in plain English and get results formatted as tables or strings. Perfect for data analysis, reporting, and exploration without writing SQL.

Key Capabilities:

  • Convert natural language to SQL automatically

  • Support for COUNT, SELECT, AVG, SUM operations

  • Smart condition parsing (age, price, category, rating, stock)

  • Multiple result formats (string for single values, table for multiple rows)

  • Works seamlessly with Kiro and Cline

  • 9 comprehensive unit tests included

Related MCP server: AnyDB MCP Server

Quick Start (5 minutes)

# 1. Populate database with sample data
python populate_kinto_db.py

# 2. Run example client
python src/text2sql_example.py

# 3. Try questions like:
# "How many users do I have?"
# "Show me top 2 users aged above 70"
# "What is the average product price?"

Setup with Kiro

./setup_mcp.sh
# Restart Kiro

Then ask questions naturally:

"How many users do I have?"
"Show me top 2 users aged above 70"
"What is the average product price?"
"Show me products in Electronics category"

Setup with Cline

./setup_cline.sh
# Restart VSCode

Use the same natural language queries in Cline.

Query Examples

Question

Answer

"How many users do I have?"

50

"Show me top 2 users aged above 70"

[Table with 2 rows]

"What is the average product price?"

125.50

"Show me products in Electronics category"

[Table with products]

"How many orders have been placed?"

100

Database Schema

Table

Columns

users

id, name, email, age, created_at

products

id, name, price, stock, category

orders

id, user_id, product_id, quantity, order_date

reviews

id, product_id, user_id, rating, comment, review_date

inventory

id, product_id, warehouse_location, quantity_available, last_updated

Supported Query Types

  • Count: "How many users?" → SELECT COUNT(*) FROM users

  • Select: "Show me users" → SELECT * FROM users

  • Conditional: "Users aged above 70" → SELECT * FROM users WHERE age > 70

  • Limit: "Top 5 users" → SELECT * FROM users LIMIT 5

  • Aggregate: "Average price?" → SELECT AVG(price) FROM products

Supported Conditions

  • Age: "above 70", "over 70", "> 70", "below 30"

  • Price: "above 100", "below 50"

  • Category: "Electronics", "Books", etc.

  • Rating: "above 4", "over 4"

  • Stock: "above 100"

MCP Tools

query_database

Convert natural language to SQL and execute.

{"question": "How many users do I have?"}

get_database_schema

Get database schema information.

execute_sql

Execute raw SQL (advanced users).

{"sql": "SELECT * FROM users WHERE age > 70 LIMIT 5"}

Python Usage

from text2sql import Text2SQL

text2sql = Text2SQL(db_path="kinto.db")
result = text2sql.query("How many users do I have?")

if result.success:
    print(f"SQL: {result.query}")
    print(f"Answer: {text2sql.format_result(result)}")

Installation

Option 1: Manual installation

pip install -r requirements.txt

Option 2: Using Docker

docker-compose up -d
# or
make docker-build
make docker-run

Option 3: Using Makefile

make install    # Install dependencies
make run        # Run servers
make example    # Run example client
make test       # Run tests
make help       # Show all commands

Testing

Quick Test

# Run the example client with pre-defined queries
python src/text2sql_example.py

This will show you example queries and their results, then enter interactive mode where you can ask your own questions.

Unit Tests

# Run all unit tests (9 test cases)
make test-text2sql

Or directly:

python -m unittest src.test_text2sql -v

Manual Testing with Kiro

  1. Run setup:

./setup_mcp.sh
  1. Restart Kiro

  2. Ask questions naturally:

"How many users do I have?"
"Show me top 2 users aged above 70"
"What is the average product price?"

Manual Testing with Cline

  1. Run setup:

./setup_cline.sh
  1. Restart VSCode

  2. Use Cline with same questions

Python Testing

from text2sql import Text2SQL

text2sql = Text2SQL(db_path="kinto.db")

# Test a query
result = text2sql.query("How many users do I have?")
print(f"Success: {result.success}")
print(f"SQL: {result.query}")
print(f"Answer: {text2sql.format_result(result)}")

Check Database

# Verify database exists and has data
python -c "import sqlite3; conn = sqlite3.connect('kinto.db'); print('Users:', conn.execute('SELECT COUNT(*) FROM users').fetchone()[0])"

File Structure

src/
├── text2sql.py              # Core module (400+ lines)
├── text2sql_server.py       # MCP server
├── text2sql_example.py      # Example client
└── test_text2sql.py         # Unit tests (9 tests)

mcp_text2sql_config.json     # MCP configuration
kinto.db                     # SQLite database

How It Works

  1. Parse natural language query

  2. Extract conditions (age, price, category, etc.)

  3. Generate SQL query

  4. Execute against SQLite database

  5. Format results (string or table)

Result Formats

String Format (single values):

Answer: 50

Table Format (multiple rows):

id | name  | email             | age
───────────────────────────────────
1  | Alice | alice@example.com | 75
2  | Bob   | bob@example.com   | 72

Troubleshooting

Issue

Solution

Module not found

pip install -r requirements.txt

Database not found

python populate_kinto_db.py

Query not recognized

Try rephrasing: "Show me users aged above 70"

No results

Check table name and condition values

SQL error

Use execute_sql tool to debug

Logs

Server logs: logs/text2sql_server.log

Performance

  • Query parsing: < 1ms

  • SQL execution: < 10ms (typical)

  • Total response: < 20ms (typical)

Features

✅ Natural language queries
✅ Automatic SQL generation
✅ Multiple result formats
✅ Smart condition parsing
✅ Aggregate functions (COUNT, AVG, SUM)
✅ Kiro/Cline integration
✅ SQLite database support
✅ 9 comprehensive unit tests

Limitations

  • Pattern-based parsing (not AI-powered)

  • Supports SELECT, COUNT, AVG, SUM operations

  • Complex JOINs not automatically generated

  • Use execute_sql tool for complex queries

Future Enhancements

  • LLM-based query generation

  • Support for JOIN operations

  • INSERT/UPDATE/DELETE operations

  • Query optimization suggestions

  • Result caching

  • Multi-language support

Architecture

System Flow

User Question
    ↓
Parse Query Type (count/select/aggregate/limit)
    ↓
Extract Conditions (age, price, category, etc.)
    ↓
Generate SQL Query
    ↓
Execute Against SQLite
    ↓
Format Results (string or table)
    ↓
Return Answer

Component Structure

text2sql_server.py (MCP Server)
├── query_database tool
├── get_database_schema tool
└── execute_sql tool
    ↓
text2sql.py (Core Module)
├── Query Parsing
├── Condition Extraction
├── SQL Generation
└── Result Formatting
    ↓
SQLite Database (kinto.db)
├── users (50 rows)
├── products (30 rows)
├── orders (100 rows)
├── reviews (75 rows)
└── inventory (30 rows)

Detailed Query Examples

Sample Questions

1. How many users do I have?
2. Show me top 5 products with price above 100
3. What is the average rating for all reviews?
4. Show me users aged above 70
5. How many orders have been placed in Electronics category?
6. What is the average product price?
7. Show me all products in Electronics category
8. How many reviews have rating above 4?
9. Show me top 10 users
10. What is the total stock available?
11. Show me products with stock below 20
12. How many products are in Books category?
13. What is the average age of users?
14. Show me orders with quantity above 5
15. How many inventory records do we have?
16. Show me top 3 products with highest price
17. What is the sum of all product prices?
18. Show me users aged below 30
19. How many products have price above 200?
20. Show me reviews with rating below 3
21. What is the average order quantity?
22. Show me products in Warehouse A location
23. How many users were created this year?
24. Show me top 5 most expensive products
25. What is the total quantity available in inventory?

Count Queries

Q: "How many users do I have?"
SQL: SELECT COUNT(*) as count FROM users
A: 50

Q: "How many products are in stock?"
SQL: SELECT COUNT(*) as count FROM products
A: 30

Select Queries

Q: "Show me all users"
SQL: SELECT * FROM users
A: [Table with all 50 users]

Q: "Get products"
SQL: SELECT * FROM products
A: [Table with all 30 products]

Conditional Queries

Q: "Show me users aged above 70"
SQL: SELECT * FROM users WHERE age > 70
A: [Table with users over 70]

Q: "Products with price below 50"
SQL: SELECT * FROM products WHERE price < 50
A: [Table with affordable products]

Q: "Show me products in Electronics category"
SQL: SELECT * FROM products WHERE category = 'Electronics'
A: [Table with Electronics products]

Limit Queries

Q: "Show me top 2 users"
SQL: SELECT * FROM users LIMIT 2
A: [Table with first 2 users]

Q: "Top 5 products"
SQL: SELECT * FROM products LIMIT 5
A: [Table with first 5 products]

Combined Queries

Q: "Show me top 2 users aged above 70"
SQL: SELECT * FROM users WHERE age > 70 LIMIT 2
A: [Table with 2 users over 70]

Q: "Top 10 products in Electronics with stock above 20"
SQL: SELECT * FROM products WHERE category = 'Electronics' AND stock > 20 LIMIT 10
A: [Table with matching products]

Aggregate Queries

Q: "What is the average product price?"
SQL: SELECT AVG(price) as result FROM products
A: 125.50

Q: "What is the total stock?"
SQL: SELECT SUM(stock) as result FROM products
A: 5000

Q: "Average user age?"
SQL: SELECT AVG(age) as result FROM users
A: 52.3

Advanced Usage

Using with Python

from text2sql import Text2SQL

# Initialize
text2sql = Text2SQL(db_path="kinto.db")

# Simple query
result = text2sql.query("How many users do I have?")

# Check result
if result.success:
    print(f"Generated SQL: {result.query}")
    print(f"Raw Data: {result.data}")
    print(f"Formatted: {text2sql.format_result(result)}")
else:
    print(f"Error: {result.message}")

# Access result data directly
for row in result.data:
    print(row)

Using with MCP Client

import json
from mcp.client import Client

client = Client()

# Query database
response = client.use_tool(
    "text2sql-mcp-server",
    "query_database",
    {"question": "How many users do I have?"}
)

# Get schema
schema = client.use_tool(
    "text2sql-mcp-server",
    "get_database_schema",
    {}
)

# Execute raw SQL
result = client.use_tool(
    "text2sql-mcp-server",
    "execute_sql",
    {"sql": "SELECT * FROM users WHERE age > 70 LIMIT 5"}
)

Custom Database

To use with your own database:

from text2sql import Text2SQL

# Point to your database
text2sql = Text2SQL(db_path="path/to/your/database.db")

# Query as normal
result = text2sql.query("Your question here")

Configuration

MCP Server Configuration

The MCP server is configured in mcp_text2sql_config.json:

{
  "mcpServers": {
    "text2sql-mcp-server": {
      "command": "python",
      "args": ["src/text2sql_server.py"],
      "env": {
        "PYTHONUNBUFFERED": "1"
      },
      "disabled": false,
      "autoApprove": [
        "query_database",
        "get_database_schema",
        "execute_sql"
      ]
    }
  }
}

Database Configuration

Default database: kinto.db

To use a different database, modify src/text2sql_server.py:

# Change this line:
text2sql = Text2SQL(db_path="kinto.db")

# To:
text2sql = Text2SQL(db_path="path/to/your/database.db")

Logging Configuration

Logs are written to logs/text2sql_server.log

To change log level in src/text2sql_server.py:

logging.basicConfig(
    level=logging.DEBUG,  # Change to DEBUG for verbose logging
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('logs/text2sql_server.log'),
        logging.StreamHandler()
    ]
)

Query Pattern Reference

Query Type Detection

Pattern

Type

Example

"How many", "Count", "Total"

Count

"How many users?"

"Show", "Get", "List", "Find"

Select

"Show me users"

"Average", "Avg", "Sum"

Aggregate

"Average price?"

"Top", "First", "Limit"

Limit

"Top 5 users"

"Aged", "Priced", "Category"

Conditional

"Users aged above 70"

Condition Patterns

Condition

Patterns

Example

Age

above, over, >, below, under, <

"aged above 70"

Price

above, over, >, below, under, <

"price below 50"

Category

category name

"Electronics category"

Rating

above, over, >

"rating above 4"

Stock

above, over, >

"stock above 100"

Real-World Scenarios

Scenario 1: Customer Analysis

Q: "How many customers are over 70 years old?"
A: 8

Q: "Show me top 5 oldest customers"
A: [Table with oldest customers]

Q: "What is the average age of our customers?"
A: 52.3

Scenario 2: Product Management

Q: "How many products do we have?"
A: 30

Q: "What is the average product price?"
A: 125.50

Q: "Show me products in Electronics category"
A: [Table with Electronics products]

Q: "How many products have stock above 50?"
A: 15

Scenario 3: Order Analysis

Q: "How many orders have been placed?"
A: 100

Q: "What is the average order quantity?"
A: 4.5

Q: "Show me top 10 orders"
A: [Table with top 10 orders]

Scenario 4: Inventory Management

Q: "What is the total quantity available?"
A: 8500

Q: "Show me inventory in Warehouse A"
A: [Table with Warehouse A inventory]

Q: "How many inventory records do we have?"
A: 30

Troubleshooting Guide

Issue: "Module not found" error

Cause: Dependencies not installed

Solution:

pip install -r requirements.txt

Issue: "Database file not found"

Cause: kinto.db doesn't exist

Solution:

python populate_kinto_db.py

Issue: Query not recognized

Cause: Query phrasing doesn't match patterns

Solution: Try rephrasing:

  • ❌ "Give me users over 70"

  • ✅ "Show me users aged above 70"

Issue: No results found

Cause: Condition values don't match data

Solution:

  1. Check table name is correct

  2. Verify condition values exist in database

  3. Try simpler query first

Issue: SQL execution error

Cause: Generated SQL is invalid

Solution:

  1. Check the generated SQL query in output

  2. Use execute_sql tool to debug

  3. Verify database file exists and is readable

Issue: Kiro doesn't recognize Text2SQL server

Cause: MCP configuration not loaded

Solution:

  1. Verify mcp_text2sql_config.json exists

  2. Check MCP configuration in Kiro settings

  3. Restart Kiro

  4. Check logs: logs/text2sql_server.log

Issue: Unexpected query results

Cause: Query parsed differently than expected

Solution:

  1. Check the generated SQL query

  2. Use execute_sql tool to test SQL directly

  3. Verify database schema with get_database_schema

Performance Characteristics

Query Execution Timeline

Step

Time

Parse query

< 1ms

Extract conditions

< 1ms

Generate SQL

< 1ms

Execute SQL

< 10ms (typical)

Format results

< 5ms

Total

< 20ms (typical)

Scalability

  • Supports databases with thousands of rows

  • Efficient pattern-based parsing

  • No external API calls required

  • Minimal memory footprint

Security Considerations

Input Validation

  • Query pattern matching prevents invalid SQL

  • Parameterized queries prevent SQL injection

  • Safe error messages don't expose database details

Database Access

  • Read-only operations by default

  • Optional raw SQL execution with execute_sql tool

  • Audit trail via logging

Best Practices

  1. Use query_database for user-facing queries

  2. Use execute_sql only for trusted queries

  3. Monitor logs for suspicious activity

  4. Restrict database file permissions

Development

Project Structure

Text2SQL/
├── src/
│   ├── __init__.py
│   ├── text2sql.py              # Core module
│   ├── text2sql_server.py       # MCP server
│   ├── text2sql_example.py      # Example client
│   └── test_text2sql.py         # Unit tests
├── logs/
│   └── text2sql_server.log      # Server logs
├── kinto.db                     # SQLite database
├── mcp_text2sql_config.json     # MCP config
├── populate_kinto_db.py         # Database setup
├── README.md                    # This file
├── Makefile                     # Build commands
├── requirements.txt             # Dependencies
└── setup.py                     # Package setup

Running Tests

# Run all tests
make test

# Run specific test
python -m unittest src.test_text2sql.TestText2SQL.test_count_query -v

# Run with coverage
python -m coverage run -m unittest src.test_text2sql
python -m coverage report

Test Coverage

The project includes 9 comprehensive unit tests:

  1. test_count_query - Count queries

  2. test_select_query - Select queries

  3. test_age_condition - Age condition parsing

  4. test_category_condition - Category condition parsing

  5. test_limit_query - Limit queries

  6. test_average_query - Average queries

  7. test_format_result_string - String formatting

  8. test_format_result_table - Table formatting

  9. test_invalid_query - Error handling

Adding New Query Types

To add support for new query types:

  1. Add pattern detection in _parse_query() method

  2. Create parsing method (e.g., _parse_custom_query())

  3. Add condition extraction if needed

  4. Add unit tests

  5. Update documentation

Example:

def _parse_custom_query(self, query: str) -> Optional[str]:
    """Parse custom query type."""
    # Your logic here
    return sql_query

Extending Condition Support

To add new condition types:

  1. Add pattern matching in _extract_conditions()

  2. Build WHERE clause condition

  3. Add unit tests

  4. Update documentation

Example:

# In _extract_conditions()
if 'custom_field' in query:
    match = re.search(r'custom_field\s+(?:above|over|>)\s+(\d+)', query)
    if match:
        conditions.append(f"custom_field > {match.group(1)}")

API Reference

Text2SQL Class

class Text2SQL:
    def __init__(self, db_path: str = "kinto.db")
    def query(self, natural_language: str) -> QueryResult
    def format_result(self, result: QueryResult) -> str

QueryResult Dataclass

@dataclass
class QueryResult:
    success: bool              # Query executed successfully
    query: str                 # Generated SQL query
    data: List[Dict]          # Query results
    message: str              # Status message
    format_type: str          # 'table' or 'string'

MCP Tools

query_database

Convert natural language to SQL and execute.

Input:

{
  "question": "How many users do I have?"
}

Output:

Query: SELECT COUNT(*) as count FROM users

Result:
50

get_database_schema

Get database schema information.

Input: (empty)

Output:

Database Schema:

Table: users
  Columns: id, name, email, age, created_at

Table: products
  Columns: id, name, price, stock, category

...

execute_sql

Execute raw SQL query.

Input:

{
  "sql": "SELECT * FROM users WHERE age > 70 LIMIT 5"
}

Output:

SQL: SELECT * FROM users WHERE age > 70 LIMIT 5

Result:
id | name  | email             | age
───────────────────────────────────
1  | Alice | alice@example.com | 75
2  | Bob   | bob@example.com   | 72

Deployment

Docker Deployment

# Build image
make docker-build

# Run container
make docker-run

# View logs
make docker-logs

# Stop container
make docker-stop

Local Deployment

# Install dependencies
make install

# Run example
make example

# Run tests
make test

Production Considerations

  1. Use environment variables for database path

  2. Enable logging for audit trail

  3. Restrict database file permissions

  4. Use read-only database user if possible

  5. Monitor server logs regularly

  6. Set up automated backups

Limitations & Future Work

Current Limitations

  • Pattern-based parsing (not AI-powered)

  • Supports SELECT, COUNT, AVG, SUM operations only

  • Complex JOINs not automatically generated

  • No support for subqueries

  • No support for GROUP BY, ORDER BY

  • No support for INSERT/UPDATE/DELETE

Future Enhancements

  • LLM-based query generation for complex queries

  • Support for JOIN operations

  • Support for GROUP BY and ORDER BY

  • INSERT/UPDATE/DELETE operations

  • Query optimization suggestions

  • Result caching for repeated queries

  • Multi-language support

  • Query history and analytics

  • Custom function support

  • Parameterized query templates

Contributing

To contribute to this project:

  1. Fork the repository

  2. Create a feature branch

  3. Make your changes

  4. Add tests for new functionality

  5. Update documentation

  6. Submit a pull request

Support & Documentation

  • Quick Start: See "Quick Start" section above

  • Examples: See "Query Examples" section

  • Troubleshooting: See "Troubleshooting Guide" section

  • API Reference: See "API Reference" section

  • Logs: Check logs/text2sql_server.log

FAQ

Q: Can I use this with my own database? A: Yes! Just point to your database file: Text2SQL(db_path="your_db.db")

Q: Does it support complex queries? A: For complex queries, use the execute_sql tool to run raw SQL directly.

Q: Is it secure? A: Yes, it uses parameterized queries and pattern-based parsing to prevent SQL injection.

Q: Can I modify the database? A: By default, only SELECT operations are supported. Use execute_sql for other operations.

Q: How do I add new query types? A: See "Adding New Query Types" in the Development section.

Q: What databases are supported? A: Currently SQLite. Other databases can be added by modifying the database connection code.

Q: Can I use this in production? A: Yes, with proper configuration and monitoring. See "Production Considerations" section.

Q: How do I report bugs? A: Check the logs in logs/text2sql_server.log and review the Troubleshooting Guide.

Screenshots

1771256825596 1771257194168

License

This project is licensed under the MIT License - see the LICENSE file for details.

sqlite-mcp-csp

A
license - permissive license
-
quality - not tested
D
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • -
    license
    -
    quality
    D
    maintenance
    Handles SQL query execution for a natural language interface to SQLite databases, enabling users to interact with databases using plain English rather than writing SQL manually.
    Last updated
    1
  • F
    license
    -
    quality
    D
    maintenance
    Enables natural language database operations and semantic document search through SQLite and vector database integration. Converts plain English instructions into SQL queries and provides RAG capabilities for uploaded documents.
    Last updated

View all related MCP servers

Related MCP Connectors

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rajacsp/sqlite-mcp-csp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server