mongodb-mcp-server 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/code_health.yaml +65 -0
- package/.github/workflows/prepare_release.yaml +45 -0
- package/.github/workflows/publish.yaml +70 -0
- package/.prettierignore +5 -0
- package/.prettierrc.json +37 -0
- package/.vscode/launch.json +17 -0
- package/CONTRIBUTING.md +185 -0
- package/LICENSE +202 -0
- package/README.md +234 -0
- package/dist/common/atlas/apiClient.js +147 -0
- package/dist/common/atlas/apiClient.js.map +1 -0
- package/dist/common/atlas/apiClientError.js +17 -0
- package/dist/common/atlas/apiClientError.js.map +1 -0
- package/dist/config.js +85 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.js +12 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.js +97 -0
- package/dist/logger.js.map +1 -0
- package/dist/server.js +45 -0
- package/dist/server.js.map +1 -0
- package/dist/session.js +30 -0
- package/dist/session.js.map +1 -0
- package/dist/tools/atlas/atlasTool.js +9 -0
- package/dist/tools/atlas/atlasTool.js.map +1 -0
- package/dist/tools/atlas/createAccessList.js +64 -0
- package/dist/tools/atlas/createAccessList.js.map +1 -0
- package/dist/tools/atlas/createDBUser.js +58 -0
- package/dist/tools/atlas/createDBUser.js.map +1 -0
- package/dist/tools/atlas/createFreeCluster.js +51 -0
- package/dist/tools/atlas/createFreeCluster.js.map +1 -0
- package/dist/tools/atlas/createProject.js +53 -0
- package/dist/tools/atlas/createProject.js.map +1 -0
- package/dist/tools/atlas/inspectAccessList.js +41 -0
- package/dist/tools/atlas/inspectAccessList.js.map +1 -0
- package/dist/tools/atlas/inspectCluster.js +42 -0
- package/dist/tools/atlas/inspectCluster.js.map +1 -0
- package/dist/tools/atlas/listClusters.js +97 -0
- package/dist/tools/atlas/listClusters.js.map +1 -0
- package/dist/tools/atlas/listDBUsers.js +52 -0
- package/dist/tools/atlas/listDBUsers.js.map +1 -0
- package/dist/tools/atlas/listOrgs.js +30 -0
- package/dist/tools/atlas/listOrgs.js.map +1 -0
- package/dist/tools/atlas/listProjects.js +42 -0
- package/dist/tools/atlas/listProjects.js.map +1 -0
- package/dist/tools/atlas/tools.js +23 -0
- package/dist/tools/atlas/tools.js.map +1 -0
- package/dist/tools/mongodb/create/createCollection.js +23 -0
- package/dist/tools/mongodb/create/createCollection.js.map +1 -0
- package/dist/tools/mongodb/create/createIndex.js +33 -0
- package/dist/tools/mongodb/create/createIndex.js.map +1 -0
- package/dist/tools/mongodb/create/insertMany.js +33 -0
- package/dist/tools/mongodb/create/insertMany.js.map +1 -0
- package/dist/tools/mongodb/delete/deleteMany.js +31 -0
- package/dist/tools/mongodb/delete/deleteMany.js.map +1 -0
- package/dist/tools/mongodb/delete/dropCollection.js +25 -0
- package/dist/tools/mongodb/delete/dropCollection.js.map +1 -0
- package/dist/tools/mongodb/delete/dropDatabase.js +25 -0
- package/dist/tools/mongodb/delete/dropDatabase.js.map +1 -0
- package/dist/tools/mongodb/metadata/collectionSchema.js +38 -0
- package/dist/tools/mongodb/metadata/collectionSchema.js.map +1 -0
- package/dist/tools/mongodb/metadata/collectionStorageSize.js +28 -0
- package/dist/tools/mongodb/metadata/collectionStorageSize.js.map +1 -0
- package/dist/tools/mongodb/metadata/connect.js +86 -0
- package/dist/tools/mongodb/metadata/connect.js.map +1 -0
- package/dist/tools/mongodb/metadata/dbStats.js +28 -0
- package/dist/tools/mongodb/metadata/dbStats.js.map +1 -0
- package/dist/tools/mongodb/metadata/explain.js +77 -0
- package/dist/tools/mongodb/metadata/explain.js.map +1 -0
- package/dist/tools/mongodb/metadata/listCollections.js +35 -0
- package/dist/tools/mongodb/metadata/listCollections.js.map +1 -0
- package/dist/tools/mongodb/metadata/listDatabases.js +23 -0
- package/dist/tools/mongodb/metadata/listDatabases.js.map +1 -0
- package/dist/tools/mongodb/mongodbTool.js +58 -0
- package/dist/tools/mongodb/mongodbTool.js.map +1 -0
- package/dist/tools/mongodb/read/aggregate.js +38 -0
- package/dist/tools/mongodb/read/aggregate.js.map +1 -0
- package/dist/tools/mongodb/read/collectionIndexes.js +23 -0
- package/dist/tools/mongodb/read/collectionIndexes.js.map +1 -0
- package/dist/tools/mongodb/read/count.js +34 -0
- package/dist/tools/mongodb/read/count.js.map +1 -0
- package/dist/tools/mongodb/read/find.js +51 -0
- package/dist/tools/mongodb/read/find.js.map +1 -0
- package/dist/tools/mongodb/tools.js +41 -0
- package/dist/tools/mongodb/tools.js.map +1 -0
- package/dist/tools/mongodb/update/renameCollection.js +31 -0
- package/dist/tools/mongodb/update/renameCollection.js.map +1 -0
- package/dist/tools/mongodb/update/updateMany.js +56 -0
- package/dist/tools/mongodb/update/updateMany.js.map +1 -0
- package/dist/tools/tool.js +56 -0
- package/dist/tools/tool.js.map +1 -0
- package/eslint.config.js +35 -0
- package/jest.config.js +22 -0
- package/package.json +76 -0
- package/scripts/apply.ts +129 -0
- package/scripts/filter.ts +67 -0
- package/scripts/generate.sh +11 -0
- package/src/common/atlas/apiClient.ts +202 -0
- package/src/common/atlas/apiClientError.ts +21 -0
- package/src/common/atlas/openapi.d.ts +5849 -0
- package/src/config.ts +124 -0
- package/src/errors.ts +13 -0
- package/src/index.ts +30 -0
- package/src/logger.ts +117 -0
- package/src/server.ts +64 -0
- package/src/session.ts +37 -0
- package/src/tools/atlas/atlasTool.ts +10 -0
- package/src/tools/atlas/createAccessList.ts +78 -0
- package/src/tools/atlas/createDBUser.ts +70 -0
- package/src/tools/atlas/createFreeCluster.ts +55 -0
- package/src/tools/atlas/createProject.ts +63 -0
- package/src/tools/atlas/inspectAccessList.ts +44 -0
- package/src/tools/atlas/inspectCluster.ts +47 -0
- package/src/tools/atlas/listClusters.ts +104 -0
- package/src/tools/atlas/listDBUsers.ts +62 -0
- package/src/tools/atlas/listOrgs.ts +34 -0
- package/src/tools/atlas/listProjects.ts +46 -0
- package/src/tools/atlas/tools.ts +23 -0
- package/src/tools/mongodb/create/createCollection.ts +26 -0
- package/src/tools/mongodb/create/createIndex.ts +41 -0
- package/src/tools/mongodb/create/insertMany.ts +40 -0
- package/src/tools/mongodb/delete/deleteMany.ts +38 -0
- package/src/tools/mongodb/delete/dropCollection.ts +27 -0
- package/src/tools/mongodb/delete/dropDatabase.ts +26 -0
- package/src/tools/mongodb/metadata/collectionSchema.ts +41 -0
- package/src/tools/mongodb/metadata/collectionStorageSize.ts +30 -0
- package/src/tools/mongodb/metadata/connect.ts +94 -0
- package/src/tools/mongodb/metadata/dbStats.ts +30 -0
- package/src/tools/mongodb/metadata/explain.ts +90 -0
- package/src/tools/mongodb/metadata/listCollections.ts +38 -0
- package/src/tools/mongodb/metadata/listDatabases.ts +26 -0
- package/src/tools/mongodb/mongodbTool.ts +69 -0
- package/src/tools/mongodb/read/aggregate.ts +45 -0
- package/src/tools/mongodb/read/collectionIndexes.ts +24 -0
- package/src/tools/mongodb/read/count.ts +39 -0
- package/src/tools/mongodb/read/find.ts +62 -0
- package/src/tools/mongodb/tools.ts +41 -0
- package/src/tools/mongodb/update/renameCollection.ts +37 -0
- package/src/tools/mongodb/update/updateMany.ts +65 -0
- package/src/tools/tool.ts +90 -0
- package/src/types/mongodb-redact.d.ts +4 -0
- package/tests/integration/helpers.ts +241 -0
- package/tests/integration/inMemoryTransport.ts +58 -0
- package/tests/integration/server.test.ts +35 -0
- package/tests/integration/tools/atlas/accessLists.test.ts +100 -0
- package/tests/integration/tools/atlas/atlasHelpers.ts +110 -0
- package/tests/integration/tools/atlas/clusters.test.ts +122 -0
- package/tests/integration/tools/atlas/dbUsers.test.ts +80 -0
- package/tests/integration/tools/atlas/orgs.test.ts +24 -0
- package/tests/integration/tools/atlas/projects.test.ts +80 -0
- package/tests/integration/tools/mongodb/create/createCollection.test.ts +138 -0
- package/tests/integration/tools/mongodb/create/createIndex.test.ts +249 -0
- package/tests/integration/tools/mongodb/create/insertMany.test.ts +141 -0
- package/tests/integration/tools/mongodb/delete/deleteMany.test.ts +191 -0
- package/tests/integration/tools/mongodb/delete/dropCollection.test.ts +118 -0
- package/tests/integration/tools/mongodb/delete/dropDatabase.test.ts +114 -0
- package/tests/integration/tools/mongodb/metadata/connect.test.ts +137 -0
- package/tests/integration/tools/mongodb/metadata/listCollections.test.ts +104 -0
- package/tests/integration/tools/mongodb/metadata/listDatabases.test.ts +67 -0
- package/tests/integration/tools/mongodb/read/count.test.ts +138 -0
- package/tsconfig.jest.json +10 -0
- package/tsconfig.json +19 -0
package/scripts/apply.ts
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import fs from "fs/promises";
|
|
2
|
+
import { OpenAPIV3_1 } from "openapi-types";
|
|
3
|
+
import argv from "yargs-parser";
|
|
4
|
+
|
|
5
|
+
function findObjectFromRef<T>(obj: T | OpenAPIV3_1.ReferenceObject, openapi: OpenAPIV3_1.Document): T {
|
|
6
|
+
const ref = (obj as OpenAPIV3_1.ReferenceObject).$ref;
|
|
7
|
+
if (ref === undefined) {
|
|
8
|
+
return obj as T;
|
|
9
|
+
}
|
|
10
|
+
const paramParts = ref.split("/");
|
|
11
|
+
paramParts.shift(); // Remove the first part which is always '#'
|
|
12
|
+
let foundObj: any = openapi; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
13
|
+
while (true) {
|
|
14
|
+
const part = paramParts.shift();
|
|
15
|
+
if (!part) {
|
|
16
|
+
break;
|
|
17
|
+
}
|
|
18
|
+
foundObj = foundObj[part];
|
|
19
|
+
}
|
|
20
|
+
return foundObj as T;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function main() {
|
|
24
|
+
const { spec, file } = argv(process.argv.slice(2));
|
|
25
|
+
|
|
26
|
+
if (!spec || !file) {
|
|
27
|
+
console.error("Please provide both --spec and --file arguments.");
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const specFile = (await fs.readFile(spec, "utf8")) as string;
|
|
32
|
+
|
|
33
|
+
const operations: {
|
|
34
|
+
path: string;
|
|
35
|
+
method: string;
|
|
36
|
+
operationId: string;
|
|
37
|
+
requiredParams: boolean;
|
|
38
|
+
tag: string;
|
|
39
|
+
hasResponseBody: boolean;
|
|
40
|
+
}[] = [];
|
|
41
|
+
|
|
42
|
+
const openapi = JSON.parse(specFile) as OpenAPIV3_1.Document;
|
|
43
|
+
for (const path in openapi.paths) {
|
|
44
|
+
for (const method in openapi.paths[path]) {
|
|
45
|
+
const operation: OpenAPIV3_1.OperationObject = openapi.paths[path][method];
|
|
46
|
+
|
|
47
|
+
if (!operation.operationId || !operation.tags?.length) {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let requiredParams = !!operation.requestBody;
|
|
52
|
+
let hasResponseBody = false;
|
|
53
|
+
for (const code in operation.responses) {
|
|
54
|
+
try {
|
|
55
|
+
const httpCode = parseInt(code, 10);
|
|
56
|
+
if (httpCode >= 200 && httpCode < 300) {
|
|
57
|
+
const response = operation.responses[code];
|
|
58
|
+
const responseObject = findObjectFromRef(response, openapi);
|
|
59
|
+
if (responseObject.content) {
|
|
60
|
+
for (const contentType in responseObject.content) {
|
|
61
|
+
const content = responseObject.content[contentType];
|
|
62
|
+
hasResponseBody = !!content.schema;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
} catch {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
for (const param of operation.parameters || []) {
|
|
72
|
+
const paramObject = findObjectFromRef(param, openapi);
|
|
73
|
+
if (paramObject.in === "path") {
|
|
74
|
+
requiredParams = true;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
operations.push({
|
|
79
|
+
path,
|
|
80
|
+
method: method.toUpperCase(),
|
|
81
|
+
operationId: operation.operationId || "",
|
|
82
|
+
requiredParams,
|
|
83
|
+
hasResponseBody,
|
|
84
|
+
tag: operation.tags[0],
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const operationOutput = operations
|
|
90
|
+
.map((operation) => {
|
|
91
|
+
const { operationId, method, path, requiredParams, hasResponseBody } = operation;
|
|
92
|
+
return `async ${operationId}(options${requiredParams ? "" : "?"}: FetchOptions<operations["${operationId}"]>) {
|
|
93
|
+
${hasResponseBody ? `const { data } = ` : ``}await this.client.${method}("${path}", options);
|
|
94
|
+
${
|
|
95
|
+
hasResponseBody
|
|
96
|
+
? `return data;
|
|
97
|
+
`
|
|
98
|
+
: ``
|
|
99
|
+
}}
|
|
100
|
+
`;
|
|
101
|
+
})
|
|
102
|
+
.join("\n");
|
|
103
|
+
|
|
104
|
+
const templateFile = (await fs.readFile(file, "utf8")) as string;
|
|
105
|
+
const templateLines = templateFile.split("\n");
|
|
106
|
+
let outputLines: string[] = [];
|
|
107
|
+
let addLines = true;
|
|
108
|
+
for (const line of templateLines) {
|
|
109
|
+
if (line.includes("DO NOT EDIT. This is auto-generated code.")) {
|
|
110
|
+
addLines = !addLines;
|
|
111
|
+
outputLines.push(line);
|
|
112
|
+
if (!addLines) {
|
|
113
|
+
outputLines.push(operationOutput);
|
|
114
|
+
}
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (addLines) {
|
|
118
|
+
outputLines.push(line);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const output = outputLines.join("\n");
|
|
122
|
+
|
|
123
|
+
await fs.writeFile(file, output, "utf8");
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
main().catch((error) => {
|
|
127
|
+
console.error("Error:", error);
|
|
128
|
+
process.exit(1);
|
|
129
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { OpenAPIV3_1 } from "openapi-types";
|
|
2
|
+
|
|
3
|
+
async function readStdin() {
|
|
4
|
+
return new Promise<string>((resolve, reject) => {
|
|
5
|
+
let data = "";
|
|
6
|
+
process.stdin.setEncoding("utf8");
|
|
7
|
+
process.stdin.on("error", (err) => {
|
|
8
|
+
reject(err);
|
|
9
|
+
});
|
|
10
|
+
process.stdin.on("data", (chunk) => {
|
|
11
|
+
data += chunk;
|
|
12
|
+
});
|
|
13
|
+
process.stdin.on("end", () => {
|
|
14
|
+
resolve(data);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function filterOpenapi(openapi: OpenAPIV3_1.Document): OpenAPIV3_1.Document {
|
|
20
|
+
const allowedOperations = [
|
|
21
|
+
"listProjects",
|
|
22
|
+
"listOrganizations",
|
|
23
|
+
"getProject",
|
|
24
|
+
"createProject",
|
|
25
|
+
"deleteProject",
|
|
26
|
+
"listClusters",
|
|
27
|
+
"getCluster",
|
|
28
|
+
"createCluster",
|
|
29
|
+
"deleteCluster",
|
|
30
|
+
"listClustersForAllProjects",
|
|
31
|
+
"createDatabaseUser",
|
|
32
|
+
"deleteDatabaseUser",
|
|
33
|
+
"listDatabaseUsers",
|
|
34
|
+
"listProjectIpAccessLists",
|
|
35
|
+
"createProjectIpAccessList",
|
|
36
|
+
"deleteProjectIpAccessList",
|
|
37
|
+
"listOrganizationProjects",
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
const filteredPaths = {};
|
|
41
|
+
|
|
42
|
+
for (const path in openapi.paths) {
|
|
43
|
+
const filteredMethods = {} as OpenAPIV3_1.PathItemObject;
|
|
44
|
+
for (const method in openapi.paths[path]) {
|
|
45
|
+
if (allowedOperations.includes(openapi.paths[path][method].operationId)) {
|
|
46
|
+
filteredMethods[method] = openapi.paths[path][method];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (Object.keys(filteredMethods).length > 0) {
|
|
50
|
+
filteredPaths[path] = filteredMethods;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return { ...openapi, paths: filteredPaths };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function main() {
|
|
58
|
+
const openapiText = await readStdin();
|
|
59
|
+
const openapi = JSON.parse(openapiText) as OpenAPIV3_1.Document;
|
|
60
|
+
const filteredOpenapi = filterOpenapi(openapi);
|
|
61
|
+
console.log(JSON.stringify(filteredOpenapi));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
main().catch((error) => {
|
|
65
|
+
console.error("Error:", error);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
set -Eeou pipefail
|
|
4
|
+
|
|
5
|
+
curl -Lo ./scripts/spec.json https://github.com/mongodb/openapi/raw/refs/heads/main/openapi/v2/openapi-2025-03-12.json
|
|
6
|
+
tsx ./scripts/filter.ts > ./scripts/filteredSpec.json < ./scripts/spec.json
|
|
7
|
+
redocly bundle --ext json --remove-unused-components ./scripts/filteredSpec.json --output ./scripts/bundledSpec.json
|
|
8
|
+
openapi-typescript ./scripts/bundledSpec.json --root-types-no-schema-prefix --root-types --output ./src/common/atlas/openapi.d.ts
|
|
9
|
+
tsx ./scripts/apply.ts --spec ./scripts/bundledSpec.json --file ./src/common/atlas/apiClient.ts
|
|
10
|
+
prettier --write ./src/common/atlas/openapi.d.ts ./src/common/atlas/apiClient.ts
|
|
11
|
+
rm -rf ./scripts/bundledSpec.json ./scripts/filteredSpec.json ./scripts/spec.json
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import config from "../../config.js";
|
|
2
|
+
import createClient, { Client, FetchOptions, Middleware } from "openapi-fetch";
|
|
3
|
+
import { AccessToken, ClientCredentials } from "simple-oauth2";
|
|
4
|
+
import { ApiClientError } from "./apiClientError.js";
|
|
5
|
+
import { paths, operations } from "./openapi.js";
|
|
6
|
+
|
|
7
|
+
const ATLAS_API_VERSION = "2025-03-12";
|
|
8
|
+
|
|
9
|
+
export interface ApiClientOptions {
|
|
10
|
+
credentials?: {
|
|
11
|
+
clientId: string;
|
|
12
|
+
clientSecret: string;
|
|
13
|
+
};
|
|
14
|
+
baseUrl?: string;
|
|
15
|
+
userAgent?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class ApiClient {
|
|
19
|
+
private options: {
|
|
20
|
+
baseUrl: string;
|
|
21
|
+
userAgent: string;
|
|
22
|
+
credentials?: {
|
|
23
|
+
clientId: string;
|
|
24
|
+
clientSecret: string;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
private client: Client<paths>;
|
|
28
|
+
private oauth2Client?: ClientCredentials;
|
|
29
|
+
private accessToken?: AccessToken;
|
|
30
|
+
|
|
31
|
+
private getAccessToken = async () => {
|
|
32
|
+
if (this.oauth2Client && (!this.accessToken || this.accessToken.expired())) {
|
|
33
|
+
this.accessToken = await this.oauth2Client.getToken({});
|
|
34
|
+
}
|
|
35
|
+
return this.accessToken?.token.access_token as string | undefined;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
private authMiddleware: Middleware = {
|
|
39
|
+
onRequest: async ({ request, schemaPath }) => {
|
|
40
|
+
if (schemaPath.startsWith("/api/private/unauth") || schemaPath.startsWith("/api/oauth")) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
const accessToken = await this.getAccessToken();
|
|
46
|
+
request.headers.set("Authorization", `Bearer ${accessToken}`);
|
|
47
|
+
return request;
|
|
48
|
+
} catch {
|
|
49
|
+
// ignore not availble tokens, API will return 401
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
private readonly errorMiddleware: Middleware = {
|
|
55
|
+
async onResponse({ response }) {
|
|
56
|
+
if (!response.ok) {
|
|
57
|
+
throw await ApiClientError.fromResponse(response);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
constructor(options?: ApiClientOptions) {
|
|
63
|
+
this.options = {
|
|
64
|
+
...options,
|
|
65
|
+
baseUrl: options?.baseUrl || "https://cloud.mongodb.com/",
|
|
66
|
+
userAgent:
|
|
67
|
+
options?.userAgent ||
|
|
68
|
+
`AtlasMCP/${config.version} (${process.platform}; ${process.arch}; ${process.env.HOSTNAME || "unknown"})`,
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
this.client = createClient<paths>({
|
|
72
|
+
baseUrl: this.options.baseUrl,
|
|
73
|
+
headers: {
|
|
74
|
+
"User-Agent": this.options.userAgent,
|
|
75
|
+
Accept: `application/vnd.atlas.${ATLAS_API_VERSION}+json`,
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
if (this.options.credentials?.clientId && this.options.credentials?.clientSecret) {
|
|
79
|
+
this.oauth2Client = new ClientCredentials({
|
|
80
|
+
client: {
|
|
81
|
+
id: this.options.credentials.clientId,
|
|
82
|
+
secret: this.options.credentials.clientSecret,
|
|
83
|
+
},
|
|
84
|
+
auth: {
|
|
85
|
+
tokenHost: this.options.baseUrl,
|
|
86
|
+
tokenPath: "/api/oauth/token",
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
this.client.use(this.authMiddleware);
|
|
90
|
+
}
|
|
91
|
+
this.client.use(this.errorMiddleware);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public async getIpInfo(): Promise<{
|
|
95
|
+
currentIpv4Address: string;
|
|
96
|
+
}> {
|
|
97
|
+
const accessToken = await this.getAccessToken();
|
|
98
|
+
|
|
99
|
+
const endpoint = "api/private/ipinfo";
|
|
100
|
+
const url = new URL(endpoint, this.options.baseUrl);
|
|
101
|
+
const response = await fetch(url, {
|
|
102
|
+
method: "GET",
|
|
103
|
+
headers: {
|
|
104
|
+
Accept: "application/json",
|
|
105
|
+
Authorization: `Bearer ${accessToken}`,
|
|
106
|
+
"User-Agent": this.options.userAgent,
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
if (!response.ok) {
|
|
111
|
+
throw await ApiClientError.fromResponse(response);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return (await response.json()) as Promise<{
|
|
115
|
+
currentIpv4Address: string;
|
|
116
|
+
}>;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// DO NOT EDIT. This is auto-generated code.
|
|
120
|
+
async listClustersForAllProjects(options?: FetchOptions<operations["listClustersForAllProjects"]>) {
|
|
121
|
+
const { data } = await this.client.GET("/api/atlas/v2/clusters", options);
|
|
122
|
+
return data;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async listProjects(options?: FetchOptions<operations["listProjects"]>) {
|
|
126
|
+
const { data } = await this.client.GET("/api/atlas/v2/groups", options);
|
|
127
|
+
return data;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async createProject(options: FetchOptions<operations["createProject"]>) {
|
|
131
|
+
const { data } = await this.client.POST("/api/atlas/v2/groups", options);
|
|
132
|
+
return data;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async deleteProject(options: FetchOptions<operations["deleteProject"]>) {
|
|
136
|
+
await this.client.DELETE("/api/atlas/v2/groups/{groupId}", options);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async getProject(options: FetchOptions<operations["getProject"]>) {
|
|
140
|
+
const { data } = await this.client.GET("/api/atlas/v2/groups/{groupId}", options);
|
|
141
|
+
return data;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async listProjectIpAccessLists(options: FetchOptions<operations["listProjectIpAccessLists"]>) {
|
|
145
|
+
const { data } = await this.client.GET("/api/atlas/v2/groups/{groupId}/accessList", options);
|
|
146
|
+
return data;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async createProjectIpAccessList(options: FetchOptions<operations["createProjectIpAccessList"]>) {
|
|
150
|
+
const { data } = await this.client.POST("/api/atlas/v2/groups/{groupId}/accessList", options);
|
|
151
|
+
return data;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async deleteProjectIpAccessList(options: FetchOptions<operations["deleteProjectIpAccessList"]>) {
|
|
155
|
+
await this.client.DELETE("/api/atlas/v2/groups/{groupId}/accessList/{entryValue}", options);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async listClusters(options: FetchOptions<operations["listClusters"]>) {
|
|
159
|
+
const { data } = await this.client.GET("/api/atlas/v2/groups/{groupId}/clusters", options);
|
|
160
|
+
return data;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
async createCluster(options: FetchOptions<operations["createCluster"]>) {
|
|
164
|
+
const { data } = await this.client.POST("/api/atlas/v2/groups/{groupId}/clusters", options);
|
|
165
|
+
return data;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async deleteCluster(options: FetchOptions<operations["deleteCluster"]>) {
|
|
169
|
+
await this.client.DELETE("/api/atlas/v2/groups/{groupId}/clusters/{clusterName}", options);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
async getCluster(options: FetchOptions<operations["getCluster"]>) {
|
|
173
|
+
const { data } = await this.client.GET("/api/atlas/v2/groups/{groupId}/clusters/{clusterName}", options);
|
|
174
|
+
return data;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async listDatabaseUsers(options: FetchOptions<operations["listDatabaseUsers"]>) {
|
|
178
|
+
const { data } = await this.client.GET("/api/atlas/v2/groups/{groupId}/databaseUsers", options);
|
|
179
|
+
return data;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
async createDatabaseUser(options: FetchOptions<operations["createDatabaseUser"]>) {
|
|
183
|
+
const { data } = await this.client.POST("/api/atlas/v2/groups/{groupId}/databaseUsers", options);
|
|
184
|
+
return data;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
async deleteDatabaseUser(options: FetchOptions<operations["deleteDatabaseUser"]>) {
|
|
188
|
+
await this.client.DELETE("/api/atlas/v2/groups/{groupId}/databaseUsers/{databaseName}/{username}", options);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async listOrganizations(options?: FetchOptions<operations["listOrganizations"]>) {
|
|
192
|
+
const { data } = await this.client.GET("/api/atlas/v2/orgs", options);
|
|
193
|
+
return data;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async listOrganizationProjects(options: FetchOptions<operations["listOrganizationProjects"]>) {
|
|
197
|
+
const { data } = await this.client.GET("/api/atlas/v2/orgs/{orgId}/groups", options);
|
|
198
|
+
return data;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// DO NOT EDIT. This is auto-generated code.
|
|
202
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export class ApiClientError extends Error {
|
|
2
|
+
response?: Response;
|
|
3
|
+
|
|
4
|
+
constructor(message: string, response: Response | undefined = undefined) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = "ApiClientError";
|
|
7
|
+
this.response = response;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
static async fromResponse(
|
|
11
|
+
response: Response,
|
|
12
|
+
message: string = `error calling Atlas API`
|
|
13
|
+
): Promise<ApiClientError> {
|
|
14
|
+
try {
|
|
15
|
+
const text = await response.text();
|
|
16
|
+
return new ApiClientError(`${message}: [${response.status} ${response.statusText}] ${text}`, response);
|
|
17
|
+
} catch {
|
|
18
|
+
return new ApiClientError(`${message}: ${response.status} ${response.statusText}`, response);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|