MCP Hub
Back to servers

mcp-mongo

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.

glama
Updated
Apr 3, 2026

mcp-mongo

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.


Índice


Visão Geral

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:

  • Executar queries find() e aggregate() com filtros, projeções e ordenação
  • Inspecionar databases, collections e inferir esquemas via amostragem de documentos
  • Listar índices e obter estatísticas de collections
  • Executar operações de escrita (quando explicitamente habilitado)

O servidor é read-only por padrão e funciona com qualquer instância MongoDB — basta mudar o .env ou a variável MONGODB_URI.


Arquitetura

┌─────────────────────────────────────────────────────────┐
│              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.


Estrutura de Ficheiros

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

Instalação

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

Configuração

Toda a configuração é feita no ficheiro .env na raiz do projeto.

cp .env .env.local
# editar com os dados do teu ambiente

Conexão com o Banco

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:password@cluster.mongodb.net/dbname

Opção B — variáveis individuais

MONGODB_HOST=localhost
MONGODB_PORT=27017
MONGODB_DB=mydb
MONGODB_USER=myuser
MONGODB_PASSWORD=secret

Se MONGODB_URI estiver definida, os valores de MONGODB_HOST, MONGODB_PORT, etc., são ignorados. Caso contrário, as vars individuais são usadas. Se nenhuma for fornecida, o servidor tenta ligar a localhost:27017/test.

Transporte MCP

A variável MCP_TRANSPORT define como o servidor comunica com o agente:

ValorProtocoloEndpointIndicado para
stdio (padrão)stdin/stdoutClaude Code, Claude Desktop, agentes locais
sseHTTP Server-Sent Eventshttp://host:port/sseLangChain, LlamaIndex, agentes HTTP legados
streamable-httpHTTP streaminghttp://host:port/mcpAgentes 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

Referência completa de variáveis

VariávelPadrãoDescrição
MONGODB_URIURI completa (prioridade sobre vars individuais)
MONGODB_HOSTlocalhostHost do MongoDB
MONGODB_PORT27017Porta
MONGODB_DBtestDatabase padrão
MONGODB_USER(vazio)Utilizador
MONGODB_PASSWORD(vazio)Password
MONGODB_AUTH_SOURCEadminDatabase de autenticação
MONGODB_MIN_POOL_SIZE2Conexões mínimas no pool
MONGODB_MAX_POOL_SIZE10Conexões máximas no pool
MONGODB_SERVER_SELECTION_TIMEOUT5000Timeout de seleção de servidor (ms)
MONGODB_ALLOWED_DATABASES(vazio = todos)Databases expostos (vírgula separados)
MONGODB_ALLOW_WRITESfalseHabilita insert/update/delete
MCP_SERVER_NAMEmongo-mcpNome do servidor MCP
MCP_LOG_LEVELINFONível de log (DEBUG, INFO, WARNING, ERROR)
MCP_TRANSPORTstdioTransporte: stdio, sse, streamable-http
MCP_HOST0.0.0.0Host do servidor HTTP (só para SSE/streamable-http)
MCP_PORT8080Porta do servidor HTTP (só para SSE/streamable-http)

Execução

# 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

Capacidades MCP

Tools

Tools são funções que o agente chama activamente para executar operações.


find

Executa um find() em uma collection e retorna os documentos como JSON.

ParâmetroTipoObrigatórioPadrãoDescrição
databasestrsimNome do database MongoDB
collectionstrsimNome da collection
filterdictnão{}Filtro MongoDB (ex: {"status": "active"})
projectiondictnão{}Campos a incluir/excluir (ex: {"name": 1, "_id": 0})
sortlistnãoLista de pares [campo, direção] (ex: [["age", -1]])
limitintnão100Número máximo de documentos
skipintnão0Documentos a saltar (paginação)
// Exemplo
{
  "database": "shop",
  "collection": "orders",
  "filter": {"status": "pending"},
  "sort": [["created_at", -1]],
  "limit": 20
}

find_one

Executa um find_one() e retorna o primeiro documento encontrado.

ParâmetroTipoObrigatórioPadrãoDescrição
databasestrsimNome do database
collectionstrsimNome da collection
filterdictnão{}Filtro MongoDB
projectiondictnão{}Campos a incluir/excluir

aggregate

Executa um aggregation pipeline e retorna os resultados como JSON.

ParâmetroTipoObrigatórioDescrição
databasestrsimNome do database
collectionstrsimNome da collection
pipelinelistsimLista 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_documents

Conta documentos que correspondem ao filtro.

ParâmetroTipoObrigatórioPadrãoDescrição
databasestrsimNome do database
collectionstrsimNome da collection
filterdictnão{}Filtro MongoDB (vazio = conta todos)

insert_documents

Insere um ou mais documentos. Requer MONGODB_ALLOW_WRITES=true.

ParâmetroTipoObrigatórioDescrição
databasestrsimNome do database
collectionstrsimNome da collection
documentslistsimLista de documentos a inserir

Retorna os IDs gerados (inserted_id para um, inserted_ids para múltiplos).


update_documents

Atualiza documentos correspondentes ao filtro. Requer MONGODB_ALLOW_WRITES=true.

ParâmetroTipoObrigatórioPadrãoDescrição
databasestrsimNome do database
collectionstrsimNome da collection
filterdictsimFiltro para selecionar documentos
updatedictsimOperação de atualização (ex: {"$set": {...}})
upsertboolnãofalseCria o documento se não existir

Retorna matched_count, modified_count e upserted_id.


delete_documents

Remove documentos correspondentes ao filtro. Requer MONGODB_ALLOW_WRITES=true.

ParâmetroTipoObrigatórioDescrição
databasestrsimNome do database
collectionstrsimNome da collection
filterdictsimFiltro para selecionar documentos a remover

Atenção: filter: {} remove todos os documentos da collection.

Retorna deleted_count.


list_databases

Lista todos os databases não-sistema disponíveis no servidor MongoDB (admin, local e config são sempre excluídos).


list_collections

Lista collections de um database.

ParâmetroTipoObrigatórioDescrição
databasestrsimNome do database

describe_collection

Infere o esquema de uma collection via amostragem de documentos. Retorna campos, tipos dominantes e frequência de presença.

ParâmetroTipoObrigatórioPadrãoDescrição
databasestrsimNome do database
collectionstrsimNome da collection
sample_sizeintnão100Nú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_indexes

Lista os índices de uma collection com unicidade, esparsidade e campos cobertos.

ParâmetroTipoObrigatórioDescrição
databasestrsimNome do database
collectionstrsimNome da collection

get_collection_stats

Retorna estatísticas de uma collection via $collStats (MongoDB 3.6+).

ParâmetroTipoObrigatórioDescrição
databasestrsimNome do database
collectionstrsimNome da collection

Inclui: document_count, size_kb, avg_document_size_bytes, storage_size_kb, index_count, total_index_size_kb.


Resources

Resources expõem dados como URIs navegáveis — o agente lê-os para obter contexto antes de agir.

URIDescrição
mongo://databasesLista todos os databases não-sistema
mongo://db/{database}/collectionsLista collections de um database
mongo://db/{database}/collection/{collection}Schema inferido + índices + stats de uma collection

Prompts

Prompts são templates reutilizáveis que guiam o agente numa tarefa complexa.

PromptParâmetrosDescrição
explore_databaseRoteiro para explorar um banco MongoDB desconhecido
analyse_collectiondatabase, collectionAnálise detalhada de uma collection
write_queryquestionGera um find() ou aggregate() a partir de linguagem natural
write_aggregationquestionGera um aggregation pipeline para análise de dados
optimise_querydatabase, collection, filter_hintAnalisa e sugere optimizações para uma query

Segurança

MecanismoDetalhe
Read-only por padrãoWrites bloqueados por guard em cada método — sem acesso ao banco
Databases permitidosMONGODB_ALLOWED_DATABASES limita a exposição de dados
Serialização BSON seguraObjectId, Decimal128 e outros tipos BSON são convertidos para strings — sem falhas de serialização
Logs sanitizadosPassword nunca aparece em logs (safe_uri)
Erros sanitizadosExceções retornam mensagem simples ao agente, sem stack trace
Pool limitadomax_pool_size=10 por padrão — evita saturar o servidor
Ping no startupFalha imediatamente se as credenciais ou o host estiverem incorrectos

Para habilitar escritas:

MONGODB_ALLOW_WRITES=true

Testes

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

Integração com Agentes

Claude Code / Claude Desktop

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"
      }
    }
  }
}

LangChain / LlamaIndex

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()

Agentes HTTP genéricos

Iniciar em modo streamable-http:

MCP_TRANSPORT=streamable-http MCP_PORT=8080 uv run mcp-mongo

Endpoint disponível em http://localhost:8080/mcp.


Docker

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

Decisões de Arquitetura

Conexão dinâmica — 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 em vez de PyMongo síncrono

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.

Schema por amostragem — sem $jsonSchema

MongoDB é 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.

Serialização BSON centralizada em _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.

Transporte configurável

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/ layout

Previne 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.

Repository Pattern

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.

Lifespan para o client Motor

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.

Reviews

No reviews yet

Sign in to write a review