Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,068 changes: 1,068 additions & 0 deletions MCP_SERVER_LIBRARY.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions knip.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"entry": [
"src/index.ts!",
"src/lib.ts!",
"src/tools/index.ts!",
"tests/**/*.ts",
"scripts/**/*.ts",
"eslint-rules/*.js"
Expand Down
15 changes: 9 additions & 6 deletions src/lib.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
export { Server, type ServerOptions } from "./server.js";
export { Session, type SessionOptions } from "./common/session.js";
export { type UserConfig, UserConfigSchema } from "./common/config/userConfig.js";
export { createUserConfig as parseCliArgumentsAsUserConfig } from "./common/config/createUserConfig.js";
export { LoggerBase, type LogPayload, type LoggerType, type LogLevel } from "./common/logger.js";
export { StreamableHttpRunner } from "./transports/streamableHttp.js";
export { StdioRunner } from "./transports/stdio.js";
export { TransportRunnerBase, type TransportRunnerConfig } from "./transports/base.js";
export {
ConnectionManager,
ConnectionStateConnected,
createMCPConnectionManager,
type AnyConnectionState,
type ConnectionState,
type ConnectionStateDisconnected,
type ConnectionStateErrored,
type ConnectionManagerFactoryFn,
} from "./common/connectionManager.js";
export type {
ConnectionErrorHandler,
ConnectionErrorHandled,
ConnectionErrorUnhandled,
ConnectionErrorHandlerContext,
export {
connectionErrorHandler,
type ConnectionErrorHandler,
type ConnectionErrorHandled,
type ConnectionErrorUnhandled,
type ConnectionErrorHandlerContext,
} from "./common/connectionErrorHandler.js";
export { ErrorCodes } from "./common/errors.js";
export { ErrorCodes, MongoDBError } from "./common/errors.js";
export { Telemetry } from "./telemetry/telemetry.js";
export { Keychain, registerGlobalSecretToRedact } from "./common/keychain.js";
export type { Secret } from "./common/keychain.js";
Expand Down
23 changes: 17 additions & 6 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
UnsubscribeRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import assert from "assert";
import type { ToolBase, ToolCategory, ToolConstructorParams } from "./tools/tool.js";
import type { ToolBase, ToolCategory, ToolClass } from "./tools/tool.js";
import { validateConnectionString } from "./helpers/connectionOptions.js";
import { packageInfo } from "./common/packageInfo.js";
import { type ConnectionErrorHandler } from "./common/connectionErrorHandler.js";
Expand All @@ -35,10 +35,19 @@ export interface ServerOptions {
* This will override any default tools. You can use both existing and custom tools by using the `mongodb-mcp-server/tools` export.
*
* ```ts
* import { AllTools, ToolBase } from "mongodb-mcp-server/tools";
* import { AllTools, ToolBase, type ToolCategory, type OperationType } from "mongodb-mcp-server/tools";
* class CustomTool extends ToolBase {
* name = "custom_tool";
* // ...
* override name = "custom_tool";
* static category: ToolCategory = "mongodb";
* static operationType: OperationType = "read";
* protected description = "Custom tool description";
* protected argsShape = {};
* protected async execute() {
* return { content: [{ type: "text", text: "Result" }] };
* }
* protected resolveTelemetryMetadata() {
* return {};
* }
* }
* const server = new Server({
* session: mySession,
Expand All @@ -51,7 +60,7 @@ export interface ServerOptions {
* });
* ```
*/
tools?: (new (params: ToolConstructorParams) => ToolBase)[];
tools?: ToolClass[];
}

export class Server {
Expand All @@ -60,7 +69,7 @@ export class Server {
private readonly telemetry: Telemetry;
public readonly userConfig: UserConfig;
public readonly elicitation: Elicitation;
private readonly toolConstructors: (new (params: ToolConstructorParams) => ToolBase)[];
private readonly toolConstructors: ToolClass[];
public readonly tools: ToolBase[] = [];
public readonly connectionErrorHandler: ConnectionErrorHandler;

Expand Down Expand Up @@ -242,6 +251,8 @@ export class Server {
private registerTools(): void {
for (const toolConstructor of this.toolConstructors) {
const tool = new toolConstructor({
category: toolConstructor.category,
operationType: toolConstructor.operationType,
session: this.session,
config: this.userConfig,
telemetry: this.telemetry,
Expand Down
2 changes: 1 addition & 1 deletion src/tools/atlas/atlasTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { z } from "zod";
import { ApiClientError } from "../../common/atlas/apiClientError.js";

export abstract class AtlasToolBase extends ToolBase {
public category: ToolCategory = "atlas";
static category: ToolCategory = "atlas";

protected verifyAllowed(): boolean {
if (!this.config.apiClientId || !this.config.apiClientSecret) {
Expand Down
2 changes: 1 addition & 1 deletion src/tools/atlas/connect/connectCluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const ConnectClusterArgs = {
export class ConnectClusterTool extends AtlasToolBase {
public name = "atlas-connect-cluster";
protected description = "Connect to MongoDB Atlas cluster";
public operationType: OperationType = "connect";
static operationType: OperationType = "connect";
protected argsShape = {
...ConnectClusterArgs,
};
Expand Down
2 changes: 1 addition & 1 deletion src/tools/atlas/create/createAccessList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const CreateAccessListArgs = {
export class CreateAccessListTool extends AtlasToolBase {
public name = "atlas-create-access-list";
protected description = "Allow Ip/CIDR ranges to access your MongoDB Atlas clusters.";
public operationType: OperationType = "create";
static operationType: OperationType = "create";
protected argsShape = {
...CreateAccessListArgs,
};
Expand Down
2 changes: 1 addition & 1 deletion src/tools/atlas/create/createDBUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const CreateDBUserArgs = {
export class CreateDBUserTool extends AtlasToolBase {
public name = "atlas-create-db-user";
protected description = "Create an MongoDB Atlas database user";
public operationType: OperationType = "create";
static operationType: OperationType = "create";
protected argsShape = {
...CreateDBUserArgs,
};
Expand Down
2 changes: 1 addition & 1 deletion src/tools/atlas/create/createFreeCluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { AtlasArgs } from "../../args.js";
export class CreateFreeClusterTool extends AtlasToolBase {
public name = "atlas-create-free-cluster";
protected description = "Create a free MongoDB Atlas cluster";
public operationType: OperationType = "create";
static operationType: OperationType = "create";
protected argsShape = {
projectId: AtlasArgs.projectId().describe("Atlas project ID to create the cluster in"),
name: AtlasArgs.clusterName().describe("Name of the cluster"),
Expand Down
2 changes: 1 addition & 1 deletion src/tools/atlas/create/createProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { AtlasArgs } from "../../args.js";
export class CreateProjectTool extends AtlasToolBase {
public name = "atlas-create-project";
protected description = "Create a MongoDB Atlas project";
public operationType: OperationType = "create";
static operationType: OperationType = "create";
protected argsShape = {
projectName: AtlasArgs.projectName().optional().describe("Name for the new project"),
organizationId: AtlasArgs.organizationId().optional().describe("Organization ID for the new project"),
Expand Down
2 changes: 1 addition & 1 deletion src/tools/atlas/read/getPerformanceAdvisor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const PerformanceAdvisorOperationType = z.enum([
export class GetPerformanceAdvisorTool extends AtlasToolBase {
public name = "atlas-get-performance-advisor";
protected description = `Get MongoDB Atlas performance advisor recommendations, which includes the operations: suggested indexes, drop index suggestions, schema suggestions, and a sample of the most recent (max ${DEFAULT_SLOW_QUERY_LOGS_LIMIT}) slow query logs`;
public operationType: OperationType = "read";
static operationType: OperationType = "read";
protected argsShape = {
projectId: AtlasArgs.projectId().describe(
"Atlas project ID to get performance advisor recommendations. The project ID is a hexadecimal identifier of 24 characters. If the user has only specified the name, use the `atlas-list-projects` tool to retrieve the user's projects with their ids."
Expand Down
2 changes: 1 addition & 1 deletion src/tools/atlas/read/inspectAccessList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const InspectAccessListArgs = {
export class InspectAccessListTool extends AtlasToolBase {
public name = "atlas-inspect-access-list";
protected description = "Inspect Ip/CIDR ranges with access to your MongoDB Atlas clusters.";
public operationType: OperationType = "read";
static operationType: OperationType = "read";
protected argsShape = {
...InspectAccessListArgs,
};
Expand Down
2 changes: 1 addition & 1 deletion src/tools/atlas/read/inspectCluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const InspectClusterArgs = {
export class InspectClusterTool extends AtlasToolBase {
public name = "atlas-inspect-cluster";
protected description = "Inspect MongoDB Atlas cluster";
public operationType: OperationType = "read";
static operationType: OperationType = "read";
protected argsShape = {
...InspectClusterArgs,
};
Expand Down
2 changes: 1 addition & 1 deletion src/tools/atlas/read/listAlerts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const ListAlertsArgs = {
export class ListAlertsTool extends AtlasToolBase {
public name = "atlas-list-alerts";
protected description = "List MongoDB Atlas alerts";
public operationType: OperationType = "read";
static operationType: OperationType = "read";
protected argsShape = {
...ListAlertsArgs,
};
Expand Down
2 changes: 1 addition & 1 deletion src/tools/atlas/read/listClusters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const ListClustersArgs = {
export class ListClustersTool extends AtlasToolBase {
public name = "atlas-list-clusters";
protected description = "List MongoDB Atlas clusters";
public operationType: OperationType = "read";
static operationType: OperationType = "read";
protected argsShape = {
...ListClustersArgs,
};
Expand Down
2 changes: 1 addition & 1 deletion src/tools/atlas/read/listDBUsers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const ListDBUsersArgs = {
export class ListDBUsersTool extends AtlasToolBase {
public name = "atlas-list-db-users";
protected description = "List MongoDB Atlas database users";
public operationType: OperationType = "read";
static operationType: OperationType = "read";
protected argsShape = {
...ListDBUsersArgs,
};
Expand Down
2 changes: 1 addition & 1 deletion src/tools/atlas/read/listOrgs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { formatUntrustedData } from "../../tool.js";
export class ListOrganizationsTool extends AtlasToolBase {
public name = "atlas-list-orgs";
protected description = "List MongoDB Atlas organizations";
public operationType: OperationType = "read";
static operationType: OperationType = "read";
protected argsShape = {};

protected async execute(): Promise<CallToolResult> {
Expand Down
2 changes: 1 addition & 1 deletion src/tools/atlas/read/listProjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { AtlasArgs } from "../../args.js";
export class ListProjectsTool extends AtlasToolBase {
public name = "atlas-list-projects";
protected description = "List MongoDB Atlas projects";
public operationType: OperationType = "read";
static operationType: OperationType = "read";
protected argsShape = {
orgId: AtlasArgs.organizationId()
.describe("Atlas organization ID to filter projects. If not provided, projects for all orgs are returned.")
Expand Down
42 changes: 13 additions & 29 deletions src/tools/atlas/tools.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,13 @@
import { ListClustersTool } from "./read/listClusters.js";
import { ListProjectsTool } from "./read/listProjects.js";
import { InspectClusterTool } from "./read/inspectCluster.js";
import { CreateFreeClusterTool } from "./create/createFreeCluster.js";
import { CreateAccessListTool } from "./create/createAccessList.js";
import { InspectAccessListTool } from "./read/inspectAccessList.js";
import { ListDBUsersTool } from "./read/listDBUsers.js";
import { CreateDBUserTool } from "./create/createDBUser.js";
import { CreateProjectTool } from "./create/createProject.js";
import { ListOrganizationsTool } from "./read/listOrgs.js";
import { ConnectClusterTool } from "./connect/connectCluster.js";
import { ListAlertsTool } from "./read/listAlerts.js";
import { GetPerformanceAdvisorTool } from "./read/getPerformanceAdvisor.js";

export const AtlasTools = [
ListClustersTool,
ListProjectsTool,
InspectClusterTool,
CreateFreeClusterTool,
CreateAccessListTool,
InspectAccessListTool,
ListDBUsersTool,
CreateDBUserTool,
CreateProjectTool,
ListOrganizationsTool,
ConnectClusterTool,
ListAlertsTool,
GetPerformanceAdvisorTool,
];
export { ListClustersTool } from "./read/listClusters.js";
export { ListProjectsTool } from "./read/listProjects.js";
export { InspectClusterTool } from "./read/inspectCluster.js";
export { CreateFreeClusterTool } from "./create/createFreeCluster.js";
export { CreateAccessListTool } from "./create/createAccessList.js";
export { InspectAccessListTool } from "./read/inspectAccessList.js";
export { ListDBUsersTool } from "./read/listDBUsers.js";
export { CreateDBUserTool } from "./create/createDBUser.js";
export { CreateProjectTool } from "./create/createProject.js";
export { ListOrganizationsTool } from "./read/listOrgs.js";
export { ConnectClusterTool } from "./connect/connectCluster.js";
export { ListAlertsTool } from "./read/listAlerts.js";
export { GetPerformanceAdvisorTool } from "./read/getPerformanceAdvisor.js";
2 changes: 1 addition & 1 deletion src/tools/atlasLocal/atlasLocalTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { ConnectionMetadata } from "../../telemetry/types.js";
export const AtlasLocalToolMetadataDeploymentIdKey = "deploymentId";

export abstract class AtlasLocalToolBase extends ToolBase {
public category: ToolCategory = "atlas-local";
static category: ToolCategory = "atlas-local";

protected verifyAllowed(): boolean {
return this.session.atlasLocalClient !== undefined && super.verifyAllowed();
Expand Down
2 changes: 1 addition & 1 deletion src/tools/atlasLocal/connect/connectDeployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { ConnectionMetadata } from "../../../telemetry/types.js";
export class ConnectDeploymentTool extends AtlasLocalToolBase {
public name = "atlas-local-connect-deployment";
protected description = "Connect to a MongoDB Atlas Local deployment";
public operationType: OperationType = "connect";
static operationType: OperationType = "connect";
protected argsShape = {
deploymentName: CommonArgs.string().describe("Name of the deployment to connect to"),
};
Expand Down
2 changes: 1 addition & 1 deletion src/tools/atlasLocal/create/createDeployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { CommonArgs } from "../../args.js";
export class CreateDeploymentTool extends AtlasLocalToolBase {
public name = "atlas-local-create-deployment";
protected description = "Create a MongoDB Atlas local deployment";
public operationType: OperationType = "create";
static operationType: OperationType = "create";
protected argsShape = {
deploymentName: CommonArgs.string().describe("Name of the deployment to create").optional(),
};
Expand Down
2 changes: 1 addition & 1 deletion src/tools/atlasLocal/delete/deleteDeployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { CommonArgs } from "../../args.js";
export class DeleteDeploymentTool extends AtlasLocalToolBase {
public name = "atlas-local-delete-deployment";
protected description = "Delete a MongoDB Atlas local deployment";
public operationType: OperationType = "delete";
static operationType: OperationType = "delete";
protected argsShape = {
deploymentName: CommonArgs.string().describe("Name of the deployment to delete"),
};
Expand Down
2 changes: 1 addition & 1 deletion src/tools/atlasLocal/read/listDeployments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { Client } from "@mongodb-js/atlas-local";
export class ListDeploymentsTool extends AtlasLocalToolBase {
public name = "atlas-local-list-deployments";
protected description = "List MongoDB Atlas local deployments";
public operationType: OperationType = "read";
static operationType: OperationType = "read";
protected argsShape = {};

protected async executeWithAtlasLocalClient(client: Client): Promise<CallToolResult> {
Expand Down
10 changes: 4 additions & 6 deletions src/tools/atlasLocal/tools.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { DeleteDeploymentTool } from "./delete/deleteDeployment.js";
import { ListDeploymentsTool } from "./read/listDeployments.js";
import { CreateDeploymentTool } from "./create/createDeployment.js";
import { ConnectDeploymentTool } from "./connect/connectDeployment.js";

export const AtlasLocalTools = [ListDeploymentsTool, DeleteDeploymentTool, CreateDeploymentTool, ConnectDeploymentTool];
export { DeleteDeploymentTool } from "./delete/deleteDeployment.js";
export { ListDeploymentsTool } from "./read/listDeployments.js";
export { CreateDeploymentTool } from "./create/createDeployment.js";
export { ConnectDeploymentTool } from "./connect/connectDeployment.js";
21 changes: 16 additions & 5 deletions src/tools/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
import { AtlasTools } from "./atlas/tools.js";
import { AtlasLocalTools } from "./atlasLocal/tools.js";
import { MongoDbTools } from "./mongodb/tools.js";
import * as AtlasTools from "./atlas/tools.js";
import * as AtlasLocalTools from "./atlasLocal/tools.js";
import * as MongoDbTools from "./mongodb/tools.js";
import type { ToolClass } from "./tool.js";

const AllTools = [...MongoDbTools, ...AtlasTools, ...AtlasLocalTools];
// Export the collection of tools for easier reference
export const AllTools: ToolClass[] = Object.values({
...MongoDbTools,
...AtlasTools,
...AtlasLocalTools,
});

export { AllTools, MongoDbTools, AtlasTools, AtlasLocalTools };
// Export all the individual tools for handpicking
export * from "./atlas/tools.js";
export * from "./atlasLocal/tools.js";
export * from "./mongodb/tools.js";

// Export the base tool class and supporting types.
export {
ToolBase,
type ToolClass,
type ToolConstructorParams,
type ToolCategory,
type OperationType,
Expand Down
10 changes: 5 additions & 5 deletions src/tools/mongodb/connect/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ export class ConnectTool extends MongoDBToolBase {
connectionString: z.string().describe("MongoDB connection string (in the mongodb:// or mongodb+srv:// format)"),
};

public override operationType: OperationType = "connect";
static operationType: OperationType = "connect";

constructor({ session, config, telemetry, elicitation }: ToolConstructorParams) {
super({ session, config, telemetry, elicitation });
session.on("connect", () => {
constructor(params: ToolConstructorParams) {
super(params);
params.session.on("connect", () => {
this.disable();
});

session.on("disconnect", () => {
params.session.on("disconnect", () => {
this.enable();
});
}
Expand Down
10 changes: 5 additions & 5 deletions src/tools/mongodb/connect/switchConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ export class SwitchConnectionTool extends MongoDBToolBase {
),
};

public override operationType: OperationType = "connect";
static operationType: OperationType = "connect";

constructor({ session, config, telemetry, elicitation }: ToolConstructorParams) {
super({ session, config, telemetry, elicitation });
session.on("connect", () => {
constructor(params: ToolConstructorParams) {
super(params);
params.session.on("connect", () => {
this.enable();
});

session.on("disconnect", () => {
params.session.on("disconnect", () => {
this.disable();
});
}
Expand Down
Loading