@speakai/mcp-server 1.0.2 → 1.0.4
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/index.js +858 -215
- package/package.json +3 -1
package/dist/index.js
CHANGED
|
@@ -6,6 +6,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __esm = (fn, res) => function __init() {
|
|
10
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
11
|
+
};
|
|
9
12
|
var __export = (target, all) => {
|
|
10
13
|
for (var name in all)
|
|
11
14
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -28,45 +31,32 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
31
|
));
|
|
29
32
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
33
|
|
|
31
|
-
// src/
|
|
32
|
-
var
|
|
33
|
-
__export(
|
|
34
|
+
// src/client.ts
|
|
35
|
+
var client_exports = {};
|
|
36
|
+
__export(client_exports, {
|
|
34
37
|
createSpeakClient: () => createSpeakClient,
|
|
35
38
|
formatAxiosError: () => formatAxiosError,
|
|
36
|
-
|
|
39
|
+
speakClient: () => speakClient
|
|
37
40
|
});
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
var media_exports = {};
|
|
44
|
-
__export(media_exports, {
|
|
45
|
-
register: () => register
|
|
46
|
-
});
|
|
47
|
-
var import_zod = require("zod");
|
|
48
|
-
|
|
49
|
-
// src/client.ts
|
|
50
|
-
var import_axios = __toESM(require("axios"));
|
|
51
|
-
var BASE_URL = process.env.SPEAK_BASE_URL ?? "https://api.speakai.co";
|
|
52
|
-
var API_KEY = process.env.SPEAK_API_KEY ?? "";
|
|
53
|
-
if (!API_KEY && !process.env.SPEAK_MCP_LIBRARY_MODE) {
|
|
54
|
-
process.stderr.write(
|
|
55
|
-
"[speak-mcp] Warning: SPEAK_API_KEY is not set. All requests will fail.\n"
|
|
56
|
-
);
|
|
41
|
+
function getBaseUrl() {
|
|
42
|
+
return process.env.SPEAK_BASE_URL ?? "https://api.speakai.co";
|
|
43
|
+
}
|
|
44
|
+
function getApiKey() {
|
|
45
|
+
return process.env.SPEAK_API_KEY ?? "";
|
|
57
46
|
}
|
|
58
|
-
var accessToken = process.env.SPEAK_ACCESS_TOKEN ?? "";
|
|
59
|
-
var refreshToken = "";
|
|
60
|
-
var tokenExpiresAt = 0;
|
|
61
47
|
async function authenticate() {
|
|
48
|
+
const apiKey = getApiKey();
|
|
49
|
+
if (!apiKey) {
|
|
50
|
+
throw new Error("SPEAK_API_KEY is not set. Run 'speak-mcp config set-key' or set the environment variable.");
|
|
51
|
+
}
|
|
62
52
|
try {
|
|
63
53
|
const res = await import_axios.default.post(
|
|
64
|
-
`${
|
|
54
|
+
`${getBaseUrl()}/v1/auth/accessToken`,
|
|
65
55
|
{},
|
|
66
56
|
{
|
|
67
57
|
headers: {
|
|
68
58
|
"Content-Type": "application/json",
|
|
69
|
-
"x-speakai-key":
|
|
59
|
+
"x-speakai-key": apiKey
|
|
70
60
|
}
|
|
71
61
|
}
|
|
72
62
|
);
|
|
@@ -89,12 +79,12 @@ async function refreshAccessToken() {
|
|
|
89
79
|
}
|
|
90
80
|
try {
|
|
91
81
|
const res = await import_axios.default.post(
|
|
92
|
-
`${
|
|
82
|
+
`${getBaseUrl()}/v1/auth/refreshToken`,
|
|
93
83
|
{ refreshToken },
|
|
94
84
|
{
|
|
95
85
|
headers: {
|
|
96
86
|
"Content-Type": "application/json",
|
|
97
|
-
"x-speakai-key":
|
|
87
|
+
"x-speakai-key": getApiKey(),
|
|
98
88
|
"x-access-token": accessToken
|
|
99
89
|
}
|
|
100
90
|
}
|
|
@@ -118,34 +108,6 @@ async function ensureAuthenticated() {
|
|
|
118
108
|
}
|
|
119
109
|
}
|
|
120
110
|
}
|
|
121
|
-
var speakClient = import_axios.default.create({
|
|
122
|
-
baseURL: BASE_URL,
|
|
123
|
-
headers: { "Content-Type": "application/json" },
|
|
124
|
-
timeout: 6e4
|
|
125
|
-
});
|
|
126
|
-
speakClient.interceptors.request.use(
|
|
127
|
-
async (config) => {
|
|
128
|
-
await ensureAuthenticated();
|
|
129
|
-
config.headers.set("x-speakai-key", API_KEY);
|
|
130
|
-
config.headers.set("x-access-token", accessToken);
|
|
131
|
-
return config;
|
|
132
|
-
}
|
|
133
|
-
);
|
|
134
|
-
speakClient.interceptors.response.use(
|
|
135
|
-
(response) => response,
|
|
136
|
-
async (error) => {
|
|
137
|
-
const originalRequest = error.config;
|
|
138
|
-
if (error.response?.status === 401 && !originalRequest._retried) {
|
|
139
|
-
originalRequest._retried = true;
|
|
140
|
-
tokenExpiresAt = 0;
|
|
141
|
-
await ensureAuthenticated();
|
|
142
|
-
originalRequest.headers["x-speakai-key"] = API_KEY;
|
|
143
|
-
originalRequest.headers["x-access-token"] = accessToken;
|
|
144
|
-
return speakClient(originalRequest);
|
|
145
|
-
}
|
|
146
|
-
return Promise.reject(error);
|
|
147
|
-
}
|
|
148
|
-
);
|
|
149
111
|
function createSpeakClient(options) {
|
|
150
112
|
return import_axios.default.create({
|
|
151
113
|
baseURL: options.baseUrl,
|
|
@@ -167,16 +129,59 @@ function formatAxiosError(error) {
|
|
|
167
129
|
if (error instanceof Error) return error.message;
|
|
168
130
|
return String(error);
|
|
169
131
|
}
|
|
132
|
+
var import_axios, accessToken, refreshToken, tokenExpiresAt, speakClient;
|
|
133
|
+
var init_client = __esm({
|
|
134
|
+
"src/client.ts"() {
|
|
135
|
+
"use strict";
|
|
136
|
+
import_axios = __toESM(require("axios"));
|
|
137
|
+
accessToken = process.env.SPEAK_ACCESS_TOKEN ?? "";
|
|
138
|
+
refreshToken = "";
|
|
139
|
+
tokenExpiresAt = 0;
|
|
140
|
+
speakClient = import_axios.default.create({
|
|
141
|
+
headers: { "Content-Type": "application/json" },
|
|
142
|
+
timeout: 6e4
|
|
143
|
+
});
|
|
144
|
+
speakClient.interceptors.request.use(
|
|
145
|
+
async (config) => {
|
|
146
|
+
config.baseURL = getBaseUrl();
|
|
147
|
+
await ensureAuthenticated();
|
|
148
|
+
config.headers.set("x-speakai-key", getApiKey());
|
|
149
|
+
config.headers.set("x-access-token", accessToken);
|
|
150
|
+
return config;
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
speakClient.interceptors.response.use(
|
|
154
|
+
(response) => response,
|
|
155
|
+
async (error) => {
|
|
156
|
+
const originalRequest = error.config;
|
|
157
|
+
const retryCount = originalRequest._retryCount ?? 0;
|
|
158
|
+
if (error.response?.status === 401 && retryCount < 2) {
|
|
159
|
+
originalRequest._retryCount = retryCount + 1;
|
|
160
|
+
tokenExpiresAt = 0;
|
|
161
|
+
await ensureAuthenticated();
|
|
162
|
+
originalRequest.headers["x-speakai-key"] = getApiKey();
|
|
163
|
+
originalRequest.headers["x-access-token"] = accessToken;
|
|
164
|
+
return speakClient(originalRequest);
|
|
165
|
+
}
|
|
166
|
+
return Promise.reject(error);
|
|
167
|
+
}
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
170
171
|
|
|
171
172
|
// src/tools/media.ts
|
|
172
|
-
|
|
173
|
+
var media_exports = {};
|
|
174
|
+
__export(media_exports, {
|
|
175
|
+
register: () => register
|
|
176
|
+
});
|
|
177
|
+
function register(server, client) {
|
|
173
178
|
const api = client ?? speakClient;
|
|
174
|
-
|
|
179
|
+
server.tool(
|
|
175
180
|
"get_signed_upload_url",
|
|
176
181
|
"Get a pre-signed S3 URL for direct media file upload. Use this before uploading a file directly to Speak AI storage.",
|
|
177
182
|
{
|
|
178
183
|
isVideo: import_zod.z.boolean().describe("Set true for video files, false for audio files"),
|
|
179
|
-
filename: import_zod.z.string().describe("Original filename including extension"),
|
|
184
|
+
filename: import_zod.z.string().min(1).describe("Original filename including extension"),
|
|
180
185
|
mimeType: import_zod.z.string().describe('MIME type of the file, e.g. "audio/mp4" or "video/mp4"')
|
|
181
186
|
},
|
|
182
187
|
async ({ isVideo, filename, mimeType }) => {
|
|
@@ -197,11 +202,11 @@ function register(server2, client) {
|
|
|
197
202
|
}
|
|
198
203
|
}
|
|
199
204
|
);
|
|
200
|
-
|
|
205
|
+
server.tool(
|
|
201
206
|
"upload_media",
|
|
202
207
|
"Upload a media file to Speak AI by providing a publicly accessible URL. Speak AI will fetch and process the file asynchronously.",
|
|
203
208
|
{
|
|
204
|
-
name: import_zod.z.string().describe("Display name for the media file"),
|
|
209
|
+
name: import_zod.z.string().min(1).describe("Display name for the media file"),
|
|
205
210
|
url: import_zod.z.string().describe("Publicly accessible URL of the media file (or pre-signed S3 URL)"),
|
|
206
211
|
mediaType: import_zod.z.enum(["audio", "video"]).describe('Type of media: "audio" or "video"'),
|
|
207
212
|
description: import_zod.z.string().optional().describe("Description of the media file"),
|
|
@@ -211,8 +216,8 @@ function register(server2, client) {
|
|
|
211
216
|
callbackUrl: import_zod.z.string().optional().describe("Webhook callback URL for this specific upload"),
|
|
212
217
|
fields: import_zod.z.array(
|
|
213
218
|
import_zod.z.object({
|
|
214
|
-
id: import_zod.z.string().describe("Custom field ID"),
|
|
215
|
-
value: import_zod.z.string().describe("Custom field value")
|
|
219
|
+
id: import_zod.z.string().min(1).describe("Custom field ID"),
|
|
220
|
+
value: import_zod.z.string().min(1).describe("Custom field value")
|
|
216
221
|
})
|
|
217
222
|
).optional().describe("Custom field values to attach to the media")
|
|
218
223
|
},
|
|
@@ -232,7 +237,7 @@ function register(server2, client) {
|
|
|
232
237
|
}
|
|
233
238
|
}
|
|
234
239
|
);
|
|
235
|
-
|
|
240
|
+
server.tool(
|
|
236
241
|
"list_media",
|
|
237
242
|
"List all media files in the workspace with optional filtering, pagination, and sorting.",
|
|
238
243
|
{
|
|
@@ -263,11 +268,11 @@ function register(server2, client) {
|
|
|
263
268
|
}
|
|
264
269
|
}
|
|
265
270
|
);
|
|
266
|
-
|
|
271
|
+
server.tool(
|
|
267
272
|
"get_media_insights",
|
|
268
273
|
"Retrieve AI-generated insights for a media file, including topics, sentiment, action items, and summaries.",
|
|
269
274
|
{
|
|
270
|
-
mediaId: import_zod.z.string().describe("Unique identifier of the media file")
|
|
275
|
+
mediaId: import_zod.z.string().min(1).describe("Unique identifier of the media file")
|
|
271
276
|
},
|
|
272
277
|
async ({ mediaId }) => {
|
|
273
278
|
try {
|
|
@@ -285,11 +290,11 @@ function register(server2, client) {
|
|
|
285
290
|
}
|
|
286
291
|
}
|
|
287
292
|
);
|
|
288
|
-
|
|
293
|
+
server.tool(
|
|
289
294
|
"get_transcript",
|
|
290
295
|
"Retrieve the full transcript for a media file, including speaker labels and timestamps.",
|
|
291
296
|
{
|
|
292
|
-
mediaId: import_zod.z.string().describe("Unique identifier of the media file")
|
|
297
|
+
mediaId: import_zod.z.string().min(1).describe("Unique identifier of the media file")
|
|
293
298
|
},
|
|
294
299
|
async ({ mediaId }) => {
|
|
295
300
|
try {
|
|
@@ -307,15 +312,15 @@ function register(server2, client) {
|
|
|
307
312
|
}
|
|
308
313
|
}
|
|
309
314
|
);
|
|
310
|
-
|
|
315
|
+
server.tool(
|
|
311
316
|
"update_transcript_speakers",
|
|
312
317
|
"Update or rename speaker labels in a media transcript.",
|
|
313
318
|
{
|
|
314
|
-
mediaId: import_zod.z.string().describe("Unique identifier of the media file"),
|
|
319
|
+
mediaId: import_zod.z.string().min(1).describe("Unique identifier of the media file"),
|
|
315
320
|
speakers: import_zod.z.array(
|
|
316
321
|
import_zod.z.object({
|
|
317
|
-
id: import_zod.z.string().describe("Speaker identifier from the transcript"),
|
|
318
|
-
name: import_zod.z.string().describe("Display name to assign to the speaker")
|
|
322
|
+
id: import_zod.z.string().min(1).describe("Speaker identifier from the transcript"),
|
|
323
|
+
name: import_zod.z.string().min(1).describe("Display name to assign to the speaker")
|
|
319
324
|
})
|
|
320
325
|
).describe("Array of speaker ID to name mappings")
|
|
321
326
|
},
|
|
@@ -338,11 +343,11 @@ function register(server2, client) {
|
|
|
338
343
|
}
|
|
339
344
|
}
|
|
340
345
|
);
|
|
341
|
-
|
|
346
|
+
server.tool(
|
|
342
347
|
"get_media_status",
|
|
343
348
|
"Check the processing status of a media file (e.g. pending, transcribing, completed, failed).",
|
|
344
349
|
{
|
|
345
|
-
mediaId: import_zod.z.string().describe("Unique identifier of the media file")
|
|
350
|
+
mediaId: import_zod.z.string().min(1).describe("Unique identifier of the media file")
|
|
346
351
|
},
|
|
347
352
|
async ({ mediaId }) => {
|
|
348
353
|
try {
|
|
@@ -360,11 +365,11 @@ function register(server2, client) {
|
|
|
360
365
|
}
|
|
361
366
|
}
|
|
362
367
|
);
|
|
363
|
-
|
|
368
|
+
server.tool(
|
|
364
369
|
"update_media_metadata",
|
|
365
370
|
"Update metadata fields (name, description, tags, status) for an existing media file.",
|
|
366
371
|
{
|
|
367
|
-
mediaId: import_zod.z.string().describe("Unique identifier of the media file"),
|
|
372
|
+
mediaId: import_zod.z.string().min(1).describe("Unique identifier of the media file"),
|
|
368
373
|
name: import_zod.z.string().optional().describe("New display name for the media"),
|
|
369
374
|
description: import_zod.z.string().optional().describe("Description or notes for the media"),
|
|
370
375
|
folderId: import_zod.z.string().optional().describe("Move media to this folder ID"),
|
|
@@ -389,11 +394,11 @@ function register(server2, client) {
|
|
|
389
394
|
}
|
|
390
395
|
}
|
|
391
396
|
);
|
|
392
|
-
|
|
397
|
+
server.tool(
|
|
393
398
|
"delete_media",
|
|
394
399
|
"Permanently delete a media file and all associated transcripts and insights.",
|
|
395
400
|
{
|
|
396
|
-
mediaId: import_zod.z.string().describe("Unique identifier of the media file to delete")
|
|
401
|
+
mediaId: import_zod.z.string().min(1).describe("Unique identifier of the media file to delete")
|
|
397
402
|
},
|
|
398
403
|
async ({ mediaId }) => {
|
|
399
404
|
try {
|
|
@@ -412,20 +417,27 @@ function register(server2, client) {
|
|
|
412
417
|
}
|
|
413
418
|
);
|
|
414
419
|
}
|
|
420
|
+
var import_zod;
|
|
421
|
+
var init_media = __esm({
|
|
422
|
+
"src/tools/media.ts"() {
|
|
423
|
+
"use strict";
|
|
424
|
+
import_zod = require("zod");
|
|
425
|
+
init_client();
|
|
426
|
+
}
|
|
427
|
+
});
|
|
415
428
|
|
|
416
429
|
// src/tools/text.ts
|
|
417
430
|
var text_exports = {};
|
|
418
431
|
__export(text_exports, {
|
|
419
432
|
register: () => register2
|
|
420
433
|
});
|
|
421
|
-
|
|
422
|
-
function register2(server2, client) {
|
|
434
|
+
function register2(server, client) {
|
|
423
435
|
const api = client ?? speakClient;
|
|
424
|
-
|
|
436
|
+
server.tool(
|
|
425
437
|
"create_text_note",
|
|
426
438
|
"Create a new text note in Speak AI for analysis. The content will be analyzed for insights, topics, and sentiment.",
|
|
427
439
|
{
|
|
428
|
-
name: import_zod2.z.string().describe("Title/name for the text note"),
|
|
440
|
+
name: import_zod2.z.string().min(1).describe("Title/name for the text note"),
|
|
429
441
|
text: import_zod2.z.string().optional().describe("Full text content to analyze"),
|
|
430
442
|
description: import_zod2.z.string().optional().describe("Description for the text note"),
|
|
431
443
|
folderId: import_zod2.z.string().optional().describe("ID of the folder to place the note in"),
|
|
@@ -433,8 +445,8 @@ function register2(server2, client) {
|
|
|
433
445
|
callbackUrl: import_zod2.z.string().optional().describe("Webhook callback URL for completion notification"),
|
|
434
446
|
fields: import_zod2.z.array(
|
|
435
447
|
import_zod2.z.object({
|
|
436
|
-
id: import_zod2.z.string().describe("Custom field ID"),
|
|
437
|
-
value: import_zod2.z.string().describe("Custom field value")
|
|
448
|
+
id: import_zod2.z.string().min(1).describe("Custom field ID"),
|
|
449
|
+
value: import_zod2.z.string().min(1).describe("Custom field value")
|
|
438
450
|
})
|
|
439
451
|
).optional().describe("Custom field values to attach to the text note")
|
|
440
452
|
},
|
|
@@ -454,11 +466,11 @@ function register2(server2, client) {
|
|
|
454
466
|
}
|
|
455
467
|
}
|
|
456
468
|
);
|
|
457
|
-
|
|
469
|
+
server.tool(
|
|
458
470
|
"get_text_insight",
|
|
459
471
|
"Retrieve AI-generated insights for a text note, including topics, sentiment, summaries, and action items.",
|
|
460
472
|
{
|
|
461
|
-
mediaId: import_zod2.z.string().describe("Unique identifier of the text note")
|
|
473
|
+
mediaId: import_zod2.z.string().min(1).describe("Unique identifier of the text note")
|
|
462
474
|
},
|
|
463
475
|
async ({ mediaId }) => {
|
|
464
476
|
try {
|
|
@@ -476,7 +488,7 @@ function register2(server2, client) {
|
|
|
476
488
|
}
|
|
477
489
|
}
|
|
478
490
|
);
|
|
479
|
-
|
|
491
|
+
server.tool(
|
|
480
492
|
"reanalyze_text",
|
|
481
493
|
"Trigger a re-analysis of an existing text note to regenerate insights with the latest AI models.",
|
|
482
494
|
{
|
|
@@ -498,11 +510,11 @@ function register2(server2, client) {
|
|
|
498
510
|
}
|
|
499
511
|
}
|
|
500
512
|
);
|
|
501
|
-
|
|
513
|
+
server.tool(
|
|
502
514
|
"update_text_note",
|
|
503
515
|
"Update an existing text note's name, content, or metadata. Updating text content will trigger re-analysis.",
|
|
504
516
|
{
|
|
505
|
-
mediaId: import_zod2.z.string().describe("Unique identifier of the text note"),
|
|
517
|
+
mediaId: import_zod2.z.string().min(1).describe("Unique identifier of the text note"),
|
|
506
518
|
name: import_zod2.z.string().optional().describe("New name for the text note"),
|
|
507
519
|
text: import_zod2.z.string().optional().describe("New text content (will trigger re-analysis)"),
|
|
508
520
|
description: import_zod2.z.string().optional().describe("Updated description"),
|
|
@@ -529,20 +541,27 @@ function register2(server2, client) {
|
|
|
529
541
|
}
|
|
530
542
|
);
|
|
531
543
|
}
|
|
544
|
+
var import_zod2;
|
|
545
|
+
var init_text = __esm({
|
|
546
|
+
"src/tools/text.ts"() {
|
|
547
|
+
"use strict";
|
|
548
|
+
import_zod2 = require("zod");
|
|
549
|
+
init_client();
|
|
550
|
+
}
|
|
551
|
+
});
|
|
532
552
|
|
|
533
553
|
// src/tools/exports.ts
|
|
534
554
|
var exports_exports = {};
|
|
535
555
|
__export(exports_exports, {
|
|
536
556
|
register: () => register3
|
|
537
557
|
});
|
|
538
|
-
|
|
539
|
-
function register3(server2, client) {
|
|
558
|
+
function register3(server, client) {
|
|
540
559
|
const api = client ?? speakClient;
|
|
541
|
-
|
|
560
|
+
server.tool(
|
|
542
561
|
"export_media",
|
|
543
562
|
"Export a media file's transcript or insights in various formats (pdf, docx, srt, vtt, txt, csv, md).",
|
|
544
563
|
{
|
|
545
|
-
mediaId: import_zod3.z.string().describe("Unique identifier of the media file"),
|
|
564
|
+
mediaId: import_zod3.z.string().min(1).describe("Unique identifier of the media file"),
|
|
546
565
|
fileType: import_zod3.z.enum(["pdf", "docx", "srt", "vtt", "txt", "csv", "md"]).describe("Desired export format"),
|
|
547
566
|
isSpeakerNames: import_zod3.z.boolean().optional().describe("Include speaker names in export"),
|
|
548
567
|
isSpeakerEmail: import_zod3.z.boolean().optional().describe("Include speaker emails in export"),
|
|
@@ -571,7 +590,7 @@ function register3(server2, client) {
|
|
|
571
590
|
}
|
|
572
591
|
}
|
|
573
592
|
);
|
|
574
|
-
|
|
593
|
+
server.tool(
|
|
575
594
|
"export_multiple_media",
|
|
576
595
|
"Export multiple media files at once, optionally merged into a single file.",
|
|
577
596
|
{
|
|
@@ -605,16 +624,23 @@ function register3(server2, client) {
|
|
|
605
624
|
}
|
|
606
625
|
);
|
|
607
626
|
}
|
|
627
|
+
var import_zod3;
|
|
628
|
+
var init_exports = __esm({
|
|
629
|
+
"src/tools/exports.ts"() {
|
|
630
|
+
"use strict";
|
|
631
|
+
import_zod3 = require("zod");
|
|
632
|
+
init_client();
|
|
633
|
+
}
|
|
634
|
+
});
|
|
608
635
|
|
|
609
636
|
// src/tools/folders.ts
|
|
610
637
|
var folders_exports = {};
|
|
611
638
|
__export(folders_exports, {
|
|
612
639
|
register: () => register4
|
|
613
640
|
});
|
|
614
|
-
|
|
615
|
-
function register4(server2, client) {
|
|
641
|
+
function register4(server, client) {
|
|
616
642
|
const api = client ?? speakClient;
|
|
617
|
-
|
|
643
|
+
server.tool(
|
|
618
644
|
"get_all_folder_views",
|
|
619
645
|
"Retrieve all saved views across all folders.",
|
|
620
646
|
{},
|
|
@@ -634,11 +660,11 @@ function register4(server2, client) {
|
|
|
634
660
|
}
|
|
635
661
|
}
|
|
636
662
|
);
|
|
637
|
-
|
|
663
|
+
server.tool(
|
|
638
664
|
"get_folder_views",
|
|
639
665
|
"Retrieve all saved views for a specific folder.",
|
|
640
666
|
{
|
|
641
|
-
folderId: import_zod4.z.string().describe("Unique identifier of the folder")
|
|
667
|
+
folderId: import_zod4.z.string().min(1).describe("Unique identifier of the folder")
|
|
642
668
|
},
|
|
643
669
|
async ({ folderId }) => {
|
|
644
670
|
try {
|
|
@@ -656,11 +682,11 @@ function register4(server2, client) {
|
|
|
656
682
|
}
|
|
657
683
|
}
|
|
658
684
|
);
|
|
659
|
-
|
|
685
|
+
server.tool(
|
|
660
686
|
"create_folder_view",
|
|
661
687
|
"Create a new saved view for a folder with custom filters and display settings.",
|
|
662
688
|
{
|
|
663
|
-
folderId: import_zod4.z.string().describe("Unique identifier of the folder"),
|
|
689
|
+
folderId: import_zod4.z.string().min(1).describe("Unique identifier of the folder"),
|
|
664
690
|
name: import_zod4.z.string().optional().describe("Display name for the view"),
|
|
665
691
|
filters: import_zod4.z.record(import_zod4.z.unknown()).optional().describe("Filter configuration object")
|
|
666
692
|
},
|
|
@@ -683,12 +709,12 @@ function register4(server2, client) {
|
|
|
683
709
|
}
|
|
684
710
|
}
|
|
685
711
|
);
|
|
686
|
-
|
|
712
|
+
server.tool(
|
|
687
713
|
"update_folder_view",
|
|
688
714
|
"Update an existing saved view's name, filters, or display settings.",
|
|
689
715
|
{
|
|
690
|
-
folderId: import_zod4.z.string().describe("Unique identifier of the folder"),
|
|
691
|
-
viewId: import_zod4.z.string().describe("Unique identifier of the view to update"),
|
|
716
|
+
folderId: import_zod4.z.string().min(1).describe("Unique identifier of the folder"),
|
|
717
|
+
viewId: import_zod4.z.string().min(1).describe("Unique identifier of the view to update"),
|
|
692
718
|
name: import_zod4.z.string().optional().describe("New display name for the view"),
|
|
693
719
|
filters: import_zod4.z.record(import_zod4.z.unknown()).optional().describe("Updated filter configuration")
|
|
694
720
|
},
|
|
@@ -711,11 +737,11 @@ function register4(server2, client) {
|
|
|
711
737
|
}
|
|
712
738
|
}
|
|
713
739
|
);
|
|
714
|
-
|
|
740
|
+
server.tool(
|
|
715
741
|
"clone_folder_view",
|
|
716
742
|
"Duplicate an existing folder view.",
|
|
717
743
|
{
|
|
718
|
-
viewId: import_zod4.z.string().describe("Unique identifier of the view to clone")
|
|
744
|
+
viewId: import_zod4.z.string().min(1).describe("Unique identifier of the view to clone")
|
|
719
745
|
},
|
|
720
746
|
async (body) => {
|
|
721
747
|
try {
|
|
@@ -733,7 +759,7 @@ function register4(server2, client) {
|
|
|
733
759
|
}
|
|
734
760
|
}
|
|
735
761
|
);
|
|
736
|
-
|
|
762
|
+
server.tool(
|
|
737
763
|
"list_folders",
|
|
738
764
|
"List all folders in the workspace with pagination and sorting.",
|
|
739
765
|
{
|
|
@@ -757,11 +783,11 @@ function register4(server2, client) {
|
|
|
757
783
|
}
|
|
758
784
|
}
|
|
759
785
|
);
|
|
760
|
-
|
|
786
|
+
server.tool(
|
|
761
787
|
"get_folder_info",
|
|
762
788
|
"Get detailed information about a specific folder including its contents.",
|
|
763
789
|
{
|
|
764
|
-
folderId: import_zod4.z.string().describe("Unique identifier of the folder")
|
|
790
|
+
folderId: import_zod4.z.string().min(1).describe("Unique identifier of the folder")
|
|
765
791
|
},
|
|
766
792
|
async ({ folderId }) => {
|
|
767
793
|
try {
|
|
@@ -779,11 +805,11 @@ function register4(server2, client) {
|
|
|
779
805
|
}
|
|
780
806
|
}
|
|
781
807
|
);
|
|
782
|
-
|
|
808
|
+
server.tool(
|
|
783
809
|
"create_folder",
|
|
784
810
|
"Create a new folder in the workspace.",
|
|
785
811
|
{
|
|
786
|
-
name: import_zod4.z.string().describe("Display name for the new folder"),
|
|
812
|
+
name: import_zod4.z.string().min(1).describe("Display name for the new folder"),
|
|
787
813
|
parentFolderId: import_zod4.z.string().optional().describe("ID of the parent folder for nesting")
|
|
788
814
|
},
|
|
789
815
|
async (body) => {
|
|
@@ -802,11 +828,11 @@ function register4(server2, client) {
|
|
|
802
828
|
}
|
|
803
829
|
}
|
|
804
830
|
);
|
|
805
|
-
|
|
831
|
+
server.tool(
|
|
806
832
|
"clone_folder",
|
|
807
833
|
"Duplicate an existing folder and all of its contents.",
|
|
808
834
|
{
|
|
809
|
-
folderId: import_zod4.z.string().describe("ID of the folder to clone")
|
|
835
|
+
folderId: import_zod4.z.string().min(1).describe("ID of the folder to clone")
|
|
810
836
|
},
|
|
811
837
|
async (body) => {
|
|
812
838
|
try {
|
|
@@ -824,11 +850,11 @@ function register4(server2, client) {
|
|
|
824
850
|
}
|
|
825
851
|
}
|
|
826
852
|
);
|
|
827
|
-
|
|
853
|
+
server.tool(
|
|
828
854
|
"update_folder",
|
|
829
855
|
"Update a folder's name or other properties.",
|
|
830
856
|
{
|
|
831
|
-
folderId: import_zod4.z.string().describe("Unique identifier of the folder"),
|
|
857
|
+
folderId: import_zod4.z.string().min(1).describe("Unique identifier of the folder"),
|
|
832
858
|
name: import_zod4.z.string().optional().describe("New display name for the folder")
|
|
833
859
|
},
|
|
834
860
|
async ({ folderId, ...body }) => {
|
|
@@ -847,11 +873,11 @@ function register4(server2, client) {
|
|
|
847
873
|
}
|
|
848
874
|
}
|
|
849
875
|
);
|
|
850
|
-
|
|
876
|
+
server.tool(
|
|
851
877
|
"delete_folder",
|
|
852
878
|
"Permanently delete a folder. Media within the folder will be moved, not deleted.",
|
|
853
879
|
{
|
|
854
|
-
folderId: import_zod4.z.string().describe("Unique identifier of the folder to delete")
|
|
880
|
+
folderId: import_zod4.z.string().min(1).describe("Unique identifier of the folder to delete")
|
|
855
881
|
},
|
|
856
882
|
async ({ folderId }) => {
|
|
857
883
|
try {
|
|
@@ -870,20 +896,27 @@ function register4(server2, client) {
|
|
|
870
896
|
}
|
|
871
897
|
);
|
|
872
898
|
}
|
|
899
|
+
var import_zod4;
|
|
900
|
+
var init_folders = __esm({
|
|
901
|
+
"src/tools/folders.ts"() {
|
|
902
|
+
"use strict";
|
|
903
|
+
import_zod4 = require("zod");
|
|
904
|
+
init_client();
|
|
905
|
+
}
|
|
906
|
+
});
|
|
873
907
|
|
|
874
908
|
// src/tools/recorder.ts
|
|
875
909
|
var recorder_exports = {};
|
|
876
910
|
__export(recorder_exports, {
|
|
877
911
|
register: () => register5
|
|
878
912
|
});
|
|
879
|
-
|
|
880
|
-
function register5(server2, client) {
|
|
913
|
+
function register5(server, client) {
|
|
881
914
|
const api = client ?? speakClient;
|
|
882
|
-
|
|
915
|
+
server.tool(
|
|
883
916
|
"check_recorder_status",
|
|
884
917
|
"Check whether a recorder/survey is active and accepting submissions.",
|
|
885
918
|
{
|
|
886
|
-
token: import_zod5.z.string().describe("Unique token identifying the recorder")
|
|
919
|
+
token: import_zod5.z.string().min(1).describe("Unique token identifying the recorder")
|
|
887
920
|
},
|
|
888
921
|
async ({ token }) => {
|
|
889
922
|
try {
|
|
@@ -899,7 +932,7 @@ function register5(server2, client) {
|
|
|
899
932
|
}
|
|
900
933
|
}
|
|
901
934
|
);
|
|
902
|
-
|
|
935
|
+
server.tool(
|
|
903
936
|
"create_recorder",
|
|
904
937
|
"Create a new recorder or survey for collecting audio/video submissions.",
|
|
905
938
|
{
|
|
@@ -921,7 +954,7 @@ function register5(server2, client) {
|
|
|
921
954
|
}
|
|
922
955
|
}
|
|
923
956
|
);
|
|
924
|
-
|
|
957
|
+
server.tool(
|
|
925
958
|
"list_recorders",
|
|
926
959
|
"List all recorders/surveys in the workspace.",
|
|
927
960
|
{
|
|
@@ -943,11 +976,11 @@ function register5(server2, client) {
|
|
|
943
976
|
}
|
|
944
977
|
}
|
|
945
978
|
);
|
|
946
|
-
|
|
979
|
+
server.tool(
|
|
947
980
|
"clone_recorder",
|
|
948
981
|
"Duplicate an existing recorder including all its settings and questions.",
|
|
949
982
|
{
|
|
950
|
-
recorderId: import_zod5.z.string().describe("ID of the recorder to clone")
|
|
983
|
+
recorderId: import_zod5.z.string().min(1).describe("ID of the recorder to clone")
|
|
951
984
|
},
|
|
952
985
|
async (body) => {
|
|
953
986
|
try {
|
|
@@ -963,11 +996,11 @@ function register5(server2, client) {
|
|
|
963
996
|
}
|
|
964
997
|
}
|
|
965
998
|
);
|
|
966
|
-
|
|
999
|
+
server.tool(
|
|
967
1000
|
"get_recorder_info",
|
|
968
1001
|
"Get detailed information about a specific recorder including its settings and questions.",
|
|
969
1002
|
{
|
|
970
|
-
recorderId: import_zod5.z.string().describe("Unique identifier of the recorder")
|
|
1003
|
+
recorderId: import_zod5.z.string().min(1).describe("Unique identifier of the recorder")
|
|
971
1004
|
},
|
|
972
1005
|
async ({ recorderId }) => {
|
|
973
1006
|
try {
|
|
@@ -983,11 +1016,11 @@ function register5(server2, client) {
|
|
|
983
1016
|
}
|
|
984
1017
|
}
|
|
985
1018
|
);
|
|
986
|
-
|
|
1019
|
+
server.tool(
|
|
987
1020
|
"get_recorder_recordings",
|
|
988
1021
|
"List all submissions/recordings collected by a specific recorder.",
|
|
989
1022
|
{
|
|
990
|
-
recorderId: import_zod5.z.string().describe("Unique identifier of the recorder")
|
|
1023
|
+
recorderId: import_zod5.z.string().min(1).describe("Unique identifier of the recorder")
|
|
991
1024
|
},
|
|
992
1025
|
async ({ recorderId }) => {
|
|
993
1026
|
try {
|
|
@@ -1003,11 +1036,11 @@ function register5(server2, client) {
|
|
|
1003
1036
|
}
|
|
1004
1037
|
}
|
|
1005
1038
|
);
|
|
1006
|
-
|
|
1039
|
+
server.tool(
|
|
1007
1040
|
"generate_recorder_url",
|
|
1008
1041
|
"Generate a shareable public URL for a recorder/survey.",
|
|
1009
1042
|
{
|
|
1010
|
-
recorderId: import_zod5.z.string().describe("Unique identifier of the recorder")
|
|
1043
|
+
recorderId: import_zod5.z.string().min(1).describe("Unique identifier of the recorder")
|
|
1011
1044
|
},
|
|
1012
1045
|
async ({ recorderId }) => {
|
|
1013
1046
|
try {
|
|
@@ -1023,11 +1056,11 @@ function register5(server2, client) {
|
|
|
1023
1056
|
}
|
|
1024
1057
|
}
|
|
1025
1058
|
);
|
|
1026
|
-
|
|
1059
|
+
server.tool(
|
|
1027
1060
|
"update_recorder_settings",
|
|
1028
1061
|
"Update configuration settings for a recorder (branding, permissions, etc.).",
|
|
1029
1062
|
{
|
|
1030
|
-
recorderId: import_zod5.z.string().describe("Unique identifier of the recorder"),
|
|
1063
|
+
recorderId: import_zod5.z.string().min(1).describe("Unique identifier of the recorder"),
|
|
1031
1064
|
settings: import_zod5.z.record(import_zod5.z.unknown()).describe("Settings object with updated values")
|
|
1032
1065
|
},
|
|
1033
1066
|
async ({ recorderId, settings }) => {
|
|
@@ -1044,11 +1077,11 @@ function register5(server2, client) {
|
|
|
1044
1077
|
}
|
|
1045
1078
|
}
|
|
1046
1079
|
);
|
|
1047
|
-
|
|
1080
|
+
server.tool(
|
|
1048
1081
|
"update_recorder_questions",
|
|
1049
1082
|
"Update the survey questions for a recorder.",
|
|
1050
1083
|
{
|
|
1051
|
-
recorderId: import_zod5.z.string().describe("Unique identifier of the recorder"),
|
|
1084
|
+
recorderId: import_zod5.z.string().min(1).describe("Unique identifier of the recorder"),
|
|
1052
1085
|
questions: import_zod5.z.array(import_zod5.z.record(import_zod5.z.unknown())).describe("Array of question objects")
|
|
1053
1086
|
},
|
|
1054
1087
|
async ({ recorderId, questions }) => {
|
|
@@ -1065,11 +1098,11 @@ function register5(server2, client) {
|
|
|
1065
1098
|
}
|
|
1066
1099
|
}
|
|
1067
1100
|
);
|
|
1068
|
-
|
|
1101
|
+
server.tool(
|
|
1069
1102
|
"delete_recorder",
|
|
1070
1103
|
"Permanently delete a recorder/survey. Existing recordings are preserved.",
|
|
1071
1104
|
{
|
|
1072
|
-
recorderId: import_zod5.z.string().describe("Unique identifier of the recorder to delete")
|
|
1105
|
+
recorderId: import_zod5.z.string().min(1).describe("Unique identifier of the recorder to delete")
|
|
1073
1106
|
},
|
|
1074
1107
|
async ({ recorderId }) => {
|
|
1075
1108
|
try {
|
|
@@ -1086,20 +1119,27 @@ function register5(server2, client) {
|
|
|
1086
1119
|
}
|
|
1087
1120
|
);
|
|
1088
1121
|
}
|
|
1122
|
+
var import_zod5;
|
|
1123
|
+
var init_recorder = __esm({
|
|
1124
|
+
"src/tools/recorder.ts"() {
|
|
1125
|
+
"use strict";
|
|
1126
|
+
import_zod5 = require("zod");
|
|
1127
|
+
init_client();
|
|
1128
|
+
}
|
|
1129
|
+
});
|
|
1089
1130
|
|
|
1090
1131
|
// src/tools/embed.ts
|
|
1091
1132
|
var embed_exports = {};
|
|
1092
1133
|
__export(embed_exports, {
|
|
1093
1134
|
register: () => register6
|
|
1094
1135
|
});
|
|
1095
|
-
|
|
1096
|
-
function register6(server2, client) {
|
|
1136
|
+
function register6(server, client) {
|
|
1097
1137
|
const api = client ?? speakClient;
|
|
1098
|
-
|
|
1138
|
+
server.tool(
|
|
1099
1139
|
"create_embed",
|
|
1100
1140
|
"Create an embeddable player/transcript widget for a media file.",
|
|
1101
1141
|
{
|
|
1102
|
-
mediaId: import_zod6.z.string().describe("Unique identifier of the media file"),
|
|
1142
|
+
mediaId: import_zod6.z.string().min(1).describe("Unique identifier of the media file"),
|
|
1103
1143
|
settings: import_zod6.z.record(import_zod6.z.unknown()).optional().describe("Embed configuration settings")
|
|
1104
1144
|
},
|
|
1105
1145
|
async (body) => {
|
|
@@ -1116,11 +1156,11 @@ function register6(server2, client) {
|
|
|
1116
1156
|
}
|
|
1117
1157
|
}
|
|
1118
1158
|
);
|
|
1119
|
-
|
|
1159
|
+
server.tool(
|
|
1120
1160
|
"update_embed",
|
|
1121
1161
|
"Update settings for an existing embed widget.",
|
|
1122
1162
|
{
|
|
1123
|
-
embedId: import_zod6.z.string().describe("Unique identifier of the embed"),
|
|
1163
|
+
embedId: import_zod6.z.string().min(1).describe("Unique identifier of the embed"),
|
|
1124
1164
|
settings: import_zod6.z.record(import_zod6.z.unknown()).optional().describe("Updated embed settings")
|
|
1125
1165
|
},
|
|
1126
1166
|
async ({ embedId, ...body }) => {
|
|
@@ -1137,11 +1177,11 @@ function register6(server2, client) {
|
|
|
1137
1177
|
}
|
|
1138
1178
|
}
|
|
1139
1179
|
);
|
|
1140
|
-
|
|
1180
|
+
server.tool(
|
|
1141
1181
|
"check_embed",
|
|
1142
1182
|
"Check if an embed exists for a media file and retrieve its configuration.",
|
|
1143
1183
|
{
|
|
1144
|
-
mediaId: import_zod6.z.string().describe("Unique identifier of the media file")
|
|
1184
|
+
mediaId: import_zod6.z.string().min(1).describe("Unique identifier of the media file")
|
|
1145
1185
|
},
|
|
1146
1186
|
async ({ mediaId }) => {
|
|
1147
1187
|
try {
|
|
@@ -1157,11 +1197,11 @@ function register6(server2, client) {
|
|
|
1157
1197
|
}
|
|
1158
1198
|
}
|
|
1159
1199
|
);
|
|
1160
|
-
|
|
1200
|
+
server.tool(
|
|
1161
1201
|
"get_embed_iframe_url",
|
|
1162
1202
|
"Get the iframe URL for embedding a media player/transcript on a webpage.",
|
|
1163
1203
|
{
|
|
1164
|
-
mediaId: import_zod6.z.string().describe("Unique identifier of the media file")
|
|
1204
|
+
mediaId: import_zod6.z.string().min(1).describe("Unique identifier of the media file")
|
|
1165
1205
|
},
|
|
1166
1206
|
async ({ mediaId }) => {
|
|
1167
1207
|
try {
|
|
@@ -1180,16 +1220,23 @@ function register6(server2, client) {
|
|
|
1180
1220
|
}
|
|
1181
1221
|
);
|
|
1182
1222
|
}
|
|
1223
|
+
var import_zod6;
|
|
1224
|
+
var init_embed = __esm({
|
|
1225
|
+
"src/tools/embed.ts"() {
|
|
1226
|
+
"use strict";
|
|
1227
|
+
import_zod6 = require("zod");
|
|
1228
|
+
init_client();
|
|
1229
|
+
}
|
|
1230
|
+
});
|
|
1183
1231
|
|
|
1184
1232
|
// src/tools/prompt.ts
|
|
1185
1233
|
var prompt_exports = {};
|
|
1186
1234
|
__export(prompt_exports, {
|
|
1187
1235
|
register: () => register7
|
|
1188
1236
|
});
|
|
1189
|
-
|
|
1190
|
-
function register7(server2, client) {
|
|
1237
|
+
function register7(server, client) {
|
|
1191
1238
|
const api = client ?? speakClient;
|
|
1192
|
-
|
|
1239
|
+
server.tool(
|
|
1193
1240
|
"list_prompts",
|
|
1194
1241
|
"List all available Magic Prompt templates for AI-powered questions about your media.",
|
|
1195
1242
|
{},
|
|
@@ -1207,12 +1254,12 @@ function register7(server2, client) {
|
|
|
1207
1254
|
}
|
|
1208
1255
|
}
|
|
1209
1256
|
);
|
|
1210
|
-
|
|
1257
|
+
server.tool(
|
|
1211
1258
|
"ask_magic_prompt",
|
|
1212
1259
|
"Ask an AI-powered question about a specific media file using Speak AI's Magic Prompt.",
|
|
1213
1260
|
{
|
|
1214
|
-
mediaId: import_zod7.z.string().describe("Unique identifier of the media file to query"),
|
|
1215
|
-
prompt: import_zod7.z.string().describe("The question or prompt to ask about the media"),
|
|
1261
|
+
mediaId: import_zod7.z.string().min(1).describe("Unique identifier of the media file to query"),
|
|
1262
|
+
prompt: import_zod7.z.string().min(1).describe("The question or prompt to ask about the media"),
|
|
1216
1263
|
promptId: import_zod7.z.string().optional().describe("ID of a predefined prompt template to use")
|
|
1217
1264
|
},
|
|
1218
1265
|
async (body) => {
|
|
@@ -1230,16 +1277,23 @@ function register7(server2, client) {
|
|
|
1230
1277
|
}
|
|
1231
1278
|
);
|
|
1232
1279
|
}
|
|
1280
|
+
var import_zod7;
|
|
1281
|
+
var init_prompt = __esm({
|
|
1282
|
+
"src/tools/prompt.ts"() {
|
|
1283
|
+
"use strict";
|
|
1284
|
+
import_zod7 = require("zod");
|
|
1285
|
+
init_client();
|
|
1286
|
+
}
|
|
1287
|
+
});
|
|
1233
1288
|
|
|
1234
1289
|
// src/tools/meeting.ts
|
|
1235
1290
|
var meeting_exports = {};
|
|
1236
1291
|
__export(meeting_exports, {
|
|
1237
1292
|
register: () => register8
|
|
1238
1293
|
});
|
|
1239
|
-
|
|
1240
|
-
function register8(server2, client) {
|
|
1294
|
+
function register8(server, client) {
|
|
1241
1295
|
const api = client ?? speakClient;
|
|
1242
|
-
|
|
1296
|
+
server.tool(
|
|
1243
1297
|
"list_meeting_events",
|
|
1244
1298
|
"List scheduled or completed meeting assistant events with filtering and pagination.",
|
|
1245
1299
|
{
|
|
@@ -1264,11 +1318,11 @@ function register8(server2, client) {
|
|
|
1264
1318
|
}
|
|
1265
1319
|
}
|
|
1266
1320
|
);
|
|
1267
|
-
|
|
1321
|
+
server.tool(
|
|
1268
1322
|
"schedule_meeting_event",
|
|
1269
1323
|
"Schedule the Speak AI meeting assistant to join and record an upcoming meeting.",
|
|
1270
1324
|
{
|
|
1271
|
-
meetingUrl: import_zod8.z.string().describe("URL of the meeting to join"),
|
|
1325
|
+
meetingUrl: import_zod8.z.string().min(1).describe("URL of the meeting to join"),
|
|
1272
1326
|
title: import_zod8.z.string().optional().describe("Display title for the event"),
|
|
1273
1327
|
scheduledAt: import_zod8.z.string().optional().describe("ISO 8601 datetime for when the meeting starts")
|
|
1274
1328
|
},
|
|
@@ -1289,7 +1343,7 @@ function register8(server2, client) {
|
|
|
1289
1343
|
}
|
|
1290
1344
|
}
|
|
1291
1345
|
);
|
|
1292
|
-
|
|
1346
|
+
server.tool(
|
|
1293
1347
|
"remove_assistant_from_meeting",
|
|
1294
1348
|
"Remove the Speak AI assistant from an active or scheduled meeting.",
|
|
1295
1349
|
{
|
|
@@ -1313,7 +1367,7 @@ function register8(server2, client) {
|
|
|
1313
1367
|
}
|
|
1314
1368
|
}
|
|
1315
1369
|
);
|
|
1316
|
-
|
|
1370
|
+
server.tool(
|
|
1317
1371
|
"delete_scheduled_assistant",
|
|
1318
1372
|
"Cancel and delete a scheduled meeting assistant event.",
|
|
1319
1373
|
{
|
|
@@ -1337,16 +1391,23 @@ function register8(server2, client) {
|
|
|
1337
1391
|
}
|
|
1338
1392
|
);
|
|
1339
1393
|
}
|
|
1394
|
+
var import_zod8;
|
|
1395
|
+
var init_meeting = __esm({
|
|
1396
|
+
"src/tools/meeting.ts"() {
|
|
1397
|
+
"use strict";
|
|
1398
|
+
import_zod8 = require("zod");
|
|
1399
|
+
init_client();
|
|
1400
|
+
}
|
|
1401
|
+
});
|
|
1340
1402
|
|
|
1341
1403
|
// src/tools/fields.ts
|
|
1342
1404
|
var fields_exports = {};
|
|
1343
1405
|
__export(fields_exports, {
|
|
1344
1406
|
register: () => register9
|
|
1345
1407
|
});
|
|
1346
|
-
|
|
1347
|
-
function register9(server2, client) {
|
|
1408
|
+
function register9(server, client) {
|
|
1348
1409
|
const api = client ?? speakClient;
|
|
1349
|
-
|
|
1410
|
+
server.tool(
|
|
1350
1411
|
"list_fields",
|
|
1351
1412
|
"List all custom fields defined in the workspace.",
|
|
1352
1413
|
{},
|
|
@@ -1364,11 +1425,11 @@ function register9(server2, client) {
|
|
|
1364
1425
|
}
|
|
1365
1426
|
}
|
|
1366
1427
|
);
|
|
1367
|
-
|
|
1428
|
+
server.tool(
|
|
1368
1429
|
"create_field",
|
|
1369
1430
|
"Create a new custom field for categorizing and tagging media.",
|
|
1370
1431
|
{
|
|
1371
|
-
name: import_zod9.z.string().describe("Display name for the field"),
|
|
1432
|
+
name: import_zod9.z.string().min(1).describe("Display name for the field"),
|
|
1372
1433
|
type: import_zod9.z.string().optional().describe("Field type (text, number, select, etc.)"),
|
|
1373
1434
|
options: import_zod9.z.array(import_zod9.z.string()).optional().describe("Options for select/multi-select field types")
|
|
1374
1435
|
},
|
|
@@ -1386,7 +1447,7 @@ function register9(server2, client) {
|
|
|
1386
1447
|
}
|
|
1387
1448
|
}
|
|
1388
1449
|
);
|
|
1389
|
-
|
|
1450
|
+
server.tool(
|
|
1390
1451
|
"update_multiple_fields",
|
|
1391
1452
|
"Update multiple custom fields in a single batch operation.",
|
|
1392
1453
|
{
|
|
@@ -1406,11 +1467,11 @@ function register9(server2, client) {
|
|
|
1406
1467
|
}
|
|
1407
1468
|
}
|
|
1408
1469
|
);
|
|
1409
|
-
|
|
1470
|
+
server.tool(
|
|
1410
1471
|
"update_field",
|
|
1411
1472
|
"Update a specific custom field by ID.",
|
|
1412
1473
|
{
|
|
1413
|
-
id: import_zod9.z.string().describe("Unique identifier of the field"),
|
|
1474
|
+
id: import_zod9.z.string().min(1).describe("Unique identifier of the field"),
|
|
1414
1475
|
name: import_zod9.z.string().optional().describe("New display name"),
|
|
1415
1476
|
type: import_zod9.z.string().optional().describe("New field type"),
|
|
1416
1477
|
options: import_zod9.z.array(import_zod9.z.string()).optional().describe("Updated options for select types")
|
|
@@ -1430,16 +1491,23 @@ function register9(server2, client) {
|
|
|
1430
1491
|
}
|
|
1431
1492
|
);
|
|
1432
1493
|
}
|
|
1494
|
+
var import_zod9;
|
|
1495
|
+
var init_fields = __esm({
|
|
1496
|
+
"src/tools/fields.ts"() {
|
|
1497
|
+
"use strict";
|
|
1498
|
+
import_zod9 = require("zod");
|
|
1499
|
+
init_client();
|
|
1500
|
+
}
|
|
1501
|
+
});
|
|
1433
1502
|
|
|
1434
1503
|
// src/tools/automations.ts
|
|
1435
1504
|
var automations_exports = {};
|
|
1436
1505
|
__export(automations_exports, {
|
|
1437
1506
|
register: () => register10
|
|
1438
1507
|
});
|
|
1439
|
-
|
|
1440
|
-
function register10(server2, client) {
|
|
1508
|
+
function register10(server, client) {
|
|
1441
1509
|
const api = client ?? speakClient;
|
|
1442
|
-
|
|
1510
|
+
server.tool(
|
|
1443
1511
|
"list_automations",
|
|
1444
1512
|
"List all automation rules configured in the workspace.",
|
|
1445
1513
|
{},
|
|
@@ -1457,11 +1525,11 @@ function register10(server2, client) {
|
|
|
1457
1525
|
}
|
|
1458
1526
|
}
|
|
1459
1527
|
);
|
|
1460
|
-
|
|
1528
|
+
server.tool(
|
|
1461
1529
|
"get_automation",
|
|
1462
1530
|
"Get detailed information about a specific automation rule.",
|
|
1463
1531
|
{
|
|
1464
|
-
automationId: import_zod10.z.string().describe("Unique identifier of the automation")
|
|
1532
|
+
automationId: import_zod10.z.string().min(1).describe("Unique identifier of the automation")
|
|
1465
1533
|
},
|
|
1466
1534
|
async ({ automationId }) => {
|
|
1467
1535
|
try {
|
|
@@ -1477,7 +1545,7 @@ function register10(server2, client) {
|
|
|
1477
1545
|
}
|
|
1478
1546
|
}
|
|
1479
1547
|
);
|
|
1480
|
-
|
|
1548
|
+
server.tool(
|
|
1481
1549
|
"create_automation",
|
|
1482
1550
|
"Create a new automation rule for automatic media processing workflows.",
|
|
1483
1551
|
{
|
|
@@ -1500,11 +1568,11 @@ function register10(server2, client) {
|
|
|
1500
1568
|
}
|
|
1501
1569
|
}
|
|
1502
1570
|
);
|
|
1503
|
-
|
|
1571
|
+
server.tool(
|
|
1504
1572
|
"update_automation",
|
|
1505
1573
|
"Update an existing automation rule's configuration.",
|
|
1506
1574
|
{
|
|
1507
|
-
automationId: import_zod10.z.string().describe("Unique identifier of the automation"),
|
|
1575
|
+
automationId: import_zod10.z.string().min(1).describe("Unique identifier of the automation"),
|
|
1508
1576
|
name: import_zod10.z.string().optional().describe("New display name"),
|
|
1509
1577
|
trigger: import_zod10.z.record(import_zod10.z.unknown()).optional().describe("Updated trigger configuration"),
|
|
1510
1578
|
actions: import_zod10.z.array(import_zod10.z.record(import_zod10.z.unknown())).optional().describe("Updated action configurations"),
|
|
@@ -1527,11 +1595,11 @@ function register10(server2, client) {
|
|
|
1527
1595
|
}
|
|
1528
1596
|
}
|
|
1529
1597
|
);
|
|
1530
|
-
|
|
1598
|
+
server.tool(
|
|
1531
1599
|
"toggle_automation_status",
|
|
1532
1600
|
"Enable or disable an automation rule.",
|
|
1533
1601
|
{
|
|
1534
|
-
automationId: import_zod10.z.string().describe("Unique identifier of the automation"),
|
|
1602
|
+
automationId: import_zod10.z.string().min(1).describe("Unique identifier of the automation"),
|
|
1535
1603
|
enabled: import_zod10.z.boolean().describe("Set to true to enable, false to disable")
|
|
1536
1604
|
},
|
|
1537
1605
|
async ({ automationId, enabled }) => {
|
|
@@ -1552,16 +1620,23 @@ function register10(server2, client) {
|
|
|
1552
1620
|
}
|
|
1553
1621
|
);
|
|
1554
1622
|
}
|
|
1623
|
+
var import_zod10;
|
|
1624
|
+
var init_automations = __esm({
|
|
1625
|
+
"src/tools/automations.ts"() {
|
|
1626
|
+
"use strict";
|
|
1627
|
+
import_zod10 = require("zod");
|
|
1628
|
+
init_client();
|
|
1629
|
+
}
|
|
1630
|
+
});
|
|
1555
1631
|
|
|
1556
1632
|
// src/tools/webhooks.ts
|
|
1557
1633
|
var webhooks_exports = {};
|
|
1558
1634
|
__export(webhooks_exports, {
|
|
1559
1635
|
register: () => register11
|
|
1560
1636
|
});
|
|
1561
|
-
|
|
1562
|
-
function register11(server2, client) {
|
|
1637
|
+
function register11(server, client) {
|
|
1563
1638
|
const api = client ?? speakClient;
|
|
1564
|
-
|
|
1639
|
+
server.tool(
|
|
1565
1640
|
"create_webhook",
|
|
1566
1641
|
"Create a new webhook to receive real-time notifications when events occur in Speak AI.",
|
|
1567
1642
|
{
|
|
@@ -1582,7 +1657,7 @@ function register11(server2, client) {
|
|
|
1582
1657
|
}
|
|
1583
1658
|
}
|
|
1584
1659
|
);
|
|
1585
|
-
|
|
1660
|
+
server.tool(
|
|
1586
1661
|
"list_webhooks",
|
|
1587
1662
|
"List all configured webhooks in the workspace.",
|
|
1588
1663
|
{},
|
|
@@ -1600,11 +1675,11 @@ function register11(server2, client) {
|
|
|
1600
1675
|
}
|
|
1601
1676
|
}
|
|
1602
1677
|
);
|
|
1603
|
-
|
|
1678
|
+
server.tool(
|
|
1604
1679
|
"update_webhook",
|
|
1605
1680
|
"Update an existing webhook's URL or subscribed events.",
|
|
1606
1681
|
{
|
|
1607
|
-
webhookId: import_zod11.z.string().describe("Unique identifier of the webhook"),
|
|
1682
|
+
webhookId: import_zod11.z.string().min(1).describe("Unique identifier of the webhook"),
|
|
1608
1683
|
url: import_zod11.z.string().url().optional().describe("New endpoint URL"),
|
|
1609
1684
|
events: import_zod11.z.array(import_zod11.z.string()).optional().describe("Updated array of event types")
|
|
1610
1685
|
},
|
|
@@ -1622,11 +1697,11 @@ function register11(server2, client) {
|
|
|
1622
1697
|
}
|
|
1623
1698
|
}
|
|
1624
1699
|
);
|
|
1625
|
-
|
|
1700
|
+
server.tool(
|
|
1626
1701
|
"delete_webhook",
|
|
1627
1702
|
"Delete a webhook and stop receiving notifications at its endpoint.",
|
|
1628
1703
|
{
|
|
1629
|
-
webhookId: import_zod11.z.string().describe("Unique identifier of the webhook to delete")
|
|
1704
|
+
webhookId: import_zod11.z.string().min(1).describe("Unique identifier of the webhook to delete")
|
|
1630
1705
|
},
|
|
1631
1706
|
async ({ webhookId }) => {
|
|
1632
1707
|
try {
|
|
@@ -1643,43 +1718,611 @@ function register11(server2, client) {
|
|
|
1643
1718
|
}
|
|
1644
1719
|
);
|
|
1645
1720
|
}
|
|
1721
|
+
var import_zod11;
|
|
1722
|
+
var init_webhooks = __esm({
|
|
1723
|
+
"src/tools/webhooks.ts"() {
|
|
1724
|
+
"use strict";
|
|
1725
|
+
import_zod11 = require("zod");
|
|
1726
|
+
init_client();
|
|
1727
|
+
}
|
|
1728
|
+
});
|
|
1646
1729
|
|
|
1647
1730
|
// src/tools/index.ts
|
|
1648
|
-
var
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
recorder_exports,
|
|
1654
|
-
embed_exports,
|
|
1655
|
-
prompt_exports,
|
|
1656
|
-
meeting_exports,
|
|
1657
|
-
fields_exports,
|
|
1658
|
-
automations_exports,
|
|
1659
|
-
webhooks_exports
|
|
1660
|
-
];
|
|
1661
|
-
function registerAllTools(server2, client) {
|
|
1731
|
+
var tools_exports = {};
|
|
1732
|
+
__export(tools_exports, {
|
|
1733
|
+
registerAllTools: () => registerAllTools
|
|
1734
|
+
});
|
|
1735
|
+
function registerAllTools(server, client) {
|
|
1662
1736
|
for (const mod of modules) {
|
|
1663
|
-
mod.register(
|
|
1737
|
+
mod.register(server, client);
|
|
1664
1738
|
}
|
|
1665
1739
|
}
|
|
1740
|
+
var modules;
|
|
1741
|
+
var init_tools = __esm({
|
|
1742
|
+
"src/tools/index.ts"() {
|
|
1743
|
+
"use strict";
|
|
1744
|
+
init_media();
|
|
1745
|
+
init_text();
|
|
1746
|
+
init_exports();
|
|
1747
|
+
init_folders();
|
|
1748
|
+
init_recorder();
|
|
1749
|
+
init_embed();
|
|
1750
|
+
init_prompt();
|
|
1751
|
+
init_meeting();
|
|
1752
|
+
init_fields();
|
|
1753
|
+
init_automations();
|
|
1754
|
+
init_webhooks();
|
|
1755
|
+
modules = [
|
|
1756
|
+
media_exports,
|
|
1757
|
+
text_exports,
|
|
1758
|
+
exports_exports,
|
|
1759
|
+
folders_exports,
|
|
1760
|
+
recorder_exports,
|
|
1761
|
+
embed_exports,
|
|
1762
|
+
prompt_exports,
|
|
1763
|
+
meeting_exports,
|
|
1764
|
+
fields_exports,
|
|
1765
|
+
automations_exports,
|
|
1766
|
+
webhooks_exports
|
|
1767
|
+
];
|
|
1768
|
+
}
|
|
1769
|
+
});
|
|
1666
1770
|
|
|
1667
|
-
// src/
|
|
1668
|
-
var
|
|
1669
|
-
|
|
1670
|
-
|
|
1771
|
+
// src/cli/config.ts
|
|
1772
|
+
var config_exports = {};
|
|
1773
|
+
__export(config_exports, {
|
|
1774
|
+
getConfigPath: () => getConfigPath,
|
|
1775
|
+
loadConfig: () => loadConfig,
|
|
1776
|
+
resolveApiKey: () => resolveApiKey,
|
|
1777
|
+
resolveBaseUrl: () => resolveBaseUrl,
|
|
1778
|
+
saveConfig: () => saveConfig
|
|
1671
1779
|
});
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1780
|
+
function ensureDir() {
|
|
1781
|
+
if (!import_fs.default.existsSync(CONFIG_DIR)) {
|
|
1782
|
+
import_fs.default.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
function loadConfig() {
|
|
1786
|
+
try {
|
|
1787
|
+
if (import_fs.default.existsSync(CONFIG_FILE)) {
|
|
1788
|
+
return JSON.parse(import_fs.default.readFileSync(CONFIG_FILE, "utf-8"));
|
|
1789
|
+
}
|
|
1790
|
+
} catch {
|
|
1791
|
+
}
|
|
1792
|
+
return {};
|
|
1793
|
+
}
|
|
1794
|
+
function saveConfig(config) {
|
|
1795
|
+
ensureDir();
|
|
1796
|
+
import_fs.default.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n", {
|
|
1797
|
+
mode: 384
|
|
1798
|
+
// Owner read/write only
|
|
1799
|
+
});
|
|
1800
|
+
}
|
|
1801
|
+
function resolveApiKey() {
|
|
1802
|
+
if (process.env.SPEAK_API_KEY) return process.env.SPEAK_API_KEY;
|
|
1803
|
+
const config = loadConfig();
|
|
1804
|
+
if (config.apiKey) {
|
|
1805
|
+
process.env.SPEAK_API_KEY = config.apiKey;
|
|
1806
|
+
return config.apiKey;
|
|
1807
|
+
}
|
|
1808
|
+
return void 0;
|
|
1809
|
+
}
|
|
1810
|
+
function resolveBaseUrl() {
|
|
1811
|
+
if (process.env.SPEAK_BASE_URL) return process.env.SPEAK_BASE_URL;
|
|
1812
|
+
const config = loadConfig();
|
|
1813
|
+
if (config.baseUrl) {
|
|
1814
|
+
process.env.SPEAK_BASE_URL = config.baseUrl;
|
|
1815
|
+
return config.baseUrl;
|
|
1816
|
+
}
|
|
1817
|
+
return "https://api.speakai.co";
|
|
1818
|
+
}
|
|
1819
|
+
function getConfigPath() {
|
|
1820
|
+
return CONFIG_FILE;
|
|
1821
|
+
}
|
|
1822
|
+
var import_fs, import_path, import_os, CONFIG_DIR, CONFIG_FILE;
|
|
1823
|
+
var init_config = __esm({
|
|
1824
|
+
"src/cli/config.ts"() {
|
|
1825
|
+
"use strict";
|
|
1826
|
+
import_fs = __toESM(require("fs"));
|
|
1827
|
+
import_path = __toESM(require("path"));
|
|
1828
|
+
import_os = __toESM(require("os"));
|
|
1829
|
+
CONFIG_DIR = import_path.default.join(import_os.default.homedir(), ".speakai");
|
|
1830
|
+
CONFIG_FILE = import_path.default.join(CONFIG_DIR, "config.json");
|
|
1831
|
+
}
|
|
1832
|
+
});
|
|
1833
|
+
|
|
1834
|
+
// src/cli/format.ts
|
|
1835
|
+
function printJson(data) {
|
|
1836
|
+
console.log(JSON.stringify(data, null, 2));
|
|
1837
|
+
}
|
|
1838
|
+
function printTable(rows, columns) {
|
|
1839
|
+
if (rows.length === 0) {
|
|
1840
|
+
console.log("No results found.");
|
|
1841
|
+
return;
|
|
1842
|
+
}
|
|
1843
|
+
const widths = columns.map((col) => {
|
|
1844
|
+
const maxData = rows.reduce(
|
|
1845
|
+
(max, row) => Math.max(max, String(row[col.key] ?? "").length),
|
|
1846
|
+
0
|
|
1847
|
+
);
|
|
1848
|
+
return col.width ?? Math.max(col.label.length, Math.min(maxData, 50));
|
|
1849
|
+
});
|
|
1850
|
+
const header = columns.map((col, i) => col.label.padEnd(widths[i])).join(" ");
|
|
1851
|
+
console.log(header);
|
|
1852
|
+
console.log(widths.map((w) => "\u2500".repeat(w)).join("\u2500\u2500"));
|
|
1853
|
+
for (const row of rows) {
|
|
1854
|
+
const line = columns.map((col, i) => {
|
|
1855
|
+
const val = String(row[col.key] ?? "\u2014");
|
|
1856
|
+
return val.length > widths[i] ? val.slice(0, widths[i] - 1) + "\u2026" : val.padEnd(widths[i]);
|
|
1857
|
+
}).join(" ");
|
|
1858
|
+
console.log(line);
|
|
1859
|
+
}
|
|
1860
|
+
console.log(`
|
|
1861
|
+
${rows.length} result${rows.length === 1 ? "" : "s"}`);
|
|
1677
1862
|
}
|
|
1678
|
-
|
|
1679
|
-
|
|
1863
|
+
function printError(message) {
|
|
1864
|
+
console.error(`Error: ${message}`);
|
|
1865
|
+
}
|
|
1866
|
+
function printSuccess(message) {
|
|
1867
|
+
console.log(message);
|
|
1868
|
+
}
|
|
1869
|
+
var init_format = __esm({
|
|
1870
|
+
"src/cli/format.ts"() {
|
|
1871
|
+
"use strict";
|
|
1872
|
+
}
|
|
1873
|
+
});
|
|
1874
|
+
|
|
1875
|
+
// src/cli/index.ts
|
|
1876
|
+
var cli_exports = {};
|
|
1877
|
+
__export(cli_exports, {
|
|
1878
|
+
createCli: () => createCli
|
|
1879
|
+
});
|
|
1880
|
+
async function getClient() {
|
|
1881
|
+
const { speakClient: speakClient2 } = await Promise.resolve().then(() => (init_client(), client_exports));
|
|
1882
|
+
return speakClient2;
|
|
1883
|
+
}
|
|
1884
|
+
function requireApiKey() {
|
|
1885
|
+
const key = resolveApiKey();
|
|
1886
|
+
resolveBaseUrl();
|
|
1887
|
+
if (!key) {
|
|
1888
|
+
printError(
|
|
1889
|
+
'No API key configured. Run "speak-mcp config set-key" or set SPEAK_API_KEY.'
|
|
1890
|
+
);
|
|
1891
|
+
process.exit(1);
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
function createCli() {
|
|
1895
|
+
const program = new import_commander.Command();
|
|
1896
|
+
program.name("speak-mcp").description(
|
|
1897
|
+
"Speak AI CLI & MCP Server \u2014 transcribe, analyze, and manage media from the command line"
|
|
1898
|
+
).version("1.0.0");
|
|
1899
|
+
const config = program.command("config").description("Manage configuration");
|
|
1900
|
+
config.command("set-key").description("Set your Speak AI API key").argument("[key]", "API key (omit for interactive prompt)").action(async (key) => {
|
|
1901
|
+
if (!key) {
|
|
1902
|
+
const rl = (0, import_readline.createInterface)({
|
|
1903
|
+
input: process.stdin,
|
|
1904
|
+
output: process.stdout
|
|
1905
|
+
});
|
|
1906
|
+
key = await new Promise(
|
|
1907
|
+
(resolve) => rl.question("Enter your Speak AI API key: ", (answer) => {
|
|
1908
|
+
rl.close();
|
|
1909
|
+
resolve(answer.trim());
|
|
1910
|
+
})
|
|
1911
|
+
);
|
|
1912
|
+
}
|
|
1913
|
+
if (!key) {
|
|
1914
|
+
printError("No key provided.");
|
|
1915
|
+
process.exit(1);
|
|
1916
|
+
}
|
|
1917
|
+
const cfg = loadConfig();
|
|
1918
|
+
cfg.apiKey = key;
|
|
1919
|
+
saveConfig(cfg);
|
|
1920
|
+
printSuccess(`API key saved to ${getConfigPath()}`);
|
|
1921
|
+
});
|
|
1922
|
+
config.command("show").description("Show current configuration").action(() => {
|
|
1923
|
+
const cfg = loadConfig();
|
|
1924
|
+
const envKey = process.env.SPEAK_API_KEY;
|
|
1925
|
+
console.log(`Config file: ${getConfigPath()}`);
|
|
1926
|
+
console.log(
|
|
1927
|
+
`API key: ${cfg.apiKey ? cfg.apiKey.slice(0, 8) + "..." : "(not set)"}`
|
|
1928
|
+
);
|
|
1929
|
+
console.log(
|
|
1930
|
+
`Base URL: ${cfg.baseUrl ?? "https://api.speakai.co (default)"}`
|
|
1931
|
+
);
|
|
1932
|
+
if (envKey) {
|
|
1933
|
+
console.log(
|
|
1934
|
+
`Env override: SPEAK_API_KEY=${envKey.slice(0, 8)}...`
|
|
1935
|
+
);
|
|
1936
|
+
}
|
|
1937
|
+
});
|
|
1938
|
+
config.command("set-url").description("Set custom API base URL").argument("<url>", "Base URL (e.g. https://api.speakai.co)").action((url) => {
|
|
1939
|
+
const cfg = loadConfig();
|
|
1940
|
+
cfg.baseUrl = url;
|
|
1941
|
+
saveConfig(cfg);
|
|
1942
|
+
printSuccess(`Base URL set to ${url}`);
|
|
1943
|
+
});
|
|
1944
|
+
program.command("list-media").alias("ls").description("List media files").option("-t, --type <type>", "Filter by type (audio, video, text)").option("-p, --page <n>", "Page number (0-based)", "0").option("-s, --page-size <n>", "Results per page", "20").option("--sort <field>", "Sort field", "createdAt:desc").option("-f, --folder <id>", "Filter by folder ID").option("-n, --name <filter>", "Filter by name").option("--favorites", "Show only favorites").option("--json", "Output raw JSON").action(async (opts) => {
|
|
1945
|
+
requireApiKey();
|
|
1946
|
+
const client = await getClient();
|
|
1947
|
+
try {
|
|
1948
|
+
const params = {
|
|
1949
|
+
page: parseInt(opts.page),
|
|
1950
|
+
pageSize: parseInt(opts.pageSize),
|
|
1951
|
+
sortBy: opts.sort,
|
|
1952
|
+
filterMedia: 2
|
|
1953
|
+
// 0=Uploaded, 1=Assigned, 2=Both
|
|
1954
|
+
};
|
|
1955
|
+
if (opts.type) params.mediaType = opts.type;
|
|
1956
|
+
if (opts.folder) params.folderId = opts.folder;
|
|
1957
|
+
if (opts.name) params.filterName = opts.name;
|
|
1958
|
+
if (opts.favorites) params.isFavorites = true;
|
|
1959
|
+
const res = await client.get("/v1/media", { params });
|
|
1960
|
+
const data = res.data?.data;
|
|
1961
|
+
if (opts.json) {
|
|
1962
|
+
printJson(data);
|
|
1963
|
+
return;
|
|
1964
|
+
}
|
|
1965
|
+
console.log(`Total: ${data.totalCount} | Page ${opts.page} of ${data.pages}
|
|
1680
1966
|
`);
|
|
1681
|
-
|
|
1967
|
+
printTable(data.mediaList ?? [], [
|
|
1968
|
+
{ key: "_id", label: "ID", width: 14 },
|
|
1969
|
+
{ key: "name", label: "Name", width: 40 },
|
|
1970
|
+
{ key: "mediaType", label: "Type", width: 6 },
|
|
1971
|
+
{ key: "state", label: "Status", width: 12 },
|
|
1972
|
+
{ key: "createdAt", label: "Created", width: 20 }
|
|
1973
|
+
]);
|
|
1974
|
+
} catch (err) {
|
|
1975
|
+
printError(err.response?.data?.message ?? err.message);
|
|
1976
|
+
process.exit(1);
|
|
1977
|
+
}
|
|
1978
|
+
});
|
|
1979
|
+
program.command("get-transcript").alias("transcript").description("Get transcript for a media file").argument("<mediaId>", "Media file ID").option("--json", "Output raw JSON").option("--plain", "Output plain text only (no timestamps)").action(async (mediaId, opts) => {
|
|
1980
|
+
requireApiKey();
|
|
1981
|
+
const client = await getClient();
|
|
1982
|
+
try {
|
|
1983
|
+
const res = await client.get(`/v1/media/transcript/${mediaId}`);
|
|
1984
|
+
const data = res.data?.data;
|
|
1985
|
+
if (opts.json) {
|
|
1986
|
+
printJson(data);
|
|
1987
|
+
return;
|
|
1988
|
+
}
|
|
1989
|
+
if (opts.plain) {
|
|
1990
|
+
const segments2 = data?.transcript ?? data ?? [];
|
|
1991
|
+
for (const seg of segments2) {
|
|
1992
|
+
console.log(seg.text ?? "");
|
|
1993
|
+
}
|
|
1994
|
+
return;
|
|
1995
|
+
}
|
|
1996
|
+
const segments = data?.transcript ?? data ?? [];
|
|
1997
|
+
let lastSpeaker = "";
|
|
1998
|
+
for (const seg of segments) {
|
|
1999
|
+
const speaker = seg.speakerId ?? "?";
|
|
2000
|
+
const start = seg.instances?.[0]?.start ?? "";
|
|
2001
|
+
const text = seg.text ?? "";
|
|
2002
|
+
if (speaker !== lastSpeaker) {
|
|
2003
|
+
console.log(`
|
|
2004
|
+
[Speaker ${speaker}] ${start}`);
|
|
2005
|
+
lastSpeaker = speaker;
|
|
2006
|
+
}
|
|
2007
|
+
process.stdout.write(text + " ");
|
|
2008
|
+
}
|
|
2009
|
+
console.log();
|
|
2010
|
+
} catch (err) {
|
|
2011
|
+
printError(err.response?.data?.message ?? err.message);
|
|
2012
|
+
process.exit(1);
|
|
2013
|
+
}
|
|
2014
|
+
});
|
|
2015
|
+
program.command("get-insights").alias("insights").description("Get AI-generated insights for a media file").argument("<mediaId>", "Media file ID").option("--json", "Output raw JSON").action(async (mediaId, opts) => {
|
|
2016
|
+
requireApiKey();
|
|
2017
|
+
const client = await getClient();
|
|
2018
|
+
try {
|
|
2019
|
+
const res = await client.get(`/v1/media/insight/${mediaId}`);
|
|
2020
|
+
const data = res.data?.data;
|
|
2021
|
+
if (opts.json) {
|
|
2022
|
+
printJson(data);
|
|
2023
|
+
return;
|
|
2024
|
+
}
|
|
2025
|
+
if (data?.summary) {
|
|
2026
|
+
console.log("\u2500\u2500 Summary \u2500\u2500");
|
|
2027
|
+
console.log(data.summary + "\n");
|
|
2028
|
+
}
|
|
2029
|
+
const categories = [
|
|
2030
|
+
"keywords",
|
|
2031
|
+
"topics",
|
|
2032
|
+
"people",
|
|
2033
|
+
"locations",
|
|
2034
|
+
"brands",
|
|
2035
|
+
"sentiment"
|
|
2036
|
+
];
|
|
2037
|
+
for (const cat of categories) {
|
|
2038
|
+
const items = data?.[cat];
|
|
2039
|
+
if (items && Array.isArray(items) && items.length > 0) {
|
|
2040
|
+
console.log(`\u2500\u2500 ${cat.charAt(0).toUpperCase() + cat.slice(1)} \u2500\u2500`);
|
|
2041
|
+
for (const item of items.slice(0, 20)) {
|
|
2042
|
+
const name = typeof item === "string" ? item : item.name ?? item.text ?? JSON.stringify(item);
|
|
2043
|
+
console.log(` ${name}`);
|
|
2044
|
+
}
|
|
2045
|
+
if (items.length > 20) console.log(` ... and ${items.length - 20} more`);
|
|
2046
|
+
console.log();
|
|
2047
|
+
}
|
|
2048
|
+
}
|
|
2049
|
+
if (data?.sentiment && !Array.isArray(data.sentiment)) {
|
|
2050
|
+
console.log("\u2500\u2500 Sentiment \u2500\u2500");
|
|
2051
|
+
printJson(data.sentiment);
|
|
2052
|
+
console.log();
|
|
2053
|
+
}
|
|
2054
|
+
} catch (err) {
|
|
2055
|
+
printError(err.response?.data?.message ?? err.message);
|
|
2056
|
+
process.exit(1);
|
|
2057
|
+
}
|
|
2058
|
+
});
|
|
2059
|
+
program.command("upload").description("Upload media from a URL").argument("<url>", "Publicly accessible media URL").option("-n, --name <name>", "Display name").option("-t, --type <type>", "Media type (audio or video)", "audio").option("-l, --language <lang>", "Source language (BCP-47)", "en-US").option("-f, --folder <id>", "Destination folder ID").option("--tags <tags>", "Comma-separated tags").option("--wait", "Wait for processing to complete").option("--json", "Output raw JSON").action(async (url, opts) => {
|
|
2060
|
+
requireApiKey();
|
|
2061
|
+
const client = await getClient();
|
|
2062
|
+
try {
|
|
2063
|
+
const body = {
|
|
2064
|
+
name: opts.name ?? url.split("/").pop()?.split("?")[0] ?? "Upload",
|
|
2065
|
+
url,
|
|
2066
|
+
mediaType: opts.type,
|
|
2067
|
+
sourceLanguage: opts.language
|
|
2068
|
+
};
|
|
2069
|
+
if (opts.folder) body.folderId = opts.folder;
|
|
2070
|
+
if (opts.tags) body.tags = opts.tags;
|
|
2071
|
+
const res = await client.post("/v1/media/upload", body);
|
|
2072
|
+
const data = res.data?.data;
|
|
2073
|
+
if (opts.json && !opts.wait) {
|
|
2074
|
+
printJson(data);
|
|
2075
|
+
return;
|
|
2076
|
+
}
|
|
2077
|
+
const mediaId = data?.mediaId;
|
|
2078
|
+
printSuccess(`Uploaded: ${mediaId} (state: ${data?.state})`);
|
|
2079
|
+
if (opts.wait && mediaId) {
|
|
2080
|
+
process.stdout.write("Processing");
|
|
2081
|
+
let status = data?.state;
|
|
2082
|
+
while (status !== "processed" && status !== "failed") {
|
|
2083
|
+
await new Promise((r) => setTimeout(r, 5e3));
|
|
2084
|
+
process.stdout.write(".");
|
|
2085
|
+
const statusRes = await client.get(`/v1/media/status/${mediaId}`);
|
|
2086
|
+
status = statusRes.data?.data?.state;
|
|
2087
|
+
}
|
|
2088
|
+
console.log();
|
|
2089
|
+
if (status === "processed") {
|
|
2090
|
+
printSuccess(`Done! Media ${mediaId} is ready.`);
|
|
2091
|
+
} else {
|
|
2092
|
+
printError(`Processing failed for ${mediaId}`);
|
|
2093
|
+
process.exit(1);
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
} catch (err) {
|
|
2097
|
+
printError(err.response?.data?.message ?? err.message);
|
|
2098
|
+
process.exit(1);
|
|
2099
|
+
}
|
|
2100
|
+
});
|
|
2101
|
+
program.command("export").description("Export media transcript/insights").argument("<mediaId>", "Media file ID").option(
|
|
2102
|
+
"-f, --format <type>",
|
|
2103
|
+
"Export format (pdf, docx, srt, vtt, txt, csv, md)",
|
|
2104
|
+
"txt"
|
|
2105
|
+
).option("--speakers", "Include speaker names").option("--timestamps", "Include timestamps").option("--redacted", "Apply PII redaction").option("--json", "Output raw JSON").action(async (mediaId, opts) => {
|
|
2106
|
+
requireApiKey();
|
|
2107
|
+
const client = await getClient();
|
|
2108
|
+
try {
|
|
2109
|
+
const params = {};
|
|
2110
|
+
if (opts.speakers) params.isSpeakerNames = true;
|
|
2111
|
+
if (opts.timestamps) params.isTimeStamps = true;
|
|
2112
|
+
if (opts.redacted) params.isRedacted = true;
|
|
2113
|
+
const res = await client.post(
|
|
2114
|
+
`/v1/media/export/${mediaId}/${opts.format}`,
|
|
2115
|
+
null,
|
|
2116
|
+
{ params }
|
|
2117
|
+
);
|
|
2118
|
+
if (opts.json) {
|
|
2119
|
+
printJson(res.data);
|
|
2120
|
+
} else {
|
|
2121
|
+
printJson(res.data?.data ?? res.data);
|
|
2122
|
+
}
|
|
2123
|
+
} catch (err) {
|
|
2124
|
+
printError(err.response?.data?.message ?? err.message);
|
|
2125
|
+
process.exit(1);
|
|
2126
|
+
}
|
|
2127
|
+
});
|
|
2128
|
+
program.command("status").description("Check processing status of a media file").argument("<mediaId>", "Media file ID").option("--json", "Output raw JSON").action(async (mediaId, opts) => {
|
|
2129
|
+
requireApiKey();
|
|
2130
|
+
const client = await getClient();
|
|
2131
|
+
try {
|
|
2132
|
+
const res = await client.get(`/v1/media/status/${mediaId}`);
|
|
2133
|
+
const data = res.data?.data;
|
|
2134
|
+
if (opts.json) {
|
|
2135
|
+
printJson(data);
|
|
2136
|
+
return;
|
|
2137
|
+
}
|
|
2138
|
+
console.log(`Name: ${data?.name ?? "\u2014"}`);
|
|
2139
|
+
console.log(`Status: ${data?.state ?? "\u2014"}`);
|
|
2140
|
+
console.log(`Type: ${data?.mediaType ?? "\u2014"}`);
|
|
2141
|
+
const dur = data?.duration;
|
|
2142
|
+
const durStr = dur?.inSecond ? `${Math.round(dur.inSecond)}s` : typeof dur === "number" ? `${Math.round(dur)}s` : "\u2014";
|
|
2143
|
+
console.log(`Duration: ${durStr}`);
|
|
2144
|
+
console.log(`Created: ${data?.createdAt ?? "\u2014"}`);
|
|
2145
|
+
} catch (err) {
|
|
2146
|
+
printError(err.response?.data?.message ?? err.message);
|
|
2147
|
+
process.exit(1);
|
|
2148
|
+
}
|
|
2149
|
+
});
|
|
2150
|
+
program.command("create-text").description("Create a text note for AI analysis").argument("<name>", "Note title").option("-t, --text <text>", "Text content (or pipe via stdin)").option("-f, --folder <id>", "Folder ID").option("--tags <tags>", "Comma-separated tags").option("--json", "Output raw JSON").action(async (name, opts) => {
|
|
2151
|
+
requireApiKey();
|
|
2152
|
+
const client = await getClient();
|
|
2153
|
+
try {
|
|
2154
|
+
let text = opts.text;
|
|
2155
|
+
if (!text && !process.stdin.isTTY) {
|
|
2156
|
+
const chunks = [];
|
|
2157
|
+
for await (const chunk of process.stdin) {
|
|
2158
|
+
chunks.push(chunk);
|
|
2159
|
+
}
|
|
2160
|
+
text = Buffer.concat(chunks).toString("utf-8").trim();
|
|
2161
|
+
}
|
|
2162
|
+
if (!text) {
|
|
2163
|
+
printError("Provide text via --text or pipe via stdin");
|
|
2164
|
+
process.exit(1);
|
|
2165
|
+
}
|
|
2166
|
+
const body = { name, text, rawText: text };
|
|
2167
|
+
if (opts.folder) body.folderId = opts.folder;
|
|
2168
|
+
if (opts.tags) body.tags = opts.tags;
|
|
2169
|
+
const res = await client.post("/v1/text/create", body);
|
|
2170
|
+
const data = res.data?.data;
|
|
2171
|
+
if (opts.json) {
|
|
2172
|
+
printJson(data);
|
|
2173
|
+
} else {
|
|
2174
|
+
printSuccess(`Created text note: ${data?.mediaId ?? data?._id}`);
|
|
2175
|
+
}
|
|
2176
|
+
} catch (err) {
|
|
2177
|
+
printError(err.response?.data?.message ?? err.message);
|
|
2178
|
+
process.exit(1);
|
|
2179
|
+
}
|
|
2180
|
+
});
|
|
2181
|
+
program.command("list-folders").alias("folders").description("List all folders").option("--json", "Output raw JSON").action(async (opts) => {
|
|
2182
|
+
requireApiKey();
|
|
2183
|
+
const client = await getClient();
|
|
2184
|
+
try {
|
|
2185
|
+
const res = await client.get("/v1/folder", {
|
|
2186
|
+
params: { page: 0, pageSize: 100, sortBy: "createdAt:desc" }
|
|
2187
|
+
});
|
|
2188
|
+
const data = res.data?.data;
|
|
2189
|
+
if (opts.json) {
|
|
2190
|
+
printJson(data);
|
|
2191
|
+
return;
|
|
2192
|
+
}
|
|
2193
|
+
const folders = Array.isArray(data) ? data : data?.folderList ?? data?.folders ?? [];
|
|
2194
|
+
printTable(folders, [
|
|
2195
|
+
{ key: "_id", label: "ID", width: 14 },
|
|
2196
|
+
{ key: "name", label: "Name", width: 40 },
|
|
2197
|
+
{ key: "createdAt", label: "Created", width: 20 }
|
|
2198
|
+
]);
|
|
2199
|
+
} catch (err) {
|
|
2200
|
+
printError(err.response?.data?.message ?? err.message);
|
|
2201
|
+
process.exit(1);
|
|
2202
|
+
}
|
|
2203
|
+
});
|
|
2204
|
+
program.command("ask").description("Ask an AI question about a media file").argument("<mediaId>", "Media file ID").argument("<prompt>", "Your question").option("--assistant <type>", "Assistant type (general, researcher, marketer, sales, recruiter)", "general").option("--json", "Output raw JSON").action(async (mediaId, prompt, opts) => {
|
|
2205
|
+
requireApiKey();
|
|
2206
|
+
const client = await getClient();
|
|
2207
|
+
try {
|
|
2208
|
+
const res = await client.post("/v1/prompt", {
|
|
2209
|
+
mediaIds: [mediaId],
|
|
2210
|
+
prompt,
|
|
2211
|
+
assistantType: opts.assistant
|
|
2212
|
+
});
|
|
2213
|
+
const data = res.data?.data;
|
|
2214
|
+
if (opts.json) {
|
|
2215
|
+
printJson(data);
|
|
2216
|
+
} else {
|
|
2217
|
+
console.log(data?.answer ?? data?.message ?? JSON.stringify(data, null, 2));
|
|
2218
|
+
}
|
|
2219
|
+
} catch (err) {
|
|
2220
|
+
printError(err.response?.data?.message ?? err.message);
|
|
2221
|
+
process.exit(1);
|
|
2222
|
+
}
|
|
2223
|
+
});
|
|
2224
|
+
program.command("schedule-meeting").description("Schedule AI assistant to join a meeting").argument("<url>", "Meeting URL (Zoom, Meet, Teams)").option("-t, --title <title>", "Meeting title").option("-d, --date <datetime>", "Meeting date/time (ISO 8601, omit to join now)").option("-l, --language <lang>", "Meeting language", "en-US").option("--json", "Output raw JSON").action(async (url, opts) => {
|
|
2225
|
+
requireApiKey();
|
|
2226
|
+
const client = await getClient();
|
|
2227
|
+
try {
|
|
2228
|
+
const body = {
|
|
2229
|
+
meetingURL: url,
|
|
2230
|
+
title: opts.title ?? "Meeting",
|
|
2231
|
+
meetingLanguage: opts.language
|
|
2232
|
+
};
|
|
2233
|
+
if (opts.date) body.meetingDate = opts.date;
|
|
2234
|
+
const res = await client.post(
|
|
2235
|
+
"/v1/meeting-assistant/events/schedule",
|
|
2236
|
+
body
|
|
2237
|
+
);
|
|
2238
|
+
const data = res.data?.data;
|
|
2239
|
+
if (opts.json) {
|
|
2240
|
+
printJson(data);
|
|
2241
|
+
} else {
|
|
2242
|
+
printSuccess(`Meeting scheduled: ${data?._id ?? "OK"}`);
|
|
2243
|
+
if (!opts.date) console.log("Assistant will join immediately.");
|
|
2244
|
+
}
|
|
2245
|
+
} catch (err) {
|
|
2246
|
+
printError(err.response?.data?.message ?? err.message);
|
|
2247
|
+
process.exit(1);
|
|
2248
|
+
}
|
|
2249
|
+
});
|
|
2250
|
+
return program;
|
|
2251
|
+
}
|
|
2252
|
+
var import_commander, import_readline;
|
|
2253
|
+
var init_cli = __esm({
|
|
2254
|
+
"src/cli/index.ts"() {
|
|
2255
|
+
"use strict";
|
|
2256
|
+
import_commander = require("commander");
|
|
2257
|
+
import_readline = require("readline");
|
|
2258
|
+
init_config();
|
|
2259
|
+
init_format();
|
|
2260
|
+
}
|
|
2261
|
+
});
|
|
2262
|
+
|
|
2263
|
+
// src/index.ts
|
|
2264
|
+
var index_exports = {};
|
|
2265
|
+
__export(index_exports, {
|
|
2266
|
+
createSpeakClient: () => createSpeakClient,
|
|
2267
|
+
formatAxiosError: () => formatAxiosError,
|
|
2268
|
+
registerAllTools: () => registerAllTools
|
|
1682
2269
|
});
|
|
2270
|
+
module.exports = __toCommonJS(index_exports);
|
|
2271
|
+
init_tools();
|
|
2272
|
+
init_client();
|
|
2273
|
+
var args = process.argv.slice(2);
|
|
2274
|
+
var cliCommands = [
|
|
2275
|
+
"config",
|
|
2276
|
+
"list-media",
|
|
2277
|
+
"ls",
|
|
2278
|
+
"get-transcript",
|
|
2279
|
+
"transcript",
|
|
2280
|
+
"get-insights",
|
|
2281
|
+
"insights",
|
|
2282
|
+
"upload",
|
|
2283
|
+
"export",
|
|
2284
|
+
"status",
|
|
2285
|
+
"create-text",
|
|
2286
|
+
"list-folders",
|
|
2287
|
+
"folders",
|
|
2288
|
+
"ask",
|
|
2289
|
+
"schedule-meeting",
|
|
2290
|
+
"help"
|
|
2291
|
+
];
|
|
2292
|
+
var isCliMode = args.length > 0 && (args[0].startsWith("-") || cliCommands.includes(args[0]));
|
|
2293
|
+
if (isCliMode) {
|
|
2294
|
+
Promise.resolve().then(() => (init_config(), config_exports)).then(({ resolveApiKey: resolveApiKey2, resolveBaseUrl: resolveBaseUrl2 }) => {
|
|
2295
|
+
resolveApiKey2();
|
|
2296
|
+
resolveBaseUrl2();
|
|
2297
|
+
Promise.resolve().then(() => (init_cli(), cli_exports)).then(({ createCli: createCli2 }) => {
|
|
2298
|
+
const program = createCli2();
|
|
2299
|
+
program.parseAsync(process.argv).catch((err) => {
|
|
2300
|
+
console.error(`Error: ${err.message}`);
|
|
2301
|
+
process.exit(1);
|
|
2302
|
+
});
|
|
2303
|
+
});
|
|
2304
|
+
});
|
|
2305
|
+
} else {
|
|
2306
|
+
import("@modelcontextprotocol/sdk/server/mcp.js").then(({ McpServer }) => {
|
|
2307
|
+
import("@modelcontextprotocol/sdk/server/stdio.js").then(
|
|
2308
|
+
({ StdioServerTransport }) => {
|
|
2309
|
+
Promise.resolve().then(() => (init_tools(), tools_exports)).then(({ registerAllTools: registerAllTools2 }) => {
|
|
2310
|
+
const server = new McpServer({
|
|
2311
|
+
name: "speak-ai",
|
|
2312
|
+
version: "1.0.0"
|
|
2313
|
+
});
|
|
2314
|
+
registerAllTools2(server);
|
|
2315
|
+
const transport = new StdioServerTransport();
|
|
2316
|
+
server.connect(transport).then(() => {
|
|
2317
|
+
process.stderr.write(
|
|
2318
|
+
"[speak-mcp] Server started on stdio transport\n"
|
|
2319
|
+
);
|
|
2320
|
+
});
|
|
2321
|
+
});
|
|
2322
|
+
}
|
|
2323
|
+
);
|
|
2324
|
+
});
|
|
2325
|
+
}
|
|
1683
2326
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1684
2327
|
0 && (module.exports = {
|
|
1685
2328
|
createSpeakClient,
|