@speakai/mcp-server 1.7.11 → 1.9.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 +4 -2
- package/dist/index.js +85 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -242,7 +242,7 @@ For questions about data handling, see [speakai.co/privacy](https://speakai.co/p
|
|
|
242
242
|
|
|
243
243
|
## What you can do once installed
|
|
244
244
|
|
|
245
|
-
Speak AI ships
|
|
245
|
+
Speak AI ships 84 tools your AI assistant can call. You don't memorize them — Claude/ChatGPT pick the right ones based on what you ask. Examples by category:
|
|
246
246
|
|
|
247
247
|
| Ask | Tools used (auto) |
|
|
248
248
|
|---|---|
|
|
@@ -250,6 +250,7 @@ Speak AI ships 83 tools your AI assistant can call. You don't memorize them —
|
|
|
250
250
|
| "Summarize this week's meetings into decisions, owners, and risks" | `list_media`, `get_media_insights` |
|
|
251
251
|
| "Pull action items from yesterday's call" | `get_media_insights`, `ask_magic_prompt` |
|
|
252
252
|
| "Schedule the AI to join my 2pm Zoom" | `schedule_meeting_event` |
|
|
253
|
+
| "Pull the live transcript from my current MS Teams meeting since last fetch" | `list_meeting_events`, `get_live_meeting_transcript` |
|
|
253
254
|
| "Find a 30-second webinar highlight and export captions" | `create_clip`, `export_media` |
|
|
254
255
|
| "Export the transcript as a PDF and captions as SRT" | `export_media` |
|
|
255
256
|
| "Compare Q1 sales calls against Q2 sales calls and summarize changed objections" | `search_media`, `ask_magic_prompt` |
|
|
@@ -526,7 +527,7 @@ SPEAK_API_KEY=your-key npx @speakai/mcp-server
|
|
|
526
527
|
</details>
|
|
527
528
|
|
|
528
529
|
<details>
|
|
529
|
-
<summary>Meeting Assistant (
|
|
530
|
+
<summary>Meeting Assistant (5 tools)</summary>
|
|
530
531
|
|
|
531
532
|
| Tool | Description |
|
|
532
533
|
|---|---|
|
|
@@ -534,6 +535,7 @@ SPEAK_API_KEY=your-key npx @speakai/mcp-server
|
|
|
534
535
|
| `schedule_meeting_event` | Schedule AI assistant to join a meeting |
|
|
535
536
|
| `remove_assistant_from_meeting` | Remove assistant from active meeting |
|
|
536
537
|
| `delete_scheduled_assistant` | Cancel a scheduled meeting assistant |
|
|
538
|
+
| `get_live_meeting_transcript` | Pull only the new sentences added to a live (or just-ended) meeting transcript since your previous call. Works on Zoom / Google Meet / MS Teams while the bot is recording. |
|
|
537
539
|
|
|
538
540
|
</details>
|
|
539
541
|
|
package/dist/index.js
CHANGED
|
@@ -1335,7 +1335,7 @@ function register(server, client) {
|
|
|
1335
1335
|
registerSpeakTool(
|
|
1336
1336
|
server,
|
|
1337
1337
|
"get_transcript",
|
|
1338
|
-
"Retrieve the full transcript for a
|
|
1338
|
+
"Retrieve the full transcript for a media file with speaker labels and timestamps. Works on processed media and also returns the partial, in-progress transcript while a meeting bot is still recording (LIVE_TRANSCRIPT state). To fetch only the new sentences added since your previous call during a live meeting, use get_live_meeting_transcript instead. Use update_transcript_speakers to rename speaker labels after reviewing. For subtitle-formatted output, use get_captions instead.",
|
|
1339
1339
|
{
|
|
1340
1340
|
mediaId: import_zod2.z.string().min(1).describe("Unique identifier of the media file")
|
|
1341
1341
|
},
|
|
@@ -3309,6 +3309,90 @@ function register8(server, client) {
|
|
|
3309
3309
|
}
|
|
3310
3310
|
}
|
|
3311
3311
|
);
|
|
3312
|
+
registerSpeakTool(
|
|
3313
|
+
server,
|
|
3314
|
+
"get_live_meeting_transcript",
|
|
3315
|
+
"Pull the transcript for an in-progress (or just-ended) meeting and receive only the sentences added since your last call. Pass meetingAssistantEventId from list_meeting_events (preferred) or mediaId directly. Pass sinceEndInSec from the previous response's nextCursor to skip already-seen sentences; omit it on the first call. Returns newSentences, nextCursor (pass back on the next call), isLive (true while the bot is recording), and meetingStatus. Works while the meeting is live and after it ends.",
|
|
3316
|
+
{
|
|
3317
|
+
meetingAssistantEventId: import_zod9.z.string().optional().describe("Meeting assistant event id from list_meeting_events. Either this or mediaId is required."),
|
|
3318
|
+
mediaId: import_zod9.z.string().optional().describe("Media id of the live meeting. Either this or meetingAssistantEventId is required."),
|
|
3319
|
+
sinceEndInSec: import_zod9.z.number().min(0).optional().describe("Pass the nextCursor value from your previous response to skip already-seen sentences. Omit on the first call.")
|
|
3320
|
+
},
|
|
3321
|
+
{
|
|
3322
|
+
title: "Get Live Meeting Transcript",
|
|
3323
|
+
readOnlyHint: true,
|
|
3324
|
+
destructiveHint: false,
|
|
3325
|
+
idempotentHint: false,
|
|
3326
|
+
openWorldHint: true
|
|
3327
|
+
},
|
|
3328
|
+
async ({ meetingAssistantEventId, mediaId, sinceEndInSec }) => {
|
|
3329
|
+
if (!meetingAssistantEventId && !mediaId) {
|
|
3330
|
+
return {
|
|
3331
|
+
content: [{ type: "text", text: "Error: provide either meetingAssistantEventId or mediaId." }],
|
|
3332
|
+
isError: true
|
|
3333
|
+
};
|
|
3334
|
+
}
|
|
3335
|
+
try {
|
|
3336
|
+
let resolvedMediaId = mediaId;
|
|
3337
|
+
let meetingStatus = null;
|
|
3338
|
+
let meetingName;
|
|
3339
|
+
if (meetingAssistantEventId) {
|
|
3340
|
+
const eventsRes = await api.get("/v1/meeting-assistant/events", {
|
|
3341
|
+
params: { pageSize: 500 }
|
|
3342
|
+
});
|
|
3343
|
+
const events = eventsRes.data?.data?.events ?? eventsRes.data?.events ?? [];
|
|
3344
|
+
const event = events.find((e) => e.meetingAssistantEventId === meetingAssistantEventId);
|
|
3345
|
+
if (!event) {
|
|
3346
|
+
return {
|
|
3347
|
+
content: [{ type: "text", text: JSON.stringify({ status: "not_found", meetingAssistantEventId }, null, 2) }],
|
|
3348
|
+
structuredContent: { data: { status: "not_found", meetingAssistantEventId } }
|
|
3349
|
+
};
|
|
3350
|
+
}
|
|
3351
|
+
meetingStatus = event.currentStatus ?? null;
|
|
3352
|
+
meetingName = event.title;
|
|
3353
|
+
const mediaRef = event.mediaId;
|
|
3354
|
+
const linkedMediaId = typeof mediaRef === "string" ? mediaRef : mediaRef?.mediaId;
|
|
3355
|
+
if (!linkedMediaId) {
|
|
3356
|
+
const payload2 = {
|
|
3357
|
+
status: "not_started",
|
|
3358
|
+
meetingAssistantEventId,
|
|
3359
|
+
meetingStatus,
|
|
3360
|
+
message: "Meeting has no linked media yet \u2014 the bot may not have joined or started recording."
|
|
3361
|
+
};
|
|
3362
|
+
return {
|
|
3363
|
+
content: [{ type: "text", text: JSON.stringify(payload2, null, 2) }],
|
|
3364
|
+
structuredContent: { data: payload2 }
|
|
3365
|
+
};
|
|
3366
|
+
}
|
|
3367
|
+
resolvedMediaId = linkedMediaId;
|
|
3368
|
+
}
|
|
3369
|
+
const transcriptRes = await api.get(`/v1/media/transcript/${resolvedMediaId}`, {
|
|
3370
|
+
params: Number.isFinite(sinceEndInSec) ? { sinceEndInSec } : void 0
|
|
3371
|
+
});
|
|
3372
|
+
const data = transcriptRes.data?.data ?? transcriptRes.data ?? {};
|
|
3373
|
+
const sentences = data?.insight?.transcript ?? [];
|
|
3374
|
+
const maxEnd = sentences.reduce((m, s) => Math.max(m, s.instances?.[0]?.endInSec ?? 0), 0);
|
|
3375
|
+
const nextCursor = sentences.length > 0 ? maxEnd : sinceEndInSec ?? 0;
|
|
3376
|
+
const payload = {
|
|
3377
|
+
mediaId: resolvedMediaId,
|
|
3378
|
+
name: data?.name ?? meetingName ?? null,
|
|
3379
|
+
meetingStatus,
|
|
3380
|
+
isLive: meetingStatus === "inCallRecording",
|
|
3381
|
+
newSentences: sentences,
|
|
3382
|
+
nextCursor
|
|
3383
|
+
};
|
|
3384
|
+
return {
|
|
3385
|
+
content: [{ type: "text", text: JSON.stringify(payload, null, 2) }],
|
|
3386
|
+
structuredContent: { data: payload }
|
|
3387
|
+
};
|
|
3388
|
+
} catch (err) {
|
|
3389
|
+
return {
|
|
3390
|
+
content: [{ type: "text", text: `Error: ${formatAxiosError(err)}` }],
|
|
3391
|
+
isError: true
|
|
3392
|
+
};
|
|
3393
|
+
}
|
|
3394
|
+
}
|
|
3395
|
+
);
|
|
3312
3396
|
}
|
|
3313
3397
|
var import_zod9;
|
|
3314
3398
|
var init_meeting3 = __esm({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@speakai/mcp-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"mcpName": "io.github.speakai/mcp-server",
|
|
5
5
|
"description": "Official Speak AI MCP Server — capture meetings, search thousands of recordings, run async voice and video surveys, create clips, and automate workflows from your AI assistant.",
|
|
6
6
|
"homepage": "https://mcp.speakai.co",
|