Skip to content

Commit 8062288

Browse files
committed
wip
1 parent 97aa690 commit 8062288

File tree

9 files changed

+28
-33
lines changed

9 files changed

+28
-33
lines changed

package-lock.json

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/common/atlas/apiClient.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import createClient, { Client, FetchOptions, Middleware } from "openapi-fetch";
33
import { AccessToken, ClientCredentials } from "simple-oauth2";
44

55
import { paths, operations } from "./openapi.js";
6-
import { State } from "../../state.js";
76

87
const ATLAS_API_VERSION = "2025-03-12";
98

@@ -70,7 +69,8 @@ export class ApiClient {
7069
// ignore not availble tokens, API will return 401
7170
}
7271
},
73-
};
72+
});
73+
7474
private readonly errorMiddleware: Middleware = {
7575
async onResponse({ response }) {
7676
if (!response.ok) {
@@ -79,7 +79,7 @@ export class ApiClient {
7979
},
8080
};
8181

82-
constructor(options?: ApiClientOptions) {
82+
constructor(options: ApiClientOptions) {
8383
const defaultOptions = {
8484
baseUrl: "https://cloud.mongodb.com/",
8585
userAgent: `AtlasMCP/${config.version} (${process.platform}; ${process.arch}; ${process.env.HOSTNAME || "unknown"})`,
@@ -110,7 +110,7 @@ export class ApiClient {
110110
});
111111
this.client.use(this.authMiddleware(this));
112112
}
113-
this.client.use(this.errorMiddleware());
113+
this.client.use(this.errorMiddleware);
114114
}
115115

116116
public async getIpInfo(): Promise<{

src/config.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ function getLogPath(): string {
6060
// to SNAKE_UPPER_CASE.
6161
function getEnvConfig(): Partial<UserConfig> {
6262
function setValue(obj: Record<string, unknown>, path: string[], value: string): void {
63-
const currentField = path.shift()!;
63+
const currentField = path.shift();
64+
if (!currentField) {
65+
return;
66+
}
6467
if (path.length === 0) {
6568
const numberValue = Number(value);
6669
if (!isNaN(numberValue)) {

src/index.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,15 @@ import { Server } from "./server.js";
1111

1212
try {
1313
const state = new State();
14-
await state.loadCredentials();
15-
16-
const apiClient = ApiClient.fromState(state);
17-
1814
const mcpServer = new McpServer({
1915
name: "MongoDB Atlas",
2016
version: config.version,
2117
});
22-
2318
const transport = new StdioServerTransport();
2419

25-
const server = new Server({
20+
const server = new Seriver({
2621
mcpServer,
2722
state,
28-
apiClient,
2923
transport,
3024
});
3125

src/server.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2-
import defaultState, { State } from "./state.js";
2+
import { State } from "./state.js";
33
import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
44
import { registerAtlasTools } from "./tools/atlas/tools.js";
55
import { registerMongoDBTools } from "./tools/mongodb/index.js";
66
import logger, { initializeLogger } from "./logger.js";
77
import { mongoLogId } from "mongodb-log-writer";
8+
import { ApiClient } from "./common/atlas/apiClient.js";
89

910
export class Server {
10-
state: State = defaultState;
11-
private server?: McpServer;
11+
public readonly state: State;
12+
private readonly mcpServer: McpServer;
13+
14+
constructor({ mcpServer, state, transport }: { mcpServer: McpServer; state: State; transport: Transport }) {
15+
this.mcpServer = server;
16+
this.state = new State();
17+
}
1218

1319
async connect(transport: Transport) {
1420
this.server = new McpServer({

src/state.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { ApiClient } from "./common/atlas/apiClient.js";
33
import config from "./config.js";
44

55
export class State {
6-
serviceProvider?: NodeDriverServiceProvider;
76
apiClient?: ApiClient;
87

98
ensureApiClient(): asserts this is { apiClient: ApiClient } {

src/tools/mongodb/connect.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export class ConnectTool extends MongoDBToolBase {
5757
throw new MongoDBError(ErrorCodes.InvalidParams, "Invalid connection options");
5858
}
5959

60-
await this.connectToMongoDB(connectionString, this.state);
60+
await this.connectToMongoDB(connectionString);
6161

6262
return {
6363
content: [{ type: "text", text: `Successfully connected to ${connectionString}.` }],

src/tools/mongodb/mongodbTool.ts

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { z } from "zod";
22
import { ToolBase } from "../tool.js";
3-
import { State } from "../../state.js";
43
import { NodeDriverServiceProvider } from "@mongosh/service-provider-node-driver";
54
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
65
import { ErrorCodes, MongoDBError } from "../../errors.js";
@@ -14,23 +13,22 @@ export const DbOperationArgs = {
1413
export type DbOperationType = "metadata" | "read" | "create" | "update" | "delete";
1514

1615
export abstract class MongoDBToolBase extends ToolBase {
17-
constructor(state: State) {
18-
super(state);
16+
constructor(private serviceProvider: NodeDriverServiceProvider | undefined) {
17+
super();
1918
}
2019

2120
protected abstract operationType: DbOperationType;
2221

2322
protected async ensureConnected(): Promise<NodeDriverServiceProvider> {
24-
const provider = this.state.serviceProvider;
25-
if (!provider && config.connectionString) {
26-
await this.connectToMongoDB(config.connectionString, this.state);
23+
if (!this.serviceProvider && config.connectionString) {
24+
this.serviceProvider = await this.connectToMongoDB(config.connectionString);
2725
}
2826

29-
if (!provider) {
27+
if (!this.serviceProvider) {
3028
throw new MongoDBError(ErrorCodes.NotConnectedToMongoDB, "Not connected to MongoDB");
3129
}
3230

33-
return provider;
31+
return this.serviceProvider;
3432
}
3533

3634
protected handleError(error: unknown): Promise<CallToolResult> | CallToolResult {
@@ -53,8 +51,8 @@ export abstract class MongoDBToolBase extends ToolBase {
5351
return super.handleError(error);
5452
}
5553

56-
protected async connectToMongoDB(connectionString: string, state: State): Promise<void> {
57-
const provider = await NodeDriverServiceProvider.connect(connectionString, {
54+
protected async connectToMongoDB(connectionString: string): Promise<NodeDriverServiceProvider> {
55+
return NodeDriverServiceProvider.connect(connectionString, {
5856
productDocsLink: "https://docs.mongodb.com/todo-mcp",
5957
productName: "MongoDB MCP",
6058
readConcern: {
@@ -66,7 +64,5 @@ export abstract class MongoDBToolBase extends ToolBase {
6664
},
6765
timeoutMS: config.connectOptions.timeoutMS,
6866
});
69-
70-
state.serviceProvider = provider;
7167
}
7268
}

src/tools/tool.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { McpServer, ToolCallback } from "@modelcontextprotocol/sdk/server/mcp.js";
22
import { z, ZodNever, ZodRawShape } from "zod";
33
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
4-
import { State } from "../state.js";
54
import logger from "../logger.js";
65
import { mongoLogId } from "mongodb-log-writer";
76

@@ -16,7 +15,7 @@ export abstract class ToolBase {
1615

1716
protected abstract execute(...args: Parameters<ToolCallback<typeof this.argsShape>>): Promise<CallToolResult>;
1817

19-
protected constructor(protected state: State) {}
18+
protected constructor() {}
2019

2120
public register(server: McpServer): void {
2221
const callback: ToolCallback<typeof this.argsShape> = async (...args) => {

0 commit comments

Comments
 (0)