AI Sales Query Agent MCP Server
Enables natural-language sales queries against a SQLite database, generating and executing read-only SQL through a secure MCP server with table listing, schema description, and query execution.
README
AI Sales Query Agent
An AI-powered sales analytics API that converts natural-language questions into SQL and executes them against a SQLite sales database through a secure MCP-style database server.
The application is built with FastAPI and supports both an optional Claude API integration and a deterministic offline SQL planner.
๐๏ธ Architecture
โโโโโโโโโโโโโโโโโโโโโโโ
โ Client โ
โ Swagger / Browser โ
โโโโโโโโโโโโฌโโโโโโโโโโโ
โ
โ POST /query
โผ
โโโโโโโโโโโโโโโโโโโโโโโ
โ FastAPI โ
โ main.py โ
โโโโโโโโโโโโฌโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโ
โ SQLAgent โ
โ agent.py โ
โโโโโโโโโโโโฌโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโดโโโโโโโโโโโโโ
โ โ
โผ โผ
โโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
โ ClaudeSQLAgent โ โ LocalSQLPlanner โ
โ Claude API โ โ Offline Mode โ
โโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
โ โ
โโโโโโโโโโโโโโฌโโโโโโโโโโโโโ
โ
โ Generated SQL
โผ
โโโโโโโโโโโโโโโโโโโโโโโ
โ MCPServer โ
โ mcp_server.py โ
โ โ
โ list_tables() โ
โ describe_schema() โ
โ execute_query() โ
โโโโโโโโโโโโฌโโโโโโโโโโโ
โ
Read-only SQL
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโ
โ SQLite Database โ
โ data/sales.db โ
โโโโโโโโโโโโโโโโโโโโโโโ
๐ How It Works
The application follows this flow:
User Question
โ
โผ
POST /query
โ
โผ
SQLAgent
โ
โโโ Claude API
โ
โโโ LocalSQLPlanner
โ
โผ
Generated SQL
โ
โผ
MCPServer
โ
โโโ Validate SQL
โโโ Check read-only operation
โโโ Reject dangerous keywords
โโโ SQLite Authorizer
โ
โผ
SQLite Database
โ
โผ
Query Results
โ
โผ
JSON Response
๐ก๏ธ Database Security
The execute_query() method uses multiple security checks.
1. Only SELECT queries
The server accepts:
SELECT ...
and:
WITH ... SELECT ...
Write operations are rejected.
2. Multiple statements are rejected
For example:
SELECT * FROM customers;
DROP TABLE customers;
is rejected.
3. Dangerous keywords are blocked
The application checks for operations such as:
INSERT
UPDATE
DELETE
DROP
ALTER
CREATE
PRAGMA
ATTACH
DETACH
4. SQLite Authorizer
The application also uses SQLite's built-in authorizer callback.
This provides database-level protection against:
- INSERT
- UPDATE
- DELETE
- DROP
- ALTER
- CREATE
- Other restricted database operations
Therefore, SQL execution is protected by both application-level validation and the SQLite engine.
๐ค SQL Generation
The application supports two modes.
Claude Mode
If ANTHROPIC_API_KEY is configured:
ANTHROPIC_API_KEY
โ
โผ
ClaudeSQLAgent
โ
โผ
Claude API
โ
โผ
Generated SQL
โ
โผ
MCPServer
The Claude agent receives the database schema and instructions for generating safe SQL.
Offline Mode
If ANTHROPIC_API_KEY is not configured:
User Question
โ
โผ
LocalSQLPlanner
โ
โผ
Pattern Matching
โ
โผ
SQL Query
โ
โผ
MCPServer
The offline planner supports common sales queries including:
- Customer counts
- Revenue calculations
- Category revenue
- Top-N products
- Regional aggregations
- Group-by queries
- Products that were never ordered
- Basic filtering
- Aggregations
This means the project can run without an API key or internet connection.
๐ Database Schema
The project uses SQLite.
Database location:
data/sales.db
๐ Project Structure
partnr-sales-agent/
โ
โโโ app/
โ โโโ __init__.py
โ โโโ main.py
โ โโโ agent.py
โ โโโ mcp_server.py
โ
โโโ data/
โ โโโ sales.db
โ
โโโ tests/
โ โโโ test_query.py
โ
โโโ generate_db.py
โโโ evaluator.sh
โโโ Dockerfile
โโโ docker-compose.yml
โโโ requirements.txt
โโโ .env.example
โโโ .gitignore
โโโ README.md
โ๏ธ Requirements
Required
- Python 3.10+
- pip
- SQLite
Optional
- Docker Desktop
- Docker Compose
- Anthropic API key
๐ Installation
Windows PowerShell
Step 1 โ Open the project
Step 2 โ Create virtual environment
python -m venv .venv
Step 3 โ Activate virtual environment
.\.venv\Scripts\Activate.ps1
Important:
source .venv/bin/activateis a Linux/macOS command. Do not use it in Windows PowerShell.
Step 4 โ Upgrade pip
python -m pip install --upgrade pip
Step 5 โ Install dependencies
pip install -r requirements.txt
๐๏ธ Generate the Database
If data/sales.db does not exist, run:
python generate_db.py
Verify:
data/
โโโ sales.db
โถ๏ธ Run the Application
Start the FastAPI development server:
uvicorn app.main:app --reload
You should see:
Uvicorn running on http://127.0.0.1:8000
The API is now running at:
http://127.0.0.1:8000
๐ API Documentation
FastAPI automatically generates interactive documentation.
Open:
http://127.0.0.1:8000/docs
You can use Swagger UI to test the API without Postman.
Alternative documentation:
http://127.0.0.1:8000/redoc
๐ API Usage
POST /query
The endpoint accepts a natural-language question.
Request
{
"question": "What is the total number of customers?"
}
Example Response
{
"sql": "SELECT COUNT(*) AS total_customers FROM customers;",
"results": [
{
"total_customers": 500
}
],
"chart_data": {
"labels": [
"500"
],
"values": [
500
]
}
}
๐งช Example Queries
1. Total Customers
What is the total number of customers?
2. Technology Revenue
What is the total revenue from the Technology category?
3. Top Products
What are the top 5 products by revenue?
4. Regional Sales
What is the total sales amount by region?
5. Never Ordered Products
Which products have never been ordered?
6. Unsupported Question
What is the weather today?
The unsupported question should return:
HTTP 400
with an explanatory error message.
๐งช Testing
Run the complete test suite:
pytest tests/ -v
The tests cover:
- API endpoint
- Response format
- Customer count
- Revenue queries
- Complex SQL joins
- Unsupported questions
- MCP security
- SQL injection protection
list_tables()describe_schema()- Read-only SQL execution
All tests use the offline planner and therefore do not require an API key.
๐ End-to-End Evaluation
The repository contains:
evaluator.sh
The script executes predefined questions against the API.
Git Bash
chmod +x evaluator.sh
./evaluator.sh
PowerShell
If you are using Git Bash on Windows:
./evaluator.sh
You can also test all queries manually using:
http://127.0.0.1:8000/docs
๐ณ Docker
Docker can be used instead of installing Python dependencies locally.
Build and start
docker compose up --build -d
If your system uses the older Docker Compose command:
docker-compose up --build -d
Check the containers:
docker compose ps
View logs:
docker compose logs -f api
Open:
http://localhost:8000/docs
Run Tests in Docker
docker compose exec api pytest tests/ -v
Stop Docker
docker compose down
โ Error Handling
The application does not guess when a question cannot be answered.
For unsupported questions, the agent raises:
UnanswerableQuestionError
The API converts this into:
HTTP 400 Bad Request
Example:
Question:
What is the weather today?
Response:
400 Bad Request
This prevents unrelated questions from producing meaningless SQL.
๐ Security Architecture
The security model follows defense in depth:
Natural Language Question
โ
โผ
SQLAgent
โ
โผ
Generated SQL
โ
โผ
SQL Validation
โ
โโโ Single statement
โโโ SELECT / WITH only
โโโ Forbidden keyword check
โ
โผ
SQLite Authorizer
โ
โโโ Reject writes
โโโ Reject DDL
โโโ Reject restricted actions
โ
โผ
SQLite DB
The important principle is:
The AI agent generates SQL, but it never directly controls the database.
๐งฉ Components
app/main.py
Responsible for:
- FastAPI application
/queryendpoint- Request validation
- Agent orchestration
- Response formatting
- Error handling
app/agent.py
Responsible for:
- Natural-language processing
- SQL generation
- Claude integration
- Offline SQL planning
- Unsupported-question detection
app/mcp_server.py
Responsible for:
- Database connection
- Table listing
- Schema inspection
- SQL validation
- Read-only enforcement
- SQLite authorizer
generate_db.py
Responsible for:
- Creating the SQLite database
- Generating customers
- Generating orders
- Generating products
- Generating order items
tests/test_query.py
Responsible for:
- API tests
- SQL tests
- Security tests
- Schema tests
๐ ๏ธ Technology Stack
| Technology | Purpose |
|---|---|
| Python | Application development |
| FastAPI | REST API |
| SQLite | Database |
| Anthropic Claude | Optional AI SQL generation |
| MCP-style Server | Secure database gateway |
| Pydantic | Data validation |
| Pytest | Testing |
| Docker | Containerization |
| Docker Compose | Container orchestration |
๐ Example End-to-End Flow
For the question:
What is the total revenue from the Technology category?
The application performs:
1. User sends question
โ
2. FastAPI receives /query
โ
3. SQLAgent analyzes question
โ
4. SQL is generated
โ
5. MCPServer validates SQL
โ
6. SQLite authorizer checks operation
โ
7. Query executes
โ
8. Results are returned
โ
9. Chart data is generated
Example SQL:
SELECT
SUM(p.price * oi.quantity) AS total_revenue
FROM order_items oi
JOIN products p
ON p.id = oi.product_id
WHERE p.category = 'Technology';
๐ฎ Future Improvements
Potential improvements include:
- Ollama/local LLM integration
- Additional LLM providers
- PostgreSQL support
- Authentication
- Rate limiting
- Query caching
- Conversation history
- Advanced SQL generation
- Automatic chart selection
- Frontend dashboard
- Production logging
- Monitoring
- Streaming responses
๐ฏ Project Objective
The main objective of this project is to demonstrate a secure architecture for querying structured sales data using natural language.
Instead of manually writing SQL:
"What is the total revenue from Technology?"
the user can ask a natural-language question and receive a structured result.
User
โ
โผ
FastAPI
โ
โผ
SQL Agent
โ
โผ
MCPServer
โ
โผ
SQLite
โ
โผ
Sales Result
The architecture keeps AI-generated SQL separate from database execution, making the system easier to test, secure, and extend.
๐ฉโ๐ป Running the Project โ Quick Start
For an existing local setup, these are the only commands normally required:
cd D:\partnr-sales-agent
.\.venv\Scripts\Activate.ps1
uvicorn app.main:app --reload
Then open:
http://127.0.0.1:8000/docs
Test:
{
"question": "What is the total number of customers?"
}
๐ License
This project is intended for educational, development, and demonstration purposes.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.