@okostream/mcp 0.18.1 → 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.
Files changed (2) hide show
  1. package/dist/server.js +24 -14
  2. package/package.json +1 -1
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.1";
116323
+ var OKO_MCP_VERSION = "0.18.2";
116324
116324
 
116325
116325
  // build/auth.js
116326
116326
  var state = null;
@@ -122958,6 +122958,7 @@ function workspaceRefusalResult(tool, error3, subject = {}) {
122958
122958
  }
122959
122959
 
122960
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])?)+$/;
122961
122962
  function registerWorkspaceTools(server2) {
122962
122963
  server2.registerTool("oko_list_workspaces", {
122963
122964
  title: "List workspaces",
@@ -123198,8 +123199,8 @@ function registerWorkspaceTools(server2) {
123198
123199
  description: toolDescription({
123199
123200
  summary: "List workspace invite links for a workspace owned by the organizer.",
123200
123201
  args: ["workspaceId: workspace owned by the organizer."],
123201
- returns: "invites array with code, claim status, permissions, and inviteUrl.",
123202
- 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."]
123203
123204
  }),
123204
123205
  inputSchema: { workspaceId: external_exports.string().min(1) },
123205
123206
  outputSchema: external_exports.object({ workspaceId: external_exports.string(), invites: external_exports.array(unknownRecordSchema), count: external_exports.number().int().nonnegative() }).passthrough(),
@@ -123271,20 +123272,23 @@ function registerWorkspaceTools(server2) {
123271
123272
  server2.registerTool("oko_create_workspace_invite", {
123272
123273
  title: "Create workspace invite",
123273
123274
  description: toolDescription({
123274
- 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.",
123275
123276
  args: [
123276
123277
  "workspaceId: workspace owned by the authenticated organizer.",
123277
123278
  "code: optional invite code, 16-64 chars; omitted means generated (recommended).",
123278
- "email: optional intended recipient email.",
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.",
123279
123280
  // The schema is `workspacePermissionsSchema`: nine booleans, all
123280
123281
  // required, no extra keys. "optional whitelist" read as "send the
123281
123282
  // ones you want", and every such call was rejected by validation
123282
123283
  // before it reached the platform.
123283
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.",
123284
- "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."
123285
123286
  ],
123286
- returns: "workspaceId, invite code, inviteUrl, and created=true.",
123287
- 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
+ ]
123288
123292
  }),
123289
123293
  inputSchema: {
123290
123294
  workspaceId: external_exports.string().min(1),
@@ -123296,25 +123300,31 @@ function registerWorkspaceTools(server2) {
123296
123300
  // deliberately stays 4: they accept codes that ALREADY exist, including
123297
123301
  // the historical six-character ones.
123298
123302
  code: external_exports.string().min(16).max(MAX_WORKSPACE_INVITE_CODE_LENGTH).optional(),
123299
- 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."),
123300
123304
  comment: external_exports.string().max(500).default(""),
123301
123305
  permissions: workspacePermissionsSchema,
123302
- 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.")
123303
123307
  },
123304
- 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(),
123305
123309
  annotations: writeTool
123306
123310
  }, async (args) => {
123307
123311
  const { uid } = await authed(["workspace:write"]);
123308
123312
  const workspace = await readWorkspaceForOwner(args.workspaceId, uid);
123309
123313
  if (!isSharedWorkspaceId(args.workspaceId))
123310
123314
  throw new Error(personalWorkspaceLimitMessage("creating invites"));
123311
- requireConfirm(args.confirm, "oko_create_workspace_invite", { workspaceId: args.workspaceId, code: args.code, email: args.email });
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
+ });
123312
123321
  const code = (args.code?.trim() || randomInviteCode()).toUpperCase();
123313
123322
  const url = inviteUrl(code);
123323
+ const email2 = args.email?.trim() ?? "";
123314
123324
  await setDoc(doc(firestore, "workspaceInvites", code), {
123315
123325
  workspaceId: args.workspaceId,
123316
123326
  workspaceName: safeString(workspace.name, "Workspace"),
123317
- email: args.email ?? "",
123327
+ email: email2,
123318
123328
  comment: args.comment,
123319
123329
  permissions: normalizeWorkspacePermissions(args.permissions),
123320
123330
  createdBy: uid,
@@ -123322,7 +123332,7 @@ function registerWorkspaceTools(server2) {
123322
123332
  claimed: false,
123323
123333
  claimedBy: null
123324
123334
  });
123325
- return textResult({ workspaceId: args.workspaceId, code, inviteUrl: url, created: true });
123335
+ return textResult({ workspaceId: args.workspaceId, code, inviteUrl: url, created: true, ...email2 ? { emailRequested: true } : {} });
123326
123336
  });
123327
123337
  }
123328
123338
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@okostream/mcp",
3
- "version": "0.18.1",
3
+ "version": "0.18.2",
4
4
  "description": "Control OKO Stream webinars from Claude, Codex, and other MCP clients.",
5
5
  "license": "UNLICENSED",
6
6
  "author": {