MCP Server de usuários (com busca semântica)
Este projeto expõe 4 tools MCP para trabalhar com usuários:
- criar usuário
- buscar usuário por ID
- buscar usuários por similaridade semântica
- listar usuários com paginação
A ideia é simples: os dados ficam no SQLite (users.db) e os vetores de embedding ficam no FAISS (faiss_index/).
Quickstart (3 comandos)
pipenv install
pipenv run streamlit run app.py
pipenv run pytest tools_tests -qDica: rode o pytest em outro terminal se o servidor estiver em execução no primeiro.O que tem aqui
server.py: sobe o servidor MCP e registra as toolsapp.py: interface Streamlit para testar as funcionalidadesservices/user_service.py: regras de negóciodatabase/connect.pyedatabase/database.py: conexão SQLite e criação da tabelaembeddings.py: geração de embedding comsentence-transformersvector_store.py: persistência e consulta no FAISSmodels.py: schemas Pydanticlogging_config.py: logging estruturado em JSONtools_tests/: testes das tools
Pré-requisitos
Para rodar local:
- Python 3.11
- Pipenv
Para rodar em container:
- Docker
Rodando com Docker
1) Build da imagem
docker build -t case-tecnico-mcp .2) Subir no modo MCP (server)
docker run -p 8000:8000 \
-e APP_MODE=mcp \
-v $(pwd)/users.db:/app/users.db \
-v $(pwd)/faiss_index:/app/faiss_index \
case-tecnico-mcp3) Subir no modo Streamlit (front para testes)
docker run -p 8501:8501 \
-e APP_MODE=streamlit \
-v $(pwd)/users.db:/app/users.db \
-v $(pwd)/faiss_index:/app/faiss_index \
case-tecnico-mcpAbra no navegador:
http://localhost:8501(Streamlit)
Observações:
- A tabela
usersé criada automaticamente no startup. - No primeiro boot, o modelo de embedding pode demorar para baixar do Hugging Face.
- Docker Compose não é obrigatório neste projeto (apenas um serviço).
4) Persistir dados entre execuções (recomendado)
Sem volume, o banco/índice podem se perder quando o container for removido. Para manter dados:
docker run -p 8000:8000 \
-e APP_MODE=mcp \
-v $(pwd)/users.db:/app/users.db \
-v $(pwd)/faiss_index:/app/faiss_index \
case-tecnico-mcpRodando local com Pipenv
1) Instalar dependências
pipenv install2) Entrar no ambiente virtual
pipenv shell3) Rodar em modo MCP (server)
python server.py4) Rodar em modo Streamlit (front para testes)
streamlit run app.pyObservação: a tabela users é criada automaticamente no startup do serviço.
Tools disponíveis
1) create_user
Cria usuário no SQLite e salva embedding no FAISS.
Entrada
{
"name": "Ana Silva",
"email": "ana.silva@example.com",
"description": "Engenheira backend Python com foco em APIs"
}Saída (sucesso)
{
"message": "Usuário criado com sucesso",
"user_id": 1
}Saída (erro comum)
{
"error": "UNIQUE constraint failed: users.email"
}2) get_user
Busca um usuário por ID.
Entrada
{
"user_id": 1
}Saída (sucesso)
{
"id": 1,
"name": "Ana Silva",
"email": "ana.silva@example.com",
"description": "Engenheira backend Python com foco em APIs"
}Saída (não encontrado)
{
"error": "Usuario com ID 999 não encontrado"
}3) search_users
Faz busca semântica por texto usando embedding + FAISS.
Entrada
{
"query": "backend python api",
"top_k": 3
}Saída (exemplo)
[
{
"id": 1,
"name": "Ana Silva",
"email": "ana.silva@example.com",
"description": "Engenheira backend Python com foco em APIs",
"score": 0.3867
}
]Observação: no score do FAISS (L2), quanto menor, mais próximo semanticamente.
4) list_users
Lista usuários com paginação por limit e offset.
Entrada
{
"limit": 10,
"offset": 0
}Saída (exemplo)
[
{
"id": 1,
"name": "Ana Silva",
"email": "ana.silva@example.com",
"description": "Engenheira backend Python com foco em APIs"
},
{
"id": 2,
"name": "Carlos Mendes",
"email": "carlos.mendes@example.com",
"description": "Cientista de dados com foco em machine learning e análise de dados"
}
]Como rodar os testes
Os testes estão na pasta tools_tests/.
Rodar suite completa
Da raiz do projeto:
pipenv run pytest tools_tests -qOu de dentro da pasta de testes:
cd tools_tests
pytest -qRodar por etapa (separado)
pipenv run pytest tools_tests/test_create_user.py -q
pipenv run pytest tools_tests/test_get_user.py -q
pipenv run pytest tools_tests/test_search_users.py -q
pipenv run pytest tools_tests/test_list_users.py -qO que cada teste cobre
test_create_user.py
- criação de usuários válidos - tentativa de e-mail duplicado - validação de e-mail inválido
test_get_user.py
- busca por ID existente - busca por ID inexistente - busca por ID negativo
test_search_users.py
- consultas semânticas com validação de relevância - validação de top_k - query vazia sem quebrar execução
test_list_users.py
- listagem básica - validação de paginação (limit/offset) - offset fora do range retorna lista vazia
Dicas para quem vai estudar/evoluir o projeto
- A tabela
usersé criada automaticamente na inicialização do serviço (fase de startup). - Se mudar o schema de usuário, revise:
- models.py - services/user_service.py - testes em tools_tests/
- Se adicionar/remover uma tool:
- atualizar server.py - atualizar services/user_service.py - criar/ajustar teste correspondente - garantir cobertura em tools_tests/ e validar com pytest
- O índice FAISS usa caminho absoluto baseado na raiz do projeto, então não depende do diretório de execução.
Dependências principais
fastmcpsentence-transformersfaiss-cpuemail-validator
Versão de Python do projeto: 3.11.
