Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mongo-schema-explainer-mcp

Production-grade MCP server for safe MongoDB inspection. It lets AI agents list collections, infer schemas from live documents, and run strictly read-only queries with bounded output.

Why this project exists

Most agents need database context, but raw database access is too dangerous. This server narrows the surface area:

  • list_collections gives discovery without mutation.
  • get_schema infers structure from real sample data.
  • run_safe_query exposes a small, allowlisted read API.

The implementation is intentionally educational. The code uses strict TypeScript, runtime validation, recursive schema inference, cache-aware reads, and MCP tool wiring that is ready for real clients.

Architecture

src/
├── index.ts
├── config/
│   └── env.ts
├── constants/
│   └── allowedOperations.ts
├── db/
│   └── mongo.ts
├── tools/
│   ├── getSchema.ts
│   ├── listCollections.ts
│   └── runSafeQuery.ts
├── types/
│   └── schema.ts
└── utils/
    ├── safeOperations.ts
    ├── schemaInferer.ts
    ├── typeHelpers.ts
    └── validators.ts

scripts/
└── test-mcp-server.ts

TypeScript highlights

This codebase intentionally demonstrates advanced TypeScript patterns in production context:

  • interfaces for public response contracts
  • literal union types for read-only operation allowlists
  • branded types for validated collection names
  • discriminated control flow by operation type
  • generics for reusable schema/query helpers
  • recursive types for schema trees and ReadonlyDeep
  • conditional types through ArrayElement<T>
  • type guards for ObjectId, Date, and plain objects
  • strict null checks with exactOptionalPropertyTypes

The compiler is configured with:

  • strict: true
  • noImplicitAny: true
  • exactOptionalPropertyTypes: true
  • noUncheckedIndexedAccess: true

Setup

  1. Install dependencies:
npm install
  1. Copy environment variables:
cp .env.example .env
  1. Fill in:
MONGODB_URI=mongodb://127.0.0.1:27017
DATABASE_NAME=sample_mcp
PORT=3001
SCHEMA_SAMPLE_SIZE=10
SAFE_QUERY_MAX_LIMIT=50
ENABLE_SCHEMA_CACHE=true
SCHEMA_CACHE_TTL_MS=300000
LOG_LEVEL=info
  1. Run in development:
npm run mcp:dev
  1. Build for production:
npm run mcp:build
npm run mcp:start

MCP tools

list_collections

Input:

{
  "includeSample": true
}

Response shape:

{
  "collections": [
    {
      "name": "users",
      "count": 123,
      "sampleDocument": {
        "_id": "66465e4db15c0708d8f13c20",
        "name": "Dhruv"
      }
    }
  ]
}

get_schema

Input:

{
  "collection": "users",
  "sampleSize": 10,
  "refresh": false
}

Response includes:

  • recursive field tree
  • merged union types like number | string
  • nullable detection
  • array item inference including mixed arrays
  • collection stats
  • index summaries
  • generated TypeScript interface
  • generated Mongoose schema
  • cache metadata and confidence scores

run_safe_query

Allowed operations:

  • find
  • findOne
  • aggregate
  • countDocuments

Blocked operations:

  • deleteMany
  • deleteOne
  • updateMany
  • updateOne
  • replaceOne
  • insertOne
  • drop
  • createIndex
  • bulkWrite
  • findOneAndDelete
  • findOneAndUpdate

Example:

{
  "operation": "find",
  "collection": "users",
  "query": {
    "age": {
      "$gt": 18
    }
  },
  "limit": 10,
  "sort": {
    "age": -1
  }
}

How schema inference works

The core logic lives in src/utils/schemaInferer.ts.

  1. Sample real MongoDB documents with a bounded $sample.
  2. Walk each document recursively.
  3. Infer each runtime value via inferFieldType(value).
  4. Merge observations into a tree of schema nodes.
  5. Mark fields as nullable when they are missing or explicitly null.
  6. Collapse inconsistent observations into unions such as string | number.
  7. Export the final structure as:
    • machine-readable JSON
    • TypeScript interface
    • Mongoose schema draft

Type detection rules:

  • Date instances become date
  • ObjectId becomes objectId
  • ISO date strings stay string
  • arrays are represented as array<...>
  • empty arrays default to array<unknown>
  • nested objects produce children

Security model

The server is read-only by construction.

  • Operations are allowlisted in src/constants/allowedOperations.ts.
  • Tool input is validated with Zod before execution.
  • Collection names are restricted to safe characters.
  • Query payloads are recursively sanitized.
  • $where, $function, $accumulator, and eval-like strings are rejected.
  • Aggregation stages are filtered by allowlist.
  • Results are hard-limited to at most 50 documents.
  • Logs go to stderr, preserving stdout for MCP protocol traffic.

Logging, caching, and metadata

Implemented bonus features:

  • schema caching with TTL
  • query execution timing
  • structured logging middleware
  • collection statistics
  • index inspection
  • schema confidence scoring
  • TypeScript export generation
  • Mongoose export generation
  • CLI smoke test script
  • Docker support

Testing

Build the server first:

npm run mcp:build

Run the local smoke script:

node dist-mcp/scripts/test-mcp-server.js

Or use MCP Inspector:

npm run mcp:inspector

Claude Desktop configuration

Add this server to your Claude Desktop MCP config:

{
  "mcpServers": {
    "mongo-schema-explainer-mcp": {
      "command": "node",
      "args": ["/absolute/path/to/mern-mcp-web/dist-mcp/src/index.js"],
      "env": {
        "MONGODB_URI": "mongodb://127.0.0.1:27017",
        "DATABASE_NAME": "sample_mcp",
        "SCHEMA_SAMPLE_SIZE": "10",
        "SAFE_QUERY_MAX_LIMIT": "50",
        "ENABLE_SCHEMA_CACHE": "true",
        "SCHEMA_CACHE_TTL_MS": "300000",
        "LOG_LEVEL": "info"
      }
    }
  }
}

For development, you can point Claude Desktop at tsx instead:

{
  "mcpServers": {
    "mongo-schema-explainer-mcp": {
      "command": "npx",
      "args": ["tsx", "/absolute/path/to/mern-mcp-web/src/index.ts"],
      "env": {
        "MONGODB_URI": "mongodb://127.0.0.1:27017",
        "DATABASE_NAME": "sample_mcp"
      }
    }
  }
}

Docker

Build:

docker build -t mongo-schema-explainer-mcp .

Run:

docker run --rm \
  -e MONGODB_URI=mongodb://host.docker.internal:27017 \
  -e DATABASE_NAME=sample_mcp \
  mongo-schema-explainer-mcp

Future improvements

  • configurable BSON-aware query parsing for extended operators
  • richer schema confidence heuristics based on larger samples
  • schema diffing between environments
  • optional HTTP transport for remote MCP deployment
  • RBAC-aware collection allowlists per client

About

AI-powered MongoDB schema inspection MCP server with safe read-only querying.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages