@vibetools/dokploy-mcp 1.0.0 → 1.2.0
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 +20 -14
- package/dist/api/client.d.ts +2 -0
- package/dist/api/client.js +44 -11
- package/dist/tools/_database.js +25 -6
- package/dist/tools/_factory.d.ts +2 -0
- package/dist/tools/_factory.js +21 -4
- package/dist/tools/application.js +219 -82
- package/dist/tools/backup.js +30 -0
- package/dist/tools/compose.js +273 -35
- package/dist/tools/deployment.js +82 -2
- package/dist/tools/docker.js +62 -2
- package/dist/tools/domain.js +15 -2
- package/dist/tools/environment.d.ts +2 -0
- package/dist/tools/environment.js +104 -0
- package/dist/tools/git-provider.d.ts +2 -0
- package/dist/tools/git-provider.js +22 -0
- package/dist/tools/github.d.ts +2 -0
- package/dist/tools/github.js +66 -0
- package/dist/tools/gitlab.d.ts +2 -0
- package/dist/tools/gitlab.js +98 -0
- package/dist/tools/index.js +24 -0
- package/dist/tools/mariadb.js +1 -1
- package/dist/tools/mongo.js +2 -1
- package/dist/tools/mounts.js +53 -9
- package/dist/tools/mysql.js +1 -1
- package/dist/tools/notification.d.ts +2 -0
- package/dist/tools/notification.js +559 -0
- package/dist/tools/patch.d.ts +2 -0
- package/dist/tools/patch.js +179 -0
- package/dist/tools/postgres.js +1 -1
- package/dist/tools/preview-deployment.d.ts +2 -0
- package/dist/tools/preview-deployment.js +50 -0
- package/dist/tools/project.js +32 -1
- package/dist/tools/redis.js +1 -1
- package/dist/tools/rollback.d.ts +2 -0
- package/dist/tools/rollback.js +28 -0
- package/dist/tools/schedule.d.ts +2 -0
- package/dist/tools/schedule.js +92 -0
- package/dist/tools/server.d.ts +2 -0
- package/dist/tools/server.js +192 -0
- package/dist/tools/settings.js +251 -0
- package/dist/tools/ssh-key.d.ts +2 -0
- package/dist/tools/ssh-key.js +74 -0
- package/dist/tools/user.js +75 -2
- package/dist/tools/volume-backups.d.ts +2 -0
- package/dist/tools/volume-backups.js +96 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
[](https://nodejs.org/)
|
|
6
6
|
|
|
7
|
-
MCP server for the Dokploy API.
|
|
7
|
+
MCP server for the Dokploy API. 377 tools across 35 modules. Your AI agent can now deploy apps, manage databases, configure domains, and handle backups -- without you touching a dashboard.
|
|
8
8
|
|
|
9
|
-
Forked from [Dokploy/mcp](https://github.com/Dokploy/mcp) and rebuilt with expanded API coverage, tool annotations, Zod v4 schemas, lazy config loading, and a setup wizard. The original had 67 tools. This one has
|
|
9
|
+
Forked from [Dokploy/mcp](https://github.com/Dokploy/mcp) and rebuilt with expanded API coverage, tool annotations, Zod v4 schemas, lazy config loading, and a setup wizard. The original had 67 tools. This one has 377. Standing on shoulders, etc.
|
|
10
10
|
|
|
11
11
|
## Quick Start
|
|
12
12
|
|
|
@@ -45,7 +45,7 @@ If you already have the [Dokploy CLI](https://github.com/Dokploy/cli) installed
|
|
|
45
45
|
|
|
46
46
|
## Features
|
|
47
47
|
|
|
48
|
-
- **
|
|
48
|
+
- **377 tools, 35 modules** -- applications, compose, environments, servers, Git providers, notifications, databases (Postgres/MySQL/MariaDB/MongoDB/Redis), domains, backups, deployment queues, rollback, patching, Docker, settings, preview deployments, schedules, and more
|
|
49
49
|
- **Tool annotations** -- `readOnlyHint`, `destructiveHint`, `idempotentHint` so clients can warn before you nuke something
|
|
50
50
|
- **Type-safe schemas** -- Zod v4 validation on every parameter
|
|
51
51
|
- **Lazy config loading** -- validates credentials on first API call, not at startup
|
|
@@ -136,18 +136,24 @@ Already ran `setup` or have Dokploy CLI authenticated? Drop the `env` block enti
|
|
|
136
136
|
|
|
137
137
|
| Module | Tools | Module | Tools |
|
|
138
138
|
|--------|-------|--------|-------|
|
|
139
|
-
| Project |
|
|
140
|
-
|
|
|
141
|
-
|
|
|
142
|
-
|
|
|
143
|
-
|
|
|
144
|
-
|
|
|
145
|
-
|
|
|
146
|
-
|
|
|
147
|
-
|
|
|
139
|
+
| Project | 8 | Deployment | 8 |
|
|
140
|
+
| Environment | 7 | Docker | 7 |
|
|
141
|
+
| Application | 29 | Server | 16 |
|
|
142
|
+
| Compose | 28 | Certificates | 4 |
|
|
143
|
+
| Domain | 9 | Registry | 6 |
|
|
144
|
+
| Patch | 12 | SSH Key | 6 |
|
|
145
|
+
| Git Provider | 2 | GitHub | 6 |
|
|
146
|
+
| GitLab | 7 | PostgreSQL | 14 |
|
|
147
|
+
| Notification | 38 | MySQL | 14 |
|
|
148
|
+
| Destination | 6 | MariaDB | 14 |
|
|
149
|
+
| Backup | 11 | MongoDB | 14 |
|
|
150
|
+
| Mounts | 6 | Redis | 14 |
|
|
151
|
+
| Port | 4 | Volume Backups | 6 |
|
|
152
|
+
| Redirects | 4 | Rollback | 2 |
|
|
153
|
+
| Preview Deployment | 4 | Schedule | 6 |
|
|
148
154
|
| Security | 4 | Cluster | 4 |
|
|
149
|
-
| Settings |
|
|
150
|
-
| User |
|
|
155
|
+
| Settings | 49 | Admin | 1 |
|
|
156
|
+
| User | 7 | | |
|
|
151
157
|
|
|
152
158
|
Full reference with parameters and descriptions: **[docs/tools.md](docs/tools.md)**
|
|
153
159
|
|
package/dist/api/client.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export declare function unwrapTrpcResponse(data: unknown): unknown;
|
|
1
2
|
export declare class ApiError extends Error {
|
|
2
3
|
readonly status: number;
|
|
3
4
|
readonly statusText: string;
|
|
@@ -5,6 +6,7 @@ export declare class ApiError extends Error {
|
|
|
5
6
|
readonly endpoint: string;
|
|
6
7
|
constructor(status: number, statusText: string, body: unknown, endpoint: string);
|
|
7
8
|
}
|
|
9
|
+
export declare function buildQueryString(body: unknown): string;
|
|
8
10
|
export declare const api: {
|
|
9
11
|
get: <T = unknown>(path: string, params?: Record<string, unknown>) => Promise<T>;
|
|
10
12
|
post: <T = unknown>(path: string, body?: unknown) => Promise<T>;
|
package/dist/api/client.js
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
import { resolveConfig } from '../config/resolver.js';
|
|
2
2
|
const DEFAULT_TIMEOUT = 30_000;
|
|
3
|
+
function getErrorMessage(body, statusText) {
|
|
4
|
+
if (typeof body !== 'object' || body === null) {
|
|
5
|
+
return statusText;
|
|
6
|
+
}
|
|
7
|
+
if ('message' in body && typeof body.message === 'string') {
|
|
8
|
+
return body.message;
|
|
9
|
+
}
|
|
10
|
+
if ('error' in body && typeof body.error === 'object' && body.error !== null) {
|
|
11
|
+
const error = body.error;
|
|
12
|
+
if ('message' in error && typeof error.message === 'string') {
|
|
13
|
+
return error.message;
|
|
14
|
+
}
|
|
15
|
+
if ('json' in error && typeof error.json === 'object' && error.json !== null) {
|
|
16
|
+
const json = error.json;
|
|
17
|
+
if ('message' in json && typeof json.message === 'string') {
|
|
18
|
+
return json.message;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return statusText;
|
|
23
|
+
}
|
|
24
|
+
export function unwrapTrpcResponse(data) {
|
|
25
|
+
if (typeof data !== 'object' || data === null)
|
|
26
|
+
return data;
|
|
27
|
+
const outer = data;
|
|
28
|
+
if (typeof outer.result !== 'object' || outer.result === null)
|
|
29
|
+
return data;
|
|
30
|
+
const result = outer.result;
|
|
31
|
+
if (typeof result.data !== 'object' || result.data === null)
|
|
32
|
+
return data;
|
|
33
|
+
const inner = result.data;
|
|
34
|
+
return 'json' in inner ? inner.json : data;
|
|
35
|
+
}
|
|
3
36
|
function getConfig() {
|
|
4
37
|
const resolved = resolveConfig();
|
|
5
38
|
if (!resolved) {
|
|
@@ -29,9 +62,7 @@ export class ApiError extends Error {
|
|
|
29
62
|
body;
|
|
30
63
|
endpoint;
|
|
31
64
|
constructor(status, statusText, body, endpoint) {
|
|
32
|
-
const msg =
|
|
33
|
-
? body.message
|
|
34
|
-
: statusText;
|
|
65
|
+
const msg = getErrorMessage(body, statusText);
|
|
35
66
|
super(`Dokploy API error (${status}): ${msg}`);
|
|
36
67
|
this.status = status;
|
|
37
68
|
this.statusText = statusText;
|
|
@@ -40,13 +71,15 @@ export class ApiError extends Error {
|
|
|
40
71
|
this.name = 'ApiError';
|
|
41
72
|
}
|
|
42
73
|
}
|
|
43
|
-
function buildQueryString(body) {
|
|
44
|
-
if (
|
|
74
|
+
export function buildQueryString(body) {
|
|
75
|
+
if (body == null)
|
|
76
|
+
return '';
|
|
77
|
+
if (typeof body !== 'object')
|
|
45
78
|
return '';
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
.
|
|
49
|
-
|
|
79
|
+
const params = Object.fromEntries(Object.entries(body).filter(([, value]) => value != null));
|
|
80
|
+
return new URLSearchParams({
|
|
81
|
+
input: JSON.stringify({ json: params }),
|
|
82
|
+
}).toString();
|
|
50
83
|
}
|
|
51
84
|
/**
|
|
52
85
|
* Checks whether an error was caused by an aborted fetch.
|
|
@@ -70,7 +103,7 @@ async function request(method, path, body) {
|
|
|
70
103
|
Accept: 'application/json',
|
|
71
104
|
'x-api-key': apiKey,
|
|
72
105
|
},
|
|
73
|
-
body: method === 'POST' && body ? JSON.stringify(body) : undefined,
|
|
106
|
+
body: method === 'POST' && body ? JSON.stringify({ json: body }) : undefined,
|
|
74
107
|
signal: controller.signal,
|
|
75
108
|
});
|
|
76
109
|
const text = await response.text();
|
|
@@ -84,7 +117,7 @@ async function request(method, path, body) {
|
|
|
84
117
|
if (!response.ok) {
|
|
85
118
|
throw new ApiError(response.status, response.statusText, data, path);
|
|
86
119
|
}
|
|
87
|
-
return data;
|
|
120
|
+
return unwrapTrpcResponse(data);
|
|
88
121
|
}
|
|
89
122
|
catch (error) {
|
|
90
123
|
if (error instanceof ApiError) {
|
package/dist/tools/_database.js
CHANGED
|
@@ -6,7 +6,7 @@ export function createDatabaseTools(config) {
|
|
|
6
6
|
.object({ [idField]: z.string().min(1).describe(`Unique ${displayName} database ID`) })
|
|
7
7
|
.strict();
|
|
8
8
|
function tool(action, title, description, schema, opts = {}) {
|
|
9
|
-
const endpoint =
|
|
9
|
+
const endpoint = `/${type}.${action}`;
|
|
10
10
|
const name = `dokploy_${type}_${action.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`)}`;
|
|
11
11
|
if (opts.get) {
|
|
12
12
|
return getTool({ name, title, description, schema, endpoint, annotations: opts.annotations });
|
|
@@ -14,12 +14,18 @@ export function createDatabaseTools(config) {
|
|
|
14
14
|
return postTool({ name, title, description, schema, endpoint, annotations: opts.annotations });
|
|
15
15
|
}
|
|
16
16
|
const one = tool('one', `Get ${displayName} Details`, `Retrieve detailed information about a specific ${displayName} database managed by Dokploy. Returns the full configuration including connection settings, resource limits, environment variables, and current status. Requires the unique ${displayName} database ID.`, idSchema, { get: true });
|
|
17
|
-
const create = tool('create', `Create ${displayName} Database`, `Create a new ${displayName} database instance inside a Dokploy
|
|
17
|
+
const create = tool('create', `Create ${displayName} Database`, `Create a new ${displayName} database instance inside a Dokploy environment. Requires a display name and the target environment ID. Optionally specify an app-level identifier, Docker image, description, or remote server. Returns the newly created database record.`, z
|
|
18
18
|
.object({
|
|
19
19
|
name: z.string().min(1).describe('Display name for the database'),
|
|
20
|
-
appName: z
|
|
20
|
+
appName: z
|
|
21
|
+
.string()
|
|
22
|
+
.min(1)
|
|
23
|
+
.max(63)
|
|
24
|
+
.regex(/^[a-zA-Z0-9._-]+$/)
|
|
25
|
+
.optional()
|
|
26
|
+
.describe('Unique app-level identifier'),
|
|
21
27
|
...createFields.shape,
|
|
22
|
-
|
|
28
|
+
environmentId: z.string().min(1).describe('Environment ID to create the database in'),
|
|
23
29
|
dockerImage: z.string().optional().describe(`Docker image (default: ${defaultImage})`),
|
|
24
30
|
description: z.string().nullable().optional().describe('Optional description'),
|
|
25
31
|
serverId: z.string().nullable().optional().describe('Target server ID (null for local)'),
|
|
@@ -42,10 +48,10 @@ export function createDatabaseTools(config) {
|
|
|
42
48
|
})
|
|
43
49
|
.strict());
|
|
44
50
|
const remove = tool('remove', `Remove ${displayName} Database`, `Permanently delete a ${displayName} database from Dokploy. This action removes the database container, its data, and all associated configuration. Requires the ${displayName} database ID. This operation is destructive and cannot be undone.`, idSchema, { annotations: { destructiveHint: true } });
|
|
45
|
-
const move = tool('move', `Move ${displayName} Database`, `Move a ${displayName} database from its current
|
|
51
|
+
const move = tool('move', `Move ${displayName} Database`, `Move a ${displayName} database from its current environment to a different environment within Dokploy. Requires the ${displayName} database ID and the destination environment ID. The database configuration and data are preserved during the move.`, z
|
|
46
52
|
.object({
|
|
47
53
|
[idField]: z.string().min(1).describe(`Unique ${displayName} database ID`),
|
|
48
|
-
|
|
54
|
+
targetEnvironmentId: z.string().min(1).describe('Destination environment ID'),
|
|
49
55
|
})
|
|
50
56
|
.strict());
|
|
51
57
|
const deploy = tool('deploy', `Deploy ${displayName} Database`, `Deploy a ${displayName} database container in Dokploy. Triggers the build and start process for the specified database. Requires the ${displayName} database ID. Returns the deployment status.`, idSchema);
|
|
@@ -78,6 +84,18 @@ export function createDatabaseTools(config) {
|
|
|
78
84
|
env: z.string().nullable().optional().describe('Environment variables as a string'),
|
|
79
85
|
})
|
|
80
86
|
.strict());
|
|
87
|
+
const search = tool('search', `Search ${displayName} Databases`, `Search ${displayName} databases in Dokploy by free text or field-specific filters. Supports pagination through limit and offset.`, z
|
|
88
|
+
.object({
|
|
89
|
+
q: z.string().optional().describe('Free-text query'),
|
|
90
|
+
name: z.string().optional().describe('Display name'),
|
|
91
|
+
appName: z.string().optional().describe('App-level identifier'),
|
|
92
|
+
description: z.string().optional().describe('Description'),
|
|
93
|
+
projectId: z.string().optional().describe('Project ID'),
|
|
94
|
+
environmentId: z.string().optional().describe('Environment ID'),
|
|
95
|
+
limit: z.number().min(1).max(100).optional().describe('Maximum number of results'),
|
|
96
|
+
offset: z.number().min(0).optional().describe('Number of results to skip'),
|
|
97
|
+
})
|
|
98
|
+
.strict(), { get: true });
|
|
81
99
|
return [
|
|
82
100
|
one,
|
|
83
101
|
create,
|
|
@@ -92,5 +110,6 @@ export function createDatabaseTools(config) {
|
|
|
92
110
|
changeStatus,
|
|
93
111
|
saveExternalPort,
|
|
94
112
|
saveEnvironment,
|
|
113
|
+
search,
|
|
95
114
|
];
|
|
96
115
|
}
|
package/dist/tools/_factory.d.ts
CHANGED
package/dist/tools/_factory.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { ApiError, api } from '../api/client.js';
|
|
2
|
+
function wrapStructured(data) {
|
|
3
|
+
if (Array.isArray(data))
|
|
4
|
+
return { items: data };
|
|
5
|
+
if (data === null || data === undefined || typeof data !== 'object')
|
|
6
|
+
return { value: data };
|
|
7
|
+
return data;
|
|
8
|
+
}
|
|
2
9
|
function success(data) {
|
|
3
10
|
return {
|
|
4
11
|
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
5
|
-
structuredContent: data,
|
|
12
|
+
structuredContent: wrapStructured(data),
|
|
6
13
|
};
|
|
7
14
|
}
|
|
8
15
|
function error(message, details) {
|
|
@@ -55,7 +62,7 @@ export function createTool(def) {
|
|
|
55
62
|
};
|
|
56
63
|
}
|
|
57
64
|
export function postTool(opts) {
|
|
58
|
-
|
|
65
|
+
const tool = createTool({
|
|
59
66
|
name: opts.name,
|
|
60
67
|
title: opts.title,
|
|
61
68
|
description: opts.description,
|
|
@@ -63,9 +70,14 @@ export function postTool(opts) {
|
|
|
63
70
|
annotations: opts.annotations,
|
|
64
71
|
handler: async ({ input, api }) => api.post(opts.endpoint, input),
|
|
65
72
|
});
|
|
73
|
+
return {
|
|
74
|
+
...tool,
|
|
75
|
+
endpoint: opts.endpoint,
|
|
76
|
+
method: 'POST',
|
|
77
|
+
};
|
|
66
78
|
}
|
|
67
79
|
export function getTool(opts) {
|
|
68
|
-
|
|
80
|
+
const tool = createTool({
|
|
69
81
|
name: opts.name,
|
|
70
82
|
title: opts.title,
|
|
71
83
|
description: opts.description,
|
|
@@ -82,7 +94,12 @@ export function getTool(opts) {
|
|
|
82
94
|
params[k] = v;
|
|
83
95
|
}
|
|
84
96
|
}
|
|
85
|
-
return api.get(opts.endpoint,
|
|
97
|
+
return api.get(opts.endpoint, params);
|
|
86
98
|
},
|
|
87
99
|
});
|
|
100
|
+
return {
|
|
101
|
+
...tool,
|
|
102
|
+
endpoint: opts.endpoint,
|
|
103
|
+
method: 'GET',
|
|
104
|
+
};
|
|
88
105
|
}
|