Skip to content

Commit 96d8f83

Browse files
authored
chore: improve descriptions about connection - MCP-224 (#592)
1 parent 91c99e5 commit 96d8f83

File tree

4 files changed

+74
-32
lines changed

4 files changed

+74
-32
lines changed

src/common/logger.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export const LogId = {
4848

4949
toolUpdateFailure: mongoLogId(1_005_001),
5050
resourceUpdateFailure: mongoLogId(1_005_002),
51+
updateToolMetadata: mongoLogId(1_005_003),
5152

5253
streamableHttpTransportStarted: mongoLogId(1_006_001),
5354
streamableHttpTransportSessionCloseFailure: mongoLogId(1_006_002),

src/server.ts

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,15 @@ export class Server {
6262
}
6363

6464
async connect(transport: Transport): Promise<void> {
65-
// Resources are now reactive, so we register them ASAP so they can listen to events like
65+
await this.validateConfig();
66+
// Register resources after the server is initialized so they can listen to events like
6667
// connection events.
6768
this.registerResources();
68-
await this.validateConfig();
69-
70-
this.mcpServer.server.registerCapabilities({ logging: {}, resources: { listChanged: true, subscribe: true } });
69+
this.mcpServer.server.registerCapabilities({
70+
logging: {},
71+
resources: { listChanged: true, subscribe: true },
72+
instructions: this.getInstructions(),
73+
});
7174

7275
// TODO: Eventually we might want to make tools reactive too instead of relying on custom logic.
7376
this.registerTools();
@@ -134,17 +137,17 @@ export class Server {
134137
message: `Server with version ${packageInfo.version} started with transport ${transport.constructor.name} and agent runner ${JSON.stringify(this.session.mcpClient)}`,
135138
});
136139

137-
this.emitServerEvent("start", Date.now() - this.startTime);
140+
this.emitServerTelemetryEvent("start", Date.now() - this.startTime);
138141
};
139142

140143
this.mcpServer.server.onclose = (): void => {
141144
const closeTime = Date.now();
142-
this.emitServerEvent("stop", Date.now() - closeTime);
145+
this.emitServerTelemetryEvent("stop", Date.now() - closeTime);
143146
};
144147

145148
this.mcpServer.server.onerror = (error: Error): void => {
146149
const closeTime = Date.now();
147-
this.emitServerEvent("stop", Date.now() - closeTime, error);
150+
this.emitServerTelemetryEvent("stop", Date.now() - closeTime, error);
148151
};
149152

150153
await this.mcpServer.connect(transport);
@@ -161,17 +164,18 @@ export class Server {
161164
}
162165

163166
public sendResourceUpdated(uri: string): void {
167+
this.session.logger.info({
168+
id: LogId.resourceUpdateFailure,
169+
context: "resources",
170+
message: `Resource updated: ${uri}`,
171+
});
172+
164173
if (this.subscriptions.has(uri)) {
165174
void this.mcpServer.server.sendResourceUpdated({ uri });
166175
}
167176
}
168177

169-
/**
170-
* Emits a server event
171-
* @param command - The server command (e.g., "start", "stop", "register", "deregister")
172-
* @param additionalProperties - Additional properties specific to the event
173-
*/
174-
private emitServerEvent(command: ServerCommand, commandDuration: number, error?: Error): void {
178+
private emitServerTelemetryEvent(command: ServerCommand, commandDuration: number, error?: Error): void {
175179
const event: ServerEvent = {
176180
timestamp: new Date().toISOString(),
177181
source: "mdbmcp",
@@ -262,6 +266,24 @@ export class Server {
262266
}
263267
}
264268

269+
private getInstructions(): string {
270+
let instructions = `
271+
This is the MongoDB MCP server.
272+
`;
273+
if (this.userConfig.connectionString) {
274+
instructions += `
275+
This MCP server was configured with a MongoDB connection string, and you can assume that you are connected to a MongoDB cluster.
276+
`;
277+
}
278+
279+
if (this.userConfig.apiClientId && this.userConfig.apiClientSecret) {
280+
instructions += `
281+
This MCP server was configured with MongoDB Atlas API credentials.`;
282+
}
283+
284+
return instructions;
285+
}
286+
265287
private async connectToConfigConnectionString(): Promise<void> {
266288
if (this.userConfig.connectionString) {
267289
try {

src/tools/mongodb/connect/connect.ts

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { MongoDBToolBase } from "../mongodbTool.js";
44
import type { ToolArgs, OperationType, ToolConstructorParams } from "../../tool.js";
55
import assert from "assert";
66
import type { Server } from "../../../server.js";
7+
import { LogId } from "../../../common/logger.js";
78

89
const disconnectedSchema = z
910
.object({
@@ -27,7 +28,8 @@ const disconnectedName = "connect" as const;
2728

2829
const connectedDescription =
2930
"Switch to a different MongoDB connection. If the user has configured a connection string or has previously called the connect tool, a connection is already established and there's no need to call this tool unless the user has explicitly requested to switch to a new instance.";
30-
const disconnectedDescription = "Connect to a MongoDB instance";
31+
const disconnectedDescription =
32+
"Connect to a MongoDB instance. The config resource captures if the server is already connected to a MongoDB cluster. If the user has configured a connection string or has previously called the connect tool, a connection is already established and there's no need to call this tool unless the user has explicitly requested to switch to a new MongoDB cluster.";
3133

3234
export class ConnectTool extends MongoDBToolBase {
3335
public name: typeof connectedName | typeof disconnectedName = disconnectedName;
@@ -84,18 +86,30 @@ export class ConnectTool extends MongoDBToolBase {
8486
}
8587

8688
private updateMetadata(): void {
89+
let name: string;
90+
let description: string;
91+
let inputSchema: z.ZodObject<z.ZodRawShape>;
92+
8793
if (this.session.isConnectedToMongoDB) {
88-
this.update?.({
89-
name: connectedName,
90-
description: connectedDescription,
91-
inputSchema: connectedSchema,
92-
});
94+
name = connectedName;
95+
description = connectedDescription;
96+
inputSchema = connectedSchema;
9397
} else {
94-
this.update?.({
95-
name: disconnectedName,
96-
description: disconnectedDescription,
97-
inputSchema: disconnectedSchema,
98-
});
98+
name = disconnectedName;
99+
description = disconnectedDescription;
100+
inputSchema = disconnectedSchema;
99101
}
102+
103+
this.session.logger.info({
104+
id: LogId.updateToolMetadata,
105+
context: "tool",
106+
message: `Updating tool metadata to ${name}`,
107+
});
108+
109+
this.update?.({
110+
name,
111+
description,
112+
inputSchema,
113+
});
100114
}
101115
}

tests/integration/tools/mongodb/connect/connect.test.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,19 @@ describeWithMongoDB(
9191
describeWithMongoDB(
9292
"Connect tool",
9393
(integration) => {
94-
validateToolMetadata(integration, "connect", "Connect to a MongoDB instance", [
95-
{
96-
name: "connectionString",
97-
description: "MongoDB connection string (in the mongodb:// or mongodb+srv:// format)",
98-
type: "string",
99-
required: true,
100-
},
101-
]);
94+
validateToolMetadata(
95+
integration,
96+
"connect",
97+
"Connect to a MongoDB instance. The config resource captures if the server is already connected to a MongoDB cluster. If the user has configured a connection string or has previously called the connect tool, a connection is already established and there's no need to call this tool unless the user has explicitly requested to switch to a new MongoDB cluster.",
98+
[
99+
{
100+
name: "connectionString",
101+
description: "MongoDB connection string (in the mongodb:// or mongodb+srv:// format)",
102+
type: "string",
103+
required: true,
104+
},
105+
]
106+
);
102107

103108
validateThrowsForInvalidArguments(integration, "connect", [{}, { connectionString: 123 }]);
104109

0 commit comments

Comments
 (0)