Skip to main content
Glama
jonfreeland

MongoDB MCP Server

by jonfreeland

query

Query MongoDB collections using filters, projections, and sorting. Output results in JSON or CSV format for easy analysis. Supports read-only operations for secure data access.

Instructions

Execute a read-only query on a collection using MongoDB query syntax.

Supports both JSON and CSV output formats:

  • Use outputFormat="json" for standard JSON (default)

  • Use outputFormat="csv" for comma-separated values export

Best Practices:

  • Use projections to fetch only needed fields

  • Add limits for large collections

  • Use sort for consistent ordering

Example - Standard Query: use_mcp_tool with server_name: "mongodb", tool_name: "query", arguments: { "collection": "users", "filter": { "age": { "$gte": 21 } }, "projection": { "name": 1, "email": 1 }, "sort": { "name": 1 }, "limit": 100 }

Example - CSV Export: use_mcp_tool with server_name: "mongodb", tool_name: "query", arguments: { "collection": "users", "filter": { "active": true }, "outputFormat": "csv", "formatOptions": { "includeHeaders": true, "delimiter": "," } }

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
collectionYesCollection name
databaseNoDatabase name (optional if default database is configured)
filterYesMongoDB query filter using standard MongoDB operators ($eq, $gt, $in, etc.)
formatOptionsNoFormat-specific options
limitNoMaximum number of documents to return (optional)
outputFormatNoOutput format for results (json or csv)
projectionNoMongoDB projection to specify fields to return (optional)
sortNoMongoDB sort specification (optional)

Implementation Reference

  • Handler for the 'query' tool: executes MongoDB find operation with filter, optional projection, sort, limit. Supports JSON (default) and CSV output formats. Appends visualization hints for JSON results.
    case 'query': { const { database, collection, filter, projection, sort, limit, outputFormat = 'json', formatOptions = {} } = request.params.arguments as { database?: string; collection: string; filter: object; projection?: object; sort?: Sort; limit?: number; outputFormat?: 'json' | 'csv'; formatOptions?: any; }; const dbName = database || this.defaultDatabase; if (!dbName) { throw new McpError( ErrorCode.InvalidRequest, 'Database name is required when no default database is configured' ); } const db = client.db(dbName); let query = db.collection(collection).find(filter); if (projection) { query = query.project(projection); } if (sort) { query = query.sort(sort); } if (limit) { query = query.limit(limit); } const results = await query.toArray(); // Handle different output formats if (outputFormat.toLowerCase() === 'csv') { return { content: [ { type: 'text', text: this.documentsToCsv(results, formatOptions), }, ], }; } else { // Default JSON format const vizHint = this.generateVisualizationHint(results); return { content: [ { type: 'text', text: JSON.stringify(results, null, 2) + (vizHint ? `\n\nVisualization Hint:\n${vizHint}` : ''), }, ], }; } }
  • Input schema definition for the 'query' tool, specifying parameters like database, collection, filter (required), projection, sort, limit, outputFormat, and formatOptions.
    inputSchema: { type: 'object', properties: { database: { type: 'string', description: 'Database name (optional if default database is configured)', }, collection: { type: 'string', description: 'Collection name', }, filter: { type: 'object', description: 'MongoDB query filter using standard MongoDB operators ($eq, $gt, $in, etc.)', }, projection: { type: 'object', description: 'MongoDB projection to specify fields to return (optional)', }, sort: { type: 'object', description: 'MongoDB sort specification (optional)', }, limit: { type: 'number', description: 'Maximum number of documents to return (optional)', minimum: 1, maximum: 1000, }, outputFormat: { type: 'string', description: 'Output format for results (json or csv)', enum: ['json', 'csv'], }, formatOptions: { type: 'object', description: 'Format-specific options', properties: { delimiter: { type: 'string', description: 'CSV delimiter character (default: comma)', }, includeHeaders: { type: 'boolean', description: 'Whether to include header row in CSV (default: true)', }, }, }, }, required: ['collection', 'filter'], },
  • src/index.ts:370-458 (registration)
    Registration of the 'query' tool in the list_tools response, including name, detailed description with examples, and input schema.
    { name: 'query', description: `Execute a read-only query on a collection using MongoDB query syntax. Supports both JSON and CSV output formats: - Use outputFormat="json" for standard JSON (default) - Use outputFormat="csv" for comma-separated values export Best Practices: - Use projections to fetch only needed fields - Add limits for large collections - Use sort for consistent ordering Example - Standard Query: use_mcp_tool with server_name: "mongodb", tool_name: "query", arguments: { "collection": "users", "filter": { "age": { "$gte": 21 } }, "projection": { "name": 1, "email": 1 }, "sort": { "name": 1 }, "limit": 100 } Example - CSV Export: use_mcp_tool with server_name: "mongodb", tool_name: "query", arguments: { "collection": "users", "filter": { "active": true }, "outputFormat": "csv", "formatOptions": { "includeHeaders": true, "delimiter": "," } }`, inputSchema: { type: 'object', properties: { database: { type: 'string', description: 'Database name (optional if default database is configured)', }, collection: { type: 'string', description: 'Collection name', }, filter: { type: 'object', description: 'MongoDB query filter using standard MongoDB operators ($eq, $gt, $in, etc.)', }, projection: { type: 'object', description: 'MongoDB projection to specify fields to return (optional)', }, sort: { type: 'object', description: 'MongoDB sort specification (optional)', }, limit: { type: 'number', description: 'Maximum number of documents to return (optional)', minimum: 1, maximum: 1000, }, outputFormat: { type: 'string', description: 'Output format for results (json or csv)', enum: ['json', 'csv'], }, formatOptions: { type: 'object', description: 'Format-specific options', properties: { delimiter: { type: 'string', description: 'CSV delimiter character (default: comma)', }, includeHeaders: { type: 'boolean', description: 'Whether to include header row in CSV (default: true)', }, }, }, }, required: ['collection', 'filter'], },
  • Helper function to generate visualization suggestions based on query results characteristics (time series, numeric, categorical, geospatial). Appended to JSON query results.
    private generateVisualizationHint(data: any[]): string { if (!Array.isArray(data) || data.length === 0) return ''; // Check if the data looks like time series const hasDateFields = Object.keys(data[0]).some(key => data[0][key] instanceof Date || (typeof data[0][key] === 'string' && !isNaN(Date.parse(data[0][key]))) ); // Check if the data has numeric fields const numericFields = Object.keys(data[0]).filter(key => typeof data[0][key] === 'number' ); // Check if the data has categorical fields const categoricalFields = Object.keys(data[0]).filter(key => typeof data[0][key] === 'string' && data.every(item => typeof item[key] === 'string') ); // Check if the data has geospatial fields const hasGeoData = Object.keys(data[0]).some(key => { const value = data[0][key]; return value && typeof value === 'object' && (('type' in value && value.type === 'Point' && 'coordinates' in value) || (Array.isArray(value) && value.length === 2 && typeof value[0] === 'number' && typeof value[1] === 'number')); }); let hints = []; if (hasDateFields && numericFields.length > 0) { hints.push('Time Series Visualization:\n- Consider line charts for temporal trends\n- Time-based heat maps for density patterns\n- Area charts for cumulative values over time'); } if (categoricalFields.length > 0 && numericFields.length > 0) { hints.push('Categorical Analysis:\n- Bar charts for comparing categories\n- Box plots for distribution analysis\n- Heat maps for category correlations\n- Treemaps for hierarchical data'); } if (numericFields.length >= 2) { hints.push('Numerical Analysis:\n- Scatter plots for correlation analysis\n- Bubble charts if three numeric dimensions\n- Correlation matrices for multiple variables\n- Histograms for distribution analysis'); } if (hasGeoData) { hints.push('Geospatial Visualization:\n- Map overlays for location data\n- Choropleth maps for regional analysis\n- Heat maps for density visualization\n- Cluster maps for point concentration'); } if (data.length > 1000) { hints.push('Large Dataset Considerations:\n- Consider sampling for initial visualization\n- Use aggregation for summary views\n- Implement pagination or infinite scroll\n- Consider server-side rendering'); } return hints.join('\n\n'); }
  • Helper function to convert query results to CSV format, used when outputFormat='csv'. Handles headers, delimiters, escaping, and nested JSON.
    private documentsToCsv(docs: any[], options: { includeHeaders?: boolean; delimiter?: string; } = {}): string { if (!Array.isArray(docs) || docs.length === 0) return ''; const delimiter = options.delimiter || ','; const includeHeaders = options.includeHeaders !== false; // Extract all possible field names from all documents (handles varying schemas) const fieldsSet = new Set<string>(); docs.forEach(doc => { Object.keys(doc).forEach(key => fieldsSet.add(key)); }); const fields = Array.from(fieldsSet); let result = ''; // Add headers if (includeHeaders) { result += fields.map(field => this.escapeCsvField(field, delimiter)).join(delimiter) + '\n'; } // Add data rows docs.forEach(doc => { const row = fields.map(field => { const value = doc[field]; if (value === undefined || value === null) return ''; if (typeof value === 'object') return this.escapeCsvField(JSON.stringify(value), delimiter); return this.escapeCsvField(String(value), delimiter); }); result += row.join(delimiter) + '\n'; }); return result; }

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jonfreeland/mongodb-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server