@okostream/mcp 0.14.1 → 0.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/server.js +44 -15
  2. package/package.json +1 -1
package/dist/server.js CHANGED
@@ -85972,6 +85972,13 @@ var SERVER_TIMESTAMP = {
85972
85972
  function serverTimestamp() {
85973
85973
  return SERVER_TIMESTAMP;
85974
85974
  }
85975
+ function increment(delta) {
85976
+ return {
85977
+ ".sv": {
85978
+ "increment": delta
85979
+ }
85980
+ };
85981
+ }
85975
85982
  var TransactionResult = class {
85976
85983
  /** @hideconstructor */
85977
85984
  constructor(committed, snapshot) {
@@ -116300,7 +116307,7 @@ function sanitizeScopes(scopes) {
116300
116307
  }
116301
116308
 
116302
116309
  // build/version.js
116303
- var OKO_MCP_VERSION = "0.14.1";
116310
+ var OKO_MCP_VERSION = "0.14.2";
116304
116311
 
116305
116312
  // build/auth.js
116306
116313
  var state = null;
@@ -116370,6 +116377,15 @@ var OkoAuthError = class extends Error {
116370
116377
  this.serverMessage = details.serverMessage;
116371
116378
  }
116372
116379
  };
116380
+ function transportFailure(error3) {
116381
+ if (!(error3 instanceof Error))
116382
+ return String(error3);
116383
+ const cause = error3.cause;
116384
+ if (!(cause instanceof Error))
116385
+ return error3.message;
116386
+ const code = cause.code;
116387
+ return `${error3.message}: ${typeof code === "string" ? code : cause.message}`;
116388
+ }
116373
116389
  function versionField(value) {
116374
116390
  return typeof value === "string" && parseVersion(value) ? value.trim() : void 0;
116375
116391
  }
@@ -116403,8 +116419,8 @@ async function exchangeApiKey() {
116403
116419
  headers: { "content-type": "application/json" },
116404
116420
  body: JSON.stringify({ apiKey: env.apiKey, clientVersion: OKO_MCP_VERSION })
116405
116421
  });
116406
- } catch {
116407
- throw new OkoAuthError("unavailable", "OKO MCP could not reach the organizer authentication service. Check network access and reconnect.");
116422
+ } catch (error3) {
116423
+ throw new OkoAuthError("unavailable", `OKO MCP could not reach the organizer authentication service (${transportFailure(error3)}). Check network access and reconnect.`);
116408
116424
  }
116409
116425
  if (!response.ok) {
116410
116426
  const status = response.status;
@@ -116457,8 +116473,8 @@ var refreshSession = singleFlight(async () => {
116457
116473
  const exchanged = await exchangeApiKey();
116458
116474
  try {
116459
116475
  await signInWithCustomToken(auth, exchanged.customToken);
116460
- } catch {
116461
- throw new OkoAuthError("unavailable", "OKO MCP received an organizer session but could not initialize it. Reconnect and try again.");
116476
+ } catch (error3) {
116477
+ throw new OkoAuthError("unavailable", `OKO MCP received an organizer session but could not initialize it (${error3 instanceof Error ? error3.message : String(error3)}). Reconnect and try again.`);
116462
116478
  }
116463
116479
  state = {
116464
116480
  uid: exchanged.organizerUid,
@@ -118320,7 +118336,7 @@ function registerChatTools(server2) {
118320
118336
  description: toolDescription({
118321
118337
  summary: "Send a chat message as the authenticated organizer/moderator.",
118322
118338
  args: ["eventId: target event chat.", "text: message text, max 500 chars.", "name: display name, default OKO MCP.", "confirm: must be true."],
118323
- returns: "eventId, new messageId, and sent=true.",
118339
+ returns: "eventId, new messageId, sent=true, and counted: whether the analytics chat message counter was updated (false comes with a hint; the message itself was still sent).",
118324
118340
  examples: ["Use for organizer announcements in chat after user confirms the exact text."]
118325
118341
  }),
118326
118342
  inputSchema: {
@@ -118348,8 +118364,17 @@ function registerChatTools(server2) {
118348
118364
  [`messages/${eventId}/${msgRef.key}`]: { text: messageText, uid, name: messageName, role, ts: timestamp },
118349
118365
  [`rate_limits/${eventId}/${uid}`]: { ts: timestamp, messageId: msgRef.key }
118350
118366
  });
118351
- await runTransaction(ref(rtdb, `events/${eventId}/agg/chatMessages`), (n) => (n ?? 0) + 1).catch(() => void 0);
118352
- return textResult({ eventId, messageId: msgRef.key, sent: true });
118367
+ let counted = true;
118368
+ const hints = [];
118369
+ try {
118370
+ await update(ref(rtdb), { [`events/${eventId}/agg/chatMessages`]: increment(1) });
118371
+ } catch (error3) {
118372
+ counted = false;
118373
+ const reason = error3 instanceof Error ? error3.message : String(error3);
118374
+ console.error(`[OKO MCP] chat message counter not updated for event ${eventId}: ${reason}`);
118375
+ hints.push(`The message was sent, but the analytics chat message counter was not updated (${reason}). Analytics may show one message fewer. Do not resend the message.`);
118376
+ }
118377
+ return textResult({ eventId, messageId: msgRef.key, sent: true, counted, ...hints.length > 0 ? { hints } : {} });
118353
118378
  });
118354
118379
  server2.registerTool("oko_delete_chat_message", {
118355
118380
  title: "Delete chat message",
@@ -118565,7 +118590,7 @@ function eventRuntimeHint(runtime) {
118565
118590
 
118566
118591
  // build/tools/liveLayer.js
118567
118592
  var LIVE_FIELDS_HINT = "blocks.promoBanner.visibility, blocks.primaryCta.visibility, blocks.cards.visibility and blocks.video.placeholder.enabled are SETUP values. What viewers see right now is `live.<block>.visibleNow` \u2014 `decidedBy` says whether a live override (oko_set_block_visibility) or the setup default decided it. For the chat, `live.chat.accepting` is whether viewers can send a message right now; `blocks.chat.intake` is only the starting state. The live badge and the active analytics session are not resolved here: read oko_get_live_state (ctrl.liveBadge, ctrl.activeSessionId).";
118568
- var LIVE_UNREADABLE_HINT = "blocks.*.visibility and .enabled above are SETUP values, not what viewers see now \u2014 and the live overrides could not be read with this key (they need analytics:read or live:control). Do not report a block as shown or hidden from these fields; read oko_get_live_state with a key that holds the scope.";
118593
+ var liveUnreadableHint = (reason) => `blocks.*.visibility and .enabled above are SETUP values, not what viewers see now \u2014 and the live overrides could not be read (${reason}; a key without analytics:read or live:control is always refused here). Do not report a block as shown or hidden from these fields; read oko_get_live_state with a key that holds the scope.`;
118569
118594
  function record2(value) {
118570
118595
  return value && typeof value === "object" ? value : {};
118571
118596
  }
@@ -118591,8 +118616,8 @@ async function readLiveLayer(eventId, data, nowMs) {
118591
118616
  let ctrl;
118592
118617
  try {
118593
118618
  ctrl = record2((await get(ref(rtdb, `events/${eventId}/ctrl`))).val());
118594
- } catch {
118595
- return { live: null, hints: [LIVE_UNREADABLE_HINT] };
118619
+ } catch (error3) {
118620
+ return { live: null, hints: [liveUnreadableHint(error3 instanceof Error ? error3.message : String(error3))] };
118596
118621
  }
118597
118622
  const banner = record2(blocks.promoBanner);
118598
118623
  const cta = record2(blocks.primaryCta);
@@ -118601,11 +118626,13 @@ async function readLiveLayer(eventId, data, nowMs) {
118601
118626
  const chat = record2(blocks.chat);
118602
118627
  const showAt = millis(banner.showAt);
118603
118628
  let accepting = null;
118629
+ let acceptingUnread = "";
118604
118630
  try {
118605
118631
  const mode = (await get(ref(chatRtdb, `settings/${eventId}/mode`))).val();
118606
118632
  accepting = mode !== "off";
118607
- } catch {
118633
+ } catch (error3) {
118608
118634
  accepting = null;
118635
+ acceptingUnread = error3 instanceof Error ? error3.message : String(error3);
118609
118636
  }
118610
118637
  const live = {
118611
118638
  readAt: new Date(nowMs).toISOString(),
@@ -118617,7 +118644,7 @@ async function readLiveLayer(eventId, data, nowMs) {
118617
118644
  };
118618
118645
  const hints = [LIVE_FIELDS_HINT];
118619
118646
  if (accepting === null) {
118620
- hints.push("live.chat.accepting could not be read with this key; oko_get_live_state reports it when the key holds analytics:read.");
118647
+ hints.push(`live.chat.accepting could not be read (${acceptingUnread}); oko_get_live_state reports it when the key holds analytics:read.`);
118621
118648
  }
118622
118649
  return { live, hints };
118623
118650
  }
@@ -120385,15 +120412,17 @@ async function assertSessionHasNothingToEnd(eventId, sessionId) {
120385
120412
  if (!sessionId)
120386
120413
  return;
120387
120414
  let read;
120415
+ let readFailure = "";
120388
120416
  try {
120389
120417
  const snap = await get(ref(rtdb, `events/${eventId}/sessions/${sessionId}/baseline`));
120390
120418
  read = { ok: true, exists: snap.exists() };
120391
- } catch {
120419
+ } catch (error3) {
120392
120420
  read = { ok: false };
120421
+ readFailure = error3 instanceof Error ? error3.message : String(error3);
120393
120422
  }
120394
120423
  const refusal = sessionRepairRefusal(sessionRepairAction({ liveSessionBaseline: sessionBaselineFromRead(read) }));
120395
120424
  if (refusal)
120396
- throw new Error(refusal);
120425
+ throw new Error(readFailure ? `${refusal} (read failed: ${readFailure})` : refusal);
120397
120426
  }
120398
120427
  async function attemptCleanup(path, run) {
120399
120428
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@okostream/mcp",
3
- "version": "0.14.1",
3
+ "version": "0.14.2",
4
4
  "description": "Control OKO Stream webinars from Claude, Codex, and other MCP clients.",
5
5
  "license": "UNLICENSED",
6
6
  "author": {