Skip to content

Commit 4d887c9

Browse files
committed
Use custom fetch + treat results as untrusted
1 parent 4671347 commit 4d887c9

File tree

5 files changed

+54
-39
lines changed

5 files changed

+54
-39
lines changed

package-lock.json

Lines changed: 1 addition & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
"@types/yargs-parser": "^21.0.3",
7474
"@typescript-eslint/parser": "^8.44.0",
7575
"@vitest/coverage-v8": "^3.2.4",
76+
"@vitest/eslint-plugin": "^1.3.4",
7677
"ai": "^4.3.17",
7778
"duplexpair": "^1.0.2",
7879
"eslint": "^9.34.0",
@@ -92,7 +93,6 @@
9293
"tsx": "^4.20.5",
9394
"typescript": "^5.9.2",
9495
"typescript-eslint": "^8.41.0",
95-
"@vitest/eslint-plugin": "^1.3.4",
9696
"uuid": "^13.0.0",
9797
"vitest": "^3.2.4"
9898
},
@@ -114,6 +114,7 @@
114114
"oauth4webapi": "^3.8.0",
115115
"openapi-fetch": "^0.14.0",
116116
"ts-levenshtein": "^1.0.7",
117+
"yaml": "^2.8.1",
117118
"yargs-parser": "^22.0.0",
118119
"zod": "^3.25.76"
119120
},

src/tools/assistant/assistantTool.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ import {
55
type ToolCategory,
66
type ToolConstructorParams,
77
} from "../tool.js";
8-
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
8+
import { createFetch } from "@mongodb-js/devtools-proxy-support";
99
import { Server } from "../../server.js";
1010
import { packageInfo } from "../../common/packageInfo.js";
11+
import { formatUntrustedData } from "../tool.js";
1112

1213
export abstract class AssistantToolBase extends ToolBase {
1314
protected server?: Server;
@@ -18,10 +19,9 @@ export abstract class AssistantToolBase extends ToolBase {
1819
constructor({ session, config, telemetry, elicitation }: ToolConstructorParams) {
1920
super({ session, config, telemetry, elicitation });
2021
this.baseUrl = new URL(config.assistantBaseUrl);
21-
const serverVersion = packageInfo.version;
2222
this.requiredHeaders = new Headers({
2323
"x-request-origin": "mongodb-mcp-server",
24-
"user-agent": serverVersion ? `mongodb-mcp-server/v${serverVersion}` : "mongodb-mcp-server",
24+
"user-agent": packageInfo.version ? `mongodb-mcp-server/v${packageInfo.version}` : "mongodb-mcp-server",
2525
});
2626
}
2727

@@ -42,7 +42,14 @@ export abstract class AssistantToolBase extends ToolBase {
4242
if (args.method === "POST") {
4343
headers.set("Content-Type", "application/json");
4444
}
45-
return await fetch(endpoint, {
45+
46+
// Use the same custom fetch implementation as the Atlas API client.
47+
// We need this to support enterprise proxies.
48+
const customFetch = createFetch({
49+
useEnvironmentVariableProxies: true,
50+
}) as unknown as typeof fetch;
51+
52+
return await customFetch(endpoint, {
4653
method: args.method,
4754
headers,
4855
body: JSON.stringify(args.body),
Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,27 @@
1-
import { z } from "zod";
21
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
3-
import { OperationType } from "../tool.js";
2+
import { formatUntrustedData, type OperationType } from "../tool.js";
43
import { AssistantToolBase } from "./assistantTool.js";
54
import { LogId } from "../../common/logger.js";
5+
import { stringify as yamlStringify } from "yaml";
66

7-
export type ListKnowledgeSourcesResponse = {
8-
dataSources: {
9-
/** The name of the data source */
10-
id: string;
11-
/** The type of the data source */
12-
type: string;
13-
/** A list of available versions for this data source */
14-
versions: {
15-
/** The version label of the data source */
16-
label: string;
17-
/** Whether this version is the current/default version */
18-
isCurrent: boolean;
19-
}[];
7+
export type KnowledgeSource = {
8+
/** The name of the data source */
9+
id: string;
10+
/** The type of the data source */
11+
type: string;
12+
/** A list of available versions for this data source */
13+
versions: {
14+
/** The version label of the data source */
15+
label: string;
16+
/** Whether this version is the current/default version */
17+
isCurrent: boolean;
2018
}[];
2119
};
2220

21+
export type ListKnowledgeSourcesResponse = {
22+
dataSources: KnowledgeSource[];
23+
};
24+
2325
export class ListKnowledgeSourcesTool extends AssistantToolBase {
2426
public name = "list-knowledge-sources";
2527
protected description = "List available data sources in the MongoDB Assistant knowledge base";
@@ -50,15 +52,21 @@ export class ListKnowledgeSourcesTool extends AssistantToolBase {
5052
}
5153
const { dataSources } = (await response.json()) as ListKnowledgeSourcesResponse;
5254

55+
const text = yamlStringify(
56+
dataSources.map((ds) => {
57+
const currentVersion = ds.versions.find(({ isCurrent }) => isCurrent)?.label;
58+
if (currentVersion) {
59+
(ds as KnowledgeSource & { currentVersion: string }).currentVersion = currentVersion;
60+
}
61+
return ds;
62+
})
63+
);
64+
5365
return {
54-
content: dataSources.map(({ id, type, versions }) => ({
55-
type: "text",
56-
text: id,
57-
_meta: {
58-
type,
59-
versions,
60-
},
61-
})),
66+
content: formatUntrustedData(
67+
`Found ${dataSources.length} data sources in the MongoDB Assistant knowledge base.`,
68+
text
69+
),
6270
};
6371
}
6472
}

src/tools/assistant/searchKnowledge.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { z } from "zod";
22
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
3-
import { ToolArgs, OperationType } from "../tool.js";
3+
import { type ToolArgs, type OperationType, formatUntrustedData } from "../tool.js";
44
import { AssistantToolBase } from "./assistantTool.js";
55
import { LogId } from "../../common/logger.js";
6+
import { stringify as yamlStringify } from "yaml";
67

78
export const SearchKnowledgeToolArgs = {
89
query: z.string().describe("A natural language query to search for in the knowledge base"),
@@ -71,14 +72,14 @@ export class SearchKnowledgeTool extends AssistantToolBase {
7172
};
7273
}
7374
const { results } = (await response.json()) as SearchKnowledgeResponse;
75+
76+
const text = yamlStringify(results);
77+
7478
return {
75-
content: results.map(({ text, metadata }) => ({
76-
type: "text",
77-
text,
78-
_meta: {
79-
...metadata,
80-
},
81-
})),
79+
content: formatUntrustedData(
80+
`Found ${results.length} results in the MongoDB Assistant knowledge base.`,
81+
text
82+
),
8283
};
8384
}
8485
}

0 commit comments

Comments
 (0)