Skip to content

Commit e00143b

Browse files
chore: move category to static property
1 parent 2ea82d5 commit e00143b

File tree

11 files changed

+71
-102
lines changed

11 files changed

+71
-102
lines changed

MCP_SERVER_LIBRARY.md

Lines changed: 23 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ const AVAILABLE_CONNECTIONS = {
459459
// connected to.
460460
class ListConnectionsTool extends ToolBase {
461461
override name = "list-connections";
462-
override category: ToolCategory = "mongodb";
462+
static category: ToolCategory = "mongodb";
463463
static operationType: OperationType = "metadata";
464464
protected override description =
465465
"Lists all available pre-configured MongoDB connections";
@@ -501,7 +501,7 @@ class ListConnectionsTool extends ToolBase {
501501
// effective communication using opaque connection identifiers.
502502
class SelectConnectionTool extends ToolBase {
503503
override name = "select-connection";
504-
override category: ToolCategory = "mongodb";
504+
static category: ToolCategory = "mongodb";
505505
static operationType: OperationType = "metadata";
506506
protected override description =
507507
"Select and connect to a pre-configured MongoDB connection by ID";
@@ -583,9 +583,7 @@ const runner = new StdioRunner({
583583
}),
584584
// Register all internal tools except the default connect tools, plus our custom tools
585585
tools: [
586-
...Object.values(AllTools).filter(
587-
(tool) => tool.operationType !== "connect"
588-
),
586+
...AllTools.filter((tool) => tool.operationType !== "connect"),
589587
ListConnectionsTool,
590588
SelectConnectionTool,
591589
],
@@ -619,7 +617,7 @@ import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
619617
// Custom tool to fetch ticket details from your application
620618
class GetTicketDetailsTool extends ToolBase {
621619
override name = "get-ticket-details";
622-
override category: ToolCategory = "mongodb";
620+
static category: ToolCategory = "mongodb";
623621
static operationType: OperationType = "read";
624622

625623
protected override description =
@@ -741,7 +739,7 @@ See the TypeScript documentation in [`src/tools/tool.ts`](./src/tools/tool.ts) f
741739

742740
**Important:** All custom tools must conform to the `ToolClass` type, which requires:
743741

744-
- A **static** `operationType` property (not an instance property)
742+
- **Static** `category` and `operationType` properties (not instance properties)
745743
- Implementation of all abstract members from `ToolBase`
746744

747745
### ToolClass
@@ -751,90 +749,41 @@ The type that all tool classes must conform to when implementing custom tools.
751749
This type enforces that tool classes have:
752750

753751
- A constructor that accepts `ToolConstructorParams`
754-
- A **static** `operationType` property
752+
- **Static** `category` and `operationType` properties
755753

756-
The static `operationType` is automatically injected as an instance property during tool construction by the server.
754+
The static properties are automatically injected as instance properties during tool construction by the server.
757755

758756
See the TypeScript documentation in [`src/tools/tool.ts`](./src/tools/tool.ts) for complete details and examples.
759757

760758
### Tool Collections
761759

762760
The library exports collections of internal tool classes that can be used for selective tool registration or extension.
763761

764-
#### AllTools
765-
766-
An object containing all internal tool classes (MongoDB, Atlas, and Atlas Local tools combined).
767-
768762
```typescript
769-
import { AllTools, MongoDbTools, AtlasTools } from "mongodb-mcp-server/tools";
763+
import { AllTools, AggregateTool, FindTool } from "mongodb-mcp-server/tools";
770764

771-
// Pick a specific tool
772-
const MyTool = AllTools.AggregateTool;
765+
// Use all internal tools
766+
// An array containing all internal tool constructors (MongoDB, Atlas, and Atlas Local tools combined).
767+
const allTools = AllTools;
773768

774-
// Create a list of hand picked tools
775-
const selectedInternalTools = [
776-
AllTools.AggregateTool,
777-
AllTools.ConnectTool,
778-
AllTools.SwitchConnectionTool,
779-
];
769+
// Pick specific tools by importing them directly
770+
const selectedInternalTools = [AggregateTool, FindTool];
780771

781-
// Create a list of all internal tools except a few
782-
const filteredTools = Object.values(AllTools).filter(
783-
(tool) =>
784-
tool !== AllTools.ConnectTool && tool !== AllTools.SwitchConnectionTool
772+
// Create a list of all internal tools except a few by filtering
773+
const filteredTools = AllTools.filter(
774+
(tool) => tool !== AggregateTool && tool !== FindTool
785775
);
786776

787777
// Filter tools by operationType (static property)
788-
const connectionRelatedTools = Object.values(AllTools).filter(
778+
const connectionRelatedTools = AllTools.filter(
789779
(tool) => tool.operationType === "connect"
790780
);
791-
```
792-
793-
#### MongoDbTools
794-
795-
An object containing only MongoDB-specific tool classes (tools that interact with MongoDB deployments).
796-
797-
```typescript
798-
import { MongoDbTools } from "mongodb-mcp-server/tools";
799-
800-
// Get all MongoDB tools as an array
801-
const mongoTools = Object.values(MongoDbTools);
802-
803-
// You can check static properties like operationType
804-
const readOnlyMongoTools = mongoTools.filter(
805-
(tool) => tool.operationType === "read" || tool.operationType === "metadata"
806-
);
807-
```
808-
809-
#### AtlasTools
810-
811-
An object containing only MongoDB Atlas-specific tool classes (tools that interact with Atlas API).
812-
813-
```typescript
814-
import { AtlasTools } from "mongodb-mcp-server/tools";
815-
816-
// Get all Atlas tools as an array
817-
const atlasTools = Object.values(AtlasTools);
818781

819-
// You can check static properties like operationType
820-
const atlasCreationTools = atlasTools.filter(
821-
(tool) => tool.operationType === "create"
822-
);
823-
```
824-
825-
#### AtlasLocalTools
826-
827-
An object containing only Atlas Local-specific tool classes (tools that interact with local Atlas deployments).
828-
829-
```typescript
830-
import { AtlasLocalTools } from "mongodb-mcp-server/tools";
831-
832-
// Get all Atlas Local tools as an array
833-
const atlasLocalTools = Object.values(AtlasLocalTools);
834-
835-
// You can check static properties like operationType
836-
const atlasLocalConnectionTools = atlasLocalTools.filter(
837-
(tool) => tool.operationType === "connect"
782+
// Filter tools by category
783+
const mongodbTools = AllTools.filter((tool) => tool.category === "mongodb");
784+
const atlasTools = AllTools.filter((tool) => tool.category === "atlas");
785+
const atlasLocalTools = AllTools.filter(
786+
(tool) => tool.category === "atlas-local"
838787
);
839788
```
840789

@@ -1101,7 +1050,7 @@ For complete working examples of embedding and extending the MongoDB MCP Server,
11011050
**Problem:** Custom tools not appearing in the tool list
11021051

11031052
- **Solution:** Ensure the tool class extends `ToolBase` and is passed in the `tools` array
1104-
- **Solution:** If you want both internal and custom tools, spread `AllTools` in the array: `tools: [...Object.values(AllTools), MyCustomTool]`
1053+
- **Solution:** If you want both internal and custom tools, spread `AllTools` in the array: `tools: [...AllTools, MyCustomTool]`
11051054
- **Solution:** Check that the tool's `verifyAllowed()` returns true and the tool is not accidentally disabled by config (disabledTools)
11061055

11071056
**Problem:** Configuration overrides not working

src/server.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export interface ServerOptions {
3838
* import { AllTools, ToolBase, type ToolCategory, type OperationType } from "mongodb-mcp-server/tools";
3939
* class CustomTool extends ToolBase {
4040
* override name = "custom_tool";
41-
* override category: ToolCategory = "mongodb";
41+
* static category: ToolCategory = "mongodb";
4242
* static operationType: OperationType = "read";
4343
* protected description = "Custom tool description";
4444
* protected argsShape = {};
@@ -56,7 +56,7 @@ export interface ServerOptions {
5656
* telemetry: myTelemetry,
5757
* elicitation: myElicitation,
5858
* connectionErrorHandler: myConnectionErrorHandler,
59-
* tools: [...Object.values(AllTools), CustomTool],
59+
* tools: [...AllTools, CustomTool],
6060
* });
6161
* ```
6262
*/
@@ -98,7 +98,7 @@ export class Server {
9898
this.userConfig = userConfig;
9999
this.elicitation = elicitation;
100100
this.connectionErrorHandler = connectionErrorHandler;
101-
this.toolConstructors = tools ?? Object.values(AllTools);
101+
this.toolConstructors = tools ?? AllTools;
102102
}
103103

104104
async connect(transport: Transport): Promise<void> {
@@ -251,6 +251,7 @@ export class Server {
251251
private registerTools(): void {
252252
for (const toolConstructor of this.toolConstructors) {
253253
const tool = new toolConstructor({
254+
category: toolConstructor.category,
254255
operationType: toolConstructor.operationType,
255256
session: this.session,
256257
config: this.userConfig,

src/tools/atlas/atlasTool.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { z } from "zod";
77
import { ApiClientError } from "../../common/atlas/apiClientError.js";
88

99
export abstract class AtlasToolBase extends ToolBase {
10-
public category: ToolCategory = "atlas";
10+
static category: ToolCategory = "atlas";
1111

1212
protected verifyAllowed(): boolean {
1313
if (!this.config.apiClientId || !this.config.apiClientSecret) {

src/tools/atlasLocal/atlasLocalTool.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type { ConnectionMetadata } from "../../telemetry/types.js";
99
export const AtlasLocalToolMetadataDeploymentIdKey = "deploymentId";
1010

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

1414
protected verifyAllowed(): boolean {
1515
return this.session.atlasLocalClient !== undefined && super.verifyAllowed();

src/tools/index.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
import * as AtlasTools from "./atlas/tools.js";
22
import * as AtlasLocalTools from "./atlasLocal/tools.js";
33
import * as MongoDbTools from "./mongodb/tools.js";
4+
import type { ToolClass } from "./tool.js";
45

5-
const AllTools = {
6+
// Export the collection of tools for easier reference
7+
export const AllTools: ToolClass[] = Object.values({
68
...MongoDbTools,
79
...AtlasTools,
810
...AtlasLocalTools,
9-
} as const;
11+
});
1012

11-
// Export all the different categories of tools
12-
export { AllTools, MongoDbTools, AtlasTools, AtlasLocalTools };
13+
// Export all the individual tools for handpicking
14+
export * from "./atlas/tools.js";
15+
export * from "./atlasLocal/tools.js";
16+
export * from "./mongodb/tools.js";
1317

1418
// Export the base tool class and supporting types.
1519
export {

src/tools/mongodb/mongodbTool.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export const DbOperationArgs = {
1616

1717
export abstract class MongoDBToolBase extends ToolBase {
1818
protected server?: Server;
19-
public category: ToolCategory = "mongodb";
19+
static category: ToolCategory = "mongodb";
2020

2121
protected async ensureConnected(): Promise<NodeDriverServiceProvider> {
2222
if (!this.session.isConnectedToMongoDB) {

src/tools/tool.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ export type ToolCategory = "mongodb" | "atlas" | "atlas-local";
4949
* See `Server.registerTools` method in `src/server.ts` for further reference.
5050
*/
5151
export type ToolConstructorParams = {
52+
/**
53+
* The category that the tool belongs to (injected from the static
54+
* `category` property on the Tool class).
55+
*/
56+
category: ToolCategory;
57+
5258
/**
5359
* The type of operation the tool performs (injected from the static
5460
* `operationType` property on the Tool class).
@@ -89,8 +95,8 @@ export type ToolConstructorParams = {
8995
* The type that all tool classes must conform to when implementing custom tools
9096
* for the MongoDB MCP Server.
9197
*
92-
* This type enforces that tool classes have a static property `operationType`
93-
* which is injected during instantiation of tool classes.
98+
* This type enforces that tool classes have static properties `category` and
99+
* `operationType` which are injected during instantiation of tool classes.
94100
*
95101
* @example
96102
* ```typescript
@@ -100,11 +106,11 @@ export type ToolConstructorParams = {
100106
*
101107
* class MyCustomTool extends ToolBase {
102108
* // Required static properties for ToolClass conformance
109+
* static category: ToolCategory = "mongodb";
103110
* static operationType: OperationType = "read";
104111
*
105112
* // Required abstract properties
106113
* override name = "my-custom-tool";
107-
* public override category: ToolCategory = "mongodb";
108114
* protected description = "My custom tool description";
109115
* protected argsShape = {
110116
* query: z.string().describe("The query parameter"),
@@ -135,6 +141,9 @@ export type ToolClass = {
135141
/** Constructor signature for the tool class */
136142
new (params: ToolConstructorParams): ToolBase;
137143

144+
/** The category that the tool belongs to */
145+
category: ToolCategory;
146+
138147
/** The type of operation the tool performs */
139148
operationType: OperationType;
140149
};
@@ -149,8 +158,8 @@ export type ToolClass = {
149158
*
150159
* To create a custom tool, you must:
151160
* 1. Extend the `ToolBase` class
152-
* 2. Define static property: `operationType`
153-
* 3. Implement required abstract members: `name`, `category`, `description`,
161+
* 2. Define static properties: `category` and `operationType`
162+
* 3. Implement required abstract members: `name`, `description`,
154163
* `argsShape`, `execute()`, `resolveTelemetryMetadata()`
155164
*
156165
* @example Basic Custom Tool
@@ -161,11 +170,11 @@ export type ToolClass = {
161170
*
162171
* class MyCustomTool extends ToolBase {
163172
* // Required static property for ToolClass conformance
173+
* static category: ToolCategory = "mongodb";
164174
* static operationType: OperationType = "read";
165175
*
166176
* // Required abstract properties
167177
* override name = "my-custom-tool";
168-
* override category: ToolCategory = "mongodb";
169178
* protected description = "My custom tool description";
170179
* protected argsShape = {
171180
* query: z.string().describe("The query parameter"),
@@ -202,8 +211,9 @@ export type ToolClass = {
202211
*
203212
* ## Instance Properties Set by Constructor
204213
*
205-
* The following property is automatically set when the tool is instantiated
206-
* by the server (derived from the static property):
214+
* The following properties are automatically set when the tool is instantiated
215+
* by the server (derived from the static properties):
216+
* - `category` - The tool's category (from static `category`)
207217
* - `operationType` - The tool's operation type (from static `operationType`)
208218
*
209219
* ## Optional Overrideable Methods
@@ -229,7 +239,7 @@ export abstract class ToolBase {
229239
*
230240
* @see {@link ToolCategory} for the available tool categories.
231241
*/
232-
public abstract category: ToolCategory;
242+
public category: ToolCategory;
233243

234244
/**
235245
* The type of operation this tool performs.
@@ -390,7 +400,8 @@ export abstract class ToolBase {
390400
*/
391401
protected readonly elicitation: Elicitation;
392402

393-
constructor({ operationType, session, config, telemetry, elicitation }: ToolConstructorParams) {
403+
constructor({ category, operationType, session, config, telemetry, elicitation }: ToolConstructorParams) {
404+
this.category = category;
394405
this.operationType = operationType;
395406
this.session = session;
396407
this.config = config;

src/transports/base.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,16 @@ export type TransportRunnerConfig = {
146146
* To include internal tools, import them from `mongodb-mcp-server/tools`:
147147
*
148148
* ```typescript
149-
* import { AllTools, MongoDbTools } from "mongodb-mcp-server/tools";
149+
* import { AllTools, AggregateTool, FindTool } from "mongodb-mcp-server/tools";
150150
*
151151
* // Register all internal tools plus custom tools
152-
* tools: [...Object.values(AllTools), MyCustomTool]
152+
* tools: [...AllTools, MyCustomTool]
153153
*
154-
* // Register only MongoDB tools plus custom tools (exclude Atlas tools)
155-
* tools: [...Object.values(MongoDbTools), MyCustomTool]
154+
* // Register only specific MongoDB tools plus custom tools
155+
* tools: [AggregateTool, FindTool, MyCustomTool]
156+
*
157+
* // Register all internal tools of mongodb category
158+
* tools: [AllTools.filter((tool) => tool.category === "mongodb")]
156159
* ```
157160
*
158161
* Note: Ensure that each tool has unique names otherwise the server will

tests/integration/customTools.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ describe("Custom Tools", () => {
8080
*/
8181
class CustomGreetingTool extends ToolBase {
8282
name = "custom_greeting";
83-
category = "mongodb" as const;
83+
static category = "mongodb" as const;
8484
static operationType = "read" as const;
8585
protected description = "A custom tool that greets the user";
8686
protected argsShape = {
@@ -108,7 +108,7 @@ class CustomGreetingTool extends ToolBase {
108108
*/
109109
class CustomCalculatorTool extends ToolBase {
110110
name = "custom_calculator";
111-
category = "mongodb" as const;
111+
static category = "mongodb" as const;
112112
static operationType = "read" as const;
113113
protected description = "A custom tool that performs calculations";
114114
protected argsShape = {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { setupMongoDBIntegrationTest } from "./mongodbHelpers.js";
1919
import { ErrorCodes } from "../../../../src/common/errors.js";
2020
import { Keychain } from "../../../../src/common/keychain.js";
2121
import { Elicitation } from "../../../../src/elicitation.js";
22-
import { MongoDbTools } from "../../../../src/tools/index.js";
22+
import * as MongoDbTools from "../../../../src/tools/mongodb/tools.js";
2323
import { VectorSearchEmbeddingsManager } from "../../../../src/common/search/vectorSearchEmbeddingsManager.js";
2424

2525
const injectedErrorHandler: ConnectionErrorHandler = (error) => {

0 commit comments

Comments
 (0)