@episoda/mcp 0.1.11 → 0.1.13
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/dist/cli.js +229 -146
- package/dist/cli.js.map +1 -1
- package/dist/dev-server.js +77 -41
- package/dist/dev-server.js.map +1 -1
- package/dist/git-server.js +67 -30
- package/dist/git-server.js.map +1 -1
- package/dist/workflow-server.js +135 -76
- package/dist/workflow-server.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
2
3
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
4
|
var __esm = (fn, res) => function __init() {
|
|
4
5
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
6
|
};
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
6
11
|
|
|
7
12
|
// src/runtime-config.ts
|
|
8
13
|
import * as fs from "fs";
|
|
@@ -11,14 +16,15 @@ import * as path from "path";
|
|
|
11
16
|
async function resolveRuntimeConfig() {
|
|
12
17
|
const envConfig = readEnvConfig();
|
|
13
18
|
let fileConfig = null;
|
|
14
|
-
if (!envConfig.sessionToken || !envConfig.projectId || !envConfig.workspaceId || !envConfig.apiUrl) {
|
|
19
|
+
if (!envConfig.sessionToken || !envConfig.projectId || !envConfig.workspaceId || !envConfig.apiUrl || !envConfig.machineUuid) {
|
|
15
20
|
fileConfig = loadLocalConfig();
|
|
16
21
|
}
|
|
17
22
|
const resolved = {
|
|
18
23
|
apiUrl: envConfig.apiUrl || fileConfig?.api_url || DEFAULT_API_URL,
|
|
19
24
|
sessionToken: envConfig.sessionToken || fileConfig?.access_token || "",
|
|
20
25
|
projectId: envConfig.projectId || fileConfig?.project_id || "",
|
|
21
|
-
workspaceId: envConfig.workspaceId || fileConfig?.workspace_id || ""
|
|
26
|
+
workspaceId: envConfig.workspaceId || fileConfig?.workspace_id || "",
|
|
27
|
+
machineUuid: envConfig.machineUuid || fileConfig?.machine_uuid || fileConfig?.device_id || void 0
|
|
22
28
|
};
|
|
23
29
|
const missing = [];
|
|
24
30
|
if (!resolved.sessionToken) missing.push("EPISODA_SESSION_TOKEN");
|
|
@@ -43,6 +49,9 @@ async function hydrateRuntimeConfig() {
|
|
|
43
49
|
if (!normalizeEnv(process.env.EPISODA_WORKSPACE_ID)) {
|
|
44
50
|
process.env.EPISODA_WORKSPACE_ID = resolved.workspaceId;
|
|
45
51
|
}
|
|
52
|
+
if (resolved.machineUuid && !normalizeEnv(process.env.EPISODA_MACHINE_UUID)) {
|
|
53
|
+
process.env.EPISODA_MACHINE_UUID = resolved.machineUuid;
|
|
54
|
+
}
|
|
46
55
|
return resolved;
|
|
47
56
|
}
|
|
48
57
|
var DEFAULT_API_URL, DEFAULT_CONFIG_FILE, normalizeEnv, readEnvConfig, buildMissingMessage, getConfigPath, loadLocalConfig;
|
|
@@ -60,7 +69,8 @@ var init_runtime_config = __esm({
|
|
|
60
69
|
apiUrl: normalizeEnv(process.env.EPISODA_API_URL),
|
|
61
70
|
sessionToken: normalizeEnv(process.env.EPISODA_SESSION_TOKEN),
|
|
62
71
|
projectId: normalizeEnv(process.env.EPISODA_PROJECT_ID),
|
|
63
|
-
workspaceId: normalizeEnv(process.env.EPISODA_WORKSPACE_ID)
|
|
72
|
+
workspaceId: normalizeEnv(process.env.EPISODA_WORKSPACE_ID),
|
|
73
|
+
machineUuid: normalizeEnv(process.env.EPISODA_MACHINE_UUID)
|
|
64
74
|
});
|
|
65
75
|
buildMissingMessage = (missing, apiUrl) => {
|
|
66
76
|
return [
|
|
@@ -92,57 +102,140 @@ var init_runtime_config = __esm({
|
|
|
92
102
|
}
|
|
93
103
|
});
|
|
94
104
|
|
|
95
|
-
// src/
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
105
|
+
// src/request-executors.ts
|
|
106
|
+
function buildMcpHeaders(runtime) {
|
|
107
|
+
const headers = {
|
|
108
|
+
"Content-Type": "application/json",
|
|
109
|
+
"Authorization": `Bearer ${runtime.sessionToken}`
|
|
110
|
+
};
|
|
111
|
+
if (runtime.projectId) {
|
|
112
|
+
headers["x-project-id"] = runtime.projectId;
|
|
113
|
+
}
|
|
114
|
+
if (runtime.workspaceId) {
|
|
115
|
+
headers["x-workspace-id"] = runtime.workspaceId;
|
|
116
|
+
}
|
|
117
|
+
if (runtime.machineUuid) {
|
|
118
|
+
headers["x-machine-uuid"] = runtime.machineUuid;
|
|
119
|
+
}
|
|
120
|
+
return headers;
|
|
121
|
+
}
|
|
122
|
+
async function apiRequest(runtime, method, path2, body, fetchImpl = fetch) {
|
|
123
|
+
const url = `${runtime.apiUrl}${path2}`;
|
|
102
124
|
const options = {
|
|
103
125
|
method,
|
|
104
|
-
headers:
|
|
105
|
-
"Content-Type": "application/json",
|
|
106
|
-
"Authorization": `Bearer ${EPISODA_SESSION_TOKEN}`
|
|
107
|
-
}
|
|
126
|
+
headers: buildMcpHeaders(runtime)
|
|
108
127
|
};
|
|
109
128
|
if (body && method !== "GET") {
|
|
110
129
|
options.body = JSON.stringify(body);
|
|
111
130
|
}
|
|
112
|
-
|
|
113
|
-
options.headers["x-project-id"] = EPISODA_PROJECT_ID;
|
|
114
|
-
}
|
|
115
|
-
if (EPISODA_WORKSPACE_ID) {
|
|
116
|
-
options.headers["x-workspace-id"] = EPISODA_WORKSPACE_ID;
|
|
117
|
-
}
|
|
118
|
-
const response = await fetch(url, options);
|
|
131
|
+
const response = await fetchImpl(url, options);
|
|
119
132
|
if (!response.ok) {
|
|
120
133
|
const text = await response.text();
|
|
121
134
|
throw new Error(`API error ${response.status}: ${text}`);
|
|
122
135
|
}
|
|
123
136
|
return response.json();
|
|
124
137
|
}
|
|
125
|
-
async function
|
|
138
|
+
async function executeTransitionModule(runtime, args, fetchImpl = fetch) {
|
|
139
|
+
const result = await apiRequest(
|
|
140
|
+
runtime,
|
|
141
|
+
"POST",
|
|
142
|
+
`/api/modules/${args.module_uid}/transition`,
|
|
143
|
+
{ targetState: args.target_state },
|
|
144
|
+
fetchImpl
|
|
145
|
+
);
|
|
146
|
+
if (!result.success) {
|
|
147
|
+
return { content: [{ type: "text", text: `Error: ${result.error}` }], isError: true };
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
content: [{
|
|
151
|
+
type: "text",
|
|
152
|
+
text: `Module ${args.module_uid} transitioned to ${args.target_state}`
|
|
153
|
+
}]
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
async function executeGitCommandRequest(runtime, args, fetchImpl = fetch) {
|
|
157
|
+
const response = await fetchImpl(`${runtime.apiUrl}/api/dev/${args.target}/exec`, {
|
|
158
|
+
method: "POST",
|
|
159
|
+
headers: buildMcpHeaders(runtime),
|
|
160
|
+
body: JSON.stringify({
|
|
161
|
+
command: args.command,
|
|
162
|
+
cwd: args.cwd,
|
|
163
|
+
timeout: args.timeout ?? 3e4
|
|
164
|
+
})
|
|
165
|
+
});
|
|
166
|
+
if (!response.ok) {
|
|
167
|
+
return {
|
|
168
|
+
success: false,
|
|
169
|
+
error: `HTTP ${response.status}: ${response.statusText}`
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
return response.json();
|
|
173
|
+
}
|
|
174
|
+
var init_request_executors = __esm({
|
|
175
|
+
"src/request-executors.ts"() {
|
|
176
|
+
"use strict";
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// src/workflow-server.ts
|
|
181
|
+
var workflow_server_exports = {};
|
|
182
|
+
__export(workflow_server_exports, {
|
|
183
|
+
handleTransitionModule: () => handleTransitionModule,
|
|
184
|
+
startServer: () => startServer
|
|
185
|
+
});
|
|
186
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
187
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
188
|
+
import { z } from "zod";
|
|
189
|
+
async function apiRequest2(method, path2, body) {
|
|
190
|
+
return apiRequest(
|
|
191
|
+
{
|
|
192
|
+
apiUrl: EPISODA_API_URL,
|
|
193
|
+
sessionToken: EPISODA_SESSION_TOKEN,
|
|
194
|
+
projectId: EPISODA_PROJECT_ID,
|
|
195
|
+
workspaceId: EPISODA_WORKSPACE_ID,
|
|
196
|
+
machineUuid: EPISODA_MACHINE_UUID
|
|
197
|
+
},
|
|
198
|
+
method,
|
|
199
|
+
path2,
|
|
200
|
+
body
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
async function handleTransitionModule(args) {
|
|
204
|
+
return executeTransitionModule(
|
|
205
|
+
{
|
|
206
|
+
apiUrl: EPISODA_API_URL,
|
|
207
|
+
sessionToken: EPISODA_SESSION_TOKEN,
|
|
208
|
+
projectId: EPISODA_PROJECT_ID,
|
|
209
|
+
workspaceId: EPISODA_WORKSPACE_ID,
|
|
210
|
+
machineUuid: EPISODA_MACHINE_UUID
|
|
211
|
+
},
|
|
212
|
+
args
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
async function startServer() {
|
|
126
216
|
const runtimeConfig = await hydrateRuntimeConfig();
|
|
127
217
|
EPISODA_API_URL = runtimeConfig.apiUrl;
|
|
128
218
|
EPISODA_SESSION_TOKEN = runtimeConfig.sessionToken;
|
|
129
219
|
EPISODA_PROJECT_ID = runtimeConfig.projectId;
|
|
130
220
|
EPISODA_WORKSPACE_ID = runtimeConfig.workspaceId;
|
|
221
|
+
EPISODA_MACHINE_UUID = runtimeConfig.machineUuid || "";
|
|
131
222
|
const transport = new StdioServerTransport();
|
|
132
223
|
await server.connect(transport);
|
|
133
224
|
console.error("[episoda-workflow] MCP server started");
|
|
134
225
|
console.error(`[episoda-workflow] API URL: ${EPISODA_API_URL}`);
|
|
135
226
|
console.error(`[episoda-workflow] Token: ${EPISODA_SESSION_TOKEN ? "****" : "NOT SET"}`);
|
|
136
227
|
}
|
|
137
|
-
var EPISODA_API_URL, EPISODA_SESSION_TOKEN, EPISODA_PROJECT_ID, EPISODA_WORKSPACE_ID, server;
|
|
228
|
+
var EPISODA_API_URL, EPISODA_SESSION_TOKEN, EPISODA_PROJECT_ID, EPISODA_WORKSPACE_ID, EPISODA_MACHINE_UUID, server;
|
|
138
229
|
var init_workflow_server = __esm({
|
|
139
230
|
"src/workflow-server.ts"() {
|
|
140
231
|
"use strict";
|
|
141
232
|
init_runtime_config();
|
|
233
|
+
init_request_executors();
|
|
142
234
|
EPISODA_API_URL = process.env.EPISODA_API_URL || "https://episoda.dev";
|
|
143
235
|
EPISODA_SESSION_TOKEN = process.env.EPISODA_SESSION_TOKEN || "";
|
|
144
236
|
EPISODA_PROJECT_ID = process.env.EPISODA_PROJECT_ID || "";
|
|
145
237
|
EPISODA_WORKSPACE_ID = process.env.EPISODA_WORKSPACE_ID || "";
|
|
238
|
+
EPISODA_MACHINE_UUID = process.env.EPISODA_MACHINE_UUID || "";
|
|
146
239
|
server = new McpServer({
|
|
147
240
|
name: "episoda-workflow",
|
|
148
241
|
version: "1.0.0"
|
|
@@ -173,7 +266,7 @@ var init_workflow_server = __esm({
|
|
|
173
266
|
}
|
|
174
267
|
},
|
|
175
268
|
async (args) => {
|
|
176
|
-
const result = await
|
|
269
|
+
const result = await apiRequest2("POST", "/api/tasks", {
|
|
177
270
|
module_id: args.module_uid,
|
|
178
271
|
// API expects module_id (accepts both UUID and UID)
|
|
179
272
|
title: args.title,
|
|
@@ -201,7 +294,7 @@ var init_workflow_server = __esm({
|
|
|
201
294
|
}
|
|
202
295
|
},
|
|
203
296
|
async (args) => {
|
|
204
|
-
const result = await
|
|
297
|
+
const result = await apiRequest2("PATCH", `/api/tasks/${args.task_uid}`, {
|
|
205
298
|
state: args.state
|
|
206
299
|
});
|
|
207
300
|
if (!result.success) {
|
|
@@ -229,7 +322,7 @@ var init_workflow_server = __esm({
|
|
|
229
322
|
const updates = {};
|
|
230
323
|
if (args.title) updates.title = args.title;
|
|
231
324
|
if (args.description) updates.description_md = args.description;
|
|
232
|
-
const result = await
|
|
325
|
+
const result = await apiRequest2("PATCH", `/api/tasks/${args.task_uid}`, updates);
|
|
233
326
|
if (!result.success) {
|
|
234
327
|
return { content: [{ type: "text", text: `Error: ${result.error}` }], isError: true };
|
|
235
328
|
}
|
|
@@ -250,7 +343,7 @@ var init_workflow_server = __esm({
|
|
|
250
343
|
}
|
|
251
344
|
},
|
|
252
345
|
async (args) => {
|
|
253
|
-
const result = await
|
|
346
|
+
const result = await apiRequest2("GET", `/api/tasks/${args.task_uid}`);
|
|
254
347
|
if (!result.success || !result.task) {
|
|
255
348
|
return { content: [{ type: "text", text: `Error: ${result.error || "Task not found"}` }], isError: true };
|
|
256
349
|
}
|
|
@@ -278,7 +371,7 @@ ${task.description_md || "_No description_"}`
|
|
|
278
371
|
}
|
|
279
372
|
},
|
|
280
373
|
async (args) => {
|
|
281
|
-
const result = await
|
|
374
|
+
const result = await apiRequest2("GET", `/api/tasks?module_id=${args.module_uid}`);
|
|
282
375
|
if (!result.success || !result.tasks) {
|
|
283
376
|
return { content: [{ type: "text", text: `Error: ${result.error || "Failed to fetch tasks"}` }], isError: true };
|
|
284
377
|
}
|
|
@@ -309,7 +402,7 @@ ${taskList}`
|
|
|
309
402
|
}
|
|
310
403
|
},
|
|
311
404
|
async (args) => {
|
|
312
|
-
const result = await
|
|
405
|
+
const result = await apiRequest2("DELETE", `/api/tasks/${args.task_uid}`);
|
|
313
406
|
if (!result.success) {
|
|
314
407
|
return { content: [{ type: "text", text: `Error: ${result.error}` }], isError: true };
|
|
315
408
|
}
|
|
@@ -341,7 +434,7 @@ Reduces latency from ~1.5s (6 calls) to ~300ms (1 call).`,
|
|
|
341
434
|
async (args) => {
|
|
342
435
|
try {
|
|
343
436
|
const lookupPromises = args.task_uids.map(
|
|
344
|
-
(uid) =>
|
|
437
|
+
(uid) => apiRequest2("GET", `/api/tasks/${uid}`).then((r) => r.success && r.task ? { uid, id: r.task.id } : null).catch(() => null)
|
|
345
438
|
);
|
|
346
439
|
const lookupResults = await Promise.all(lookupPromises);
|
|
347
440
|
const validTasks = lookupResults.filter((t) => t !== null);
|
|
@@ -360,7 +453,7 @@ Not found: ${args.task_uids.join(", ")}`
|
|
|
360
453
|
id: t.id,
|
|
361
454
|
state: args.state
|
|
362
455
|
}));
|
|
363
|
-
const result = await
|
|
456
|
+
const result = await apiRequest2("PATCH", "/api/tasks/batch", {
|
|
364
457
|
updates
|
|
365
458
|
});
|
|
366
459
|
if (!result.success) {
|
|
@@ -420,7 +513,7 @@ EFFICIENCY: Single call instead of multiple create_task calls.`,
|
|
|
420
513
|
},
|
|
421
514
|
async (args) => {
|
|
422
515
|
try {
|
|
423
|
-
const result = await
|
|
516
|
+
const result = await apiRequest2("POST", "/api/tasks/bulk", {
|
|
424
517
|
module_id: args.module_uid,
|
|
425
518
|
tasks: args.tasks.map((t) => ({
|
|
426
519
|
title: t.title,
|
|
@@ -477,7 +570,7 @@ EFFICIENCY: Single MCP call instead of multiple get_task_details calls.`,
|
|
|
477
570
|
async (args) => {
|
|
478
571
|
try {
|
|
479
572
|
const fetchPromises = args.task_uids.map(
|
|
480
|
-
(uid) =>
|
|
573
|
+
(uid) => apiRequest2("GET", `/api/tasks/${uid}`).then((r) => r.success && r.task ? { found: true, task: r.task } : { found: false, uid }).catch(() => ({ found: false, uid }))
|
|
481
574
|
);
|
|
482
575
|
const results = await Promise.all(fetchPromises);
|
|
483
576
|
const foundTasks = [];
|
|
@@ -536,7 +629,7 @@ ${notFoundUids.length > 0 ? `**Not found:** ${notFoundUids.join(", ")}` : ""}`
|
|
|
536
629
|
}
|
|
537
630
|
},
|
|
538
631
|
async (args) => {
|
|
539
|
-
const result = await
|
|
632
|
+
const result = await apiRequest2("POST", "/api/modules", {
|
|
540
633
|
title: args.title,
|
|
541
634
|
description_md: args.description
|
|
542
635
|
});
|
|
@@ -565,7 +658,7 @@ ${notFoundUids.length > 0 ? `**Not found:** ${notFoundUids.join(", ")}` : ""}`
|
|
|
565
658
|
const updates = {};
|
|
566
659
|
if (args.title) updates.title = args.title;
|
|
567
660
|
if (args.description) updates.description_md = args.description;
|
|
568
|
-
const result = await
|
|
661
|
+
const result = await apiRequest2("PATCH", `/api/modules/${args.module_uid}`, updates);
|
|
569
662
|
if (!result.success) {
|
|
570
663
|
return { content: [{ type: "text", text: `Error: ${result.error}` }], isError: true };
|
|
571
664
|
}
|
|
@@ -586,7 +679,7 @@ ${notFoundUids.length > 0 ? `**Not found:** ${notFoundUids.join(", ")}` : ""}`
|
|
|
586
679
|
}
|
|
587
680
|
},
|
|
588
681
|
async (args) => {
|
|
589
|
-
const result = await
|
|
682
|
+
const result = await apiRequest2("PATCH", `/api/modules/${args.module_uid}`, {
|
|
590
683
|
state: "review"
|
|
591
684
|
});
|
|
592
685
|
if (!result.success) {
|
|
@@ -609,7 +702,7 @@ ${notFoundUids.length > 0 ? `**Not found:** ${notFoundUids.join(", ")}` : ""}`
|
|
|
609
702
|
}
|
|
610
703
|
},
|
|
611
704
|
async (args) => {
|
|
612
|
-
const result = await
|
|
705
|
+
const result = await apiRequest2("PATCH", `/api/modules/${args.module_uid}`, {
|
|
613
706
|
state: "done"
|
|
614
707
|
});
|
|
615
708
|
if (!result.success) {
|
|
@@ -632,11 +725,19 @@ ${notFoundUids.length > 0 ? `**Not found:** ${notFoundUids.join(", ")}` : ""}`
|
|
|
632
725
|
}
|
|
633
726
|
},
|
|
634
727
|
async (args) => {
|
|
635
|
-
const
|
|
636
|
-
|
|
728
|
+
const MAX_INITIAL_PROMPT_CHARS = 2e3;
|
|
729
|
+
const result = await apiRequest2("GET", `/api/modules/${args.module_uid}`);
|
|
730
|
+
const mod = result.moduleRecord || result.module;
|
|
731
|
+
if (!result.success || !mod) {
|
|
637
732
|
return { content: [{ type: "text", text: `Error: ${result.error || "Module not found"}` }], isError: true };
|
|
638
733
|
}
|
|
639
|
-
const
|
|
734
|
+
const initialPrompt = mod.initial_prompt?.trim();
|
|
735
|
+
const initialPromptSection = initialPrompt ? `
|
|
736
|
+
|
|
737
|
+
### Original Request
|
|
738
|
+
\`\`\`text
|
|
739
|
+
${initialPrompt.slice(0, MAX_INITIAL_PROMPT_CHARS)}${initialPrompt.length > MAX_INITIAL_PROMPT_CHARS ? "\n\n[Truncated for output size]" : ""}
|
|
740
|
+
\`\`\`` : "";
|
|
640
741
|
return {
|
|
641
742
|
content: [{
|
|
642
743
|
type: "text",
|
|
@@ -645,7 +746,7 @@ ${notFoundUids.length > 0 ? `**Not found:** ${notFoundUids.join(", ")}` : ""}`
|
|
|
645
746
|
**State:** ${mod.state}
|
|
646
747
|
**Branch:** ${mod.branch_name || "_Not set_"}
|
|
647
748
|
|
|
648
|
-
${mod.description_md || "_No description_"}`
|
|
749
|
+
${mod.description_md || "_No description_"}${initialPromptSection}`
|
|
649
750
|
}]
|
|
650
751
|
};
|
|
651
752
|
}
|
|
@@ -659,7 +760,7 @@ ${mod.description_md || "_No description_"}`
|
|
|
659
760
|
}
|
|
660
761
|
},
|
|
661
762
|
async (args) => {
|
|
662
|
-
const result = await
|
|
763
|
+
const result = await apiRequest2("DELETE", `/api/modules/${args.module_uid}`);
|
|
663
764
|
if (!result.success) {
|
|
664
765
|
return { content: [{ type: "text", text: `Error: ${result.error}` }], isError: true };
|
|
665
766
|
}
|
|
@@ -692,7 +793,7 @@ USE THIS WHEN:
|
|
|
692
793
|
if (args.limit) params.set("limit", String(args.limit));
|
|
693
794
|
if (args.include_task_counts) params.set("includeTaskCounts", "true");
|
|
694
795
|
const query = params.toString();
|
|
695
|
-
const result = await
|
|
796
|
+
const result = await apiRequest2("GET", `/api/modules${query ? `?${query}` : ""}`);
|
|
696
797
|
if (!result.success || !result.modules) {
|
|
697
798
|
return { content: [{ type: "text", text: `Error: ${result.error || "Failed to fetch modules"}` }], isError: true };
|
|
698
799
|
}
|
|
@@ -725,22 +826,7 @@ Use this instead of request_review or mark_done for full control.`,
|
|
|
725
826
|
target_state: z.enum(["ready", "doing", "review", "done"]).describe("Target state for the module")
|
|
726
827
|
}
|
|
727
828
|
},
|
|
728
|
-
|
|
729
|
-
const result = await apiRequest(
|
|
730
|
-
"POST",
|
|
731
|
-
`/api/modules/${args.module_uid}/transition`,
|
|
732
|
-
{ targetState: args.target_state }
|
|
733
|
-
);
|
|
734
|
-
if (!result.success) {
|
|
735
|
-
return { content: [{ type: "text", text: `Error: ${result.error}` }], isError: true };
|
|
736
|
-
}
|
|
737
|
-
return {
|
|
738
|
-
content: [{
|
|
739
|
-
type: "text",
|
|
740
|
-
text: `Module ${args.module_uid} transitioned to ${args.target_state}`
|
|
741
|
-
}]
|
|
742
|
-
};
|
|
743
|
-
}
|
|
829
|
+
handleTransitionModule
|
|
744
830
|
);
|
|
745
831
|
server.registerTool(
|
|
746
832
|
"archive_module",
|
|
@@ -751,7 +837,7 @@ Use this instead of request_review or mark_done for full control.`,
|
|
|
751
837
|
}
|
|
752
838
|
},
|
|
753
839
|
async (args) => {
|
|
754
|
-
const result = await
|
|
840
|
+
const result = await apiRequest2(
|
|
755
841
|
"POST",
|
|
756
842
|
`/api/modules/${args.module_uid}/archive`,
|
|
757
843
|
{}
|
|
@@ -776,7 +862,7 @@ Use this instead of request_review or mark_done for full control.`,
|
|
|
776
862
|
}
|
|
777
863
|
},
|
|
778
864
|
async (args) => {
|
|
779
|
-
const result = await
|
|
865
|
+
const result = await apiRequest2("GET", `/api/knowledge/${args.knowledge_id}`);
|
|
780
866
|
if (!result.success || !result.knowledge) {
|
|
781
867
|
return { content: [{ type: "text", text: `Error: ${result.error || "Knowledge not found"}` }], isError: true };
|
|
782
868
|
}
|
|
@@ -819,7 +905,7 @@ DO NOT USE WHEN:
|
|
|
819
905
|
}
|
|
820
906
|
},
|
|
821
907
|
async (args) => {
|
|
822
|
-
const result = await
|
|
908
|
+
const result = await apiRequest2(
|
|
823
909
|
"POST",
|
|
824
910
|
"/api/search/semantic",
|
|
825
911
|
{
|
|
@@ -880,7 +966,7 @@ DO NOT USE WHEN:
|
|
|
880
966
|
}
|
|
881
967
|
},
|
|
882
968
|
async (args) => {
|
|
883
|
-
const result = await
|
|
969
|
+
const result = await apiRequest2(
|
|
884
970
|
"POST",
|
|
885
971
|
"/api/search/text",
|
|
886
972
|
{
|
|
@@ -940,13 +1026,13 @@ This is the recommended default search for most queries.`,
|
|
|
940
1026
|
},
|
|
941
1027
|
async (args) => {
|
|
942
1028
|
const [semanticResult, textResult] = await Promise.all([
|
|
943
|
-
|
|
1029
|
+
apiRequest2("POST", "/api/search/semantic", {
|
|
944
1030
|
query: args.query,
|
|
945
1031
|
types: ["knowledge"],
|
|
946
1032
|
limit: 50,
|
|
947
1033
|
threshold: 0.4
|
|
948
1034
|
}),
|
|
949
|
-
|
|
1035
|
+
apiRequest2("POST", "/api/search/text", {
|
|
950
1036
|
query: args.query,
|
|
951
1037
|
types: ["knowledge"],
|
|
952
1038
|
limit: 50
|
|
@@ -1019,7 +1105,7 @@ USE THIS WHEN:
|
|
|
1019
1105
|
}
|
|
1020
1106
|
},
|
|
1021
1107
|
async (args) => {
|
|
1022
|
-
const result = await
|
|
1108
|
+
const result = await apiRequest2(
|
|
1023
1109
|
"POST",
|
|
1024
1110
|
"/api/search/conversations",
|
|
1025
1111
|
{
|
|
@@ -1064,7 +1150,7 @@ ${list}`
|
|
|
1064
1150
|
}
|
|
1065
1151
|
},
|
|
1066
1152
|
async (args) => {
|
|
1067
|
-
const result = await
|
|
1153
|
+
const result = await apiRequest2(
|
|
1068
1154
|
"GET",
|
|
1069
1155
|
`/api/modules/${args.module_uid}/knowledge`
|
|
1070
1156
|
);
|
|
@@ -1095,7 +1181,7 @@ ${list}`
|
|
|
1095
1181
|
}
|
|
1096
1182
|
},
|
|
1097
1183
|
async (args) => {
|
|
1098
|
-
const result = await
|
|
1184
|
+
const result = await apiRequest2(
|
|
1099
1185
|
"POST",
|
|
1100
1186
|
`/api/modules/${args.module_uid}/knowledge/link`,
|
|
1101
1187
|
{ knowledge_id: args.knowledge_id }
|
|
@@ -1131,7 +1217,7 @@ All documentation MUST be created in the knowledge base, not as markdown files.`
|
|
|
1131
1217
|
}
|
|
1132
1218
|
},
|
|
1133
1219
|
async (args) => {
|
|
1134
|
-
const result = await
|
|
1220
|
+
const result = await apiRequest2("POST", "/api/knowledge", {
|
|
1135
1221
|
title: args.title,
|
|
1136
1222
|
domain: args.domain,
|
|
1137
1223
|
doc_type: args.doc_type,
|
|
@@ -1170,7 +1256,7 @@ All documentation MUST be created in the knowledge base, not as markdown files.`
|
|
|
1170
1256
|
if (args.domain) updates.domain = args.domain;
|
|
1171
1257
|
if (args.doc_type) updates.doc_type = args.doc_type;
|
|
1172
1258
|
if (args.significance !== void 0) updates.significance = args.significance;
|
|
1173
|
-
const result = await
|
|
1259
|
+
const result = await apiRequest2("PATCH", `/api/knowledge/${args.knowledge_id}`, updates);
|
|
1174
1260
|
if (!result.success) {
|
|
1175
1261
|
return { content: [{ type: "text", text: `Error: ${result.error}` }], isError: true };
|
|
1176
1262
|
}
|
|
@@ -1191,7 +1277,7 @@ All documentation MUST be created in the knowledge base, not as markdown files.`
|
|
|
1191
1277
|
}
|
|
1192
1278
|
},
|
|
1193
1279
|
async (args) => {
|
|
1194
|
-
const result = await
|
|
1280
|
+
const result = await apiRequest2("DELETE", `/api/knowledge/${args.knowledge_id}`);
|
|
1195
1281
|
if (!result.success) {
|
|
1196
1282
|
return { content: [{ type: "text", text: `Error: ${result.error}` }], isError: true };
|
|
1197
1283
|
}
|
|
@@ -1212,7 +1298,7 @@ All documentation MUST be created in the knowledge base, not as markdown files.`
|
|
|
1212
1298
|
}
|
|
1213
1299
|
},
|
|
1214
1300
|
async (args) => {
|
|
1215
|
-
const result = await
|
|
1301
|
+
const result = await apiRequest2(
|
|
1216
1302
|
"GET",
|
|
1217
1303
|
`/api/agent/context/module/${args.module_uid}`
|
|
1218
1304
|
);
|
|
@@ -1234,7 +1320,7 @@ All documentation MUST be created in the knowledge base, not as markdown files.`
|
|
|
1234
1320
|
inputSchema: {}
|
|
1235
1321
|
},
|
|
1236
1322
|
async () => {
|
|
1237
|
-
const result = await
|
|
1323
|
+
const result = await apiRequest2(
|
|
1238
1324
|
"GET",
|
|
1239
1325
|
"/api/agent/context/system"
|
|
1240
1326
|
);
|
|
@@ -1249,15 +1335,20 @@ All documentation MUST be created in the knowledge base, not as markdown files.`
|
|
|
1249
1335
|
};
|
|
1250
1336
|
}
|
|
1251
1337
|
);
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1338
|
+
if (process.env.EPISODA_MCP_NO_AUTOSTART !== "1") {
|
|
1339
|
+
startServer().catch((error) => {
|
|
1340
|
+
console.error("[episoda-workflow] Fatal error:", error);
|
|
1341
|
+
process.exit(1);
|
|
1342
|
+
});
|
|
1343
|
+
}
|
|
1256
1344
|
}
|
|
1257
1345
|
});
|
|
1258
1346
|
|
|
1259
1347
|
// src/git-server.ts
|
|
1260
1348
|
var git_server_exports = {};
|
|
1349
|
+
__export(git_server_exports, {
|
|
1350
|
+
startServer: () => startServer2
|
|
1351
|
+
});
|
|
1261
1352
|
import { McpServer as McpServer2 } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
1262
1353
|
import { StdioServerTransport as StdioServerTransport2 } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
1263
1354
|
import { z as z2 } from "zod";
|
|
@@ -1270,28 +1361,17 @@ async function execCommand(command, options = {}) {
|
|
|
1270
1361
|
error: "Module target missing. Provide moduleUid in the tool call or set MODULE_UID/DEV_ENVIRONMENT_ID."
|
|
1271
1362
|
};
|
|
1272
1363
|
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
const response = await fetch(url, {
|
|
1285
|
-
method: "POST",
|
|
1286
|
-
headers,
|
|
1287
|
-
body: JSON.stringify({ command, cwd, timeout })
|
|
1288
|
-
});
|
|
1289
|
-
if (!response.ok) {
|
|
1290
|
-
const text = await response.text();
|
|
1291
|
-
return { success: false, error: `API error ${response.status}: ${text}` };
|
|
1292
|
-
}
|
|
1293
|
-
const result = await response.json();
|
|
1294
|
-
return result;
|
|
1364
|
+
return executeGitCommandRequest(
|
|
1365
|
+
{
|
|
1366
|
+
apiUrl: EPISODA_API_URL2,
|
|
1367
|
+
sessionToken: EPISODA_SESSION_TOKEN2,
|
|
1368
|
+
projectId: EPISODA_PROJECT_ID2,
|
|
1369
|
+
workspaceId: EPISODA_WORKSPACE_ID2,
|
|
1370
|
+
// EP1376: Intentional parity with workflow/dev MCP servers.
|
|
1371
|
+
machineUuid: EPISODA_MACHINE_UUID2
|
|
1372
|
+
},
|
|
1373
|
+
{ target, command, cwd, timeout }
|
|
1374
|
+
);
|
|
1295
1375
|
}
|
|
1296
1376
|
function formatGitOutput(result, errorPrefix = "Git error") {
|
|
1297
1377
|
if (!result.success || !result.data) {
|
|
@@ -1313,12 +1393,13 @@ ${errorOutput}` }],
|
|
|
1313
1393
|
content: [{ type: "text", text: stdout || "(no output)" }]
|
|
1314
1394
|
};
|
|
1315
1395
|
}
|
|
1316
|
-
async function
|
|
1396
|
+
async function startServer2() {
|
|
1317
1397
|
const runtimeConfig = await hydrateRuntimeConfig();
|
|
1318
1398
|
EPISODA_API_URL2 = runtimeConfig.apiUrl;
|
|
1319
1399
|
EPISODA_SESSION_TOKEN2 = runtimeConfig.sessionToken;
|
|
1320
1400
|
EPISODA_PROJECT_ID2 = runtimeConfig.projectId;
|
|
1321
1401
|
EPISODA_WORKSPACE_ID2 = runtimeConfig.workspaceId;
|
|
1402
|
+
EPISODA_MACHINE_UUID2 = runtimeConfig.machineUuid || "";
|
|
1322
1403
|
if (!MODULE_UID && !DEV_ENVIRONMENT_ID) {
|
|
1323
1404
|
console.warn("[episoda-git] Warning: MODULE_UID/DEV_ENVIRONMENT_ID not set. Provide moduleUid per tool call.");
|
|
1324
1405
|
}
|
|
@@ -1330,17 +1411,19 @@ async function main2() {
|
|
|
1330
1411
|
console.error(`[episoda-git] Dev Target: ${devTarget}`);
|
|
1331
1412
|
console.error(`[episoda-git] Token: ${EPISODA_SESSION_TOKEN2 ? "****" : "NOT SET"}`);
|
|
1332
1413
|
}
|
|
1333
|
-
var EPISODA_API_URL2, EPISODA_SESSION_TOKEN2, DEV_ENVIRONMENT_ID, MODULE_UID, EPISODA_PROJECT_ID2, EPISODA_WORKSPACE_ID2, targetSchema, server2;
|
|
1414
|
+
var EPISODA_API_URL2, EPISODA_SESSION_TOKEN2, DEV_ENVIRONMENT_ID, MODULE_UID, EPISODA_PROJECT_ID2, EPISODA_WORKSPACE_ID2, EPISODA_MACHINE_UUID2, targetSchema, server2;
|
|
1334
1415
|
var init_git_server = __esm({
|
|
1335
1416
|
"src/git-server.ts"() {
|
|
1336
1417
|
"use strict";
|
|
1337
1418
|
init_runtime_config();
|
|
1419
|
+
init_request_executors();
|
|
1338
1420
|
EPISODA_API_URL2 = process.env.EPISODA_API_URL || "https://episoda.dev";
|
|
1339
1421
|
EPISODA_SESSION_TOKEN2 = process.env.EPISODA_SESSION_TOKEN || "";
|
|
1340
1422
|
DEV_ENVIRONMENT_ID = process.env.DEV_ENVIRONMENT_ID || "";
|
|
1341
1423
|
MODULE_UID = process.env.MODULE_UID || "";
|
|
1342
1424
|
EPISODA_PROJECT_ID2 = process.env.EPISODA_PROJECT_ID || "";
|
|
1343
1425
|
EPISODA_WORKSPACE_ID2 = process.env.EPISODA_WORKSPACE_ID || "";
|
|
1426
|
+
EPISODA_MACHINE_UUID2 = process.env.EPISODA_MACHINE_UUID || "";
|
|
1344
1427
|
targetSchema = {
|
|
1345
1428
|
moduleUid: z2.string().optional().describe("Module UID to target (overrides server default)")
|
|
1346
1429
|
};
|
|
@@ -1839,42 +1922,37 @@ var init_git_server = __esm({
|
|
|
1839
1922
|
};
|
|
1840
1923
|
}
|
|
1841
1924
|
);
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1925
|
+
if (process.env.EPISODA_MCP_NO_AUTOSTART !== "1") {
|
|
1926
|
+
startServer2().catch((error) => {
|
|
1927
|
+
console.error("[episoda-git] Fatal error:", error);
|
|
1928
|
+
process.exit(1);
|
|
1929
|
+
});
|
|
1930
|
+
}
|
|
1846
1931
|
}
|
|
1847
1932
|
});
|
|
1848
1933
|
|
|
1849
1934
|
// src/dev-server.ts
|
|
1850
1935
|
var dev_server_exports = {};
|
|
1936
|
+
__export(dev_server_exports, {
|
|
1937
|
+
startServer: () => startServer3
|
|
1938
|
+
});
|
|
1851
1939
|
import { McpServer as McpServer3 } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
1852
1940
|
import { StdioServerTransport as StdioServerTransport3 } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
1853
1941
|
import { z as z3 } from "zod";
|
|
1854
|
-
async function
|
|
1855
|
-
|
|
1856
|
-
|
|
1942
|
+
async function apiRequest3(method, path2, body) {
|
|
1943
|
+
return apiRequest(
|
|
1944
|
+
{
|
|
1945
|
+
apiUrl: EPISODA_API_URL3,
|
|
1946
|
+
sessionToken: EPISODA_SESSION_TOKEN3,
|
|
1947
|
+
projectId: EPISODA_PROJECT_ID3,
|
|
1948
|
+
workspaceId: EPISODA_WORKSPACE_ID3,
|
|
1949
|
+
// EP1376: Intentional parity with workflow/git MCP servers.
|
|
1950
|
+
machineUuid: EPISODA_MACHINE_UUID3
|
|
1951
|
+
},
|
|
1857
1952
|
method,
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
}
|
|
1862
|
-
};
|
|
1863
|
-
if (EPISODA_PROJECT_ID3) {
|
|
1864
|
-
options.headers["x-project-id"] = EPISODA_PROJECT_ID3;
|
|
1865
|
-
}
|
|
1866
|
-
if (EPISODA_WORKSPACE_ID3) {
|
|
1867
|
-
options.headers["x-workspace-id"] = EPISODA_WORKSPACE_ID3;
|
|
1868
|
-
}
|
|
1869
|
-
if (body && method !== "GET") {
|
|
1870
|
-
options.body = JSON.stringify(body);
|
|
1871
|
-
}
|
|
1872
|
-
const response = await fetch(url, options);
|
|
1873
|
-
if (!response.ok) {
|
|
1874
|
-
const text = await response.text();
|
|
1875
|
-
throw new Error(`API error ${response.status}: ${text}`);
|
|
1876
|
-
}
|
|
1877
|
-
return response.json();
|
|
1953
|
+
path2,
|
|
1954
|
+
body
|
|
1955
|
+
);
|
|
1878
1956
|
}
|
|
1879
1957
|
function devPath(endpoint, overrideTarget) {
|
|
1880
1958
|
const target = overrideTarget || MODULE_UID2 || DEV_ENVIRONMENT_ID2;
|
|
@@ -1889,12 +1967,13 @@ function formatSize(bytes) {
|
|
|
1889
1967
|
if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
1890
1968
|
return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)}GB`;
|
|
1891
1969
|
}
|
|
1892
|
-
async function
|
|
1970
|
+
async function startServer3() {
|
|
1893
1971
|
const runtimeConfig = await hydrateRuntimeConfig();
|
|
1894
1972
|
EPISODA_API_URL3 = runtimeConfig.apiUrl;
|
|
1895
1973
|
EPISODA_SESSION_TOKEN3 = runtimeConfig.sessionToken;
|
|
1896
1974
|
EPISODA_PROJECT_ID3 = runtimeConfig.projectId;
|
|
1897
1975
|
EPISODA_WORKSPACE_ID3 = runtimeConfig.workspaceId;
|
|
1976
|
+
EPISODA_MACHINE_UUID3 = runtimeConfig.machineUuid || "";
|
|
1898
1977
|
if (!MODULE_UID2 && !DEV_ENVIRONMENT_ID2) {
|
|
1899
1978
|
console.warn("[episoda-dev] Warning: MODULE_UID/DEV_ENVIRONMENT_ID not set. Provide moduleUid per tool call.");
|
|
1900
1979
|
}
|
|
@@ -1906,17 +1985,19 @@ async function main3() {
|
|
|
1906
1985
|
console.error(`[episoda-dev] Dev Target: ${devTarget}`);
|
|
1907
1986
|
console.error(`[episoda-dev] Token: ${EPISODA_SESSION_TOKEN3 ? "****" : "NOT SET"}`);
|
|
1908
1987
|
}
|
|
1909
|
-
var EPISODA_API_URL3, EPISODA_SESSION_TOKEN3, DEV_ENVIRONMENT_ID2, MODULE_UID2, EPISODA_PROJECT_ID3, EPISODA_WORKSPACE_ID3, targetSchema2, server3;
|
|
1988
|
+
var EPISODA_API_URL3, EPISODA_SESSION_TOKEN3, DEV_ENVIRONMENT_ID2, MODULE_UID2, EPISODA_PROJECT_ID3, EPISODA_WORKSPACE_ID3, EPISODA_MACHINE_UUID3, targetSchema2, server3;
|
|
1910
1989
|
var init_dev_server = __esm({
|
|
1911
1990
|
"src/dev-server.ts"() {
|
|
1912
1991
|
"use strict";
|
|
1913
1992
|
init_runtime_config();
|
|
1993
|
+
init_request_executors();
|
|
1914
1994
|
EPISODA_API_URL3 = process.env.EPISODA_API_URL || "https://episoda.dev";
|
|
1915
1995
|
EPISODA_SESSION_TOKEN3 = process.env.EPISODA_SESSION_TOKEN || "";
|
|
1916
1996
|
DEV_ENVIRONMENT_ID2 = process.env.DEV_ENVIRONMENT_ID || "";
|
|
1917
1997
|
MODULE_UID2 = process.env.MODULE_UID || "";
|
|
1918
1998
|
EPISODA_PROJECT_ID3 = process.env.EPISODA_PROJECT_ID || "";
|
|
1919
1999
|
EPISODA_WORKSPACE_ID3 = process.env.EPISODA_WORKSPACE_ID || "";
|
|
2000
|
+
EPISODA_MACHINE_UUID3 = process.env.EPISODA_MACHINE_UUID || "";
|
|
1920
2001
|
targetSchema2 = {
|
|
1921
2002
|
moduleUid: z3.string().optional().describe("Module UID to target (overrides server default)")
|
|
1922
2003
|
};
|
|
@@ -1957,7 +2038,7 @@ var init_dev_server = __esm({
|
|
|
1957
2038
|
},
|
|
1958
2039
|
async (args) => {
|
|
1959
2040
|
try {
|
|
1960
|
-
const result = await
|
|
2041
|
+
const result = await apiRequest3(
|
|
1961
2042
|
"POST",
|
|
1962
2043
|
devPath("/read-file", args.moduleUid),
|
|
1963
2044
|
{
|
|
@@ -1996,7 +2077,7 @@ var init_dev_server = __esm({
|
|
|
1996
2077
|
},
|
|
1997
2078
|
async (args) => {
|
|
1998
2079
|
try {
|
|
1999
|
-
const result = await
|
|
2080
|
+
const result = await apiRequest3(
|
|
2000
2081
|
"POST",
|
|
2001
2082
|
devPath("/write-file", args.moduleUid),
|
|
2002
2083
|
{
|
|
@@ -2040,7 +2121,7 @@ var init_dev_server = __esm({
|
|
|
2040
2121
|
},
|
|
2041
2122
|
async (args) => {
|
|
2042
2123
|
try {
|
|
2043
|
-
const result = await
|
|
2124
|
+
const result = await apiRequest3(
|
|
2044
2125
|
"POST",
|
|
2045
2126
|
devPath("/edit-file", args.moduleUid),
|
|
2046
2127
|
{
|
|
@@ -2088,7 +2169,7 @@ var init_dev_server = __esm({
|
|
|
2088
2169
|
},
|
|
2089
2170
|
async (args) => {
|
|
2090
2171
|
try {
|
|
2091
|
-
const result = await
|
|
2172
|
+
const result = await apiRequest3(
|
|
2092
2173
|
"DELETE",
|
|
2093
2174
|
`${devPath("/delete-file", args.moduleUid)}?path=${encodeURIComponent(args.path)}&recursive=${args.recursive || false}`
|
|
2094
2175
|
);
|
|
@@ -2122,7 +2203,7 @@ var init_dev_server = __esm({
|
|
|
2122
2203
|
},
|
|
2123
2204
|
async (args) => {
|
|
2124
2205
|
try {
|
|
2125
|
-
const result = await
|
|
2206
|
+
const result = await apiRequest3(
|
|
2126
2207
|
"POST",
|
|
2127
2208
|
devPath("/list-dir", args.moduleUid),
|
|
2128
2209
|
{
|
|
@@ -2169,7 +2250,7 @@ var init_dev_server = __esm({
|
|
|
2169
2250
|
},
|
|
2170
2251
|
async (args) => {
|
|
2171
2252
|
try {
|
|
2172
|
-
const result = await
|
|
2253
|
+
const result = await apiRequest3(
|
|
2173
2254
|
"POST",
|
|
2174
2255
|
devPath("/mkdir", args.moduleUid),
|
|
2175
2256
|
{ path: args.path }
|
|
@@ -2204,7 +2285,7 @@ var init_dev_server = __esm({
|
|
|
2204
2285
|
},
|
|
2205
2286
|
async (args) => {
|
|
2206
2287
|
try {
|
|
2207
|
-
const result = await
|
|
2288
|
+
const result = await apiRequest3(
|
|
2208
2289
|
"POST",
|
|
2209
2290
|
devPath("/search-files", args.moduleUid),
|
|
2210
2291
|
{
|
|
@@ -2255,7 +2336,7 @@ ${result.data.files.join("\n")}`
|
|
|
2255
2336
|
async (args) => {
|
|
2256
2337
|
try {
|
|
2257
2338
|
const flags = args.caseSensitive === false ? "-rni" : "-rn";
|
|
2258
|
-
const result = await
|
|
2339
|
+
const result = await apiRequest3(
|
|
2259
2340
|
"POST",
|
|
2260
2341
|
devPath("/grep", args.moduleUid),
|
|
2261
2342
|
{
|
|
@@ -2306,7 +2387,7 @@ ${matches}`
|
|
|
2306
2387
|
},
|
|
2307
2388
|
async (args) => {
|
|
2308
2389
|
try {
|
|
2309
|
-
const result = await
|
|
2390
|
+
const result = await apiRequest3(
|
|
2310
2391
|
"POST",
|
|
2311
2392
|
devPath("/exec", args.moduleUid),
|
|
2312
2393
|
{
|
|
@@ -2370,7 +2451,7 @@ Exit code: ${exitCode}`;
|
|
|
2370
2451
|
},
|
|
2371
2452
|
async (args) => {
|
|
2372
2453
|
try {
|
|
2373
|
-
const result = await
|
|
2454
|
+
const result = await apiRequest3(
|
|
2374
2455
|
"POST",
|
|
2375
2456
|
devPath("/batch", args.moduleUid),
|
|
2376
2457
|
{
|
|
@@ -2407,10 +2488,12 @@ Exit code: ${exitCode}`;
|
|
|
2407
2488
|
}
|
|
2408
2489
|
}
|
|
2409
2490
|
);
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2491
|
+
if (process.env.EPISODA_MCP_NO_AUTOSTART !== "1") {
|
|
2492
|
+
startServer3().catch((error) => {
|
|
2493
|
+
console.error("[episoda-dev] Fatal error:", error);
|
|
2494
|
+
process.exit(1);
|
|
2495
|
+
});
|
|
2496
|
+
}
|
|
2414
2497
|
}
|
|
2415
2498
|
});
|
|
2416
2499
|
|
|
@@ -2419,7 +2502,7 @@ var usage = () => {
|
|
|
2419
2502
|
console.error("Usage: @episoda/mcp <workflow|git|dev>");
|
|
2420
2503
|
console.error("Aliases: episoda-workflow, episoda-git, episoda-dev");
|
|
2421
2504
|
};
|
|
2422
|
-
async function
|
|
2505
|
+
async function main() {
|
|
2423
2506
|
const [server4] = process.argv.slice(2);
|
|
2424
2507
|
if (!server4 || server4 === "-h" || server4 === "--help" || server4 === "help") {
|
|
2425
2508
|
usage();
|
|
@@ -2444,7 +2527,7 @@ async function main4() {
|
|
|
2444
2527
|
process.exit(2);
|
|
2445
2528
|
}
|
|
2446
2529
|
}
|
|
2447
|
-
|
|
2530
|
+
main().catch((error) => {
|
|
2448
2531
|
console.error("[episoda-mcp] Fatal error:", error);
|
|
2449
2532
|
process.exit(1);
|
|
2450
2533
|
});
|