@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.
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.13",
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
- "publishConfig": {
12
- "access": "public"
13
- },
14
- "bin": {
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
- "prebuild": "node -p \"'// THIS FILE IS GENERATED. DO NOT MODIFY.\\nexport const LIB_VERSION = ' + JSON.stringify(require('./package.json').version) + ';'\" > src/version.ts",
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
- "dependencies": {
28
- "@modelcontextprotocol/sdk": "^1.9.0",
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
- "devDependencies": {
33
- "@types/node": "^22.14.0",
34
- "js-yaml": "^4.1.0",
35
- "typed-openapi": "^0.10.1",
36
- "typescript": "^5.8.3"
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
- "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
35
+ "os": [
36
+ "darwin",
37
+ "linux",
38
+ "win32"
39
+ ],
40
+ "cpu": [
41
+ "x64",
42
+ "arm64"
43
+ ],
44
+ "optionalDependencies": {}
39
45
  }
@@ -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
- });