mcp-crewai-giulia-ai
Provides text-to-SQL querying for PostgreSQL databases, allowing natural language requests to be converted into read-only SQL SELECT statements and executed against configured database schemas.
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-crewai-giulia-aiWhat are the top 3 best-selling products in ecommerce?"
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.
PRJ-07 — CrewAI + MCP: Text-to-SQL
Sistema multi-agente CrewAI + servidor MCP que faz text-to-SQL: o usuário
conversa (Streamlit), um agente CrewAI usa as tools MCP, o servidor gera SQL real a
partir de linguagem natural (com base no schema) e consulta bancos PostgreSQL de
demonstração (ecommerce e clinica). Corresponde ao Capítulo 8 do livro Model
Context Protocol (Sandeco).
Os mocks originais (SQL fixo, MockCursor, URI falsa) foram substituídos por: geração de
SQL por um Crew real (crew_ai_query.py), conexão psycopg2 real (postgres_connection.py)
e URI a partir de env (postgres_databases.py). Consultas são somente-leitura — ver
Segurança.
Multi-provider
Modelo por LLM_MODEL (OpenAI/Anthropic/Gemini/OpenRouter) — ver .env.example.
Related MCP server: mcp-db-server
Pré-requisitos: PostgreSQL com massa de teste
# cria os 2 bancos e popula com os dados demo (ajuste user/host conforme seu .env)
createdb ecommerce && createdb clinica
psql -d ecommerce -f data/seed_ecommerce.sql
psql -d clinica -f data/seed_clinica.sqlSchemas descritos em src/schema_ecommerce.yaml e src/schema_clinica.yaml (o agente usa
o YAML para gerar SQL correto).
Uso
uv sync
cp .env.example .env # defina LLM_MODEL + chave do provider + credenciais PG
uv run streamlit run src/main.pyFluxo: pergunta em linguagem natural → agente CrewAI chama a tool MCP buscar_dados_sql
→ Crew gera o SELECT a partir do schema → validação → executa no Postgres em sessão
read-only → devolve os dados. Ex.: "quais os 3 produtos mais vendidos no ecommerce?"
Segurança
O SQL é gerado por um LLM a partir de texto do usuário, então o vetor a considerar é prompt injection. A defesa tem duas camadas, e só a segunda é garantia.
Camada 1 — validação na aplicação (src/sql_guard.py)
Falha cedo, com motivo legível, antes de gastar uma ida ao banco:
Um único comando. Múltiplos statements são rejeitados —
psycopg2executa vários comandos separados por;numa única chamada deexecute().Allowlist de início:
SELECT,WITH,VALUESouTABLE.Denylist complementar para CTE que escreve (
WITH x AS (DELETE ... RETURNING *), recurso real do PostgreSQL).Comentários (
--,/* */aninhados), literais ('...',$$...$$) e identificadores ("...") são analisados corretamente: uma palavra reservada dentro de um dado não vira comando, e um;dentro de um literal não separa statement.
Versão anterior: a validação era
sql.lower().lstrip().startswith("select").SELECT 1; DROP TABLE clientescomeça comselect— e passava. Validar prefixo é validar string; o necessário é validar comando. Coberto portests/test_sql_guard.py::test_rejeita_o_bypass_original.
Camada 2 — garantia no banco (src/postgres_connection.py)
A sessão é aberta com set_session(readonly=True). Quem recusa a escrita é o próprio
PostgreSQL (ReadOnlySqlTransaction), não código Python. Há também um
statement_timeout (PG_STATEMENT_TIMEOUT_MS, padrão 15s) para que uma query gerada por
LLM não prenda uma conexão indefinidamente.
Recomendado: aponte PG_USER para um role sem permissão de escrita — defesa em
profundidade, independente da aplicação.
CREATE ROLE giulia_ro LOGIN PASSWORD 'troque-isto';
GRANT CONNECT ON DATABASE ecommerce TO giulia_ro;
GRANT USAGE ON SCHEMA public TO giulia_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO giulia_ro;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO giulia_ro;Testes
uv run pytest # 58 testes do sql_guard (lógica pura, sem banco)Os testes da camada 2 exigem um PostgreSQL de verdade — é o único jeito de provar que
quem recusa a escrita é o banco. Sem PRJ07_TEST_DSN definido eles são pulados:
docker run -d --name prj07-mcp-pg -e POSTGRES_PASSWORD=postgres -p 55432:5432 postgres:16-alpine
# crie os bancos e rode os seeds (ver "Pré-requisitos" acima)
export PRJ07_TEST_DSN="postgresql://postgres:postgres@localhost:55432/ecommerce"
uv run pytest # 73 testes (58 + 15 de integração)Entre os testes de integração está
test_bypass_do_guard_ainda_seria_barrado_pelo_banco: mesmo que a camada 1 falhasse,
SELECT 1; DROP TABLE clientes levanta ReadOnlySqlTransaction. É a definição de defesa
em profundidade.
This server cannot be deployed
Maintenance
Related MCP Connectors
Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.
- mcpOAuthcom.gibsonai
GibsonAI MCP server: manage your databases with natural language
- dataOAuthco.thinair
PostgreSQL, MySQL, and SQL Server in one session. 26 read-only MCP tools for AI agents.
Query your warehouse or a CSV with Claude/ChatGPT over MCP, governed by table-level ACL + audit.
Related MCP Servers
- AlicenseAqualityBmaintenanceAn MCP server that gives AI agents direct read-only access to PostgreSQL databases, enabling natural language analytics through tools for schema exploration, querying, trend analysis, and data quality checks.115MIT
- FlicenseNot gradedqualityAmaintenanceAn MCP server that exposes relational databases (PostgreSQL/MySQL) to AI agents with natural language to SQL query support.19-
- AlicenseAqualityDmaintenanceA production-grade MCP server that gives AI agents safe, authenticated access to a PostgreSQL database.3MIT
- AlicenseNot gradedqualityAmaintenanceRead-only Text-to-SQL MCP server for PostgreSQL and MySQL that lets users query databases using natural language, with robust multi-layer safety guarantees against writes.9 npmMIT