mcpclaudeai-agentsdata-laketutorial

Como Construir um Servidor MCP para Seu Data Lake

Michael San Martim · 2026-04-24

MCP (Model Context Protocol) permite que agentes de IA chamem ferramentas — como consultar um banco de dados. O DataSpoc Lens vem com um servidor MCP integrado que transforma seu data lake Parquet em uma API consultável para Claude, GPT, agentes LangGraph e qualquer cliente compatível com MCP.

Este tutorial mostra como ir de dados brutos no S3 a um servidor MCP totalmente funcional em menos de 10 minutos.

O Resultado Final

Após a configuração, qualquer agente de IA pode:

  • Descobrir tabelas no seu data lake
  • Inspecionar schemas e dados de amostra
  • Executar consultas SQL com DuckDB
  • Fazer perguntas em linguagem natural
  • Obter métricas e KPIs pré-construídos

Tudo sem nenhum código customizado.

Passo 1: Ingerir Dados com Pipe

Se seus dados já estão em Parquet no S3/GCS/Azure, pule para o Passo 2. Caso contrário, extraia das suas fontes:

Terminal window
pip install dataspoc-pipe
dataspoc-pipe init sales-pipeline
dataspoc-pipe add postgres \
--host db.company.com \
--database sales \
--tables orders,customers,products,revenue \
--incremental updated_at \
--destination s3://company-lake
dataspoc-pipe run

Seu bucket agora tem:

s3://company-lake/
.dataspoc/manifest.json
raw/postgres/orders/*.parquet
raw/postgres/customers/*.parquet
raw/postgres/products/*.parquet
raw/postgres/revenue/*.parquet

Passo 2: Instalar DataSpoc Lens com MCP

Terminal window
pip install dataspoc-lens[mcp]

Isso instala o CLI core do Lens mais as dependências do servidor MCP.

Passo 3: Configurar e Iniciar o Servidor MCP

Terminal window
# Point Lens at your bucket
dataspoc-lens add-bucket s3://company-lake
# Discover tables
dataspoc-lens discover
# Found 4 tables: orders, customers, products, revenue
# Start the MCP server
dataspoc-lens mcp

Saída:

DataSpoc Lens MCP Server running
Transport: stdio
Tables: 4 discovered
Tools: 7 available
- list_tables
- get_schema
- sample_data
- query
- ask
- get_metrics
- explain_table
Waiting for MCP client connection...

Passo 4: Configurar Claude Desktop

Adicione ao seu arquivo de configuração do Claude Desktop (~/.config/claude/claude_desktop_config.json no Linux, ~/Library/Application Support/Claude/claude_desktop_config.json no macOS):

{
"mcpServers": {
"data-lake": {
"command": "dataspoc-lens",
"args": ["mcp"],
"env": {
"AWS_PROFILE": "data-lake",
"DATASPOC_BUCKET": "s3://company-lake"
}
}
}
}

Reinicie o Claude Desktop. Você verá o ícone de ferramentas indicando 7 ferramentas disponíveis.

As 7 Ferramentas MCP

1. list_tables — Descobrir Dados Disponíveis

Chamada:

{
"tool": "list_tables"
}

Resposta:

{
"tables": [
{"name": "raw.postgres.orders", "rows": 1247893, "size_mb": 340},
{"name": "raw.postgres.customers", "rows": 89421, "size_mb": 12},
{"name": "raw.postgres.products", "rows": 2431, "size_mb": 1.1},
{"name": "raw.postgres.revenue", "rows": 4201847, "size_mb": 890}
]
}

2. get_schema — Inspecionar Estrutura da Tabela

Chamada:

{
"tool": "get_schema",
"arguments": {"table": "raw.postgres.orders"}
}

Resposta:

{
"table": "raw.postgres.orders",
"columns": [
{"name": "id", "type": "INTEGER", "nullable": false},
{"name": "customer_id", "type": "INTEGER", "nullable": false},
{"name": "product_id", "type": "INTEGER", "nullable": false},
{"name": "amount", "type": "DECIMAL(10,2)", "nullable": false},
{"name": "status", "type": "VARCHAR", "nullable": false},
{"name": "created_at", "type": "TIMESTAMP", "nullable": false},
{"name": "updated_at", "type": "TIMESTAMP", "nullable": false}
],
"row_count": 1247893
}

3. sample_data — Visualizar Linhas de Amostra

Chamada:

{
"tool": "sample_data",
"arguments": {"table": "raw.postgres.orders", "limit": 5}
}

Resposta:

{
"table": "raw.postgres.orders",
"sample": [
{"id": 1, "customer_id": 42, "product_id": 7, "amount": 299.00, "status": "completed", "created_at": "2024-01-15T10:23:00"},
{"id": 2, "customer_id": 15, "product_id": 3, "amount": 49.99, "status": "completed", "created_at": "2024-01-15T11:05:00"},
{"id": 3, "customer_id": 42, "product_id": 12, "amount": 799.00, "status": "pending", "created_at": "2024-01-15T14:30:00"}
]
}

4. query — Executar SQL

Chamada:

{
"tool": "query",
"arguments": {
"sql": "SELECT DATE_TRUNC('month', created_at) AS month, SUM(amount) AS revenue FROM raw.postgres.orders WHERE created_at >= '2024-01-01' GROUP BY 1 ORDER BY 1"
}
}

Resposta:

{
"columns": ["month", "revenue"],
"rows": [
{"month": "2024-01-01", "revenue": 342891.50},
{"month": "2024-02-01", "revenue": 389012.75},
{"month": "2024-03-01", "revenue": 421547.00}
],
"row_count": 3,
"execution_time_ms": 234
}

5. ask — Perguntas em Linguagem Natural

Chamada:

{
"tool": "ask",
"arguments": {
"question": "Which customers spent the most last quarter?"
}
}

Resposta:

{
"answer": "The top 5 customers by spending last quarter were: Acme Corp ($89,234), GlobalTech ($67,891), Initech ($54,320), Umbrella Inc ($48,900), and Wayne Enterprises ($45,670).",
"sql": "SELECT c.name, SUM(o.amount) AS total_spent FROM raw.postgres.orders o JOIN raw.postgres.customers c ON o.customer_id = c.id WHERE o.created_at >= '2024-07-01' AND o.created_at < '2024-10-01' GROUP BY c.name ORDER BY total_spent DESC LIMIT 5",
"data": [
{"name": "Acme Corp", "total_spent": 89234.00},
{"name": "GlobalTech", "total_spent": 67891.00},
{"name": "Initech", "total_spent": 54320.00},
{"name": "Umbrella Inc", "total_spent": 48900.00},
{"name": "Wayne Enterprises", "total_spent": 45670.00}
]
}

6. get_metrics — KPIs Pré-construídos

Chamada:

{
"tool": "get_metrics",
"arguments": {"period": "last_30_days"}
}

Resposta:

{
"period": "2024-09-15 to 2024-10-15",
"metrics": {
"total_revenue": 487293.00,
"order_count": 12847,
"avg_order_value": 37.93,
"unique_customers": 3421,
"new_customers": 289
}
}

7. explain_table — Documentação dos Dados

Chamada:

{
"tool": "explain_table",
"arguments": {"table": "raw.postgres.orders"}
}

Resposta:

{
"table": "raw.postgres.orders",
"description": "Transaction records from the e-commerce platform. Each row represents one purchase.",
"columns": {
"id": "Unique order identifier",
"customer_id": "FK to customers table",
"amount": "Total order value in USD",
"status": "One of: pending, completed, refunded, cancelled",
"created_at": "When the order was placed"
},
"relationships": ["customers (customer_id)", "products (product_id)"],
"common_queries": [
"Revenue by month: SELECT DATE_TRUNC('month', created_at), SUM(amount) FROM orders GROUP BY 1",
"Orders by status: SELECT status, COUNT(*) FROM orders GROUP BY 1"
]
}

Conversação Multi-turno Realista com Agente

Veja como fica quando o Claude usa o servidor MCP:

Usuário: “Como está a tendência da nossa retenção? Estamos perdendo clientes?”

Chamadas internas de ferramentas do Claude:

  1. Chama list_tables para ver quais dados estão disponíveis
  2. Chama get_schema("raw.postgres.orders") para entender a estrutura de pedidos
  3. Chama get_schema("raw.postgres.customers") para verificar datas de cadastro
  4. Chama query com:
WITH monthly_cohorts AS (
SELECT
DATE_TRUNC('month', c.created_at) AS cohort_month,
DATE_TRUNC('month', o.created_at) AS order_month,
COUNT(DISTINCT o.customer_id) AS active_customers
FROM raw.postgres.customers c
JOIN raw.postgres.orders o ON c.id = o.customer_id
WHERE c.created_at >= '2024-01-01'
GROUP BY 1, 2
),
cohort_sizes AS (
SELECT cohort_month, COUNT(DISTINCT id) AS cohort_size
FROM raw.postgres.customers
WHERE created_at >= '2024-01-01'
GROUP BY 1
)
SELECT
mc.cohort_month,
mc.order_month,
mc.active_customers,
cs.cohort_size,
ROUND(mc.active_customers::FLOAT / cs.cohort_size * 100, 1) AS retention_pct
FROM monthly_cohorts mc
JOIN cohort_sizes cs ON mc.cohort_month = cs.cohort_month
ORDER BY mc.cohort_month, mc.order_month

Resposta do Claude:

Analisando os dados de retenção por coorte, aqui está a tendência:

CoorteMês 1Mês 2Mês 3Mês 6
Jan 2024100%68%52%34%
Abr 2024100%71%55%38%
Jul 2024100%74%59%

Boas notícias: a retenção está na verdade melhorando. A retenção do Mês 2 foi de 68% para 74% ao longo do ano. As mudanças de produto no Q2 (onboarding self-serve) parecem estar funcionando.

Porém, a queda no Mês 6 para 34% sugere que perdemos clientes por volta da marca de 6 meses — possivelmente quando contratos anuais vencem para renovação.

Modelo de Segurança

O servidor MCP é somente leitura por design:

  • Nenhuma instrução INSERT, UPDATE, DELETE, DROP ou CREATE é permitida
  • Consultas são validadas antes da execução
  • O servidor roda com as permissões IAM do processo (seu perfil AWS)
  • Controle de acesso no nível do bucket significa que agentes só veem dados que estão autorizados a ver
Terminal window
# Agent can only access buckets your IAM role permits
export AWS_PROFILE=analyst # Has access to s3://company-product only
dataspoc-lens mcp # Only exposes tables in permitted buckets

Sem chaves de API para gerenciar. Sem tokens de autenticação. Apenas IAM.

SDK Python para CrewAI / LangGraph

Se você está construindo agentes em Python em vez de usar o Claude Desktop, use o SDK diretamente:

from dataspoc_lens import LensClient
# Initialize (reads from same config as CLI)
client = LensClient(bucket="s3://company-lake")
# Same capabilities as MCP tools
tables = client.list_tables()
schema = client.get_schema("raw.postgres.orders")
result = client.query("SELECT COUNT(*) FROM raw.postgres.orders")
answer = client.ask("What's our churn rate?")

Integração com CrewAI

from crewai import Agent, Task, Crew
from crewai_tools import tool
from dataspoc_lens import LensClient
client = LensClient()
@tool
def query_data_lake(sql: str) -> str:
"""Execute a SQL query against the company data lake."""
result = client.query(sql)
return str(result)
@tool
def discover_tables() -> str:
"""List all available tables in the data lake."""
tables = client.list_tables()
return "\n".join([f"{t['name']} ({t['rows']} rows)" for t in tables])
analyst = Agent(
role="Data Analyst",
goal="Answer business questions using SQL on the data lake",
tools=[query_data_lake, discover_tables],
llm="gpt-4o",
)
task = Task(
description="Analyze customer lifetime value by acquisition channel",
agent=analyst,
)
crew = Crew(agents=[analyst], tasks=[task])
result = crew.kickoff()

Integração com LangGraph

Veja o tutorial completo: Construindo um Agente Analista de Dados com LangGraph.

O Padrão AGENT.md

Para agentes que trabalham autonomamente com seu data lake, crie um arquivo AGENT.md que descreve os dados disponíveis:

# Data Lake Agent Instructions
## Available Data
You have access to a data lake via the DataSpoc Lens MCP server.
## Tables
- `raw.postgres.orders` — All orders (1.2M rows). Key columns: customer_id, amount, status, created_at
- `raw.postgres.customers` — Customer profiles (89K rows). Key columns: name, email, plan, created_at
- `raw.postgres.products` — Product catalog (2.4K rows). Key columns: name, category, price
- `curated.finance.revenue` — Monthly revenue rollups (4.2M rows). Key columns: month, mrr, arr, churn_rate
## Common Queries
- Revenue by month: `SELECT DATE_TRUNC('month', created_at), SUM(amount) FROM raw.postgres.orders GROUP BY 1`
- Active customers: `SELECT COUNT(DISTINCT customer_id) FROM raw.postgres.orders WHERE created_at > CURRENT_DATE - INTERVAL '30 days'`
- Churn: `SELECT month, churn_rate FROM curated.finance.revenue ORDER BY month DESC LIMIT 12`
## Rules
- Always use the `query` tool for exact numbers
- Use `ask` for exploratory questions when you're not sure about the schema
- Never modify data — all queries are read-only
- When presenting numbers, always show the SQL you used (for auditability)

Coloque isso na raiz do seu projeto. Agentes que leem contexto do projeto (Claude Code, Cursor, Cline) vão usá-lo para entender como interagir com seus dados.

Executando em Produção

Para deploys em produção, rode o servidor MCP como um processo persistente:

Terminal window
# systemd service
[Unit]
Description=DataSpoc Lens MCP Server
After=network.target
[Service]
Type=simple
User=dataspoc
ExecStart=/usr/local/bin/dataspoc-lens mcp --transport sse --port 8080
Environment=AWS_PROFILE=data-lake
Environment=DATASPOC_BUCKET=s3://company-lake
Restart=always
[Install]
WantedBy=multi-user.target

Ou com Docker:

FROM python:3.11-slim
RUN pip install dataspoc-lens[mcp]
ENV DATASPOC_BUCKET=s3://company-lake
CMD ["dataspoc-lens", "mcp", "--transport", "sse", "--port", "8080"]
Terminal window
docker run -d \
-p 8080:8080 \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e DATASPOC_BUCKET=s3://company-lake \
dataspoc-lens-mcp

Resumo

Em 4 passos, você transformou um monte de arquivos Parquet em uma API inteligente para agentes de IA:

  1. Ingira dados com Pipe (ou traga seu próprio Parquet)
  2. Instale dataspoc-lens[mcp]
  3. Inicie dataspoc-lens mcp
  4. Conecte Claude Desktop, LangGraph, CrewAI ou qualquer cliente MCP

Seu data lake agora é uma ferramenta de primeira classe para qualquer agente de IA — descobrível, consultável e seguro.

Recomendados