Skip to content

Commit 3a56da3

Browse files
committed
chore: remove configFile and state.json
1 parent 9e09c1e commit 3a56da3

16 files changed

+39
-109
lines changed

README.md

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,6 @@ The MongoDB MCP Server can be configured using multiple methods, with the follow
157157

158158
1. Command-line arguments
159159
2. Environment variables
160-
3. Configuration file
161-
4. Default values
162160

163161
### Configuration Options
164162

@@ -167,6 +165,12 @@ The MongoDB MCP Server can be configured using multiple methods, with the follow
167165
| `apiClientId` | Atlas API client ID for authentication |
168166
| `apiClientSecret` | Atlas API client secret for authentication |
169167
| `connectionString` | MongoDB connection string for direct database connections (optional users may choose to inform it on every tool call) |
168+
| `logPath` | Folder to store logs |
169+
170+
**Default Log Path:**
171+
172+
- Windows: `%LOCALAPPDATA%\mongodb\mongodb-mcp\.app-logs`
173+
- macOS/Linux: `~/.mongodb/mongodb-mcp/.app-logs`
170174

171175
### Atlas API Access
172176

@@ -195,23 +199,6 @@ To use the Atlas API tools, you'll need to create a service account in MongoDB A
195199

196200
### Configuration Methods
197201

198-
#### Configuration File
199-
200-
Create a JSON configuration file at one of these locations:
201-
202-
- Linux/macOS: `/etc/mongodb-mcp.conf`
203-
- Windows: `%LOCALAPPDATA%\mongodb\mongodb-mcp\mongodb-mcp.conf`
204-
205-
Example configuration file:
206-
207-
```json
208-
{
209-
"apiClientId": "your-atlas-client-id",
210-
"apiClientSecret": "your-atlas-client-secret",
211-
"connectionString": "mongodb+srv://username:[email protected]/myDatabase"
212-
}
213-
```
214-
215202
#### Environment Variables
216203

217204
Set environment variables with the prefix `MDB_MCP_` followed by the option name in uppercase with underscores:
@@ -223,14 +210,16 @@ export MDB_MCP_API_CLIENT_SECRET="your-atlas-client-secret"
223210

224211
# Set a custom MongoDB connection string
225212
export MDB_MCP_CONNECTION_STRING="mongodb+srv://username:[email protected]/myDatabase"
213+
214+
export MDB_MCP_LOG_PATH="/path/to/logs"
226215
```
227216

228217
#### Command-Line Arguments
229218

230219
Pass configuration options as command-line arguments when starting the server:
231220

232221
```shell
233-
node dist/index.js --apiClientId="your-atlas-client-id" --apiClientSecret="your-atlas-client-secret" --connectionString="mongodb+srv://username:[email protected]/myDatabase"
222+
node dist/index.js --apiClientId="your-atlas-client-id" --apiClientSecret="your-atlas-client-secret" --connectionString="mongodb+srv://username:[email protected]/myDatabase" --logPath=/path/to/logs
234223
```
235224

236225
## 🤝 Contributing

src/config.ts

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ import argv from "yargs-parser";
55
import packageJson from "../package.json" with { type: "json" };
66
import fs from "fs";
77
import { ReadConcernLevel, ReadPreferenceMode, W } from "mongodb";
8-
const { localDataPath, configPath } = getLocalDataPath();
8+
import { log } from "console";
99

1010
// If we decide to support non-string config options, we'll need to extend the mechanism for parsing
1111
// env variables.
1212
interface UserConfig {
1313
apiBaseUrl: string;
1414
apiClientId?: string;
1515
apiClientSecret?: string;
16-
stateFile: string;
16+
logPath: string;
1717
connectionString?: string;
1818
connectOptions: {
1919
readConcern: ReadConcernLevel;
@@ -25,7 +25,7 @@ interface UserConfig {
2525

2626
const defaults: UserConfig = {
2727
apiBaseUrl: "https://cloud.mongodb.com/",
28-
stateFile: path.join(localDataPath, "state.json"),
28+
logPath: getLogPath(),
2929
connectOptions: {
3030
readConcern: "local",
3131
readPreference: "secondaryPreferred",
@@ -36,7 +36,6 @@ const defaults: UserConfig = {
3636

3737
const mergedUserConfig = {
3838
...defaults,
39-
...getFileConfig(),
4039
...getEnvConfig(),
4140
...getCliConfig(),
4241
};
@@ -46,33 +45,28 @@ const config = {
4645
atlasApiVersion: `2025-03-12`,
4746
version: packageJson.version,
4847
userAgent: `AtlasMCP/${packageJson.version} (${process.platform}; ${process.arch}; ${process.env.HOSTNAME || "unknown"})`,
49-
localDataPath,
5048
};
5149

5250
export default config;
5351

54-
function getLocalDataPath(): { localDataPath: string; configPath: string } {
52+
function getLogPath(): string {
5553
let localDataPath: string | undefined;
56-
let configPath: string | undefined;
5754

5855
if (process.platform === "win32") {
5956
const appData = process.env.APPDATA;
6057
const localAppData = process.env.LOCALAPPDATA ?? process.env.APPDATA;
6158
if (localAppData && appData) {
6259
localDataPath = path.join(localAppData, "mongodb", "mongodb-mcp");
63-
configPath = path.join(localDataPath, "mongodb-mcp.conf");
6460
}
6561
}
6662

6763
localDataPath ??= path.join(os.homedir(), ".mongodb", "mongodb-mcp");
68-
configPath ??= "/etc/mongodb-mcp.conf";
6964

70-
fs.mkdirSync(localDataPath, { recursive: true });
65+
const logPath = path.join(localDataPath, ".app-logs");
7166

72-
return {
73-
localDataPath,
74-
configPath,
75-
};
67+
fs.mkdirSync(logPath, { recursive: true });
68+
69+
return logPath;
7670
}
7771

7872
// Gets the config supplied by the user as environment variables. The variable names
@@ -125,17 +119,6 @@ function SNAKE_CASE_toCamelCase(str: string): string {
125119
return str.toLowerCase().replace(/([-_][a-z])/g, (group) => group.toUpperCase().replace("_", ""));
126120
}
127121

128-
// Gets the config supplied by the user as a JSON file. The file is expected to be located in the local data path
129-
// and named `config.json`.
130-
function getFileConfig(): Partial<UserConfig> {
131-
try {
132-
const config = fs.readFileSync(configPath, "utf8");
133-
return JSON.parse(config);
134-
} catch {
135-
return {};
136-
}
137-
}
138-
139122
// Reads the cli args and parses them into a UserConfig object.
140123
function getCliConfig() {
141124
return argv(process.argv.slice(2)) as unknown as Partial<UserConfig>;

src/logger.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,8 @@ const logger = new ProxyingLogger();
100100
export default logger;
101101

102102
export async function initializeLogger(server: McpServer): Promise<void> {
103-
const logDir = path.join(config.localDataPath, ".app-logs");
104-
await fs.mkdir(logDir, { recursive: true });
105-
106103
const manager = new MongoLogManager({
107-
directory: path.join(config.localDataPath, ".app-logs"),
104+
directory: config.logPath,
108105
retentionDays: 30,
109106
onwarn: console.warn,
110107
onerror: console.error,

src/server.ts

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ import { mongoLogId } from "mongodb-log-writer";
1111
export class Server {
1212
state: State = defaultState;
1313
apiClient?: ApiClient;
14-
initialized: boolean = false;
1514

16-
private async init() {
17-
if (this.initialized) {
18-
return;
19-
}
15+
private createMcpServer(): McpServer {
16+
const server = new McpServer({
17+
name: "MongoDB Atlas",
18+
version: config.version,
19+
});
2020

21-
await this.state.loadCredentials();
21+
server.server.registerCapabilities({ logging: {} });
2222

2323
if (config.apiClientId && config.apiClientSecret) {
2424
this.apiClient = new ApiClient({
@@ -29,25 +29,13 @@ export class Server {
2929
});
3030
}
3131

32-
this.initialized = true;
33-
}
34-
35-
private createMcpServer(): McpServer {
36-
const server = new McpServer({
37-
name: "MongoDB Atlas",
38-
version: config.version,
39-
});
40-
41-
server.server.registerCapabilities({ logging: {} });
42-
4332
registerAtlasTools(server, this.state, this.apiClient);
4433
registerMongoDBTools(server, this.state);
4534

4635
return server;
4736
}
4837

4938
async connect(transport: Transport) {
50-
await this.init();
5139
const server = this.createMcpServer();
5240
await server.connect(transport);
5341
await initializeLogger(server);

src/state.ts

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,8 @@
11
import { NodeDriverServiceProvider } from "@mongosh/service-provider-node-driver";
2-
import { AsyncEntry } from "@napi-rs/keyring";
3-
import logger from "./logger.js";
4-
import { mongoLogId } from "mongodb-log-writer";
5-
6-
interface Credentials {
7-
connectionString?: string;
8-
}
92

103
export class State {
11-
private entry = new AsyncEntry("mongodb-mcp", "credentials");
12-
credentials: Credentials = {};
134
serviceProvider?: NodeDriverServiceProvider;
14-
15-
public async persistCredentials(): Promise<void> {
16-
await this.entry.setPassword(JSON.stringify(this.credentials));
17-
}
18-
19-
public async loadCredentials(): Promise<boolean> {
20-
try {
21-
const data = await this.entry.getPassword();
22-
if (data) {
23-
this.credentials = JSON.parse(data);
24-
}
25-
26-
return true;
27-
} catch (err: unknown) {
28-
logger.error(mongoLogId(1_000_007), "state", `Failed to load state: ${err}`);
29-
return false;
30-
}
31-
}
5+
connectionString?: string;
326
}
337

348
const defaultState = new State();

src/tools/atlas/atlasTool.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export abstract class AtlasToolBase extends ToolBase {
1010
super(state);
1111
}
1212

13-
protected ensureAuthenticated(): void {
13+
protected ensureAuthenticated(): asserts this is { apiClient: ApiClient } {
1414
if (!this.apiClient) {
1515
throw new Error(
1616
"Not authenticated make sure to configure MCP server with MDB_MCP_API_CLIENT_ID and MDB_MCP_API_CLIENT_SECRET environment variables."

src/tools/atlas/createAccessList.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export class CreateAccessListTool extends AtlasToolBase {
3939
}));
4040

4141
if (currentIpAddress) {
42-
const currentIp = await this.apiClient!.getIpInfo();
42+
const currentIp = await this.apiClient.getIpInfo();
4343
const input = {
4444
groupId: projectId,
4545
ipAddress: currentIp.currentIpv4Address,
@@ -56,7 +56,7 @@ export class CreateAccessListTool extends AtlasToolBase {
5656

5757
const inputs = [...ipInputs, ...cidrInputs];
5858

59-
await this.apiClient!.createProjectIpAccessList({
59+
await this.apiClient.createProjectIpAccessList({
6060
params: {
6161
path: {
6262
groupId: projectId,

src/tools/atlas/createDBUser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export class CreateDBUserTool extends AtlasToolBase {
5353
: undefined,
5454
} as CloudDatabaseUser;
5555

56-
await this.apiClient!.createDatabaseUser({
56+
await this.apiClient.createDatabaseUser({
5757
params: {
5858
path: {
5959
groupId: projectId,

src/tools/atlas/createFreeCluster.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export class CreateFreeClusterTool extends AtlasToolBase {
3838
terminationProtectionEnabled: false,
3939
} as unknown as ClusterDescription20240805;
4040

41-
await this.apiClient!.createCluster({
41+
await this.apiClient.createCluster({
4242
params: {
4343
path: {
4444
groupId: projectId,

src/tools/atlas/inspectAccessList.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export class InspectAccessListTool extends AtlasToolBase {
1313
protected async execute({ projectId }: ToolArgs<typeof this.argsShape>): Promise<CallToolResult> {
1414
this.ensureAuthenticated();
1515

16-
const accessList = await this.apiClient!.listProjectIpAccessLists({
16+
const accessList = await this.apiClient.listProjectIpAccessLists({
1717
params: {
1818
path: {
1919
groupId: projectId,

0 commit comments

Comments
 (0)