@digitalocean/mcp 0.0.13 → 1.0.0-aplha.1
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/README.md +2 -190
- package/dist/app-create-schema.json +1946 -0
- package/dist/app-update-schema.json +1957 -0
- package/dist/mcp-digitalocean-darwin-amd64 +0 -0
- package/dist/mcp-digitalocean-darwin-arm64 +0 -0
- package/dist/mcp-digitalocean-linux-386 +0 -0
- package/dist/mcp-digitalocean-linux-amd64 +0 -0
- package/dist/mcp-digitalocean-linux-arm +0 -0
- package/dist/mcp-digitalocean-linux-arm64 +0 -0
- package/dist/mcp-digitalocean-windows-386.exe +0 -0
- package/dist/mcp-digitalocean-windows-amd64.exe +0 -0
- package/dist/mcp-digitalocean-windows-arm.exe +0 -0
- package/dist/mcp-digitalocean-windows-arm64.exe +0 -0
- package/index.js +87 -0
- package/package.json +35 -29
- package/build/DOMcpServer.js +0 -18
- package/build/api.js +0 -95
- package/build/index.js +0 -18
- package/build/index.js.map +0 -7
- package/build/logger.js +0 -47
- package/build/server.js +0 -29
- package/build/specs/digitalocean-openapi.yaml.zod.js +0 -10231
- package/build/tools/app.js +0 -613
- package/build/tools/databases.js +0 -306
- package/build/version.js +0 -5
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/index.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const path = require('path')
|
|
4
|
+
const fs = require('fs')
|
|
5
|
+
const childProcess = require('child_process')
|
|
6
|
+
const os = require('os')
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Run the platform-specific executable with the given arguments
|
|
10
|
+
* @param {string[]} args Arguments to pass to the executable
|
|
11
|
+
* @returns {Promise<number>} Returns a Promise that resolves to the exit code
|
|
12
|
+
*/
|
|
13
|
+
function runExecutable(args = []) {
|
|
14
|
+
try {
|
|
15
|
+
// Check for verbose flag
|
|
16
|
+
const verbose = args.includes('--verbose')
|
|
17
|
+
|
|
18
|
+
// Helper function to log only in verbose mode
|
|
19
|
+
const verboseLog = (message) => {
|
|
20
|
+
if (verbose) {
|
|
21
|
+
console.error(message)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const packageJson = require('./package.json')
|
|
26
|
+
|
|
27
|
+
const platform = os.platform()
|
|
28
|
+
const arch = os.arch()
|
|
29
|
+
|
|
30
|
+
verboseLog(`Detected platform: ${platform}`)
|
|
31
|
+
verboseLog(`Detected architecture: ${arch}`)
|
|
32
|
+
|
|
33
|
+
const binKey = `mcp-digitalocean-${platform}-${arch}`;
|
|
34
|
+
const execName = packageJson["mcp-server-binaries"][binKey]
|
|
35
|
+
|
|
36
|
+
// Some error messages should always show regardless of verbose mode
|
|
37
|
+
if (!execName) {
|
|
38
|
+
console.error(`No executable found for platform: ${platform}-${arch}`)
|
|
39
|
+
return Promise.resolve(1)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
verboseLog(`Found executable in package.json: ${execName}`)
|
|
43
|
+
|
|
44
|
+
// The platform-specific executable should be in the same folder
|
|
45
|
+
const execPath = path.join(__dirname, execName)
|
|
46
|
+
verboseLog(`Executable path: ${execPath}`)
|
|
47
|
+
|
|
48
|
+
if (!fs.existsSync(execPath)) {
|
|
49
|
+
console.error(`Executable "${execPath}" not found.`)
|
|
50
|
+
return Promise.resolve(1)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
verboseLog(`Starting ${execPath}`)
|
|
54
|
+
|
|
55
|
+
// Remove verbose flag before passing args to the child process
|
|
56
|
+
const childArgs = args.filter(arg => arg !== '--verbose')
|
|
57
|
+
|
|
58
|
+
const child = childProcess.spawn(execPath, childArgs, {
|
|
59
|
+
stdio: 'inherit',
|
|
60
|
+
shell: false
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
return new Promise((resolve) => {
|
|
64
|
+
child.on('error', (err) => {
|
|
65
|
+
console.error(`Error executing package: ${err.message}`)
|
|
66
|
+
resolve(1)
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
child.on('exit', (code) => {
|
|
70
|
+
resolve(code || 0)
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
} catch (err) {
|
|
74
|
+
console.error(`Error running executable: ${err.message}`)
|
|
75
|
+
return Promise.resolve(1)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Check if this file is being run directly
|
|
80
|
+
if (require.main === module) {
|
|
81
|
+
// Run the executable with command line args and exit with its code
|
|
82
|
+
runExecutable(process.argv.slice(2))
|
|
83
|
+
.then(code => process.exit(code))
|
|
84
|
+
} else {
|
|
85
|
+
// Export the function for consumers to use
|
|
86
|
+
module.exports = { runExecutable }
|
|
87
|
+
}
|
package/package.json
CHANGED
|
@@ -1,39 +1,45 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@digitalocean/mcp",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "DigitalOcean MCP",
|
|
5
|
-
"repository": {
|
|
6
|
-
"type": "git",
|
|
7
|
-
"url": "https://github.com/digitalocean/digitalocean-mcp"
|
|
8
|
-
},
|
|
3
|
+
"version": "1.0.0-aplha.1",
|
|
4
|
+
"description": "DigitalOcean MCP Implementation,",
|
|
9
5
|
"author": "DigitalOcean",
|
|
6
|
+
"homepage": "https://github.com/digitalocean-labs/mcp-digitalocean?tab=readme-ov-file#mcp-digitalocean-integration",
|
|
10
7
|
"license": "MIT",
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"mcp": "build/index.js"
|
|
16
|
-
},
|
|
17
|
-
"files": [
|
|
18
|
-
"build"
|
|
8
|
+
"keywords": [
|
|
9
|
+
"digitalocean",
|
|
10
|
+
"mcp",
|
|
11
|
+
"model-context-protocol"
|
|
19
12
|
],
|
|
13
|
+
"bin": "./index.js",
|
|
20
14
|
"scripts": {
|
|
21
|
-
"
|
|
22
|
-
"build": "tsc",
|
|
23
|
-
"dev": "tsc --watch",
|
|
24
|
-
"start:stdio": "node build/index.js",
|
|
25
|
-
"generate:schema": "npx typed-openapi src/specs/digitalocean-openapi.yaml -r zod"
|
|
15
|
+
"mcp-golang": "node ./index.js"
|
|
26
16
|
},
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"dotenv": "^16.5.0",
|
|
30
|
-
"zod": "^3.24.2"
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/digitalocean-labs/mcp-digitalocean?tab=readme-ov-file#mcp-digitalocean-integration"
|
|
31
19
|
},
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git@github.com:digitalocean-labs/mcp-digitalocean.git"
|
|
23
|
+
},
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=18.0.0"
|
|
26
|
+
},
|
|
27
|
+
"mcp-server-binaries": {
|
|
28
|
+
"mcp-digitalocean-darwin-arm64": "./dist/mcp-digitalocean-darwin-arm64",
|
|
29
|
+
"mcp-digitalocean-darwin-amd64": "./dist/mcp-digitalocean-darwin-amd64",
|
|
30
|
+
"mcp-digitalocean-linux-arm64": "./dist/mcp-digitalocean-linux-arm64",
|
|
31
|
+
"mcp-digitalocean-linux-amd64": "./dist/mcp-digitalocean-linux-amd64",
|
|
32
|
+
"mcp-digitalocean-win32-arm64": "./dist/mcp-digitalocean-windows-arm64",
|
|
33
|
+
"mcp-digitalocean-win32-amd64": "./dist/mcp-digitalocean-windows-amd64"
|
|
37
34
|
},
|
|
38
|
-
"
|
|
35
|
+
"os": [
|
|
36
|
+
"darwin",
|
|
37
|
+
"linux",
|
|
38
|
+
"win32"
|
|
39
|
+
],
|
|
40
|
+
"cpu": [
|
|
41
|
+
"x64",
|
|
42
|
+
"arm64"
|
|
43
|
+
],
|
|
44
|
+
"optionalDependencies": {}
|
|
39
45
|
}
|
package/build/DOMcpServer.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DOMcpServer = void 0;
|
|
4
|
-
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
5
|
-
class DOMcpServer extends mcp_js_1.McpServer {
|
|
6
|
-
constructor(serverInfo, options) {
|
|
7
|
-
super(serverInfo, options);
|
|
8
|
-
}
|
|
9
|
-
registerTool({ name, description, parameters, cb, }) {
|
|
10
|
-
if (parameters) {
|
|
11
|
-
this.tool(name, description, parameters, cb);
|
|
12
|
-
}
|
|
13
|
-
else {
|
|
14
|
-
this.tool(name, description, cb);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
exports.DOMcpServer = DOMcpServer;
|
package/build/api.js
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.DigitalOceanApiError = void 0;
|
|
7
|
-
exports.createClient = createClient;
|
|
8
|
-
const digitalocean_openapi_yaml_zod_1 = require("./specs/digitalocean-openapi.yaml.zod");
|
|
9
|
-
const logger_1 = __importDefault(require("./logger"));
|
|
10
|
-
const version_1 = require("./version");
|
|
11
|
-
const BASE_URL = "https://api.digitalocean.com";
|
|
12
|
-
function getToken() {
|
|
13
|
-
const token = process.env.DIGITALOCEAN_API_TOKEN;
|
|
14
|
-
if (!token) {
|
|
15
|
-
throw new Error("DIGITALOCEAN_API_TOKEN is not set");
|
|
16
|
-
}
|
|
17
|
-
return token;
|
|
18
|
-
}
|
|
19
|
-
function parsePath(path, pathParams = {}) {
|
|
20
|
-
// extract the path params from the path. Each params will be in the form {param_name}
|
|
21
|
-
const pathParts = path.split("/");
|
|
22
|
-
const newParts = pathParts.map((part) => {
|
|
23
|
-
if (part.startsWith("{") && part.endsWith("}")) {
|
|
24
|
-
const key = part.slice(1, -1);
|
|
25
|
-
return pathParams[key] || part;
|
|
26
|
-
}
|
|
27
|
-
return part;
|
|
28
|
-
});
|
|
29
|
-
return newParts.join("/");
|
|
30
|
-
}
|
|
31
|
-
function createClient(params = {}) {
|
|
32
|
-
const token = getToken();
|
|
33
|
-
const sharedHeaders = {
|
|
34
|
-
"User-Agent": `digitalocean-mcp/${version_1.LIB_VERSION}`,
|
|
35
|
-
Authorization: `Bearer ${token}`,
|
|
36
|
-
"Content-Type": "application/json",
|
|
37
|
-
Accept: "application/json",
|
|
38
|
-
};
|
|
39
|
-
const client = (0, digitalocean_openapi_yaml_zod_1.createApiClient)(async (method, url, params) => {
|
|
40
|
-
const queryString = new URLSearchParams(params?.query).toString();
|
|
41
|
-
const _headers = {
|
|
42
|
-
...sharedHeaders,
|
|
43
|
-
...params?.header,
|
|
44
|
-
};
|
|
45
|
-
const _url = parsePath(url, params?.path);
|
|
46
|
-
const urlWithQuery = queryString ? `${_url}?${queryString}` : _url;
|
|
47
|
-
const body = params?.body && !["GET", "HEAD"].includes(method)
|
|
48
|
-
? JSON.stringify(params?.body)
|
|
49
|
-
: undefined;
|
|
50
|
-
const res = await fetch(urlWithQuery, {
|
|
51
|
-
method,
|
|
52
|
-
headers: _headers,
|
|
53
|
-
body,
|
|
54
|
-
});
|
|
55
|
-
if (res.status !== 200) {
|
|
56
|
-
const errorObj = (await res.json());
|
|
57
|
-
if (errorObj.id) {
|
|
58
|
-
const error = DigitalOceanApiError.fromResponse(errorObj);
|
|
59
|
-
logger_1.default.error(`API Error: ${method.toUpperCase()} ${urlWithQuery} ${error.message}`);
|
|
60
|
-
throw error;
|
|
61
|
-
}
|
|
62
|
-
throw new Error(`${res.status} ${res.statusText}`);
|
|
63
|
-
}
|
|
64
|
-
const responseContentType = res.headers.get("content-type");
|
|
65
|
-
if (responseContentType?.includes("application/json")) {
|
|
66
|
-
return res.json();
|
|
67
|
-
}
|
|
68
|
-
else if (responseContentType?.includes("text/")) {
|
|
69
|
-
return res.text();
|
|
70
|
-
}
|
|
71
|
-
else if (responseContentType?.includes("application/octet-stream")) {
|
|
72
|
-
return res.blob();
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
return res.text();
|
|
76
|
-
}
|
|
77
|
-
}, BASE_URL);
|
|
78
|
-
return { client };
|
|
79
|
-
}
|
|
80
|
-
class DigitalOceanApiError extends Error {
|
|
81
|
-
id;
|
|
82
|
-
message;
|
|
83
|
-
static fromResponse(response) {
|
|
84
|
-
return new DigitalOceanApiError(response.id, response.message);
|
|
85
|
-
}
|
|
86
|
-
static isDigitalOceanApiError(error) {
|
|
87
|
-
return error instanceof DigitalOceanApiError;
|
|
88
|
-
}
|
|
89
|
-
constructor(id, message) {
|
|
90
|
-
super(message);
|
|
91
|
-
this.id = id;
|
|
92
|
-
this.message = message;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
exports.DigitalOceanApiError = DigitalOceanApiError;
|
package/build/index.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
-
};
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
const logger_1 = __importDefault(require("./logger"));
|
|
8
|
-
const server_1 = require("./server");
|
|
9
|
-
const dotenv_1 = __importDefault(require("dotenv"));
|
|
10
|
-
dotenv_1.default.config();
|
|
11
|
-
async function main() {
|
|
12
|
-
const server = (0, server_1.createServer)();
|
|
13
|
-
(0, server_1.startStdioServer)(server);
|
|
14
|
-
}
|
|
15
|
-
main().catch((error) => {
|
|
16
|
-
logger_1.default.error("Error starting server:", error.message);
|
|
17
|
-
process.exit(1);
|
|
18
|
-
});
|