@speakai/mcp-server 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -4
- package/dist/index.js +59 -4
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
Connect Claude, Cursor, Windsurf, and other AI assistants to your <a href="https://speakai.co">Speak AI</a> workspace.<br/>
|
|
9
|
-
|
|
9
|
+
83 tools, 5 resources, 3 prompts, 28 CLI commands — transcribe, analyze, search, and manage media at scale.
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
@@ -160,10 +160,10 @@ SPEAK_API_KEY=your-key npx @speakai/mcp-server
|
|
|
160
160
|
|
|
161
161
|
---
|
|
162
162
|
|
|
163
|
-
## MCP Tools (
|
|
163
|
+
## MCP Tools (83)
|
|
164
164
|
|
|
165
165
|
<details>
|
|
166
|
-
<summary>Media (
|
|
166
|
+
<summary>Media (16 tools)</summary>
|
|
167
167
|
|
|
168
168
|
| Tool | Description |
|
|
169
169
|
|---|---|
|
|
@@ -171,11 +171,12 @@ SPEAK_API_KEY=your-key npx @speakai/mcp-server
|
|
|
171
171
|
| `upload_media` | Upload media from a public URL for transcription |
|
|
172
172
|
| `upload_local_file` | Upload a local file directly from disk |
|
|
173
173
|
| `upload_and_analyze` | Upload, wait for processing, return transcript + insights in one call |
|
|
174
|
-
| `list_media` | List and search media files with filters and
|
|
174
|
+
| `list_media` | List and search media files with filters, pagination, and optional inline data (transcripts, speakers, keywords) via `include` param |
|
|
175
175
|
| `get_media_insights` | Get AI insights — topics, sentiment, summaries, action items |
|
|
176
176
|
| `get_transcript` | Get full transcript with speaker labels and timestamps |
|
|
177
177
|
| `get_captions` | Get subtitle-formatted captions for a media file |
|
|
178
178
|
| `update_transcript_speakers` | Rename speaker labels in a transcript |
|
|
179
|
+
| `bulk_update_transcript_speakers` | Rename speaker labels across multiple media files in one call (max 500) |
|
|
179
180
|
| `get_media_status` | Check processing status (pending -> processed) |
|
|
180
181
|
| `update_media_metadata` | Update name, description, tags, or folder |
|
|
181
182
|
| `delete_media` | Permanently delete a media file |
|
|
@@ -658,6 +659,8 @@ curl -X POST https://api.speakai.co/v1/auth/refreshToken \
|
|
|
658
659
|
- Use `export_multiple_media` over individual exports for batch operations
|
|
659
660
|
- Use `upload_and_analyze` instead of manual upload + poll + fetch loops
|
|
660
661
|
- Use `bulk_move_media` to move multiple items at once instead of updating one by one
|
|
662
|
+
- Use `bulk_update_transcript_speakers` to rename speakers across many files instead of calling `update_transcript_speakers` per file
|
|
663
|
+
- Use `list_media` with `include: ["transcription"]` to fetch media with transcripts inline, avoiding N+1 calls to `get_transcript`
|
|
661
664
|
|
|
662
665
|
### Error Format
|
|
663
666
|
|
package/dist/index.js
CHANGED
|
@@ -1145,7 +1145,7 @@ function register(server, client) {
|
|
|
1145
1145
|
);
|
|
1146
1146
|
server.tool(
|
|
1147
1147
|
"list_media",
|
|
1148
|
-
"List and search media files in the workspace with filtering, pagination, and sorting. Use filterName for text search, mediaType to filter by audio/video/text, folderId for folder-specific results, and from/to for date ranges. Returns mediaIds you can pass to get_transcript, get_media_insights, or ask_magic_prompt. For deep full-text search across transcripts, use search_media instead.",
|
|
1148
|
+
"List and search media files in the workspace with filtering, pagination, and sorting. Use filterName for text search, mediaType to filter by audio/video/text, folderId for folder-specific results, and from/to for date ranges. Use the include param to embed additional data (transcripts, speakers, keywords) inline with each result, avoiding N+1 API calls. Returns mediaIds you can pass to get_transcript, get_media_insights, or ask_magic_prompt. For deep full-text search across transcripts, use search_media instead.",
|
|
1149
1149
|
{
|
|
1150
1150
|
mediaType: import_zod.z.enum([MediaType.AUDIO, MediaType.VIDEO, MediaType.TEXT]).optional().describe('Filter by media type: "audio", "video", or "text"'),
|
|
1151
1151
|
page: import_zod.z.number().int().min(0).optional().describe("Page number for pagination (0-based, default: 0)"),
|
|
@@ -1156,11 +1156,27 @@ function register(server, client) {
|
|
|
1156
1156
|
folderId: import_zod.z.string().optional().describe("Filter media within a specific folder"),
|
|
1157
1157
|
from: import_zod.z.string().optional().describe("Start date for date range filter (ISO 8601)"),
|
|
1158
1158
|
to: import_zod.z.string().optional().describe("End date for date range filter (ISO 8601)"),
|
|
1159
|
-
isFavorites: import_zod.z.boolean().optional().describe("Filter to only show favorited media")
|
|
1159
|
+
isFavorites: import_zod.z.boolean().optional().describe("Filter to only show favorited media"),
|
|
1160
|
+
include: import_zod.z.array(
|
|
1161
|
+
import_zod.z.enum([
|
|
1162
|
+
"transcription",
|
|
1163
|
+
"keywords",
|
|
1164
|
+
"speakers",
|
|
1165
|
+
"sentiment",
|
|
1166
|
+
"custom",
|
|
1167
|
+
"fields"
|
|
1168
|
+
])
|
|
1169
|
+
).optional().describe(
|
|
1170
|
+
"Additional data to include with each media item. Without this, only metadata is returned. Use 'transcription' to include full transcripts inline, 'speakers' for speaker details, 'keywords' for extracted keywords, etc. Avoids N+1 API calls when you need data for multiple files."
|
|
1171
|
+
)
|
|
1160
1172
|
},
|
|
1161
|
-
async (params) => {
|
|
1173
|
+
async ({ include, ...params }) => {
|
|
1162
1174
|
try {
|
|
1163
|
-
const
|
|
1175
|
+
const queryParams = { ...params };
|
|
1176
|
+
if (include?.length) {
|
|
1177
|
+
queryParams.requestTypes = include.join(",");
|
|
1178
|
+
}
|
|
1179
|
+
const result = await api.get("/v1/media", { params: queryParams });
|
|
1164
1180
|
return {
|
|
1165
1181
|
content: [
|
|
1166
1182
|
{ type: "text", text: JSON.stringify(result.data, null, 2) }
|
|
@@ -1428,6 +1444,45 @@ function register(server, client) {
|
|
|
1428
1444
|
}
|
|
1429
1445
|
}
|
|
1430
1446
|
);
|
|
1447
|
+
server.tool(
|
|
1448
|
+
"bulk_update_transcript_speakers",
|
|
1449
|
+
"Update or rename speaker labels across multiple media files in a single operation. Applies the same speaker mappings to every specified media file. Use this instead of calling update_transcript_speakers repeatedly when renaming speakers across a project or folder.",
|
|
1450
|
+
{
|
|
1451
|
+
mediaIds: import_zod.z.array(import_zod.z.string().min(1)).min(1).max(500).describe("Array of media IDs to update speakers for (max 500 per call)"),
|
|
1452
|
+
speakers: import_zod.z.array(
|
|
1453
|
+
import_zod.z.object({
|
|
1454
|
+
id: import_zod.z.string().min(1).describe("Speaker identifier from the transcript"),
|
|
1455
|
+
name: import_zod.z.string().min(1).describe("Display name to assign to the speaker")
|
|
1456
|
+
})
|
|
1457
|
+
).describe("Array of speaker ID to name mappings to apply to all specified media files")
|
|
1458
|
+
},
|
|
1459
|
+
async ({ mediaIds, speakers }) => {
|
|
1460
|
+
const results = [];
|
|
1461
|
+
for (const mediaId of mediaIds) {
|
|
1462
|
+
try {
|
|
1463
|
+
await api.put(`/v1/media/speakers/${mediaId}`, { speakers });
|
|
1464
|
+
results.push({ mediaId, success: true });
|
|
1465
|
+
} catch (err) {
|
|
1466
|
+
results.push({ mediaId, success: false, error: formatAxiosError(err) });
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
const succeeded = results.filter((r) => r.success).length;
|
|
1470
|
+
const failed = results.filter((r) => !r.success).length;
|
|
1471
|
+
return {
|
|
1472
|
+
content: [
|
|
1473
|
+
{
|
|
1474
|
+
type: "text",
|
|
1475
|
+
text: JSON.stringify(
|
|
1476
|
+
{ summary: { total: mediaIds.length, succeeded, failed }, results },
|
|
1477
|
+
null,
|
|
1478
|
+
2
|
|
1479
|
+
)
|
|
1480
|
+
}
|
|
1481
|
+
],
|
|
1482
|
+
isError: failed === mediaIds.length
|
|
1483
|
+
};
|
|
1484
|
+
}
|
|
1485
|
+
);
|
|
1431
1486
|
server.tool(
|
|
1432
1487
|
"bulk_move_media",
|
|
1433
1488
|
"Move multiple media files to a folder in a single operation. Use this for batch reorganization instead of updating media one by one.",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@speakai/mcp-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Official Speak AI MCP Server — connect Claude and other AI assistants to Speak AI's transcription, insights, and media management API",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"author": "Speak AI",
|
|
28
28
|
"license": "MIT",
|
|
29
29
|
"engines": {
|
|
30
|
-
"node": ">=
|
|
30
|
+
"node": ">=22"
|
|
31
31
|
},
|
|
32
32
|
"files": [
|
|
33
33
|
"dist"
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"zod": "^3.22.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@speakai/shared": "^1.
|
|
43
|
+
"@speakai/shared": "^1.6.2",
|
|
44
44
|
"@types/node": "^20.0.0",
|
|
45
45
|
"@vitest/coverage-v8": "^4.1.2",
|
|
46
46
|
"tsup": "^8.5.1",
|