Skip to content

Commit f600d2a

Browse files
committed
add a common one way override function
1 parent 132876e commit f600d2a

File tree

4 files changed

+19
-25
lines changed

4 files changed

+19
-25
lines changed

src/common/config/configUtils.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,14 @@ export function parseBoolean(val: unknown): unknown {
125125
}
126126
return false;
127127
}
128+
129+
/** Allow overriding only to the allowed value */
130+
export function oneWayOverride<T>(allowedValue: T): CustomOverrideLogic {
131+
return (oldValue, newValue) => {
132+
// Only allow override if setting to true from false
133+
if (newValue === allowedValue) {
134+
return newValue;
135+
}
136+
throw new Error(`Can only set to ${allowedValue ? "true" : "false"}`);
137+
};
138+
}

src/common/config/userConfig.ts

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
commaSeparatedToArray,
66
getExportsPath,
77
getLogPath,
8+
oneWayOverride,
89
parseBoolean,
910
} from "./configUtils.js";
1011
import { previewFeatureValues, similarityValues } from "../schemas.js";
@@ -86,13 +87,7 @@ export const UserConfigSchema = z4.object({
8687
"When set to true, only allows read, connect, and metadata operation types, disabling create/update/delete operations."
8788
)
8889
.register(configRegistry, {
89-
overrideBehavior: (oldValue, newValue) => {
90-
// Only allow override if setting to true from false
91-
if (oldValue === false && newValue === true) {
92-
return newValue;
93-
}
94-
throw new Error("Cannot disable readOnly mode");
95-
},
90+
overrideBehavior: oneWayOverride(true),
9691
}),
9792
indexCheck: z4
9893
.preprocess(parseBoolean, z4.boolean())
@@ -101,13 +96,7 @@ export const UserConfigSchema = z4.object({
10196
"When set to true, enforces that query operations must use an index, rejecting queries that perform a collection scan."
10297
)
10398
.register(configRegistry, {
104-
overrideBehavior: (oldValue, newValue) => {
105-
// Only allow override if setting to true from false
106-
if (newValue === true) {
107-
return newValue;
108-
}
109-
throw new Error("Cannot disable indexCheck mode");
110-
},
99+
overrideBehavior: oneWayOverride(true),
111100
}),
112101
telemetry: z4
113102
.enum(["enabled", "disabled"])
@@ -198,13 +187,7 @@ export const UserConfigSchema = z4.object({
198187
.default(false)
199188
.describe("When set to true, disables validation of embeddings dimensions.")
200189
.register(configRegistry, {
201-
overrideBehavior: (oldValue, newValue) => {
202-
// Only allow override if setting to false from true (making more restrictive)
203-
if (newValue === false) {
204-
return newValue;
205-
}
206-
throw new Error("Cannot disable disableEmbeddingsValidation");
207-
},
190+
overrideBehavior: oneWayOverride(false),
208191
}),
209192
vectorSearchDimensions: z4.coerce
210193
.number()

tests/integration/transports/configOverrides.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ describe("Config Overrides via HTTP", () => {
330330
}
331331
expect(error.message).toContain("Error POSTing to endpoint (HTTP 400)");
332332
expect(error.message).toContain(
333-
`Cannot apply override for readOnly from true to false: Cannot disable readOnly mode`
333+
`Cannot apply override for readOnly from true to false: Can only set to true`
334334
);
335335
}
336336
});

tests/unit/common/config/configOverrides.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ describe("configOverrides", () => {
202202
const request: RequestContext = { headers: { "x-mongodb-mcp-read-only": "false" } };
203203
expect(() =>
204204
applyConfigOverrides({ baseConfig: { ...baseConfig, readOnly: true } as UserConfig, request })
205-
).toThrow("Cannot apply override for readOnly from true to false: Cannot disable readOnly mode");
205+
).toThrow("Cannot apply override for readOnly from true to false: Can only set to true");
206206
});
207207

208208
it("should allow indexCheck override from false to true", () => {
@@ -218,7 +218,7 @@ describe("configOverrides", () => {
218218
const request: RequestContext = { headers: { "x-mongodb-mcp-index-check": "false" } };
219219
expect(() =>
220220
applyConfigOverrides({ baseConfig: { ...baseConfig, indexCheck: true } as UserConfig, request })
221-
).toThrow("Cannot apply override for indexCheck from true to false: Cannot disable indexCheck mode");
221+
).toThrow("Cannot apply override for indexCheck from true to false: Can only set to true");
222222
});
223223

224224
it("should allow disableEmbeddingsValidation override from true to false", () => {
@@ -238,7 +238,7 @@ describe("configOverrides", () => {
238238
request,
239239
})
240240
).toThrow(
241-
"Cannot apply override for disableEmbeddingsValidation from false to true: Cannot disable disableEmbeddingsValidation"
241+
"Cannot apply override for disableEmbeddingsValidation from false to true: Can only set to false"
242242
);
243243
});
244244
});

0 commit comments

Comments
 (0)