@okostream/mcp 0.20.0 → 0.21.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 -1
- package/dist/server.js +100 -11
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -141,7 +141,9 @@ Refusals are explicit and never require guessing:
|
|
|
141
141
|
window it bought (the result carries `windowStart`, `windowEnd` and the next
|
|
142
142
|
steps); a date outside the window, a cleared date, or any date on a page whose
|
|
143
143
|
show is over is refused. `oko_update_event` may also return `warnings` (advice,
|
|
144
|
-
never a refusal).
|
|
144
|
+
never a refusal). It also sets the page's look: `pageTheme` (`auto`, `light`, `dark`) and `pageAccent`,
|
|
145
|
+
the color of buttons and links — nine palette colors are free on every plan; a custom `#rrggbb` is a Pro
|
|
146
|
+
and Max right (on other plans it is stored and the page shows the default color until the plan allows it).
|
|
145
147
|
- `WORKSPACE_LIMIT`, `SEATS_FULL`, `ENTITLEMENT_REQUIRED` — the plan of the
|
|
146
148
|
workspace owner does not hold another shared workspace, another member, or
|
|
147
149
|
the capability at all. A refused invitation stays valid. Plans are bought only
|
|
@@ -184,6 +186,10 @@ always works. The result's `sourceVia` says who fetched the image.
|
|
|
184
186
|
costs 10 lumens each for that show: the tool answers with the quote first and
|
|
185
187
|
writes only after `confirm=true`; unpublishing later does not return these
|
|
186
188
|
top-ups.
|
|
189
|
+
A block exists on the page only while it is enabled; `visibility: "hidden"` is
|
|
190
|
+
the default an enabled block starts in, and the live switch shows or hides an
|
|
191
|
+
enabled block during the show. To prepare a banner and reveal it later, enable
|
|
192
|
+
it hidden (`{"promoBanner": {"enabled": true, "visibility": "hidden"}}`).
|
|
187
193
|
The live control room is a paid option of a published page (50 lumens, Pro
|
|
188
194
|
and above) bought in the analytics screen, not through MCP.
|
|
189
195
|
- Operate live audience controls, chat, moderation, and analytics sessions.
|
package/dist/server.js
CHANGED
|
@@ -119137,7 +119137,7 @@ function sanitizeScopes(scopes) {
|
|
|
119137
119137
|
}
|
|
119138
119138
|
|
|
119139
119139
|
// build/version.js
|
|
119140
|
-
var OKO_MCP_VERSION = "0.
|
|
119140
|
+
var OKO_MCP_VERSION = "0.21.0";
|
|
119141
119141
|
|
|
119142
119142
|
// build/auth.js
|
|
119143
119143
|
var state = null;
|
|
@@ -122308,6 +122308,19 @@ function registerChatTools(server2) {
|
|
|
122308
122308
|
});
|
|
122309
122309
|
}
|
|
122310
122310
|
|
|
122311
|
+
// build/pageAccent.js
|
|
122312
|
+
var PAGE_THEMES = ["auto", "light", "dark"];
|
|
122313
|
+
var PAGE_ACCENT_KEYS = ["sky", "blue", "violet", "pink", "orange", "amber", "green", "teal", "graphite"];
|
|
122314
|
+
var HEX6 = /^#[0-9a-fA-F]{6}$/;
|
|
122315
|
+
function parsePageAccent(value) {
|
|
122316
|
+
const text = value.trim();
|
|
122317
|
+
if (PAGE_ACCENT_KEYS.includes(text))
|
|
122318
|
+
return text;
|
|
122319
|
+
if (HEX6.test(text))
|
|
122320
|
+
return text.toLowerCase();
|
|
122321
|
+
throw new Error(`pageAccent must be one of ${PAGE_ACCENT_KEYS.join(", ")} or a color like "#0a7fa3" (six hex digits); got ${JSON.stringify(value)}.`);
|
|
122322
|
+
}
|
|
122323
|
+
|
|
122311
122324
|
// build/tools/publication.js
|
|
122312
122325
|
var SERVER_REFUSAL_CODES = /* @__PURE__ */ new Set(["ENTITLEMENT_REQUIRED", "INSUFFICIENT_TOKENS", "WORKSPACE_INACTIVE"]);
|
|
122313
122326
|
function refusal2(eventId, body, tool = "oko_publish_event") {
|
|
@@ -123030,6 +123043,71 @@ async function readLiveLayer(eventId, data, nowMs) {
|
|
|
123030
123043
|
return { live, hints };
|
|
123031
123044
|
}
|
|
123032
123045
|
|
|
123046
|
+
// build/tools/blockOffAdvice.js
|
|
123047
|
+
var BLOCK_LEVELS_SENTENCE = "Three levels: `enabled` decides whether the block exists on the page at all; `visibility` (always | hidden) is the default it starts in; the live override (oko_set_block_visibility, the analytics buttons) shows or hides an ENABLED block during the show \u2014 on a disabled block it does nothing.";
|
|
123048
|
+
var PREPARING_FIELDS = {
|
|
123049
|
+
promoBanner: ["visibility", "link", "formId", "pollId"],
|
|
123050
|
+
primaryCta: ["visibility", "title", "text", "buttonLabel", "buttonUrl", "formId", "pollId"]
|
|
123051
|
+
};
|
|
123052
|
+
function touches(patch, fields) {
|
|
123053
|
+
return Boolean(patch) && fields.some((field2) => patch[field2] !== void 0);
|
|
123054
|
+
}
|
|
123055
|
+
function disabledBlockHints(args, storedBlocks) {
|
|
123056
|
+
const hints = [];
|
|
123057
|
+
const names = { promoBanner: "promo banner", primaryCta: "CTA" };
|
|
123058
|
+
for (const key of ["promoBanner", "primaryCta"]) {
|
|
123059
|
+
const patch = args[key];
|
|
123060
|
+
if (!touches(patch, PREPARING_FIELDS[key]))
|
|
123061
|
+
continue;
|
|
123062
|
+
const enabledAfter = patch?.enabled !== void 0 ? patch.enabled === true : asRecord(storedBlocks[key]).enabled === true;
|
|
123063
|
+
if (enabledAfter)
|
|
123064
|
+
continue;
|
|
123065
|
+
hints.push(`The ${names[key]} is still OFF in setup (enabled is not true), so viewers will not see it at all and a live show from analytics cannot reveal it \u2014 its visibility is only the default of an enabled block. To keep it on the page but hidden until the moment, set enabled together with visibility: oko_configure_blocks {"${key}": {"enabled": true, "visibility": "hidden"}}, then show it live with oko_set_block_visibility. On a published page turning a paid block on is charged first and needs confirm \u2014 quote it to the organizer.`);
|
|
123066
|
+
}
|
|
123067
|
+
return hints;
|
|
123068
|
+
}
|
|
123069
|
+
function disabledCardsHint(args, storedEnabled) {
|
|
123070
|
+
const preparing = args.visibility !== void 0 || Array.isArray(args.items) && args.items.length > 0;
|
|
123071
|
+
const enabledAfter = args.enabled !== void 0 ? args.enabled === true : storedEnabled;
|
|
123072
|
+
if (!preparing || enabledAfter)
|
|
123073
|
+
return [];
|
|
123074
|
+
return [
|
|
123075
|
+
'The cards block is still OFF in setup (enabled is not true), so viewers will not see the cards at all and a live show from analytics cannot reveal them \u2014 visibility is only the default of an enabled block. To keep them on the page but hidden until the moment, call oko_configure_cards {"enabled": true, "visibility": "hidden"}, then show them live with oko_set_block_visibility block "cards". On a published page turning the block on is a paid top-up and needs confirm \u2014 quote it to the organizer.'
|
|
123076
|
+
];
|
|
123077
|
+
}
|
|
123078
|
+
function disabledOverrideHint(block, visible) {
|
|
123079
|
+
const enable = block === "cards" ? 'oko_configure_cards {"enabled": true, "visibility": "hidden"}' : block === "banner" ? 'oko_configure_blocks {"promoBanner": {"enabled": true, "visibility": "hidden"}}' : block === "cta" ? 'oko_configure_blocks {"primaryCta": {"enabled": true, "visibility": "hidden"}}' : block === "placeholder" ? 'oko_configure_blocks {"videoPlaceholder": {"enabled": true}}' : 'oko_configure_blocks {"chat": {"enabled": true}}';
|
|
123080
|
+
return `The ${block} block is OFF in setup: it does not exist on the page, so ${visible === null ? "there is nothing for this override to reset" : "this live override was stored but viewers see nothing"}. Enable it first (${enable} \u2014 hidden by default if it should appear later), then use this tool at the moment of the show.`;
|
|
123081
|
+
}
|
|
123082
|
+
function preparedButOffFindings(blocks, cards) {
|
|
123083
|
+
const out = [];
|
|
123084
|
+
const tail = " Viewers will not see it, and it cannot be shown live; enable it (hidden by default if it should appear later): ";
|
|
123085
|
+
const promo = asRecord(blocks.promoBanner);
|
|
123086
|
+
if (promo.enabled !== true && (safeString(promo.imageUrl).trim() || safeString(promo.imageMasterUrl).trim() || safeString(promo.link).trim())) {
|
|
123087
|
+
out.push({
|
|
123088
|
+
code: "promo_prepared_but_off",
|
|
123089
|
+
path: "blocks.promoBanner.enabled",
|
|
123090
|
+
message: "The promo banner has an image or link prepared but is OFF in setup." + tail + 'oko_configure_blocks {"promoBanner": {"enabled": true, "visibility": "hidden"}}.'
|
|
123091
|
+
});
|
|
123092
|
+
}
|
|
123093
|
+
const cta = asRecord(blocks.primaryCta);
|
|
123094
|
+
if (cta.enabled !== true && (safeString(cta.title).trim() || safeString(cta.text).trim() || safeString(cta.buttonUrl).trim())) {
|
|
123095
|
+
out.push({
|
|
123096
|
+
code: "cta_prepared_but_off",
|
|
123097
|
+
path: "blocks.primaryCta.enabled",
|
|
123098
|
+
message: "The CTA has a title, text or button URL prepared but is OFF in setup." + tail + 'oko_configure_blocks {"primaryCta": {"enabled": true, "visibility": "hidden"}}.'
|
|
123099
|
+
});
|
|
123100
|
+
}
|
|
123101
|
+
if (!cards.enabled && cards.items.length > 0) {
|
|
123102
|
+
out.push({
|
|
123103
|
+
code: "cards_prepared_but_off",
|
|
123104
|
+
path: "blocks.cards.enabled",
|
|
123105
|
+
message: "The cards block has cards prepared but is OFF in setup." + tail + 'oko_configure_cards {"enabled": true, "visibility": "hidden"}.'
|
|
123106
|
+
});
|
|
123107
|
+
}
|
|
123108
|
+
return out;
|
|
123109
|
+
}
|
|
123110
|
+
|
|
123033
123111
|
// build/tools/setupValidation.js
|
|
123034
123112
|
function scheduleWindowPassedByPlan(event, eventDateMs, rawDurationMinutes, nowMs) {
|
|
123035
123113
|
if (event.analyticsSessionMode !== "schedule")
|
|
@@ -123142,9 +123220,10 @@ function validateEventSetup(eventId, event, nowMs = Date.now()) {
|
|
|
123142
123220
|
} else if (safeString(promo.imageMasterUrl).trim() && !readImageVariants(promo.imageVariants)) {
|
|
123143
123221
|
add(warnings, "promo_variants_pending", "blocks.promoBanner.imageVariants", "Promo banner image variants are not ready yet.");
|
|
123144
123222
|
}
|
|
123145
|
-
} else if (safeString(promo.imageUrl).trim() || safeString(promo.imageMasterUrl).trim()) {
|
|
123146
|
-
add(suggestions, "promo_disabled_with_image", "blocks.promoBanner.enabled", 'Promo banner has an uploaded image but is disabled in setup, so viewers never see it. Enable it with oko_configure_blocks promoBanner.enabled=true; to hide it only during the live show, keep it enabled and use oko_set_block_visibility block "banner" visible=false.');
|
|
123147
123223
|
}
|
|
123224
|
+
const cardsForLint = readCardsConfig(event);
|
|
123225
|
+
for (const finding of preparedButOffFindings(blocks, cardsForLint))
|
|
123226
|
+
add(warnings, finding.code, finding.path, finding.message);
|
|
123148
123227
|
const cta = asRecord(blocks.primaryCta);
|
|
123149
123228
|
if (cta.enabled === true) {
|
|
123150
123229
|
checkFormBinding("blocks.primaryCta.formId", cta.formId);
|
|
@@ -123562,6 +123641,7 @@ function registerEventTools(server2) {
|
|
|
123562
123641
|
notes: [
|
|
123563
123642
|
"billing (server-owned) is the publication record. Blocks and the control room paid AFTER publication are listed in billing.additions (one element per block or per control room, with the source payEventExtras or reconcile) and billing.controlRoom: true once the control room is paid; the show's paid set is billing.invoice plus billing.additions. Never write it.",
|
|
123564
123643
|
"blocks.promoBanner.visibility, blocks.primaryCta.visibility, blocks.cards.visibility and blocks.video.placeholder.enabled are SETUP values \u2014 the default a block starts with. A live override (oko_set_block_visibility, or the organizer's switch in analytics) replaces it without touching setup, so these fields do not say what viewers see now: `live.<block>.visibleNow` does, with `decidedBy` naming the layer that decided. oko_get_live_state shows the raw overrides (ctrl.bannerVisible and so on).",
|
|
123644
|
+
"meta.pageTheme and meta.pageAccent are the page's look AS STORED (absent = auto and sky). A custom hex in meta.pageAccent is painted only while the plan that pays for the page holds the right (Pro and Max); otherwise the page shows sky \u2014 this tool does not say which, so for a custom color on an unknown plan read oko_wallet.",
|
|
123565
123645
|
"blocks.chat: the panel exists exactly when blocks.chat.enabled is true (false HIDES the panel; messages are kept for 90 days and come back when it is enabled again). Message intake is ONE live state \u2014 oko_set_chat_mode reads and writes it; blocks.chat.intake is only the STARTING state an untouched event has (closed by default, or open), and blocks.chat.openOnSessionStart / closeOnSessionEnd are two triggers that flip that same state when an analytics session starts or ends. blocks.chat.mode and blocks.chat.visibility are legacy and read by nobody \u2014 ignore those two."
|
|
123566
123646
|
]
|
|
123567
123647
|
}),
|
|
@@ -123681,7 +123761,7 @@ function registerEventTools(server2) {
|
|
|
123681
123761
|
description: toolDescription({
|
|
123682
123762
|
summary: "Update safe top-level event/setup metadata fields.",
|
|
123683
123763
|
exampleCall: { "eventId": "Kx9pQ2mR7tL4vB8nW3cY", "title": "Autumn product webinar (rescheduled)", "eventDate": "2026-09-12T07:00:00.000Z", "speakerName": "Jane Doe", "description": "", "durationMinutes": 60 },
|
|
123684
|
-
args: ["eventId plus any subset of title, videoUrl, eventDate, speakerName, description, pinned, sessionMode, durationMinutes, sessionStartAt, sessionEndAt."],
|
|
123764
|
+
args: ["eventId plus any subset of title, videoUrl, eventDate, speakerName, description, pinned, sessionMode, durationMinutes, sessionStartAt, sessionEndAt, pageTheme, pageAccent."],
|
|
123685
123765
|
returns: "event id, the list of Firestore fields updated, and session warnings (plan versus event time, lumens versus plan, a plan with no sessions).",
|
|
123686
123766
|
examples: ["Use for title/date/speaker/video edits; use oko_configure_blocks for blocks and forms."],
|
|
123687
123767
|
notes: [
|
|
@@ -123690,6 +123770,7 @@ function registerEventTools(server2) {
|
|
|
123690
123770
|
"sessionStartAt/sessionEndAt: pass BOTH ISO datetimes to set a session time different from the show's, or pass null for both to follow the event time again. A session plan that differs from the event time is reported as a warning (moving eventDate does not move an explicit plan).",
|
|
123691
123771
|
"Setting sessionMode 'schedule' on a page with no date, or clearing the date of a page in 'schedule', in one call is refused (nothing could start from it); a page born with the auto start on and no date yet is normal and can be edited freely.",
|
|
123692
123772
|
'On a published page eventDate moves only INSIDE the show window bought at publication (from a day before the event date to two days after it): a date inside is written; a date outside, a cleared date, or any date on a page that shows "held"/\u041F\u0440\u043E\u0432\u0435\u0434\u0435\u043D\u043E is refused with errorCode EVENT_DATE_LOCKED, windowStart/windowEnd and whatToDo \u2014 every other field in the same call still goes through if eventDate is dropped from it. For a date outside the window: oko_unpublish_event (refunds, only before the window opens and only for a page that was charged), change the date, oko_publish_event (new charge); or duplicate the page with oko_duplicate_event for the new date. A draft or an unpublished page moves freely.',
|
|
123773
|
+
`pageTheme (auto | light | dark) is how the viewer page is painted: auto follows each viewer's system, light and dark look the same for everyone. pageAccent is the color of the page's buttons and links: one of the nine palette colors (sky, blue, violet, pink, orange, amber, green, teal, graphite) or a custom "#rrggbb". The nine palette colors are free on every plan. A custom hex is a right of the Pro and Max plans (of the plan that pays for the page): on a plan without it the value is still stored, but the page shows the default color (sky) until the plan allows it \u2014 the choice is not lost. The color applies to buttons and links in both the light and the dark theme and is adjusted for readability (a custom color is lightened or darkened as needed, keeping its hue). Both are read back as stored in oko_get_event, meta.pageTheme and meta.pageAccent; "sky" is the default.`,
|
|
123693
123774
|
"The result may carry warnings (never a refusal), each { code, message }: about the date \u2014 the show would start inside the window but not fit into it, or the date is already behind us while sessionMode is 'schedule' (the scheduler then starts the analytics session right away) \u2014 and about the session (see above)."
|
|
123694
123775
|
]
|
|
123695
123776
|
}),
|
|
@@ -123704,7 +123785,9 @@ function registerEventTools(server2) {
|
|
|
123704
123785
|
sessionMode: external_exports.enum(["manual", "schedule"]).optional().describe("Automatic start of the analytics session: 'schedule' starts it by itself at the start of the session plan (the default of a new page), 'manual' leaves the start to oko_start_session. The session always ends at the end of its plan."),
|
|
123705
123786
|
durationMinutes: external_exports.number().int().min(15).max(1440).optional().describe("Event duration in minutes (15-1440); with eventDate it is the default session plan."),
|
|
123706
123787
|
sessionStartAt: external_exports.string().datetime().nullable().optional().describe("Start of the session plan (ISO datetime), or null to follow the event time. Pass together with sessionEndAt."),
|
|
123707
|
-
sessionEndAt: external_exports.string().datetime().nullable().optional().describe("End of the session plan (ISO datetime), or null to follow the event time. Pass together with sessionStartAt.")
|
|
123788
|
+
sessionEndAt: external_exports.string().datetime().nullable().optional().describe("End of the session plan (ISO datetime), or null to follow the event time. Pass together with sessionStartAt."),
|
|
123789
|
+
pageTheme: external_exports.enum(PAGE_THEMES).optional().describe("How the viewer page is painted: auto (follows each viewer's system, the default), light or dark."),
|
|
123790
|
+
pageAccent: external_exports.string().max(16).optional().describe(`Color of the page's buttons and links: sky (the default), blue, violet, pink, orange, amber, green, teal, graphite \u2014 free on every plan \u2014 or a custom "#rrggbb" (Pro and Max; on other plans stored, page shows sky).`)
|
|
123708
123791
|
},
|
|
123709
123792
|
outputSchema: updateOutputSchema,
|
|
123710
123793
|
annotations: writeTool
|
|
@@ -123712,7 +123795,7 @@ function registerEventTools(server2) {
|
|
|
123712
123795
|
const requiredScopes = /* @__PURE__ */ new Set();
|
|
123713
123796
|
if (args.title !== void 0 || args.pinned !== void 0)
|
|
123714
123797
|
requiredScopes.add("events:write");
|
|
123715
|
-
if (args.videoUrl !== void 0 || args.eventDate !== void 0 || args.speakerName !== void 0 || args.description !== void 0 || args.sessionMode !== void 0 || args.durationMinutes !== void 0 || args.sessionStartAt !== void 0 || args.sessionEndAt !== void 0) {
|
|
123798
|
+
if (args.videoUrl !== void 0 || args.eventDate !== void 0 || args.speakerName !== void 0 || args.description !== void 0 || args.sessionMode !== void 0 || args.durationMinutes !== void 0 || args.sessionStartAt !== void 0 || args.sessionEndAt !== void 0 || args.pageTheme !== void 0 || args.pageAccent !== void 0) {
|
|
123716
123799
|
requiredScopes.add("setup:write");
|
|
123717
123800
|
}
|
|
123718
123801
|
if (requiredScopes.size === 0)
|
|
@@ -123739,6 +123822,10 @@ function registerEventTools(server2) {
|
|
|
123739
123822
|
}
|
|
123740
123823
|
if (args.pinned !== void 0)
|
|
123741
123824
|
patch.pinned = args.pinned;
|
|
123825
|
+
if (args.pageTheme !== void 0)
|
|
123826
|
+
patch["meta.pageTheme"] = args.pageTheme;
|
|
123827
|
+
if (args.pageAccent !== void 0)
|
|
123828
|
+
patch["meta.pageAccent"] = parsePageAccent(args.pageAccent);
|
|
123742
123829
|
if (args.sessionMode !== void 0)
|
|
123743
123830
|
patch.analyticsSessionMode = args.sessionMode;
|
|
123744
123831
|
if (args.durationMinutes !== void 0)
|
|
@@ -123772,7 +123859,7 @@ function registerEventTools(server2) {
|
|
|
123772
123859
|
server2.registerTool("oko_configure_blocks", {
|
|
123773
123860
|
title: "Configure event blocks",
|
|
123774
123861
|
description: toolDescription({
|
|
123775
|
-
summary: "Configure supported event setup blocks, forms, polls, and Telegram channel ids.",
|
|
123862
|
+
summary: "Configure supported event setup blocks, forms, polls, and Telegram channel ids. " + BLOCK_LEVELS_SENTENCE + ' To upload now and show later, set {"promoBanner": {"enabled": true, "visibility": "hidden"}} (visibility alone leaves a disabled block off the page), then call oko_set_block_visibility at the moment.',
|
|
123776
123863
|
exampleCall: { "eventId": "Kx9pQ2mR7tL4vB8nW3cY", "chat": { "enabled": true }, "promoBanner": { "enabled": false }, "primaryCta": { "enabled": true, "title": "Get the slides", "buttonLabel": "Download", "buttonUrl": "https://example.com/slides" }, "videoPlaceholder": { "enabled": true, "mode": "glass", "showTimer": true, "title": "The webinar starts at 14:00", "subtitle": "Moscow time" } },
|
|
123777
123864
|
args: [
|
|
123778
123865
|
"eventId: event to edit.",
|
|
@@ -123927,6 +124014,7 @@ function registerEventTools(server2) {
|
|
|
123927
124014
|
if (args.promoBanner?.enabled === true && !bannerHasImage) {
|
|
123928
124015
|
hints.push(`The promo banner is enabled but has no image yet: upload one with oko_upload_image kind "promoBanner". ${IMAGE_ADVICE.promoBanner}`);
|
|
123929
124016
|
}
|
|
124017
|
+
hints.push(...disabledBlockHints(args, currentBlocks));
|
|
123930
124018
|
if (args.chat?.enabled !== void 0 || args.promoBanner?.enabled !== void 0 || args.primaryCta?.enabled !== void 0 || args.videoPlaceholder?.enabled !== void 0) {
|
|
123931
124019
|
hints.push("Setup toggles (enabled) decide whether a block exists on the page and persist; live overrides (oko_set_block_visibility) show or hide an enabled block temporarily during the show. Uploading an image never enables a block.");
|
|
123932
124020
|
}
|
|
@@ -124059,6 +124147,7 @@ function registerEventTools(server2) {
|
|
|
124059
124147
|
warnings.push("The ids shown for those positions are provisional (generated on read) and were NOT stored: oko_upload_image and oko_delete_image will not accept them. Save the cards first by passing items to oko_configure_cards \u2014 the saved ids are the ones to use.");
|
|
124060
124148
|
}
|
|
124061
124149
|
}
|
|
124150
|
+
const hints = [...paid.hints ?? [], ...disabledCardsHint(args, readCardsConfig(event).enabled)];
|
|
124062
124151
|
return textResult({
|
|
124063
124152
|
eventId: args.eventId,
|
|
124064
124153
|
updated: Object.keys(patch),
|
|
@@ -124069,7 +124158,7 @@ function registerEventTools(server2) {
|
|
|
124069
124158
|
preservedImageCardIds,
|
|
124070
124159
|
warnings,
|
|
124071
124160
|
...paid.payment ? { payment: paid.payment } : {},
|
|
124072
|
-
...
|
|
124161
|
+
...hints.length ? { hints } : {}
|
|
124073
124162
|
});
|
|
124074
124163
|
});
|
|
124075
124164
|
}
|
|
@@ -125165,7 +125254,7 @@ function registerLiveTools(server2) {
|
|
|
125165
125254
|
server2.registerTool("oko_set_block_visibility", {
|
|
125166
125255
|
title: "Set live block visibility",
|
|
125167
125256
|
description: toolDescription({
|
|
125168
|
-
summary: "Set or reset a live RTDB visibility override for a public event block.",
|
|
125257
|
+
summary: "Set or reset a live RTDB visibility override for a public event block. " + BLOCK_LEVELS_SENTENCE + ' For "upload now, show later": oko_configure_blocks {"promoBanner": {"enabled": true, "visibility": "hidden"}} first, then this tool with block "banner", visible true at the moment.',
|
|
125169
125258
|
exampleCall: { "eventId": "Kx9pQ2mR7tL4vB8nW3cY", "block": "placeholder", "visible": true, "confirm": true },
|
|
125170
125259
|
args: ["eventId: event to control.", "block: chat, banner, cta, cards, or placeholder.", "visible: true/false, or null to reset override.", "confirm: must be true."],
|
|
125171
125260
|
returns: "eventId, block, and effective override value.",
|
|
@@ -125199,7 +125288,7 @@ function registerLiveTools(server2) {
|
|
|
125199
125288
|
placeholder: setupBlocks.video?.placeholder?.enabled === true
|
|
125200
125289
|
};
|
|
125201
125290
|
const chatHint = visible === null ? "Live control cleared: message intake follows the starting state (blocks.chat.intake)." : visible ? "Message sending is open (chat mode public); the panel was not touched." : "Message sending is paused (chat mode off); history stays visible, the panel was not touched.";
|
|
125202
|
-
const hints = !setupEnabled[block] ? [
|
|
125291
|
+
const hints = !setupEnabled[block] ? [disabledOverrideHint(block, visible)] : block === "chat" ? [chatHint] : [visible === null ? "Override removed: the block follows its setup visibility again." : `Live override applied on top of setup; visible=null returns the ${block} block to its setup default.`];
|
|
125203
125292
|
if (controlRoom)
|
|
125204
125293
|
hints.push(String(controlRoom.note));
|
|
125205
125294
|
const paths = {
|
|
@@ -126833,7 +126922,7 @@ function registerWalletTools(server2) {
|
|
|
126833
126922
|
"limit: ledger rows per page, default 20, max 50, newest first.",
|
|
126834
126923
|
"cursor: nextCursor returned by the previous page. The plan and the grants come with the first page only; the balance with every page."
|
|
126835
126924
|
],
|
|
126836
|
-
returns: `billingUrl (the cabinet's Billing page), plan on the first page (tier core|pro|max|legacy, status active|past_due|canceled_at_period_end|expired, source lava|operator|legacy-exit|transition-b|smoke or null, periodEnd and graceUntil as ISO times or null; plan is null when the organizer has no plan) with planRead ok|unreadable (unreadable: the plan could not be read, so null means unknown, not no plan), hasWallet, balance (whole lumens, null when the organizer has no wallet yet), unit "lumens", grants on the first page (id, bucket plan|rollover|topup, amount, remaining, expiresAt, createdAt), ledger rows (id, kind grant|charge|refund|expire|settlement, amount, delta, balanceAfter, by, at, eventId, showId, workspaceId, postId, sessionId, minutes, forgiven), unreadableGrants/unreadableLedgerRows (rows that did not read: say so, never hide them) and cursor pagination metadata.`,
|
|
126925
|
+
returns: `billingUrl (the cabinet's Billing page), plan on the first page (tier core|pro|max|legacy, status active|past_due|canceled_at_period_end|expired, source lava|tribute|operator|legacy-exit|transition-b|smoke or null, periodEnd and graceUntil as ISO times or null; plan is null when the organizer has no plan) with planRead ok|unreadable (unreadable: the plan could not be read, so null means unknown, not no plan), hasWallet, balance (whole lumens, null when the organizer has no wallet yet), unit "lumens", grants on the first page (id, bucket plan|rollover|topup, amount, remaining, expiresAt, createdAt), ledger rows (id, kind grant|charge|refund|expire|settlement, amount, delta, balanceAfter, by, at, eventId, showId, workspaceId, postId, sessionId, minutes, forgiven), unreadableGrants/unreadableLedgerRows (rows that did not read: say so, never hide them) and cursor pagination metadata.`,
|
|
126837
126926
|
examples: [
|
|
126838
126927
|
"Use before publishing a page or starting a session when the organizer asks how many lumens are left or what was charged.",
|
|
126839
126928
|
"Use to explain a charge or a refund: every ledger row names what paid (eventId, sessionId, postId) and the balance after it."
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@okostream/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "Control OKO Stream webinars from Claude, Codex, and other MCP clients.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"author": {
|
|
@@ -55,8 +55,13 @@
|
|
|
55
55
|
"firebase": "^12.16.0",
|
|
56
56
|
"ipaddr.js": "2.4.0",
|
|
57
57
|
"openai": "^6.46.0",
|
|
58
|
-
"typescript": "
|
|
58
|
+
"typescript": "~6.0.3",
|
|
59
59
|
"undici": "7.30.1",
|
|
60
60
|
"zod": "^3.25.76"
|
|
61
|
+
},
|
|
62
|
+
"allowScripts": {
|
|
63
|
+
"@firebase/util@1.15.3": true,
|
|
64
|
+
"esbuild@0.24.2": true,
|
|
65
|
+
"protobufjs@7.6.6": true
|
|
61
66
|
}
|
|
62
67
|
}
|