Skip to content

Commit 5f60f73

Browse files
Merge branch 'main' into MCP-199
2 parents 17c15bb + d6b84c7 commit 5f60f73

File tree

24 files changed

+797
-190
lines changed

24 files changed

+797
-190
lines changed

README.md

Lines changed: 108 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ node -v
4747

4848
### Quick Start
4949

50-
**Note:** When using Atlas API credentials, be sure to assign only the minimum required permissions to your service account. See [Atlas API Permissions](#atlas-api-permissions) for details.
50+
> **🔒 Security Recommendation 1:** When using Atlas API credentials, be sure to assign only the minimum required permissions to your service account. See [Atlas API Permissions](#atlas-api-permissions) for details.
51+
52+
> **🔒 Security Recommendation 2:** For enhanced security, we strongly recommend using environment variables to pass sensitive configuration such as connection strings and API credentials instead of command line arguments. Command line arguments can be visible in process lists and logged in various system locations, potentially exposing your secrets. Environment variables provide a more secure way to handle sensitive information.
5153
5254
Most MCP clients require a configuration file to be created or modified to add the MCP server.
5355

@@ -60,30 +62,27 @@ Note: The configuration file syntax can be different across clients. Please refe
6062

6163
> **Default Safety Notice:** All examples below include `--readOnly` by default to ensure safe, read-only access to your data. Remove `--readOnly` if you need to enable write operations.
6264
63-
#### Option 1: Connection String args
65+
#### Option 1: Connection String
6466

65-
You can pass your connection string via args, make sure to use a valid username and password.
67+
You can pass your connection string via environment variables, make sure to use a valid username and password.
6668

6769
```json
6870
{
6971
"mcpServers": {
7072
"MongoDB": {
7173
"command": "npx",
72-
"args": [
73-
"-y",
74-
"mongodb-mcp-server",
75-
"--connectionString",
76-
"mongodb://localhost:27017/myDatabase",
77-
"--readOnly"
78-
]
74+
"args": ["-y", "mongodb-mcp-server@latest", "--readOnly"],
75+
"env": {
76+
"MDB_MCP_CONNECTION_STRING": "mongodb://localhost:27017/myDatabase"
77+
}
7978
}
8079
}
8180
}
8281
```
8382

8483
NOTE: The connection string can be configured to connect to any MongoDB cluster, whether it's a local instance or an Atlas cluster.
8584

86-
#### Option 2: Atlas API credentials args
85+
#### Option 2: Atlas API Credentials
8786

8887
Use your Atlas API Service Accounts credentials. Must follow all the steps in [Atlas API Access](#atlas-api-access) section.
8988

@@ -92,43 +91,37 @@ Use your Atlas API Service Accounts credentials. Must follow all the steps in [A
9291
"mcpServers": {
9392
"MongoDB": {
9493
"command": "npx",
95-
"args": [
96-
"-y",
97-
"mongodb-mcp-server",
98-
"--apiClientId",
99-
"your-atlas-service-accounts-client-id",
100-
"--apiClientSecret",
101-
"your-atlas-service-accounts-client-secret",
102-
"--readOnly"
103-
]
94+
"args": ["-y", "mongodb-mcp-server@latest", "--readOnly"],
95+
"env": {
96+
"MDB_MCP_API_CLIENT_ID": "your-atlas-service-accounts-client-id",
97+
"MDB_MCP_API_CLIENT_SECRET": "your-atlas-service-accounts-client-secret"
98+
}
10499
}
105100
}
106101
}
107102
```
108103

109-
#### Option 3: Standalone Service using command arguments
104+
#### Option 3: Standalone Service using environment variables and command line arguments
110105

111-
Start Server using npx command:
106+
You can source environment variables defined in a config file or explicitly set them like we do in the example below and run the server via npx.
112107

113108
```shell
114-
npx -y mongodb-mcp-server@latest --apiClientId="your-atlas-service-accounts-client-id" --apiClientSecret="your-atlas-service-accounts-client-secret" --readOnly
115-
```
116-
117-
- For a complete list of arguments see [Configuration Options](#configuration-options)
118-
- To configure your Atlas Service Accounts credentials please refer to [Atlas API Access](#atlas-api-access)
119-
120-
#### Option 4: Standalone Service using environment variables
109+
# Set your credentials as environment variables first
110+
export MDB_MCP_API_CLIENT_ID="your-atlas-service-accounts-client-id"
111+
export MDB_MCP_API_CLIENT_SECRET="your-atlas-service-accounts-client-secret"
121112

122-
```shell
123-
npx -y mongodb-mcp-server@latest --readOnly
113+
# Then start the server
114+
npx -y mongodb-mcp-server@latest --readOnly
124115
```
125116

126-
You can use environment variables in the config file or set them and run the server via npx.
117+
> **💡 Platform Note:** The examples above use Unix/Linux/macOS syntax. For Windows users, see [Environment Variables](#environment-variables) for platform-specific instructions.
127118
119+
- For a complete list of configuration options see [Configuration Options](#configuration-options)
120+
- To configure your Atlas Service Accounts credentials please refer to [Atlas API Access](#atlas-api-access)
128121
- Connection String via environment variables in the MCP file [example](#connection-string-with-environment-variables)
129122
- Atlas API credentials via environment variables in the MCP file [example](#atlas-api-credentials-with-environment-variables)
130123

131-
#### Option 5: Using Docker
124+
#### Option 4: Using Docker
132125

133126
You can run the MongoDB MCP Server in a Docker container, which provides isolation and doesn't require a local Node.js installation.
134127

@@ -146,22 +139,35 @@ docker run --rm -i \
146139
##### Option B: With MongoDB connection string
147140

148141
```shell
142+
# Set your credentials as environment variables first
143+
export MDB_MCP_CONNECTION_STRING="mongodb+srv://username:[email protected]/myDatabase"
144+
145+
# Then start the docker container
149146
docker run --rm -i \
150-
-e MDB_MCP_CONNECTION_STRING="mongodb+srv://username:[email protected]/myDatabase" \
147+
-e MDB_MCP_CONNECTION_STRING \
151148
-e MDB_MCP_READ_ONLY="true" \
152149
mongodb/mongodb-mcp-server:latest
153150
```
154151

152+
> **💡 Platform Note:** The examples above use Unix/Linux/macOS syntax. For Windows users, see [Environment Variables](#environment-variables) for platform-specific instructions.
153+
155154
##### Option C: With Atlas API credentials
156155

157156
```shell
157+
# Set your credentials as environment variables first
158+
export MDB_MCP_API_CLIENT_ID="your-atlas-service-accounts-client-id"
159+
export MDB_MCP_API_CLIENT_SECRET="your-atlas-service-accounts-client-secret"
160+
161+
# Then start the docker container
158162
docker run --rm -i \
159-
-e MDB_MCP_API_CLIENT_ID="your-atlas-service-accounts-client-id" \
160-
-e MDB_MCP_API_CLIENT_SECRET="your-atlas-service-accounts-client-secret" \
163+
-e MDB_MCP_API_CLIENT_ID \
164+
-e MDB_MCP_API_CLIENT_SECRET \
161165
-e MDB_MCP_READ_ONLY="true" \
162166
mongodb/mongodb-mcp-server:latest
163167
```
164168

169+
> **💡 Platform Note:** The examples above use Unix/Linux/macOS syntax. For Windows users, see [Environment Variables](#environment-variables) for platform-specific instructions.
170+
165171
##### Docker in MCP Configuration File
166172

167173
Without options:
@@ -196,11 +202,14 @@ With connection string:
196202
"--rm",
197203
"-i",
198204
"-e",
199-
"MDB_MCP_CONNECTION_STRING=mongodb+srv://username:[email protected]/myDatabase",
205+
"MDB_MCP_CONNECTION_STRING",
200206
"-e",
201207
"MDB_MCP_READ_ONLY=true",
202208
"mongodb/mongodb-mcp-server:latest"
203-
]
209+
],
210+
"env": {
211+
"MDB_MCP_CONNECTION_STRING": "mongodb+srv://username:[email protected]/myDatabase"
212+
}
204213
}
205214
}
206215
}
@@ -220,17 +229,21 @@ With Atlas API credentials:
220229
"-e",
221230
"MDB_MCP_READ_ONLY=true",
222231
"-e",
223-
"MDB_MCP_API_CLIENT_ID=your-atlas-service-accounts-client-id",
232+
"MDB_MCP_API_CLIENT_ID",
224233
"-e",
225-
"MDB_MCP_API_CLIENT_SECRET=your-atlas-service-accounts-client-secret",
234+
"MDB_MCP_API_CLIENT_SECRET",
226235
"mongodb/mongodb-mcp-server:latest"
227-
]
236+
],
237+
"env": {
238+
"MDB_MCP_API_CLIENT_ID": "your-atlas-service-accounts-client-id",
239+
"MDB_MCP_API_CLIENT_SECRET": "your-atlas-service-accounts-client-secret"
240+
}
228241
}
229242
}
230243
}
231244
```
232245

233-
#### Option 6: Running as an HTTP Server
246+
#### Option 5: Running as an HTTP Server
234247

235248
> **⚠️ Security Notice:** This server now supports Streamable HTTP transport for remote connections. **HTTP transport is NOT recommended for production use without implementing proper authentication and security measures.**
236249
@@ -316,6 +329,8 @@ NOTE: atlas tools are only available when you set credentials on [configuration]
316329

317330
## Configuration
318331

332+
> **🔒 Security Best Practice:** We strongly recommend using environment variables for sensitive configuration such as API credentials (`MDB_MCP_API_CLIENT_ID`, `MDB_MCP_API_CLIENT_SECRET`) and connection strings (`MDB_MCP_CONNECTION_STRING`) instead of command-line arguments. Environment variables are not visible in process lists and provide better security for your sensitive data.
333+
319334
The MongoDB MCP Server can be configured using multiple methods, with the following precedence (highest to lowest):
320335

321336
1. Command-line arguments
@@ -362,6 +377,8 @@ You can combine multiple loggers, e.g. `--loggers disk stderr` or `export MDB_MC
362377
export MDB_MCP_LOGGERS="disk,stderr"
363378
```
364379

380+
> **💡 Platform Note:** For Windows users, see [Environment Variables](#environment-variables) for platform-specific instructions.
381+
365382
##### Example: Set logger via command-line argument
366383

367384
```shell
@@ -412,6 +429,8 @@ You can enable read-only mode using:
412429
- **Environment variable**: `export MDB_MCP_READ_ONLY=true`
413430
- **Command-line argument**: `--readOnly`
414431

432+
> **💡 Platform Note:** For Windows users, see [Environment Variables](#environment-variables) for platform-specific instructions.
433+
415434
When read-only mode is active, you'll see a message in the server logs indicating which tools were prevented from registering due to this restriction.
416435

417436
#### Index Check Mode
@@ -425,6 +444,8 @@ You can enable index check mode using:
425444
- **Environment variable**: `export MDB_MCP_INDEX_CHECK=true`
426445
- **Command-line argument**: `--indexCheck`
427446

447+
> **💡 Platform Note:** For Windows users, see [Environment Variables](#environment-variables) for platform-specific instructions.
448+
428449
When index check mode is active, you'll see an error message if a query is rejected due to not using an index.
429450

430451
#### Exports
@@ -448,6 +469,8 @@ You can disable telemetry using:
448469
- **Command-line argument**: `--telemetry disabled`
449470
- **DO_NOT_TRACK environment variable**: `export DO_NOT_TRACK=1`
450471

472+
> **💡 Platform Note:** For Windows users, see [Environment Variables](#environment-variables) for platform-specific instructions.
473+
451474
### Atlas API Access
452475

453476
To use the Atlas API tools, you'll need to create a service account in MongoDB Atlas:
@@ -501,16 +524,43 @@ For a full list of roles and their privileges, see the [Atlas User Roles documen
501524

502525
Set environment variables with the prefix `MDB_MCP_` followed by the option name in uppercase with underscores:
503526

504-
```shell
527+
**Linux/macOS (bash/zsh):**
528+
529+
```bash
505530
# Set Atlas API credentials (via Service Accounts)
506531
export MDB_MCP_API_CLIENT_ID="your-atlas-service-accounts-client-id"
507532
export MDB_MCP_API_CLIENT_SECRET="your-atlas-service-accounts-client-secret"
508533

509534
# Set a custom MongoDB connection string
510535
export MDB_MCP_CONNECTION_STRING="mongodb+srv://username:[email protected]/myDatabase"
511536

537+
# Set log path
512538
export MDB_MCP_LOG_PATH="/path/to/logs"
539+
```
513540

541+
**Windows Command Prompt (cmd):**
542+
543+
```cmd
544+
set "MDB_MCP_API_CLIENT_ID=your-atlas-service-accounts-client-id"
545+
set "MDB_MCP_API_CLIENT_SECRET=your-atlas-service-accounts-client-secret"
546+
547+
set "MDB_MCP_CONNECTION_STRING=mongodb+srv://username:[email protected]/myDatabase"
548+
549+
set "MDB_MCP_LOG_PATH=C:\path\to\logs"
550+
```
551+
552+
**Windows PowerShell:**
553+
554+
```powershell
555+
# Set Atlas API credentials (via Service Accounts)
556+
$env:MDB_MCP_API_CLIENT_ID="your-atlas-service-accounts-client-id"
557+
$env:MDB_MCP_API_CLIENT_SECRET="your-atlas-service-accounts-client-secret"
558+
559+
# Set a custom MongoDB connection string
560+
$env:MDB_MCP_CONNECTION_STRING="mongodb+srv://username:[email protected]/myDatabase"
561+
562+
# Set log path
563+
$env:MDB_MCP_LOG_PATH="C:\path\to\logs"
514564
```
515565

516566
#### MCP configuration file examples
@@ -552,14 +602,26 @@ export MDB_MCP_LOG_PATH="/path/to/logs"
552602

553603
Pass configuration options as command-line arguments when starting the server:
554604

605+
> **🔒 Security Note:** For sensitive configuration like API credentials and connection strings, use environment variables instead of command-line arguments.
606+
555607
```shell
556-
npx -y mongodb-mcp-server@latest --apiClientId="your-atlas-service-accounts-client-id" --apiClientSecret="your-atlas-service-accounts-client-secret" --connectionString="mongodb+srv://username:[email protected]/myDatabase" --logPath=/path/to/logs --readOnly --indexCheck
608+
# Set sensitive data as environment variable
609+
export MDB_MCP_API_CLIENT_ID="your-atlas-service-accounts-client-id"
610+
export MDB_MCP_API_CLIENT_SECRET="your-atlas-service-accounts-client-secret"
611+
export MDB_MCP_CONNECTION_STRING="mongodb+srv://username:[email protected]/myDatabase"
612+
613+
# Start the server with command line arguments
614+
npx -y mongodb-mcp-server@latest --logPath=/path/to/logs --readOnly --indexCheck
557615
```
558616

617+
> **💡 Platform Note:** The examples above use Unix/Linux/macOS syntax. For Windows users, see [Environment Variables](#environment-variables) for platform-specific instructions.
618+
559619
#### MCP configuration file examples
560620

561621
##### Connection String with command-line arguments
562622

623+
> **🔒 Security Note:** We do not recommend passing connection string as command line argument. Connection string might contain credentials which can be visible in process lists and logged in various system locations, potentially exposing your credentials. Instead configure [connection string through environment variables](#connection-string-with-environment-variables)
624+
563625
```json
564626
{
565627
"mcpServers": {
@@ -579,6 +641,8 @@ npx -y mongodb-mcp-server@latest --apiClientId="your-atlas-service-accounts-clie
579641

580642
##### Atlas API credentials with command-line arguments
581643

644+
> **🔒 Security Note:** We do not recommend passing Atlas API credentials as command line argument. The provided credentials can be visible in process lists and logged in various system locations, potentially exposing your credentials. Instead configure [Atlas API credentials through environment variables](#atlas-api-credentials-with-environment-variables)
645+
582646
```json
583647
{
584648
"mcpServers": {

src/common/exportsManager.ts

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ export class ExportsManager extends EventEmitter<ExportsManagerEvents> {
127127
public async readExport(exportName: string): Promise<string> {
128128
try {
129129
this.assertIsNotShuttingDown();
130-
exportName = decodeURIComponent(exportName);
130+
exportName = decodeAndNormalize(exportName);
131131
const exportHandle = this.storedExports[exportName];
132132
if (!exportHandle) {
133133
throw new Error("Requested export has either expired or does not exist.");
@@ -163,7 +163,7 @@ export class ExportsManager extends EventEmitter<ExportsManagerEvents> {
163163
}): Promise<AvailableExport> {
164164
try {
165165
this.assertIsNotShuttingDown();
166-
const exportNameWithExtension = validateExportName(ensureExtension(exportName, "json"));
166+
const exportNameWithExtension = decodeAndNormalize(ensureExtension(exportName, "json"));
167167
if (this.storedExports[exportNameWithExtension]) {
168168
return Promise.reject(
169169
new Error("Export with same name is either already available or being generated.")
@@ -363,6 +363,10 @@ export class ExportsManager extends EventEmitter<ExportsManagerEvents> {
363363
}
364364
}
365365

366+
export function decodeAndNormalize(text: string): string {
367+
return decodeURIComponent(text).normalize("NFKC");
368+
}
369+
366370
/**
367371
* Ensures the path ends with the provided extension */
368372
export function ensureExtension(pathOrName: string, extension: string): string {
@@ -373,22 +377,6 @@ export function ensureExtension(pathOrName: string, extension: string): string {
373377
return `${pathOrName}${extWithDot}`;
374378
}
375379

376-
/**
377-
* Small utility to decoding and validating provided export name for path
378-
* traversal or no extension */
379-
export function validateExportName(nameWithExtension: string): string {
380-
const decodedName = decodeURIComponent(nameWithExtension);
381-
if (!path.extname(decodedName)) {
382-
throw new Error("Provided export name has no extension");
383-
}
384-
385-
if (decodedName.includes("..") || decodedName.includes("/") || decodedName.includes("\\")) {
386-
throw new Error("Invalid export name: path traversal hinted");
387-
}
388-
389-
return decodedName;
390-
}
391-
392380
export function isExportExpired(createdAt: number, exportTimeoutMs: number): boolean {
393381
return Date.now() - createdAt > exportTimeoutMs;
394382
}

src/resources/common/exportedData.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,12 @@ export class ExportedData {
7272
private autoCompleteExportName: CompleteResourceTemplateCallback = (value) => {
7373
try {
7474
return this.session.exportsManager.availableExports
75-
.filter(({ exportName }) => exportName.startsWith(value))
75+
.filter(({ exportName, exportTitle }) => {
76+
const lcExportName = exportName.toLowerCase();
77+
const lcExportTitle = exportTitle.toLowerCase();
78+
const lcValue = value.toLowerCase();
79+
return lcExportName.startsWith(lcValue) || lcExportTitle.includes(lcValue);
80+
})
7681
.map(({ exportName }) => exportName);
7782
} catch (error) {
7883
this.session.logger.error({

0 commit comments

Comments
 (0)