@okostream/mcp 0.18.0 → 0.18.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.
- package/README.md +2 -1
- package/dist/server.js +29 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -101,7 +101,8 @@ A new page is a draft: viewers of its public URL see "not published".
|
|
|
101
101
|
the ledger of the organizer behind the key (scope `wallet:read`, included in
|
|
102
102
|
the `operator` and `full` presets, not in `readOnly`). Keys created before that scope existed get `SCOPE_REQUIRED` and
|
|
103
103
|
need a new key. A page in a shared workspace is paid from the workspace
|
|
104
|
-
owner's wallet
|
|
104
|
+
owner's wallet: its balance is told, in the previews and refusals, to whoever
|
|
105
|
+
may spend from it; its grants and ledger are the owner's to read.
|
|
105
106
|
- **Payment and terms are web-only.** Plans and lumens are bought, and terms
|
|
106
107
|
accepted, only in the OKO web cabinet, and no MCP tool collects a password,
|
|
107
108
|
card or bank details, or agreement to terms on anyone's behalf.
|
package/dist/server.js
CHANGED
|
@@ -116320,7 +116320,7 @@ function sanitizeScopes(scopes) {
|
|
|
116320
116320
|
}
|
|
116321
116321
|
|
|
116322
116322
|
// build/version.js
|
|
116323
|
-
var OKO_MCP_VERSION = "0.18.
|
|
116323
|
+
var OKO_MCP_VERSION = "0.18.2";
|
|
116324
116324
|
|
|
116325
116325
|
// build/auth.js
|
|
116326
116326
|
var state = null;
|
|
@@ -119581,7 +119581,7 @@ function sessionOutlookWarnings(outlook) {
|
|
|
119581
119581
|
if (outlook.lumens.enoughForPlan === false && outlook.lumens.neededForPlan !== null) {
|
|
119582
119582
|
warnings.push({
|
|
119583
119583
|
code: "session_lumens_not_enough_for_plan",
|
|
119584
|
-
message: `A session that runs to the end of its plan costs about ${outlook.lumens.neededForPlan} lumens (1 per minute, taken when it ends). The wallet that pays for this workspace holds less: the session would be stopped when the lumens run out. Its owner can top it up. Lumens are checked at Start (a wallet at zero refuses it) and every minute while it runs
|
|
119584
|
+
message: `A session that runs to the end of its plan costs about ${outlook.lumens.neededForPlan} lumens (1 per minute, taken when it ends). ` + (typeof outlook.lumens.available === "number" ? `The wallet that pays for this workspace holds ${outlook.lumens.available}, which is less: ` : "The wallet that pays for this workspace holds less: ") + "the session would be stopped when the lumens run out. Its owner can top it up. Lumens are checked at Start (a wallet at zero refuses it) and every minute while it runs."
|
|
119585
119585
|
});
|
|
119586
119586
|
}
|
|
119587
119587
|
return warnings;
|
|
@@ -122386,8 +122386,9 @@ function telegramPostRefusalResult(eventId, postId, error3, callerUid) {
|
|
|
122386
122386
|
eventId,
|
|
122387
122387
|
postId,
|
|
122388
122388
|
needed,
|
|
122389
|
-
// The
|
|
122390
|
-
|
|
122389
|
+
// The server tells the balance to whoever may spend from the wallet (the payer and a member who may send: decision
|
|
122390
|
+
// 2026-09-30) — this side relays what it was told, whoever the caller is.
|
|
122391
|
+
...typeof info.available === "number" ? { available: info.available } : {},
|
|
122391
122392
|
callerIsPayer,
|
|
122392
122393
|
message: text || `OKO refused to send the Telegram post: the wallet that pays for this event holds fewer than ${needed} lumens. The post was not sent and nothing was charged.`,
|
|
122393
122394
|
whatToDo: [
|
|
@@ -122853,7 +122854,7 @@ function registerWalletTools(server2) {
|
|
|
122853
122854
|
],
|
|
122854
122855
|
notes: [
|
|
122855
122856
|
"Needs the wallet:read scope. A key created before that scope existed gets SCOPE_REQUIRED and its scopes cannot be changed: the organizer creates a new key in the OKO cabinet.",
|
|
122856
|
-
"Shows only the wallet of the organizer behind the key. A page in a shared workspace is paid from the WORKSPACE OWNER's wallet: the publish, session and Telegram previews name that payer
|
|
122857
|
+
"Shows only the wallet of the organizer behind the key. A page in a shared workspace is paid from the WORKSPACE OWNER's wallet: the publish, session and Telegram previews and refusals name that payer and tell its balance to whoever may spend from it (publish, start a session, send posts); the owner's grants and ledger are theirs to read, not this key's.",
|
|
122857
122858
|
"This tool cannot buy, grant, top up or spend lumens. Plans, lumens and payment details belong to the OKO web cabinet only; never ask the organizer for card data or a password.",
|
|
122858
122859
|
"Refusals of the paid tools use the same codes as the web: ENTITLEMENT_REQUIRED (the plan does not include the feature) and INSUFFICIENT_TOKENS (not enough lumens); PLATFORM_REJECTED_READ here means the platform refused the read."
|
|
122859
122860
|
]
|
|
@@ -122957,6 +122958,7 @@ function workspaceRefusalResult(tool, error3, subject = {}) {
|
|
|
122957
122958
|
}
|
|
122958
122959
|
|
|
122959
122960
|
// build/tools/workspaces.js
|
|
122961
|
+
var INVITE_EMAIL_PATTERN = /^[A-Za-z0-9.!#$%&'*+/=?^_`{|}~-]{1,64}@[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+$/;
|
|
122960
122962
|
function registerWorkspaceTools(server2) {
|
|
122961
122963
|
server2.registerTool("oko_list_workspaces", {
|
|
122962
122964
|
title: "List workspaces",
|
|
@@ -123197,8 +123199,8 @@ function registerWorkspaceTools(server2) {
|
|
|
123197
123199
|
description: toolDescription({
|
|
123198
123200
|
summary: "List workspace invite links for a workspace owned by the organizer.",
|
|
123199
123201
|
args: ["workspaceId: workspace owned by the organizer."],
|
|
123200
|
-
returns: "invites array with code, claim status, permissions, and inviteUrl.",
|
|
123201
|
-
examples: ["Use before revoking or sharing an invite code."]
|
|
123202
|
+
returns: "invites array with code, claim status, permissions, and inviteUrl; for an invite created with an email also mailStatus (queued | sent | not_sent) and, when not_sent, mailReason (rate_limited | address | not_allowed | undeliverable) \u2014 what the platform did with the letter. No mailStatus on an invite with an email means the platform has not reported yet: do not read it as sent. sent means the provider accepted the letter, not that it was delivered.",
|
|
123203
|
+
examples: ["Use before revoking or sharing an invite code, and to check whether the platform's letter went out."]
|
|
123202
123204
|
}),
|
|
123203
123205
|
inputSchema: { workspaceId: external_exports.string().min(1) },
|
|
123204
123206
|
outputSchema: external_exports.object({ workspaceId: external_exports.string(), invites: external_exports.array(unknownRecordSchema), count: external_exports.number().int().nonnegative() }).passthrough(),
|
|
@@ -123270,20 +123272,23 @@ function registerWorkspaceTools(server2) {
|
|
|
123270
123272
|
server2.registerTool("oko_create_workspace_invite", {
|
|
123271
123273
|
title: "Create workspace invite",
|
|
123272
123274
|
description: toolDescription({
|
|
123273
|
-
summary: "Create a workspace invite for a known OKO workspace.",
|
|
123275
|
+
summary: "Create a workspace invite for a known OKO workspace. When `email` is given, OKO Stream itself emails the invitation to that address: an external effect, not a note.",
|
|
123274
123276
|
args: [
|
|
123275
123277
|
"workspaceId: workspace owned by the authenticated organizer.",
|
|
123276
123278
|
"code: optional invite code, 16-64 chars; omitted means generated (recommended).",
|
|
123277
|
-
"email: optional
|
|
123279
|
+
"email: optional email of the invitee, one plain address (`name@domain`). When given, the PLATFORM sends the invitation letter to it \u2014 the workspace name and the invite link, in the language of the account that owns that address when there is one and it has a language, otherwise in the inviter's language, otherwise English; the `comment` is never put into the letter. A letter cannot be recalled: confirm the exact address with the workspace owner first. Omit it to get only the link.",
|
|
123278
123280
|
// The schema is `workspacePermissionsSchema`: nine booleans, all
|
|
123279
123281
|
// required, no extra keys. "optional whitelist" read as "send the
|
|
123280
123282
|
// ones you want", and every such call was rejected by validation
|
|
123281
123283
|
// before it reached the platform.
|
|
123282
123284
|
"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.",
|
|
123283
|
-
"confirm: must be true."
|
|
123285
|
+
"confirm: must be true. Without it the call is refused with a preview that names the address the platform would email."
|
|
123284
123286
|
],
|
|
123285
|
-
returns: "workspaceId, invite code, inviteUrl, and
|
|
123286
|
-
examples: ["Use only after confirming the recipient and permission set with the workspace owner."]
|
|
123287
|
+
returns: "workspaceId, invite code, inviteUrl, created=true, and emailRequested=true when an address was given: the platform queues the letter AFTER the invite exists, and this result does not say the letter was delivered \u2014 what became of it is mailStatus on the invite, read with oko_list_workspace_invites a moment later.",
|
|
123288
|
+
examples: ["Use only after confirming the recipient and permission set with the workspace owner."],
|
|
123289
|
+
notes: [
|
|
123290
|
+
"The invite itself and its inviteUrl are always created and always work. The LETTER is held to limits and is checked again just before it goes out: at most 1 letter an hour for one workspace and address, 3 a day to one address, 20 a day per inviter; and none if the invite was revoked or accepted meanwhile, or the plan has no free seat. When no letter goes out the invite stays valid: pass inviteUrl on yourself \u2014 mailStatus not_sent says so (mailReason not_allowed means the invite cannot be accepted right now, so passing the link on would not help either)."
|
|
123291
|
+
]
|
|
123287
123292
|
}),
|
|
123288
123293
|
inputSchema: {
|
|
123289
123294
|
workspaceId: external_exports.string().min(1),
|
|
@@ -123295,25 +123300,31 @@ function registerWorkspaceTools(server2) {
|
|
|
123295
123300
|
// deliberately stays 4: they accept codes that ALREADY exist, including
|
|
123296
123301
|
// the historical six-character ones.
|
|
123297
123302
|
code: external_exports.string().min(16).max(MAX_WORKSPACE_INVITE_CODE_LENGTH).optional(),
|
|
123298
|
-
email: external_exports.string().email().optional(),
|
|
123303
|
+
email: external_exports.string().max(254).regex(INVITE_EMAIL_PATTERN, "One plain email address (name@domain), no names, lists or spaces.").optional().describe("Optional. When given, OKO Stream emails the invitation to this address."),
|
|
123299
123304
|
comment: external_exports.string().max(500).default(""),
|
|
123300
123305
|
permissions: workspacePermissionsSchema,
|
|
123301
|
-
confirm: external_exports.boolean().optional()
|
|
123306
|
+
confirm: external_exports.boolean().optional().describe("Required true. With an email, true also means the workspace owner has confirmed that address.")
|
|
123302
123307
|
},
|
|
123303
|
-
outputSchema: external_exports.object({ workspaceId: external_exports.string(), code: external_exports.string(), inviteUrl: external_exports.string().url(), created: external_exports.boolean() }).passthrough(),
|
|
123308
|
+
outputSchema: external_exports.object({ workspaceId: external_exports.string(), code: external_exports.string(), inviteUrl: external_exports.string().url(), created: external_exports.boolean(), emailRequested: external_exports.boolean().optional() }).passthrough(),
|
|
123304
123309
|
annotations: writeTool
|
|
123305
123310
|
}, async (args) => {
|
|
123306
123311
|
const { uid } = await authed(["workspace:write"]);
|
|
123307
123312
|
const workspace = await readWorkspaceForOwner(args.workspaceId, uid);
|
|
123308
123313
|
if (!isSharedWorkspaceId(args.workspaceId))
|
|
123309
123314
|
throw new Error(personalWorkspaceLimitMessage("creating invites"));
|
|
123310
|
-
requireConfirm(args.confirm, "oko_create_workspace_invite", {
|
|
123315
|
+
requireConfirm(args.confirm, "oko_create_workspace_invite", {
|
|
123316
|
+
workspaceId: args.workspaceId,
|
|
123317
|
+
code: args.code,
|
|
123318
|
+
email: args.email,
|
|
123319
|
+
...args.email ? { platformEmailsThisAddress: true } : {}
|
|
123320
|
+
});
|
|
123311
123321
|
const code = (args.code?.trim() || randomInviteCode()).toUpperCase();
|
|
123312
123322
|
const url = inviteUrl(code);
|
|
123323
|
+
const email2 = args.email?.trim() ?? "";
|
|
123313
123324
|
await setDoc(doc(firestore, "workspaceInvites", code), {
|
|
123314
123325
|
workspaceId: args.workspaceId,
|
|
123315
123326
|
workspaceName: safeString(workspace.name, "Workspace"),
|
|
123316
|
-
email:
|
|
123327
|
+
email: email2,
|
|
123317
123328
|
comment: args.comment,
|
|
123318
123329
|
permissions: normalizeWorkspacePermissions(args.permissions),
|
|
123319
123330
|
createdBy: uid,
|
|
@@ -123321,7 +123332,7 @@ function registerWorkspaceTools(server2) {
|
|
|
123321
123332
|
claimed: false,
|
|
123322
123333
|
claimedBy: null
|
|
123323
123334
|
});
|
|
123324
|
-
return textResult({ workspaceId: args.workspaceId, code, inviteUrl: url, created: true });
|
|
123335
|
+
return textResult({ workspaceId: args.workspaceId, code, inviteUrl: url, created: true, ...email2 ? { emailRequested: true } : {} });
|
|
123325
123336
|
});
|
|
123326
123337
|
}
|
|
123327
123338
|
|