Skip to main content
Glama
tatisstiv

MongoDB MCP Server

by tatisstiv
README.md
# MongoDB MCP Server

Stdio [Model Context Protocol](https://modelcontextprotocol.io/) server that lets an IDE agent read and write MongoDB through typed, allowlisted tools.

This transport is **stdio-only**. Do not expose it on a public network without additional auth and a hardened deployment model. The process trusts the local MCP host (OS user / IDE); there is no separate login layer.

## Features

| Tool | Purpose |
|------|---------|
| `write_to_db` | Insert or upsert (filter or `data._id`) |
| `read_from_db` | Query with `skip` / `limit` / `sort` |
| `update_in_db` | Update one or many documents |
| `delete_from_db` | Soft-delete (default) or hard-delete (opt-in) |
| `list_collections` | List collections (respects allowlist) |
| `aggregate_db` | Read-only aggregation (write/code stages blocked) |

Also registers a resource template: `mongodb://collection/{name}`.

### Safety defaults

- **Fail closed on collections**: require `MCP_ALLOWED_COLLECTIONS` or explicit `MCP_ALLOW_ALL_COLLECTIONS=true`
- Collection names must match `^[a-zA-Z][a-zA-Z0-9_-]{0,63}$`
- Rejects `$where` / `$function` / `$accumulator` / `$jsonSchema` / `$expr`
- Caps `$regex` length and object nesting depth
- Blocks dangerous aggregation stages (`$out` / `$merge` / `$function` / admin stages); `$lookup` / `$unionWith` targets must pass the allowlist
- Caps `limit` at `MCP_MAX_LIMIT` (default 100)
- Soft-deleted documents (`deletedAt`) are hidden from reads unless requested
- Hard delete disabled unless `MCP_ALLOW_HARD_DELETE=true`
- Optional `MCP_READ_ONLY=true` disables all mutating tools
- Structured audit events + sanitized tool errors on **stderr** (stdout stays clean for MCP framing)

## Quick start

```bash
# Start MongoDB
docker compose up -d mongo

# Install and run (dev)
cp .env.example .env
npm install
npm run dev
```

Production build:

```bash
npm run build
npm start
```

## Cursor MCP config

Add to your MCP settings (path varies by Cursor version):

```json
{
  "mcpServers": {
    "mongo": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-server/dist/index.js"],
      "env": {
        "MONGODB_URI": "mongodb://localhost:27018/mcp-server",
        "MCP_ALLOWED_COLLECTIONS": "notes,tasks"
      }
    }
  }
}
```

For local iteration without building:

```json
{
  "mcpServers": {
    "mongo": {
      "command": "npx",
      "args": ["tsx", "/absolute/path/to/mcp-server/src/index.ts"],
      "env": {
        "MONGODB_URI": "mongodb://localhost:27018/mcp-server",
        "MCP_ALLOWED_COLLECTIONS": "notes,tasks"
      }
    }
  }
}
```

## Environment

| Variable | Default | Description |
|----------|---------|-------------|
| `MONGODB_URI` | `mongodb://localhost:27018/mcp-server` | Mongo connection string |
| `MCP_ALLOWED_COLLECTIONS` | _(required unless allow-all)_ | Comma-separated allowlist |
| `MCP_ALLOW_ALL_COLLECTIONS` | `false` | Opt-in to allow any valid name (local/dev) |
| `MCP_READ_ONLY` | `false` | Reject write/update/delete tools |
| `MCP_ALLOW_HARD_DELETE` | `false` | Allow `soft=false` deletes |
| `MCP_DEFAULT_LIMIT` | `10` | Default read limit |
| `MCP_MAX_LIMIT` | `100` | Hard cap on read limit |
| `MCP_MAX_REGEX_LENGTH` | `200` | Max `$regex` pattern length |
| `MCP_MAX_OBJECT_DEPTH` | `32` | Max nested object depth in queries |

## Scripts

| Script | Description |
|--------|-------------|
| `npm run dev` | Run with `tsx` |
| `npm run build` | Compile to `dist/` |
| `npm start` | Run compiled server |
| `npm test` | Unit tests (validation) |
| `npm run test:integration` | Integration tests (needs Mongo) |
| `npm run audit` | Dependency vulnerability audit |

```bash
docker compose up -d mongo
npm run test:integration
```

## Docker

Mongo only (typical for local MCP + host Node process):

```bash
docker compose up -d mongo
```

Optional image build (stdio still expected from the client):

```bash
docker compose --profile app build
```

## Project layout

```
src/
  index.ts              # stdio bootstrap + secure config check
  loadEnv.ts            # optional .env loader
  server.ts             # McpServer wiring
  config.ts             # env config
  database/mongo.ts     # connection + dynamic models
  security/             # validation, access gates, audit log
  tools/                # tool handlers + Zod schemas
  resources/            # collection resources
```