Skip to main content
Glama
AHMED-DEEBB

data-analyst

by AHMED-DEEBB

Agentic Data Analyst

CI

Ask business questions in Arabic or English and get an answer, a chart, and the exact SQL behind it. A LangGraph workflow of specialised agents plans the question, retrieves the relevant schema and business rules (hybrid RAG), writes SQL, validates it, runs it read-only, self-corrects on errors, and explains the result.

Why it matters

"Talk to your data" is one of the most requested enterprise AI use cases, and most demos stop at a prompt that generates SQL. This project covers the parts production needs: guardrails, business-definition grounding, bilingual support, self-correction, evaluation in CI, tracing, and a standard MCP interface.

Related MCP server: mcp-data-server

Architecture

flowchart LR
    U[User: EN / AR] --> P[Planner agent<br/>intent + language]
    P -->|unsafe / off-topic| R[Refuse]
    P -->|data question| S[Schema agent<br/>hybrid RAG on pgvector]
    S --> W[SQL agent]
    W --> V[Validator<br/>sqlglot AST checks]
    V -->|rejected| W
    V --> E[Execute<br/>read-only role + txn]
    E -->|DB error| W
    E --> I[Insight agent<br/>answer + chart]

Agent

Job

Planner

Classifies intent (data / out of scope / unsafe), detects language, rewrites the question

Schema

Retrieves tables, business definitions and verified examples (semantic + keyword search, RRF fusion)

SQL writer

Drafts PostgreSQL; on failure receives the error and repairs (max 3 attempts)

Validator

Parses the SQL tree: one SELECT only, allowed tables only, no dangerous functions, row limit

Insight

Answers in the user's language with key numbers and picks a chart type

Security: defence in depth

Agent-generated SQL is never trusted. Four independent layers:

  1. AST validation (sqlglot): rejects writes, DDL, multiple statements, system tables, pg_sleep/file functions.

  2. Read-only database role: analyst_ro has SELECT on business tables only.

  3. Read-only transaction, always rolled back.

  4. Statement timeout and row cap.

The planner also refuses unsafe requests ("delete all orders", prompt-injection attempts) before any SQL is written.

Evaluation

51 cases: 30 English and 15 Arabic analytics questions with gold SQL, plus 6 unsafe or off-topic prompts. Scored by execution accuracy (the agent's result must match the gold query's result), refusal accuracy, self-correction rate and latency. CI runs a subset on every push and fails the build below the threshold.

Metric

Result

Execution accuracy, English

100% (30/30)

Execution accuracy, Arabic

100% (15/15)

Refusal accuracy (unsafe / off-topic)

100% (6/6)

Overall

100% (51/51), up from 90.2% on the first run

The first run exposed three issues: the model sometimes returned SQL as markdown instead of the required structured output, it occasionally invented date filters, and one correct answer used a pivoted layout. Fixes: a format-error retry, stricter prompt rules, and a layout-tolerant scorer. Measured on Groq's free tier (openai/gpt-oss-120b), run in two batches because of the daily token limit.

Full report: evals/results/report.md after a run.

Quick start

Requirements: Docker, and a free Groq API key (https://console.groq.com/keys).

cp .env.example .env        # paste your GROQ_API_KEY
docker compose up --build   # first build downloads the embedding model

Open http://localhost:8000 (UI) or http://localhost:8000/docs (API).

make evals        # full evaluation suite
make test         # guardrail + scoring unit tests (no LLM needed)

Switch provider in .env: LLM_PROVIDER=openai or LLM_PROVIDER=azure (Azure OpenAI).

Use it from Claude Desktop (MCP)

With the database running (docker compose up), install dependencies locally and add to your Claude Desktop config:

{
  "mcpServers": {
    "data-analyst": {
      "command": "python",
      "args": ["-m", "app.mcp_server"],
      "cwd": "/absolute/path/to/agentic-data-analyst"
    }
  }
}

Tools exposed: ask_analyst, list_tables, describe_table, run_sql (validated, read-only).

API

curl -X POST localhost:8000/ask -H "Content-Type: application/json" \
     -d '{"question": "ما هي الإيرادات حسب الفئة في 2024؟"}'

POST /ask/stream returns Server-Sent Events: one event per agent step, then the final result.

Stack

LangGraph, LangChain, Groq / OpenAI / Azure OpenAI, PostgreSQL + pgvector, fastembed (multilingual embeddings), sqlglot, FastAPI, MCP, Langfuse, Docker, GitHub Actions, pytest. Each tool and every design decision is explained in docs/TOOLS.md.

Data

Synthetic GCC retail dataset (8 stores in UAE, Saudi Arabia, Qatar, Kuwait; 600 customers; 6,000 orders; 2024-2025), generated with a fixed seed so results are reproducible. No real company data.

Project structure

app/
  agents/      graph.py (LangGraph workflow), prompts, schemas, runner
  api/         FastAPI service
  knowledge/   schema docs, business glossary, verified examples (RAG source)
  static/      demo UI
  safety.py    SQL validator
  retrieval.py hybrid RAG on pgvector
  mcp_server.py
evals/         dataset + runner (execution accuracy)
tests/         guardrail and scoring tests

Author

Ahmed Eldeep, AI Engineer (Dubai, UAE) LinkedIn · GitHub

License

MIT

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    C
    maintenance
    Enables read-only exploration and querying of PostgreSQL or MySQL databases via MCP, with schema discovery, safe SQL validation, natural language to SQL conversion, and CSV export.
    11
    1
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides read-only, guarded access to business databases via MCP. Enables natural language querying with built-in security barriers like table allowlists, PII masking, and audit logging.
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables natural-language querying of Postgres and MongoDB databases in read-only mode, with PII masking and row/timeout guardrails, from any MCP client.
    -