Atlas / MCP servers / luiscarbonel1991 / nlp2sql

nlp2sqlBLOCK

mcp/luiscarbonel1991/nlp2sql

Enterprise-ready Natural Language to SQL converter with multi-provider AI support (OpenAI, Anthropic, Gemini). Built for production scale databases (1000+ tables) with Clean Architecture.

Verdict
BLOCK
Grade
D
Trust score
68 /100
Exposed tools
5 4r · 1w · 0d
Transport
—
License
MIT
Stars
8
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

DSL-first natural language to SQL for PostgreSQL and Redshift

nlp2sql turns a natural language question into SQL through a reusable Python DSL:

  • await connect(...)
  • await nlp.ask(...)
  • optional few-shot examples
  • optional semantic context
  • optional validation and repair

The library is designed for both simple schemas and large warehouses, but all public examples in this repository use the local e-commerce domain shipped with the project itself.

Features

  • DSL-first API: connect() returns an NLP2SQL client with ask(), validate(), explain(), and suggest()
  • Business-aware generation: optional SemanticContext adds canonical tables, metrics, dimensions, rules, and mappings
  • Execution modes: generate only, generate plus validate, and generate plus validate plus repair
  • Few-shot examples: pass example lists directly or use an example repository implementation
  • Large schema support: FAISS plus TF-IDF hybrid retrieval, schema filters, and disk-backed caches
  • Multiple providers: OpenAI, Anthropic, and Gemini
  • Database support: PostgreSQL and Amazon Redshift
  • Async by default: built for services, APIs, notebooks, and workers

Documentation

Read from source at commit a44865a3adceOBSERVED · 2026-10-10
Advertisement
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code
claude mcp add nlp2sql --env ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} --env GOOGLE_API_KEY=${GOOGLE_API_KEY} --env NLP2SQL_TEST_POSTGRES_PASS=${NLP2SQL_TEST_POSTGRES_PASS} --env OPENAI_API_KEY=${OPENAI_API_KEY} -- uvx nlp2sql
claude-desktop
{
  "mcpServers": {
    "nlp2sql": {
      "command": "uvx",
      "args": [
        "nlp2sql"
      ],
      "env": {
        "ANTHROPIC_API_KEY": "${ANTHROPIC_API_KEY}",
        "GOOGLE_API_KEY": "${GOOGLE_API_KEY}",
        "NLP2SQL_TEST_POSTGRES_PASS": "${NLP2SQL_TEST_POSTGRES_PASS}",
        "OPENAI_API_KEY": "${OPENAI_API_KEY}"
      }
    }
  }
}
03

Exposed tools (5)

4 read · 1 write · 0 destructive.

ToolRiskDescription
ask_databasereadAsk a question about your data in natural language.
explain_sqlreadExplain what a SQL query does in plain English.
explore_schemareadExplore the database schema to understand available tables and columns.
list_databasesreadList all configured database connections.
run_sqlwriteExecute a SQL query and return results.
04

Trust audit

BLOCKgrade D · trust 68/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (2 observation(s))
Network
declared (1 observation(s))
Shell
declared (5 observation(s))
Dependencies
pinned
Secrets in source
found

Findings (18)

HIGHCode injection · code.deserialize · CWE-78, CWE-94, CWE-95
src/nlp2sql/adapters/postgres_repository.py:128
cache_data = pickle.load(f)
Why it matters. deserialises untrusted bytes into live objects
Fix. use json or yaml.safe_load
HIGHCode injection · code.deserialize · CWE-78, CWE-94, CWE-95
src/nlp2sql/adapters/postgres_repository.py:164
cache_data = pickle.load(f)
Why it matters. deserialises untrusted bytes into live objects
Fix. use json or yaml.safe_load
HIGHCode injection · code.deserialize · CWE-78, CWE-94, CWE-95
src/nlp2sql/adapters/redshift_adapter.py:74
cache_data = pickle.load(f)
Why it matters. deserialises untrusted bytes into live objects
Fix. use json or yaml.safe_load
HIGHCode injection · code.deserialize · CWE-78, CWE-94, CWE-95
src/nlp2sql/adapters/redshift_adapter.py:104
cache_data = pickle.load(f)
Why it matters. deserialises untrusted bytes into live objects
Fix. use json or yaml.safe_load
HIGHCode injection · code.deserialize · CWE-78, CWE-94, CWE-95
src/nlp2sql/cli.py:1128
cache_data = pickle.load(f)
Why it matters. deserialises untrusted bytes into live objects
Fix. use json or yaml.safe_load
HIGHHard-coded secrets · secret.db_uri · CWE-798, CWE-321
.claude/commands/db.md:12
- Simple: postgresql://testuser:testpass@localhost:5432/testdb
HIGHHard-coded secrets · secret.db_uri · CWE-798, CWE-321
.claude/commands/db.md:13
- Enterprise: postgresql://demo:demo123@localhost:5433/enterprise
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
CLAUDE.md:38
uv run nlp2sql query --database-url "postgresql://testuser:testpass@localhost:5432/testdb" --question "How many users?"
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
CLAUDE.md:42
# Simple DB: postgresql://testuser:testpass@localhost:5432/testdb
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
CLAUDE.md:43
# Enterprise DB: postgresql://demo:demo123@localhost:5433/enterprise
LOWInventory / provenance · inv.hidden_file · CWE-1104
.mcp.json.example
.mcp.json.example
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/nlp2sql/adapters/pgvector_example_repository.py:103
self.namespace = hashlib.md5(index_key.encode(), usedforsecurity=False).hexdigest()
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/nlp2sql/adapters/pgvector_example_repository.py:265
return hashlib.md5(content.encode(), usedforsecurity=False).hexdigest()
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/nlp2sql/adapters/postgres_repository.py:110
url_hash = hashlib.md5(self.connection_string.encode()).hexdigest()[:12]
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/nlp2sql/adapters/redshift_adapter.py:56
url_hash = hashlib.md5(self.connection_string.encode()).hexdigest()[:12]
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/nlp2sql/schema/embedding_manager.py:66
db_hash = hashlib.md5(index_key.encode()).hexdigest()
INFOPrompt injection · prompt.credential_read · CWE-94, CWE-1427
SECURITY.md:62
2. **Use read-only database credentials** when possible
Why it matters. asks the agent to read credentials
INFOPrompt injection · prompt.credential_read · CWE-94, CWE-1427
examples/strands-fastapi-agent/DOCKER_SETUP.md:48
cat > .env << EOF
Why it matters. asks the agent to read credentials

Gates applied: no_behavioural_pass.

Audited 2026-10-10 · audit v0.4.1 · source sha a44865a3adcefull audit observations/trust-audit/mcp-server/luiscarbonel1991__nlp2sql.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-10a44865a3adceBLOCKD68first audit
06

Questions

What is the nlp2sql MCP server?

Enterprise-ready Natural Language to SQL converter with multi-provider AI support (OpenAI, Anthropic, Gemini). Built for production scale databases (1000+ tables) with Clean Architecture.

What tools does nlp2sql expose?

5 in total: 4 read-only, 1 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.

Is nlp2sql safe to connect to an agent?

No — not without reading the findings first. The audit graded it D (68/100) and found 7 critical or high issues in the source. Each one is listed on this page with the file and line it is on.

What credentials does nlp2sql need?

It reads ANTHROPIC_API_KEY, GOOGLE_API_KEY, NLP2SQL_TEST_POSTGRES_PASS and OPENAI_API_KEY from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How current is this page?

The grade is for one exact copy of the source (a44865a3adce), read on 2026-10-10. The repository is watched and re-audited when it changes.

Advertisement