loading…
Search for a command to run...
loading…
Enables AI agents to query and introspect MongoDB databases through find, aggregate, and schema discovery operations. Supports read-only default mode with optio
Enables AI agents to query and introspect MongoDB databases through find, aggregate, and schema discovery operations. Supports read-only default mode with optional write capabilities and works with any MCP-compatible client via stdio or HTTP transports.
MCP Server com acesso a MongoDB — Clean Architecture, Repository Pattern, Motor (async).
Compatível com qualquer agente MCP: Claude Code, Claude Desktop, LangChain, LlamaIndex e outros via HTTP.
Este servidor implementa o Model Context Protocol (MCP) para expor um banco de dados MongoDB a modelos de linguagem e agentes de IA.
O agente pode:
find() e aggregate() com filtros, projeções e ordenaçãoO servidor é read-only por padrão e funciona com qualquer instância MongoDB — basta mudar o .env ou a variável MONGODB_URI.
┌─────────────────────────────────────────────────────────┐
│ Agente (Claude / LangChain / …) │
└────────────────────────┬────────────────────────────────┘
│ MCP Protocol
stdio │ ou HTTP (SSE / streamable-http)
┌────────────────────────▼────────────────────────────────┐
│ MCP Server (FastMCP) │
│ │
│ ┌──────────┐ ┌───────────┐ ┌──────────────────┐ │
│ │ Tools │ │ Resources │ │ Prompts │ │
│ └────┬─────┘ └─────┬─────┘ └──────────────────┘ │
│ │ │ │
│ ┌────▼───────────────▼────────────────────────────┐ │
│ │ Repositories │ │
│ │ BaseRepository → QueryRepository │ │
│ │ → SchemaRepository │ │
│ └────────────────────┬────────────────────────────┘ │
│ │ │
│ ┌────────────────────▼────────────────────────────┐ │
│ │ Database (Motor AsyncIOMotorClient) │ │
│ └────────────────────┬────────────────────────────┘ │
│ │ │
│ ┌────────────────────▼────────────────────────────┐ │
│ │ Config (Pydantic Settings + .env) │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
│ TCP
┌────────────────────────▼────────────────────────────────┐
│ MongoDB │
└─────────────────────────────────────────────────────────┘
Regra de dependência: cada camada conhece apenas a camada imediatamente abaixo. Tools não conhecem o banco diretamente; Config não conhece ninguém.
mcp-mongo/
│
├── .env # Configuração activa (não commitado)
├── pyproject.toml # Dependências, scripts, ruff, mypy, pytest
├── .gitignore
│
├── src/
│ └── mcp_mongo/
│ ├── __init__.py
│ ├── server.py # Entry point: cria FastMCP e selecciona transporte
│ │
│ ├── config/
│ │ ├── __init__.py
│ │ └── settings.py # Pydantic Settings — MONGODB_URI ou MONGODB_*
│ │
│ ├── database/
│ │ ├── __init__.py
│ │ └── connection.py # Singleton DatabaseClient (Motor) + lifecycle
│ │
│ ├── repositories/
│ │ ├── __init__.py
│ │ ├── base.py # find_many, find_one, aggregate, writes + _serialize BSON
│ │ ├── query_repository.py # find/aggregate com guard de writes
│ │ └── schema_repository.py # Introspecção: databases, collections, schema inferido, índices, stats
│ │
│ ├── tools/
│ │ ├── __init__.py
│ │ ├── query_tools.py # find, find_one, aggregate, count, insert, update, delete
│ │ └── schema_tools.py # list_databases, list_collections, describe_collection, list_indexes, get_collection_stats
│ │
│ ├── resources/
│ │ ├── __init__.py
│ │ └── schema_resources.py # URIs: mongo://databases, mongo://db/{db}/collections, …
│ │
│ └── prompts/
│ ├── __init__.py
│ └── mongo_prompts.py # explore_database, analyse_collection, write_query, write_aggregation, optimise_query
│
└── tests/
├── __init__.py
├── conftest.py
└── tools/
├── test_query_repository.py
└── test_schema_repository.py
Pré-requisitos: Python 3.11+, uv, MongoDB acessível.
cd mcp-mongo
# Instalar dependências
uv sync
# Com dependências de desenvolvimento
uv sync --extra dev
Toda a configuração é feita no ficheiro .env na raiz do projeto.
cp .env .env.local
# editar com os dados do teu ambiente
Existem duas formas de configurar a conexão — usa a que for mais conveniente:
Opção A — MONGODB_URI (tem prioridade)
Uma única variável com a URI completa:
MONGODB_URI=mongodb://user:password@host:27017/dbname
Também suporta URIs com replica sets e opções adicionais:
MONGODB_URI=mongodb+srv://user:[email protected]/dbname
Opção B — variáveis individuais
MONGODB_HOST=localhost
MONGODB_PORT=27017
MONGODB_DB=mydb
MONGODB_USER=myuser
MONGODB_PASSWORD=secret
Se
MONGODB_URIestiver definida, os valores deMONGODB_HOST,MONGODB_PORT, etc., são ignorados. Caso contrário, as vars individuais são usadas. Se nenhuma for fornecida, o servidor tenta ligar alocalhost:27017/test.
A variável MCP_TRANSPORT define como o servidor comunica com o agente:
| Valor | Protocolo | Endpoint | Indicado para |
|---|---|---|---|
stdio (padrão) |
stdin/stdout | — | Claude Code, Claude Desktop, agentes locais |
sse |
HTTP Server-Sent Events | http://host:port/sse |
LangChain, LlamaIndex, agentes HTTP legados |
streamable-http |
HTTP streaming | http://host:port/mcp |
Agentes MCP modernos via HTTP |
Para HTTP, define também o host e a porta:
MCP_TRANSPORT=sse
MCP_HOST=0.0.0.0
MCP_PORT=8080
| Variável | Padrão | Descrição |
|---|---|---|
MONGODB_URI |
— | URI completa (prioridade sobre vars individuais) |
MONGODB_HOST |
localhost |
Host do MongoDB |
MONGODB_PORT |
27017 |
Porta |
MONGODB_DB |
test |
Database padrão |
MONGODB_USER |
(vazio) | Utilizador |
MONGODB_PASSWORD |
(vazio) | Password |
MONGODB_AUTH_SOURCE |
admin |
Database de autenticação |
MONGODB_MIN_POOL_SIZE |
2 |
Conexões mínimas no pool |
MONGODB_MAX_POOL_SIZE |
10 |
Conexões máximas no pool |
MONGODB_SERVER_SELECTION_TIMEOUT |
5000 |
Timeout de seleção de servidor (ms) |
MONGODB_ALLOWED_DATABASES |
(vazio = todos) | Databases expostos (vírgula separados) |
MONGODB_ALLOW_WRITES |
false |
Habilita insert/update/delete |
MCP_SERVER_NAME |
mongo-mcp |
Nome do servidor MCP |
MCP_LOG_LEVEL |
INFO |
Nível de log (DEBUG, INFO, WARNING, ERROR) |
MCP_TRANSPORT |
stdio |
Transporte: stdio, sse, streamable-http |
MCP_HOST |
0.0.0.0 |
Host do servidor HTTP (só para SSE/streamable-http) |
MCP_PORT |
8080 |
Porta do servidor HTTP (só para SSE/streamable-http) |
# Modo stdio (padrão)
uv run mcp-mongo
# Modo SSE — servidor HTTP na porta 8080
MCP_TRANSPORT=sse uv run mcp-mongo
# Modo desenvolvimento com MCP Inspector
uv run mcp dev src/mcp_mongo/server.py
Tools são funções que o agente chama activamente para executar operações.
findExecuta um find() em uma collection e retorna os documentos como JSON.
| Parâmetro | Tipo | Obrigatório | Padrão | Descrição |
|---|---|---|---|---|
database |
str |
sim | — | Nome do database MongoDB |
collection |
str |
sim | — | Nome da collection |
filter |
dict |
não | {} |
Filtro MongoDB (ex: {"status": "active"}) |
projection |
dict |
não | {} |
Campos a incluir/excluir (ex: {"name": 1, "_id": 0}) |
sort |
list |
não | — | Lista de pares [campo, direção] (ex: [["age", -1]]) |
limit |
int |
não | 100 |
Número máximo de documentos |
skip |
int |
não | 0 |
Documentos a saltar (paginação) |
// Exemplo
{
"database": "shop",
"collection": "orders",
"filter": {"status": "pending"},
"sort": [["created_at", -1]],
"limit": 20
}
find_oneExecuta um find_one() e retorna o primeiro documento encontrado.
| Parâmetro | Tipo | Obrigatório | Padrão | Descrição |
|---|---|---|---|---|
database |
str |
sim | — | Nome do database |
collection |
str |
sim | — | Nome da collection |
filter |
dict |
não | {} |
Filtro MongoDB |
projection |
dict |
não | {} |
Campos a incluir/excluir |
aggregateExecuta um aggregation pipeline e retorna os resultados como JSON.
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
database |
str |
sim | Nome do database |
collection |
str |
sim | Nome da collection |
pipeline |
list |
sim | Lista de estágios de agregação |
// Exemplo — vendas por categoria
{
"database": "shop",
"collection": "orders",
"pipeline": [
{ "$match": { "status": "completed" } },
{ "$group": { "_id": "$category", "total": { "$sum": "$amount" } } },
{ "$sort": { "total": -1 } }
]
}
count_documentsConta documentos que correspondem ao filtro.
| Parâmetro | Tipo | Obrigatório | Padrão | Descrição |
|---|---|---|---|---|
database |
str |
sim | — | Nome do database |
collection |
str |
sim | — | Nome da collection |
filter |
dict |
não | {} |
Filtro MongoDB (vazio = conta todos) |
insert_documentsInsere um ou mais documentos. Requer MONGODB_ALLOW_WRITES=true.
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
database |
str |
sim | Nome do database |
collection |
str |
sim | Nome da collection |
documents |
list |
sim | Lista de documentos a inserir |
Retorna os IDs gerados (inserted_id para um, inserted_ids para múltiplos).
update_documentsAtualiza documentos correspondentes ao filtro. Requer MONGODB_ALLOW_WRITES=true.
| Parâmetro | Tipo | Obrigatório | Padrão | Descrição |
|---|---|---|---|---|
database |
str |
sim | — | Nome do database |
collection |
str |
sim | — | Nome da collection |
filter |
dict |
sim | — | Filtro para selecionar documentos |
update |
dict |
sim | — | Operação de atualização (ex: {"$set": {...}}) |
upsert |
bool |
não | false |
Cria o documento se não existir |
Retorna matched_count, modified_count e upserted_id.
delete_documentsRemove documentos correspondentes ao filtro. Requer MONGODB_ALLOW_WRITES=true.
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
database |
str |
sim | Nome do database |
collection |
str |
sim | Nome da collection |
filter |
dict |
sim | Filtro para selecionar documentos a remover |
Atenção:
filter: {}remove todos os documentos da collection.
Retorna deleted_count.
list_databasesLista todos os databases não-sistema disponíveis no servidor MongoDB (admin, local e config são sempre excluídos).
list_collectionsLista collections de um database.
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
database |
str |
sim | Nome do database |
describe_collectionInfere o esquema de uma collection via amostragem de documentos. Retorna campos, tipos dominantes e frequência de presença.
| Parâmetro | Tipo | Obrigatório | Padrão | Descrição |
|---|---|---|---|---|
database |
str |
sim | — | Nome do database |
collection |
str |
sim | — | Nome da collection |
sample_size |
int |
não | 100 |
Número de documentos a amostrar |
Exemplo de saída:
[
{ "field": "_id", "dominant_type": "string", "presence_pct": 100.0 },
{ "field": "name", "dominant_type": "string", "presence_pct": 100.0 },
{ "field": "age", "dominant_type": "int", "presence_pct": 98.0 },
{ "field": "address.city", "dominant_type": "string", "presence_pct": 75.0 },
{ "field": "address.zip", "dominant_type": "string", "presence_pct": 60.0 },
{ "field": "tags", "dominant_type": "array", "presence_pct": 45.0 }
]
Campos de documentos embutidos (address.city) são expandidos automaticamente.
list_indexesLista os índices de uma collection com unicidade, esparsidade e campos cobertos.
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
database |
str |
sim | Nome do database |
collection |
str |
sim | Nome da collection |
get_collection_statsRetorna estatísticas de uma collection via $collStats (MongoDB 3.6+).
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
database |
str |
sim | Nome do database |
collection |
str |
sim | Nome da collection |
Inclui: document_count, size_kb, avg_document_size_bytes, storage_size_kb, index_count, total_index_size_kb.
Resources expõem dados como URIs navegáveis — o agente lê-os para obter contexto antes de agir.
| URI | Descrição |
|---|---|
mongo://databases |
Lista todos os databases não-sistema |
mongo://db/{database}/collections |
Lista collections de um database |
mongo://db/{database}/collection/{collection} |
Schema inferido + índices + stats de uma collection |
Prompts são templates reutilizáveis que guiam o agente numa tarefa complexa.
| Prompt | Parâmetros | Descrição |
|---|---|---|
explore_database |
— | Roteiro para explorar um banco MongoDB desconhecido |
analyse_collection |
database, collection |
Análise detalhada de uma collection |
write_query |
question |
Gera um find() ou aggregate() a partir de linguagem natural |
write_aggregation |
question |
Gera um aggregation pipeline para análise de dados |
optimise_query |
database, collection, filter_hint |
Analisa e sugere optimizações para uma query |
| Mecanismo | Detalhe |
|---|---|
| Read-only por padrão | Writes bloqueados por guard em cada método — sem acesso ao banco |
| Databases permitidos | MONGODB_ALLOWED_DATABASES limita a exposição de dados |
| Serialização BSON segura | ObjectId, Decimal128 e outros tipos BSON são convertidos para strings — sem falhas de serialização |
| Logs sanitizados | Password nunca aparece em logs (safe_uri) |
| Erros sanitizados | Exceções retornam mensagem simples ao agente, sem stack trace |
| Pool limitado | max_pool_size=10 por padrão — evita saturar o servidor |
| Ping no startup | Falha imediatamente se as credenciais ou o host estiverem incorrectos |
Para habilitar escritas:
MONGODB_ALLOW_WRITES=true
Os testes são de integração e requerem uma instância MongoDB acessível. Usam o database temporário test_mcp_tmp, que é criado e destruído automaticamente.
# Todos os testes (usa .env por padrão)
uv run pytest
# Sobrepor a URI para os testes
TEST_MONGODB_URI=mongodb://localhost:27017/test uv run pytest
# Com coverage
uv run pytest --cov=src/mcp_mongo --cov-report=html
# Verbose
uv run pytest -v
Adicionar ao ~/.claude.json (user-level, disponível em todos os projetos):
{
"mcpServers": {
"mongo": {
"type": "stdio",
"command": "uv",
"args": [
"--directory", "/caminho/para/mcp-mongo",
"run", "mcp-mongo"
],
"env": {
"MONGODB_URI": "mongodb://user:pass@host:27017/mydb"
}
}
}
}
Iniciar o servidor em modo SSE:
MCP_TRANSPORT=sse MCP_PORT=8080 uv run mcp-mongo
Conectar a partir do agente:
# LangChain + MCP
from langchain_mcp_adapters.client import MultiServerMCPClient
client = MultiServerMCPClient({
"mongo": {
"url": "http://localhost:8080/sse",
"transport": "sse",
}
})
tools = await client.get_tools()
Iniciar em modo streamable-http:
MCP_TRANSPORT=streamable-http MCP_PORT=8080 uv run mcp-mongo
Endpoint disponível em http://localhost:8080/mcp.
FROM python:3.12-slim
WORKDIR /app
COPY . .
RUN pip install uv && uv sync
EXPOSE 8080
CMD ["uv", "run", "mcp-mongo"]
docker run -p 8080:8080 \
-e MONGODB_URI=mongodb://user:pass@host:27017/mydb \
-e MCP_TRANSPORT=sse \
mcp-mongo
MONGODB_URI vs MONGODB_*MONGODB_URI é o padrão de facto em ambientes cloud (MongoDB Atlas, Railway, Render, etc.) e suporta opções avançadas como replica sets e mongodb+srv. As vars individuais são mais legíveis para desenvolvimento local. O model_validator do Pydantic extrai os campos da URI se fornecida, garantindo que a URI interna está sempre correta independentemente de qual forma foi usada.
Motor é o driver oficial async do MongoDB para Python. Construído sobre PyMongo mas com interface asyncio nativa — não é um wrapper de thread pool. Necessário para coexistir com FastMCP que opera em loop de eventos asyncio.
$jsonSchemaMongoDB é schemaless por design. A abordagem escolhida ($sample + inferência de tipos) devolve um esquema descritivo de documentos reais sem exigir validação de schema configurada no banco. O presence_pct indica quais campos são obrigatórios na prática vs opcionais, o que é informação mais útil para o agente do que uma definição formal.
_serialize()Tipos BSON como ObjectId, Decimal128 e datetime não são serializáveis em JSON nativo. A função _serialize() no BaseRepository converte recursivamente todos os valores antes de retornar ao agente, eliminando erros de serialização em qualquer tool ou resource.
O protocolo MCP suporta vários transportes. stdio é o padrão para agentes locais (Claude Code lança o processo e comunica por stdin/stdout). Para agentes remotos ou multi-tenant, sse e streamable-http expõem o servidor como um serviço HTTP sem qualquer alteração de código — só muda a variável de ambiente.
src/ layoutPrevine que o Python encontre o módulo via path local sem instalação — o que mascararia erros de packaging e tornaria os testes menos fiáveis.
Isola as operações Motor das tools MCP. As tools expressam intenção (describe_collection), os repositórios expressam implementação ($sample + inferência). Trocar a estratégia de introspecção não exige tocar nas tools.
Garante que o client abre (e valida com ping) antes do servidor aceitar requests, e fecha sempre ao terminar — mesmo com Ctrl+C ou sinal do OS. Não há risco de conexões a vazar ou de o agente receber requests antes do banco estar pronto.
Добавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"mcp-mongo": {
"command": "npx",
"args": []
}
}
}