@vibetools/dokploy-mcp 1.0.0 → 2.0.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.
Files changed (102) hide show
  1. package/README.md +59 -160
  2. package/dist/api/client.d.ts +3 -0
  3. package/dist/api/client.js +38 -13
  4. package/dist/cli/index.js +1 -0
  5. package/dist/codemode/context/execute-context.d.ts +590 -0
  6. package/dist/codemode/context/execute-context.js +64 -0
  7. package/dist/codemode/context/search-context.d.ts +13851 -0
  8. package/dist/codemode/context/search-context.js +42 -0
  9. package/dist/codemode/gateway/api-gateway.d.ts +12 -0
  10. package/dist/codemode/gateway/api-gateway.js +160 -0
  11. package/dist/codemode/gateway/error-format.d.ts +13 -0
  12. package/dist/codemode/gateway/error-format.js +9 -0
  13. package/dist/codemode/gateway/request-normalizer.d.ts +3 -0
  14. package/dist/codemode/gateway/request-normalizer.js +21 -0
  15. package/dist/codemode/gateway/trace.d.ts +13 -0
  16. package/dist/codemode/gateway/trace.js +11 -0
  17. package/dist/codemode/sandbox/host.d.ts +11 -0
  18. package/dist/codemode/sandbox/host.js +28 -0
  19. package/dist/codemode/sandbox/limits.d.ts +2 -0
  20. package/dist/codemode/sandbox/limits.js +20 -0
  21. package/dist/codemode/sandbox/runner.d.ts +8 -0
  22. package/dist/codemode/sandbox/runner.js +113 -0
  23. package/dist/codemode/sandbox/runtime.d.ts +2 -0
  24. package/dist/codemode/sandbox/runtime.js +3 -0
  25. package/dist/codemode/sandbox/serialize.d.ts +1 -0
  26. package/dist/codemode/sandbox/serialize.js +45 -0
  27. package/dist/codemode/sandbox/subprocess-runner.d.ts +10 -0
  28. package/dist/codemode/sandbox/subprocess-runner.js +91 -0
  29. package/dist/codemode/sandbox/types.d.ts +12 -0
  30. package/dist/codemode/sandbox/types.js +1 -0
  31. package/dist/codemode/sandbox/worker-entry.d.ts +1 -0
  32. package/dist/codemode/sandbox/worker-entry.js +70 -0
  33. package/dist/codemode/server-codemode.d.ts +2 -0
  34. package/dist/codemode/server-codemode.js +17 -0
  35. package/dist/codemode/tools/execute.d.ts +583 -0
  36. package/dist/codemode/tools/execute.js +52 -0
  37. package/dist/codemode/tools/index.d.ts +2 -0
  38. package/dist/codemode/tools/index.js +3 -0
  39. package/dist/codemode/tools/search.d.ts +2 -0
  40. package/dist/codemode/tools/search.js +62 -0
  41. package/dist/generated/dokploy-catalog.d.ts +27 -0
  42. package/dist/generated/dokploy-catalog.js +16 -0
  43. package/dist/generated/dokploy-schemas.d.ts +17533 -0
  44. package/dist/generated/dokploy-schemas.js +20639 -0
  45. package/dist/generated/dokploy-sdk.d.ts +558 -0
  46. package/dist/generated/dokploy-sdk.js +561 -0
  47. package/dist/generated/openapi-index.json +10591 -0
  48. package/dist/{tools/_factory.d.ts → mcp/tool-factory.d.ts} +2 -0
  49. package/dist/{tools/_factory.js → mcp/tool-factory.js} +26 -7
  50. package/dist/server.d.ts +1 -1
  51. package/dist/server.js +2 -15
  52. package/package.json +22 -11
  53. package/dist/tools/_database.d.ts +0 -12
  54. package/dist/tools/_database.js +0 -96
  55. package/dist/tools/admin.d.ts +0 -2
  56. package/dist/tools/admin.js +0 -61
  57. package/dist/tools/application.d.ts +0 -2
  58. package/dist/tools/application.js +0 -464
  59. package/dist/tools/backup.d.ts +0 -2
  60. package/dist/tools/backup.js +0 -103
  61. package/dist/tools/certificates.d.ts +0 -2
  62. package/dist/tools/certificates.js +0 -54
  63. package/dist/tools/cluster.d.ts +0 -2
  64. package/dist/tools/cluster.js +0 -38
  65. package/dist/tools/compose.d.ts +0 -2
  66. package/dist/tools/compose.js +0 -213
  67. package/dist/tools/deployment.d.ts +0 -2
  68. package/dist/tools/deployment.js +0 -27
  69. package/dist/tools/destination.d.ts +0 -2
  70. package/dist/tools/destination.js +0 -78
  71. package/dist/tools/docker.d.ts +0 -2
  72. package/dist/tools/docker.js +0 -50
  73. package/dist/tools/domain.d.ts +0 -2
  74. package/dist/tools/domain.js +0 -134
  75. package/dist/tools/index.d.ts +0 -2
  76. package/dist/tools/index.js +0 -48
  77. package/dist/tools/mariadb.d.ts +0 -1
  78. package/dist/tools/mariadb.js +0 -14
  79. package/dist/tools/mongo.d.ts +0 -1
  80. package/dist/tools/mongo.js +0 -12
  81. package/dist/tools/mounts.d.ts +0 -2
  82. package/dist/tools/mounts.js +0 -65
  83. package/dist/tools/mysql.d.ts +0 -1
  84. package/dist/tools/mysql.js +0 -14
  85. package/dist/tools/port.d.ts +0 -2
  86. package/dist/tools/port.js +0 -54
  87. package/dist/tools/postgres.d.ts +0 -1
  88. package/dist/tools/postgres.js +0 -13
  89. package/dist/tools/project.d.ts +0 -2
  90. package/dist/tools/project.js +0 -94
  91. package/dist/tools/redirects.d.ts +0 -2
  92. package/dist/tools/redirects.js +0 -53
  93. package/dist/tools/redis.d.ts +0 -1
  94. package/dist/tools/redis.js +0 -11
  95. package/dist/tools/registry.d.ts +0 -2
  96. package/dist/tools/registry.js +0 -81
  97. package/dist/tools/security.d.ts +0 -2
  98. package/dist/tools/security.js +0 -48
  99. package/dist/tools/settings.d.ts +0 -2
  100. package/dist/tools/settings.js +0 -258
  101. package/dist/tools/user.d.ts +0 -2
  102. package/dist/tools/user.js +0 -12
package/README.md CHANGED
@@ -2,15 +2,19 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@vibetools/dokploy-mcp)](https://www.npmjs.com/package/@vibetools/dokploy-mcp)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
5
- [![Node >= 22](https://img.shields.io/badge/node-%3E%3D22-brightgreen)](https://nodejs.org/)
5
+ [![Node >= 24](https://img.shields.io/badge/node-%3E%3D24-brightgreen)](https://nodejs.org/)
6
6
 
7
- MCP server for the Dokploy API. 196 tools across 23 modules. Your AI agent can now deploy apps, manage databases, configure domains, and handle backups -- without you touching a dashboard.
7
+ MCP server for [Dokploy](https://dokploy.com). Two tools. 463 API procedures. Your AI agent can now deploy, configure, and manage your entire infrastructure without memorizing 377 endpoint definitions first.
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 196. Standing on shoulders, etc.
9
+ Most MCP servers dump hundreds of tool schemas into your context window and call it a day. This one doesn't. **Code Mode** gives your agent `search` and `execute` -- it finds what it needs from a compact API catalog, writes a workflow, and the sandbox runs the whole thing in one call. Create an app, set env vars, mount volumes, configure domains, deploy -- all in a single round-trip.
10
10
 
11
- ## Quick Start
11
+ The result: **99.8% fewer tokens** on tool definitions. Your context window can go back to doing its actual job.
12
12
 
13
- Grab your API key from **Dokploy Settings > Profile > API/CLI** and add this to your MCP client config:
13
+ > Previously: 377 tools = ~92,354 tokens just to list them. Now: 2 tools = ~218 tokens. The math is embarrassing for everyone else.
14
+
15
+ ## Quick start
16
+
17
+ Grab your API key from **Dokploy Settings > Profile > API/CLI**:
14
18
 
15
19
  ```json
16
20
  {
@@ -27,203 +31,98 @@ Grab your API key from **Dokploy Settings > Profile > API/CLI** and add this to
27
31
  }
28
32
  ```
29
33
 
30
- That's it. No setup wizard, no config files, no PhD.
31
-
32
- ### Alternative: setup wizard
33
-
34
- If you prefer saving credentials to disk instead of env vars:
35
-
36
- ```bash
37
- npx @vibetools/dokploy-mcp setup
38
- ```
34
+ Drop this into Claude Desktop, Claude Code, Cursor, VS Code, Windsurf -- anything that speaks MCP. Done. No ceremony.
39
35
 
40
- Validates credentials, saves to `~/.config/dokploy-mcp/config.json`, and shows you the minimal MCP config to copy. After that, the `env` block is optional.
36
+ Already have the [Dokploy CLI](https://github.com/Dokploy/cli) authenticated? Skip the `env` block entirely. It just works.
41
37
 
42
- ### Alternative: Dokploy CLI auto-detection
38
+ Want a wizard? `npx @vibetools/dokploy-mcp setup` -- validates credentials, saves config, holds your hand exactly once.
43
39
 
44
- If you already have the [Dokploy CLI](https://github.com/Dokploy/cli) installed and authenticated -- zero config needed. It just works.
40
+ ## How it works
45
41
 
46
- ## Features
42
+ Your agent gets two tools:
47
43
 
48
- - **196 tools, 23 modules** -- applications, compose, databases (Postgres/MySQL/MariaDB/MongoDB/Redis), domains, backups, Docker, settings, and more
49
- - **Tool annotations** -- `readOnlyHint`, `destructiveHint`, `idempotentHint` so clients can warn before you nuke something
50
- - **Type-safe schemas** -- Zod v4 validation on every parameter
51
- - **Lazy config loading** -- validates credentials on first API call, not at startup
52
- - **Three config sources** -- env vars > config file > Dokploy CLI (first match wins)
53
- - **Minimal dependencies** -- just `@modelcontextprotocol/sdk`, `zod`, and `@clack/prompts`
54
-
55
- ## MCP Client Config
56
-
57
- ### Claude Desktop
58
-
59
- Add to `claude_desktop_config.json`:
60
-
61
- ```json
62
- {
63
- "mcpServers": {
64
- "dokploy": {
65
- "command": "npx",
66
- "args": ["@vibetools/dokploy-mcp"],
67
- "env": {
68
- "DOKPLOY_URL": "https://panel.example.com",
69
- "DOKPLOY_API_KEY": "your-api-key"
70
- }
71
- }
72
- }
73
- }
74
44
  ```
75
-
76
- ### Claude Code
77
-
78
- Add to `.mcp.json`:
79
-
80
- ```json
81
- {
82
- "mcpServers": {
83
- "dokploy": {
84
- "command": "npx",
85
- "args": ["@vibetools/dokploy-mcp"],
86
- "env": {
87
- "DOKPLOY_URL": "https://panel.example.com",
88
- "DOKPLOY_API_KEY": "your-api-key"
89
- }
90
- }
91
- }
92
- }
45
+ search → "what can Dokploy do with applications?"
46
+ execute → runs a multi-step workflow in one sandboxed call
93
47
  ```
94
48
 
95
- ### Cursor
49
+ One `execute` call can spin up an app, configure resource limits, set 5 env vars, create 3 file mounts, attach a domain with HTTPS, deploy, wait for it to come up, verify it's running, and clean up after itself. Eight API calls. One context window round-trip. Sub-second sandbox overhead.
96
50
 
97
- Add to `~/.cursor/mcp.json` or `.cursor/mcp.json`:
51
+ **What this looks like in practice:**
98
52
 
99
- ```json
100
- {
101
- "mcpServers": {
102
- "dokploy": {
103
- "command": "npx",
104
- "args": ["@vibetools/dokploy-mcp"],
105
- "env": {
106
- "DOKPLOY_URL": "https://panel.example.com",
107
- "DOKPLOY_API_KEY": "your-api-key"
108
- }
109
- }
110
- }
111
- }
112
- ```
53
+ | | Old way (endpoint-per-tool) | Code Mode |
54
+ |---|---|---|
55
+ | Tool definitions sent | ~92,354 tokens (377 tools) | ~218 tokens (2 tools) |
56
+ | Deploy workflow (8 API calls) | 8 round-trips through the model | 1 execute call, done |
57
+ | Context window tax | ~738k tokens on tool schemas alone | ~218 tokens total |
113
58
 
114
- ### VS Code
59
+ That last row is why this exists. Every token spent on tool definitions is a token your agent can't use for reasoning. We just gave you 738k of them back.
115
60
 
116
- Add to `.vscode/mcp.json`:
61
+ ## Configuration
117
62
 
118
- ```json
119
- {
120
- "servers": {
121
- "dokploy": {
122
- "command": "npx",
123
- "args": ["@vibetools/dokploy-mcp"],
124
- "env": {
125
- "DOKPLOY_URL": "https://panel.example.com",
126
- "DOKPLOY_API_KEY": "your-api-key"
127
- }
128
- }
129
- }
130
- }
131
- ```
63
+ | Variable | Required | Description |
64
+ |---|---|---|
65
+ | `DOKPLOY_URL` | Yes | Your Dokploy panel URL |
66
+ | `DOKPLOY_API_KEY` | Yes | API key from Dokploy settings |
67
+ | `DOKPLOY_TIMEOUT` | No | Request timeout in ms (default: `30000`) |
132
68
 
133
- Already ran `setup` or have Dokploy CLI authenticated? Drop the `env` block entirely.
69
+ Resolution order: env vars > `~/.config/dokploy-mcp/config.json` > Dokploy CLI config. First match wins.
134
70
 
135
- ## Tools
71
+ <details>
72
+ <summary>Sandbox tuning -- for when the defaults aren't enough drama</summary>
136
73
 
137
- | Module | Tools | Module | Tools |
138
- |--------|-------|--------|-------|
139
- | Project | 6 | Deployment | 2 |
140
- | Application | 26 | Docker | 4 |
141
- | Compose | 14 | Certificates | 4 |
142
- | Domain | 8 | Registry | 6 |
143
- | PostgreSQL | 13 | Destination | 6 |
144
- | MySQL | 13 | Backup | 8 |
145
- | MariaDB | 13 | Mounts | 4 |
146
- | MongoDB | 13 | Port | 4 |
147
- | Redis | 13 | Redirects | 4 |
148
- | Security | 4 | Cluster | 4 |
149
- | Settings | 25 | Admin | 1 |
150
- | User | 1 | | |
74
+ | Variable | Default | What it does |
75
+ |---|---|---|
76
+ | `DOKPLOY_MCP_SANDBOX_TIMEOUT_MS` | `30000` | How long before the sandbox gives up on your workflow |
77
+ | `DOKPLOY_MCP_SANDBOX_MAX_CALLS` | `25` | Max API calls per execute (prevents runaway loops) |
78
+ | `DOKPLOY_MCP_SANDBOX_MAX_RESULT_BYTES` | `131072` | Max result payload (128 KB) |
79
+ | `DOKPLOY_MCP_SANDBOX_MAX_RESPONSE_BYTES` | `2097152` | Cumulative API response cap (2 MB) |
80
+ | `DOKPLOY_MCP_SANDBOX_RUNTIME` | `subprocess` | `subprocess` (isolated) or `local` (faster, less safe) |
151
81
 
152
- Full reference with parameters and descriptions: **[docs/tools.md](docs/tools.md)**
82
+ </details>
153
83
 
154
- API coverage report: **[docs/coverage.md](docs/coverage.md)**
84
+ ## What's in the box
155
85
 
156
- ## Configuration
86
+ The Code Mode catalog covers the full Dokploy OpenAPI surface -- 463 procedures across every module. Applications, compose stacks, databases (Postgres, MySQL, MariaDB, MongoDB, Redis), domains, certificates, Docker, servers, backups, notifications, and about 30 more categories you'll discover when you need them.
157
87
 
158
- | Variable | Required | Description |
159
- |---|---|---|
160
- | `DOKPLOY_URL` | Yes | Dokploy panel URL -- automatically normalized to `/api/trpc` |
161
- | `DOKPLOY_API_KEY` | Yes | API key from Dokploy Settings > API |
162
- | `DOKPLOY_TIMEOUT` | No | Request timeout in ms (default: `30000`) |
88
+ Your agent doesn't need to know any of this upfront. That's the point. It searches when it needs something, executes when it knows what to do.
163
89
 
164
- Resolution order: env vars > `~/.config/dokploy-mcp/config.json` > Dokploy CLI config.
90
+ Coverage details: **[docs/coverage.md](docs/coverage.md)**
165
91
 
166
92
  ## CLI
167
93
 
168
94
  ```bash
169
- npx @vibetools/dokploy-mcp # Start MCP server (stdio)
170
- npx @vibetools/dokploy-mcp setup # Interactive setup wizard (aliases: init, auth)
171
- npx @vibetools/dokploy-mcp version # Show version
95
+ npx @vibetools/dokploy-mcp # Start Code Mode server
96
+ npx @vibetools/dokploy-mcp setup # Interactive setup
97
+ npx @vibetools/dokploy-mcp version # Because you'll be asked
172
98
  ```
173
99
 
174
100
  ## Development
175
101
 
176
102
  ```bash
177
- git clone https://github.com/vcode-sh/dokploy-mcp.git
178
- cd dokploy-mcp
103
+ git clone https://github.com/vcode-sh/dokploy-mcp.git && cd dokploy-mcp
179
104
  npm install && npm run build
180
- ```
181
-
182
- Point your MCP client at the local build:
183
-
184
- ```json
185
- {
186
- "mcpServers": {
187
- "dokploy": {
188
- "command": "node",
189
- "args": ["/path/to/dokploy-mcp/dist/index.js"],
190
- "env": {
191
- "DOKPLOY_URL": "https://panel.example.com",
192
- "DOKPLOY_API_KEY": "your-api-key"
193
- }
194
- }
195
- }
196
- }
105
+ npm run typecheck # TypeScript 6
106
+ npm run lint # Biome
107
+ npm test # Vitest
108
+ npm run ci:budgets # Protocol and runtime budget checks
197
109
  ```
198
110
 
199
- ```bash
200
- npm run dev # Watch mode
201
- npm run typecheck # Type-check
202
- npm run lint # Lint with Biome
203
- npm run lint:fix # Auto-fix
204
- ```
205
-
206
- Test with the MCP Inspector:
207
-
208
111
  ```bash
209
112
  npx @modelcontextprotocol/inspector node dist/index.js
210
113
  ```
211
114
 
212
- ## Standing on the Shoulders of People Who Actually Did the Work
213
-
214
- This project is a fork of [Dokploy/mcp](https://github.com/Dokploy/mcp). I rewrote most of it, tripled the tool count, and added things like a setup wizard and config resolution chain -- but "rewrote" is easy when someone else already built the thing you're rewriting.
215
-
216
- [Mauricio Siu](https://github.com/Siumauricio) created [Dokploy](https://dokploy.com) itself -- a genuinely impressive open-source PaaS -- and kicked off the MCP server repo. Without Dokploy, there's no API. Without the API, there's no MCP server. Without the MCP server, I'd have had to start from zero instead of "from scratch."
115
+ ## Credits
217
116
 
218
- [Henrique Andrade](https://github.com/andradehenrique) did the actual heavy lifting on the original MCP. Projects, applications, PostgreSQL, MySQL, domains -- that was all him. 15 commits, every merged PR. The kind of contributor who doesn't just open issues, he closes them.
117
+ Forked from [Dokploy/mcp](https://github.com/Dokploy/mcp). Started at 67 tools, mass-refactored to 377, then rebuilt the whole thing into an architecture that makes the tool count irrelevant.
219
118
 
220
- And to everyone who opened PRs on the original repo -- merged or not -- your code and ideas shaped what this became:
119
+ [Mauricio Siu](https://github.com/Siumauricio) built [Dokploy](https://dokploy.com) itself -- the PaaS this server talks to. Without the platform, this is a very elaborate way to POST into the void.
221
120
 
222
- [Joshua Macauley](https://github.com/Macawls) · [lucasleal-developer](https://github.com/lucasleal-developer) · [Nour Eddine Hamaidi](https://github.com/HenkDz) · [Corey](https://github.com/limehawk) · [Azil0ne](https://github.com/Azilone)
121
+ [Henrique Andrade](https://github.com/andradehenrique) wrote the original MCP server. 15 commits, every PR merged. The kind of contributor who closes issues instead of opening them.
223
122
 
224
- Unmerged PRs are still blueprints. Someone reads your compose tools PR and thinks "right, I should cover that." Someone sees your consolidation approach and borrows the idea. That's how open source actually works -- not through clean merge histories, but through stolen inspiration with better commit messages.
123
+ Contributors who shaped the original: [Joshua Macauley](https://github.com/Macawls) -- [lucasleal-developer](https://github.com/lucasleal-developer) -- [Nour Eddine Hamaidi](https://github.com/HenkDz) -- [Corey](https://github.com/limehawk) -- [Azil0ne](https://github.com/Azilone)
225
124
 
226
- Cheers to all of you. I owe you mass-produced coffee at minimum.
125
+ Unmerged PRs are still blueprints. That's how open source works -- stolen inspiration with better commit messages.
227
126
 
228
127
  ## License
229
128
 
@@ -1,3 +1,5 @@
1
+ import { buildTrpcQueryString } from '../codemode/gateway/request-normalizer.js';
2
+ export declare function unwrapTrpcResponse(data: unknown): unknown;
1
3
  export declare class ApiError extends Error {
2
4
  readonly status: number;
3
5
  readonly statusText: string;
@@ -5,6 +7,7 @@ export declare class ApiError extends Error {
5
7
  readonly endpoint: string;
6
8
  constructor(status: number, statusText: string, body: unknown, endpoint: string);
7
9
  }
10
+ export declare const buildQueryString: typeof buildTrpcQueryString;
8
11
  export declare const api: {
9
12
  get: <T = unknown>(path: string, params?: Record<string, unknown>) => Promise<T>;
10
13
  post: <T = unknown>(path: string, body?: unknown) => Promise<T>;
@@ -1,5 +1,39 @@
1
+ import { buildTrpcPostBody, buildTrpcQueryString } from '../codemode/gateway/request-normalizer.js';
1
2
  import { resolveConfig } from '../config/resolver.js';
2
3
  const DEFAULT_TIMEOUT = 30_000;
4
+ function getErrorMessage(body, statusText) {
5
+ if (typeof body !== 'object' || body === null) {
6
+ return statusText;
7
+ }
8
+ if ('message' in body && typeof body.message === 'string') {
9
+ return body.message;
10
+ }
11
+ if ('error' in body && typeof body.error === 'object' && body.error !== null) {
12
+ const error = body.error;
13
+ if ('message' in error && typeof error.message === 'string') {
14
+ return error.message;
15
+ }
16
+ if ('json' in error && typeof error.json === 'object' && error.json !== null) {
17
+ const json = error.json;
18
+ if ('message' in json && typeof json.message === 'string') {
19
+ return json.message;
20
+ }
21
+ }
22
+ }
23
+ return statusText;
24
+ }
25
+ export function unwrapTrpcResponse(data) {
26
+ if (typeof data !== 'object' || data === null)
27
+ return data;
28
+ const outer = data;
29
+ if (typeof outer.result !== 'object' || outer.result === null)
30
+ return data;
31
+ const result = outer.result;
32
+ if (typeof result.data !== 'object' || result.data === null)
33
+ return data;
34
+ const inner = result.data;
35
+ return 'json' in inner ? inner.json : data;
36
+ }
3
37
  function getConfig() {
4
38
  const resolved = resolveConfig();
5
39
  if (!resolved) {
@@ -29,9 +63,7 @@ export class ApiError extends Error {
29
63
  body;
30
64
  endpoint;
31
65
  constructor(status, statusText, body, endpoint) {
32
- const msg = typeof body === 'object' && body !== null && 'message' in body
33
- ? body.message
34
- : statusText;
66
+ const msg = getErrorMessage(body, statusText);
35
67
  super(`Dokploy API error (${status}): ${msg}`);
36
68
  this.status = status;
37
69
  this.statusText = statusText;
@@ -40,14 +72,7 @@ export class ApiError extends Error {
40
72
  this.name = 'ApiError';
41
73
  }
42
74
  }
43
- function buildQueryString(body) {
44
- if (!body || typeof body !== 'object')
45
- return '';
46
- const entries = Object.entries(body)
47
- .filter(([, v]) => v != null)
48
- .map(([k, v]) => [k, String(v)]);
49
- return entries.length > 0 ? new URLSearchParams(entries).toString() : '';
50
- }
75
+ export const buildQueryString = buildTrpcQueryString;
51
76
  /**
52
77
  * Checks whether an error was caused by an aborted fetch.
53
78
  * Both checks are needed: older Node versions throw DOMException,
@@ -70,7 +95,7 @@ async function request(method, path, body) {
70
95
  Accept: 'application/json',
71
96
  'x-api-key': apiKey,
72
97
  },
73
- body: method === 'POST' && body ? JSON.stringify(body) : undefined,
98
+ body: method === 'POST' ? buildTrpcPostBody(body) : undefined,
74
99
  signal: controller.signal,
75
100
  });
76
101
  const text = await response.text();
@@ -84,7 +109,7 @@ async function request(method, path, body) {
84
109
  if (!response.ok) {
85
110
  throw new ApiError(response.status, response.statusText, data, path);
86
111
  }
87
- return data;
112
+ return unwrapTrpcResponse(data);
88
113
  }
89
114
  catch (error) {
90
115
  if (error instanceof ApiError) {
package/dist/cli/index.js CHANGED
@@ -41,6 +41,7 @@ Environment Variables:
41
41
  DOKPLOY_URL Dokploy panel URL (e.g. https://panel.example.com)
42
42
  DOKPLOY_API_KEY API key from Dokploy Settings
43
43
  DOKPLOY_TIMEOUT Request timeout in ms (default: 30000)
44
+ DOKPLOY_MCP_SANDBOX_RUNTIME subprocess or local (default: subprocess)
44
45
 
45
46
  Documentation:
46
47
  https://github.com/vcode-sh/dokploy-mcp