@okostream/mcp 0.12.9 → 0.12.10
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/server.js +70 -15
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -70499,6 +70499,13 @@ var OKO_CONNECTION_STATUSES = [
|
|
|
70499
70499
|
"connected",
|
|
70500
70500
|
"not_configured",
|
|
70501
70501
|
"invalid_key",
|
|
70502
|
+
// 🔴 Next to `invalid_key`, not instead of it (A7, `LR3a-2`). The key is
|
|
70503
|
+
// valid and the account behind it is switched off or blocked — the one state
|
|
70504
|
+
// in which "create a fresh key" is not merely unhelpful but impossible, and
|
|
70505
|
+
// the state in which the platform used to give exactly that advice.
|
|
70506
|
+
// A genuinely revoked key still needs the create-a-key step, so the two
|
|
70507
|
+
// states are separate codes with separate steps.
|
|
70508
|
+
"account_inactive",
|
|
70502
70509
|
"update_required",
|
|
70503
70510
|
"rate_limited",
|
|
70504
70511
|
"unavailable"
|
|
@@ -70539,6 +70546,18 @@ function nextSteps(status, minimumVersion, latestVersion) {
|
|
|
70539
70546
|
label: "Restart or reconnect the MCP server after updating the key."
|
|
70540
70547
|
}
|
|
70541
70548
|
];
|
|
70549
|
+
case "account_inactive":
|
|
70550
|
+
return [
|
|
70551
|
+
{
|
|
70552
|
+
id: "contact_support",
|
|
70553
|
+
label: "Ask OKO support to restore organizer access for this account: the key is valid, the account is switched off or blocked. Creating another key will not help \u2014 key creation needs an active account too.",
|
|
70554
|
+
url: OKO_ONBOARDING_URLS.website
|
|
70555
|
+
},
|
|
70556
|
+
{
|
|
70557
|
+
id: "restart_client",
|
|
70558
|
+
label: "Restart or reconnect the MCP server once access is restored."
|
|
70559
|
+
}
|
|
70560
|
+
];
|
|
70542
70561
|
case "update_required":
|
|
70543
70562
|
return [
|
|
70544
70563
|
{
|
|
@@ -70566,7 +70585,7 @@ function nextSteps(status, minimumVersion, latestVersion) {
|
|
|
70566
70585
|
function buildConnectionStatus(status, options2 = {}) {
|
|
70567
70586
|
const connected = status === "connected";
|
|
70568
70587
|
const errorCode = connected ? null : status === "update_required" ? "CLIENT_UPGRADE_REQUIRED" : status === "rate_limited" ? "RATE_LIMITED" : status === "unavailable" ? "SERVICE_UNAVAILABLE" : "AUTH_REQUIRED";
|
|
70569
|
-
const message = connected ? "OKO MCP is connected to an active organizer account." : status === "not_configured" ? "OKO MCP is installed, but OKO_API_KEY is not configured." : status === "invalid_key" ? "OKO MCP is installed, but the configured API key is invalid or revoked." : status === "update_required" ? options2.serverMessage ?? "This OKO MCP client version is no longer supported." : status === "rate_limited" ? "OKO temporarily rate-limited the connection attempt." : "OKO MCP could not verify the organizer connection.";
|
|
70588
|
+
const message = connected ? "OKO MCP is connected to an active organizer account." : status === "not_configured" ? "OKO MCP is installed, but OKO_API_KEY is not configured." : status === "invalid_key" ? "OKO MCP is installed, but the configured API key is invalid or revoked." : status === "account_inactive" ? options2.serverMessage ?? "The OKO API key is valid, but the organizer account behind it is switched off or blocked." : status === "update_required" ? options2.serverMessage ?? "This OKO MCP client version is no longer supported." : status === "rate_limited" ? "OKO temporarily rate-limited the connection attempt." : "OKO MCP could not verify the organizer connection.";
|
|
70570
70589
|
return {
|
|
70571
70590
|
connected,
|
|
70572
70591
|
status,
|
|
@@ -116272,7 +116291,7 @@ function sanitizeScopes(scopes) {
|
|
|
116272
116291
|
}
|
|
116273
116292
|
|
|
116274
116293
|
// build/version.js
|
|
116275
|
-
var OKO_MCP_VERSION = "0.12.
|
|
116294
|
+
var OKO_MCP_VERSION = "0.12.10";
|
|
116276
116295
|
|
|
116277
116296
|
// build/auth.js
|
|
116278
116297
|
var state = null;
|
|
@@ -116345,6 +116364,17 @@ var OkoAuthError = class extends Error {
|
|
|
116345
116364
|
function versionField(value) {
|
|
116346
116365
|
return typeof value === "string" && parseVersion(value) ? value.trim() : void 0;
|
|
116347
116366
|
}
|
|
116367
|
+
function inactiveOrganizerError(body) {
|
|
116368
|
+
const parsed = body && typeof body === "object" ? body : {};
|
|
116369
|
+
if (parsed.error !== "organizer_inactive")
|
|
116370
|
+
return null;
|
|
116371
|
+
const serverMessage = typeof parsed.message === "string" && parsed.message.trim() ? parsed.message.trim() : void 0;
|
|
116372
|
+
return new OkoAuthError("account_inactive", serverMessage ?? "The OKO API key is valid, but the organizer account behind it is switched off or blocked. Creating another key will not help \u2014 contact OKO support to restore access.", { serverMessage });
|
|
116373
|
+
}
|
|
116374
|
+
function serverRefusalNote(body) {
|
|
116375
|
+
const parsed = body && typeof body === "object" ? body : {};
|
|
116376
|
+
return typeof parsed.message === "string" && parsed.message.trim() ? parsed.message.trim() : void 0;
|
|
116377
|
+
}
|
|
116348
116378
|
function upgradeRequiredError(body) {
|
|
116349
116379
|
const parsed = body && typeof body === "object" ? body : {};
|
|
116350
116380
|
const minimumVersion = versionField(parsed.minimumVersion);
|
|
@@ -116379,7 +116409,16 @@ async function exchangeApiKey() {
|
|
|
116379
116409
|
if (status === 429) {
|
|
116380
116410
|
throw new OkoAuthError("rate_limited", "OKO API key exchange is temporarily rate-limited. Wait one minute, then restart the MCP client.");
|
|
116381
116411
|
}
|
|
116382
|
-
|
|
116412
|
+
if (status === 401) {
|
|
116413
|
+
const inactive = inactiveOrganizerError(errorBody);
|
|
116414
|
+
if (inactive)
|
|
116415
|
+
throw inactive;
|
|
116416
|
+
}
|
|
116417
|
+
throw status === 401 ? new OkoAuthError("invalid_key", "OKO API key is invalid or revoked. Create a fresh key in the OKO MCP install center and replace OKO_API_KEY.") : new OkoAuthError("unavailable", [
|
|
116418
|
+
`OKO organizer authentication failed with HTTP ${status}.`,
|
|
116419
|
+
serverRefusalNote(errorBody),
|
|
116420
|
+
"Check your connection and try again."
|
|
116421
|
+
].filter(Boolean).join(" "));
|
|
116383
116422
|
}
|
|
116384
116423
|
const data = await response.json();
|
|
116385
116424
|
if (typeof data.customToken !== "string") {
|
|
@@ -116611,17 +116650,19 @@ async function readEventAccess(eventId, uid, mode) {
|
|
|
116611
116650
|
return null;
|
|
116612
116651
|
})
|
|
116613
116652
|
]);
|
|
116614
|
-
|
|
116615
|
-
|
|
116616
|
-
|
|
116617
|
-
const allowed = grant === null ? legacyEventAllowsMode(data, uid, mode) : data.ownerId === uid || grant.exists() && grantAllowsMode(grant.data(), mode);
|
|
116618
|
-
return { data, allowed };
|
|
116653
|
+
const data = snap.data() ?? {};
|
|
116654
|
+
const holds = (wanted) => grant === null ? legacyEventAllowsMode(data, uid, wanted) : data.ownerId === uid || grant.exists() && grantAllowsMode(grant.data(), wanted);
|
|
116655
|
+
return { data, exists: snap.exists(), visible: holds("read"), allowed: holds(mode) };
|
|
116619
116656
|
}
|
|
116620
116657
|
async function eventGrantsMode(eventId, uid, mode) {
|
|
116621
116658
|
return (await readEventAccess(eventId, uid, mode)).allowed;
|
|
116622
116659
|
}
|
|
116660
|
+
var EVENT_NOT_FOUND_MESSAGE = "Event not found.";
|
|
116623
116661
|
async function readEvent(eventId, uid, mode = "read") {
|
|
116624
|
-
const { data, allowed } = await readEventAccess(eventId, uid, mode);
|
|
116662
|
+
const { data, exists, visible, allowed } = await readEventAccess(eventId, uid, mode);
|
|
116663
|
+
if (!visible || !exists) {
|
|
116664
|
+
throw new Error(EVENT_NOT_FOUND_MESSAGE);
|
|
116665
|
+
}
|
|
116625
116666
|
if (!allowed) {
|
|
116626
116667
|
throw new Error(`Event does not grant ${mode} access to this organizer.`);
|
|
116627
116668
|
}
|
|
@@ -119676,14 +119717,18 @@ function registerLifecycleTools(server2) {
|
|
|
119676
119717
|
}
|
|
119677
119718
|
|
|
119678
119719
|
// build/tools/live.js
|
|
119720
|
+
var CHAT_LIVE_SETTINGS = ["mode", "slowModeMs", "automodEnabled", "allowViewerLinks"];
|
|
119679
119721
|
function registerLiveTools(server2) {
|
|
119680
119722
|
server2.registerTool("oko_get_live_state", {
|
|
119681
119723
|
title: "Get live state",
|
|
119682
119724
|
description: toolDescription({
|
|
119683
119725
|
summary: "Read main RTDB live controls, aggregate analytics, and chat settings for an event.",
|
|
119684
119726
|
args: ["eventId: event to inspect."],
|
|
119685
|
-
returns: "eventId, agg metrics, ctrl live overrides, and chat settings.",
|
|
119686
|
-
examples: ["Use during a webinar before changing live block visibility or starting/ending sessions."]
|
|
119727
|
+
returns: "eventId, agg metrics, ctrl live overrides, and chat settings (mode, slowModeMs, automodEnabled, allowViewerLinks).",
|
|
119728
|
+
examples: ["Use during a webinar before changing live block visibility or starting/ending sessions."],
|
|
119729
|
+
notes: [
|
|
119730
|
+
"Live state does not carry the event team: to see who has access to an event and with which permissions, use oko_list_workspace_access on the event's workspace."
|
|
119731
|
+
]
|
|
119687
119732
|
}),
|
|
119688
119733
|
inputSchema: { eventId: eventIdField },
|
|
119689
119734
|
outputSchema: liveStateOutputSchema,
|
|
@@ -119691,12 +119736,18 @@ function registerLiveTools(server2) {
|
|
|
119691
119736
|
}, async ({ eventId }) => {
|
|
119692
119737
|
const { uid } = await authed(["analytics:read"]);
|
|
119693
119738
|
await readEvent(eventId, uid, "analytics");
|
|
119694
|
-
const [aggSnap, ctrlSnap,
|
|
119739
|
+
const [aggSnap, ctrlSnap, ...chatSnaps] = await Promise.all([
|
|
119695
119740
|
get(ref(rtdb, `events/${eventId}/agg`)),
|
|
119696
119741
|
get(ref(rtdb, `events/${eventId}/ctrl`)),
|
|
119697
|
-
get(ref(chatRtdb, `settings/${eventId}`))
|
|
119742
|
+
...CHAT_LIVE_SETTINGS.map((field2) => get(ref(chatRtdb, `settings/${eventId}/${field2}`)))
|
|
119698
119743
|
]);
|
|
119699
|
-
|
|
119744
|
+
const chat = {};
|
|
119745
|
+
CHAT_LIVE_SETTINGS.forEach((field2, index) => {
|
|
119746
|
+
const value = chatSnaps[index]?.val();
|
|
119747
|
+
if (value !== null && value !== void 0)
|
|
119748
|
+
chat[field2] = value;
|
|
119749
|
+
});
|
|
119750
|
+
return textResult({ eventId, agg: aggSnap.val() ?? {}, ctrl: ctrlSnap.val() ?? {}, chat });
|
|
119700
119751
|
});
|
|
119701
119752
|
server2.registerTool("oko_set_block_visibility", {
|
|
119702
119753
|
title: "Set live block visibility",
|
|
@@ -120831,7 +120882,11 @@ function registerWorkspaceTools(server2) {
|
|
|
120831
120882
|
"workspaceId: workspace owned by the authenticated organizer.",
|
|
120832
120883
|
"code: optional invite code, 16-64 chars; omitted means generated (recommended).",
|
|
120833
120884
|
"email: optional intended recipient email.",
|
|
120834
|
-
|
|
120885
|
+
// The schema is `workspacePermissionsSchema`: nine booleans, all
|
|
120886
|
+
// required, no extra keys. "optional whitelist" read as "send the
|
|
120887
|
+
// ones you want", and every such call was rejected by validation
|
|
120888
|
+
// before it reached the platform.
|
|
120889
|
+
"permissions: required object of all nine workspace permission booleans (createEvents, editSetup, deleteEvents, controlLive, moderateChat, startSession, viewAnalytics, downloadReports, sendNotifications) \u2014 every key must be present, extra keys are rejected; set false for the ones the invitee should not get.",
|
|
120835
120890
|
"confirm: must be true."
|
|
120836
120891
|
],
|
|
120837
120892
|
returns: "workspaceId, invite code, inviteUrl, and created=true.",
|