@amerged/ohmyhost-mcp 0.1.32 → 0.1.34

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/index.js CHANGED
@@ -2,7 +2,7 @@ import { createRequire as __ohmyhostCreateRequire } from "node:module"; const re
2
2
  import {
3
3
  createOhmyhostMcpServer,
4
4
  ohmyhostMcpHandler
5
- } from "./chunk-B2W7NWLK.js";
5
+ } from "./chunk-E3ZJXGBW.js";
6
6
  export {
7
7
  createOhmyhostMcpServer,
8
8
  ohmyhostMcpHandler
@@ -30,7 +30,7 @@ import {
30
30
  serverIdentityOf,
31
31
  setNegotiatedProtocolVersion,
32
32
  validateEnvelopeMeta
33
- } from "./chunk-B2W7NWLK.js";
33
+ } from "./chunk-E3ZJXGBW.js";
34
34
 
35
35
  // node_modules/.pnpm/ignore@7.0.12/node_modules/ignore/index.js
36
36
  var require_ignore = __commonJS({
@@ -20344,9 +20344,9 @@ var FRAMEWORK_CONVERSION_DETAILS = Object.freeze({
20344
20344
  paths: ["framework_config"],
20345
20345
  template: `"{{path}}" does not follow the TanStack Start plugin contract: import tanstackStart from "@tanstack/react-start/plugin/vite"; on runtime edge also import cloudflare from "@cloudflare/vite-plugin" and call cloudflare({ viteEnvironment: { name: "ssr" } }) before tanstackStart(); on runtime static do not import the Cloudflare plugin. ${PUSH_AND_PLAN}`
20346
20346
  },
20347
- next_cache_components_unsupported: {
20347
+ next_tailwind_turbopack_only: {
20348
20348
  paths: ["framework_config"],
20349
- template: `"{{path}}" sets cacheComponents: true, which ohmyho.st does not support; remove it or set it to false. ${PUSH_AND_PLAN}`
20349
+ template: `"{{path}}" loads Tailwind CSS through the Turbopack rule "@tailwindcss/turbopack", which the Webpack build on ohmyho.st ignores, and the application root has no PostCSS configuration that Webpack reads, so the site would deploy without its Tailwind classes. Add postcss.config.mjs to the application root with export default { plugins: { "@tailwindcss/postcss": {} } } and remove the Turbopack rule. Use the package manager to add @tailwindcss/postcss to devDependencies at the same version as tailwindcss and to remove @tailwindcss/turbopack, so the lockfile records both. ${PUSH_AND_PLAN}`
20350
20350
  },
20351
20351
  framework_version_unsupported: {
20352
20352
  paths: ["manifest", "lockfile"],
@@ -22322,14 +22322,25 @@ var parseDevAccessTicket = (value) => {
22322
22322
  return input;
22323
22323
  };
22324
22324
  var parseCurrentIdentity = (value) => {
22325
- const input = exactRecord2(value, ["actor_id", "organization_ids"]);
22325
+ const input = exactRecord2(value, ["actor_id", "email", "organization_ids", "organizations"]);
22326
+ const email = input["email"];
22326
22327
  const organizationIds = input["organization_ids"];
22328
+ const organizations = input["organizations"];
22327
22329
  if (typeof input["actor_id"] !== "string" || input["actor_id"].length === 0 || input["actor_id"].length > 256 || [...input["actor_id"]].some((character) => {
22328
22330
  const codePoint = character.codePointAt(0) ?? 0;
22329
22331
  return codePoint <= 31 || codePoint === 127;
22330
- }) || !Array.isArray(organizationIds) || organizationIds.some((organizationId) => !isUlid(organizationId)) || new Set(organizationIds).size !== organizationIds.length) {
22332
+ }) || email !== null && (!boundedString(email, 3, 254) || !/^[^\s@]+@[^\s@.]+(?:\.[^\s@.]+)+$/u.test(email) || /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u.test(email)) || !Array.isArray(organizationIds) || organizationIds.some((organizationId) => !isUlid(organizationId)) || new Set(organizationIds).size !== organizationIds.length || !Array.isArray(organizations) || organizations.length !== organizationIds.length) {
22331
22333
  throw new ResponseContractError();
22332
22334
  }
22335
+ organizations.forEach((organization, index) => {
22336
+ const entry = exactRecord2(organization, ["id", "name"]);
22337
+ if (entry["id"] !== organizationIds[index] || !boundedString(entry["name"], 1, 128) || entry["name"].trim() !== entry["name"] || [...entry["name"]].some((character) => {
22338
+ const codePoint = character.codePointAt(0) ?? 0;
22339
+ return codePoint <= 31 || codePoint === 127;
22340
+ })) {
22341
+ throw new ResponseContractError();
22342
+ }
22343
+ });
22333
22344
  return input;
22334
22345
  };
22335
22346
  var parseAccountProfile = (value) => {
@@ -23221,7 +23232,7 @@ function exact3(v, keys) {
23221
23232
  // apps/product-cli/package.json
23222
23233
  var package_default2 = {
23223
23234
  name: "@ohmyhost/product-cli",
23224
- version: "0.1.32",
23235
+ version: "0.1.34",
23225
23236
  private: true,
23226
23237
  ohmyhost: {
23227
23238
  deployment: "production",
@@ -24327,7 +24338,7 @@ var HELP_USAGE = Object.freeze({
24327
24338
  "project flag set": "ohmyhost project flag set --project ULID --enabled true|false --idempotency-key KEY --json (shows the small Powered by ohmyho.st flag on the production site; while it shows, this project's custom domain uses no domain credits and also works on Free, and each Paid period bought through Stripe adds 250 credits to the workspace, however many projects show the flag)",
24328
24339
  "project handle check": "ohmyhost project handle check --handle HANDLE --json (is this address free? answers with a reason and free alternatives; the address becomes HANDLE.check.omh.st)",
24329
24340
  "project handle set": "ohmyhost project handle set --project ULID --handle HANDLE --if-match ETAG --idempotency-key KEY --json (moves the project to a free address; the old one stops working and anyone may claim it)",
24330
- "database compute set": "ohmyhost database compute set --project ULID --environment dev|prod --profile standard|performance --idempotency-key KEY --yes [--wait] --json\n standard: Free 0.25 CU/1 GB/60s idle, Paid 0.5 CU/2 GB/60s idle. performance: Paid 1 CU/4 GB/300s idle, 2.5x database compute credits per equal active minute; longer idle time also consumes credits.",
24341
+ "database compute set": "ohmyhost database compute set --project ULID --environment dev|prod --profile standard|performance --idempotency-key KEY --yes [--wait] --json\n standard: Free 0.25 CU/1 GB, Paid 0.5 CU/2 GB. performance: Paid 1 CU/4 GB, 2.5x database compute credits per equal active minute. All profiles use the provider-default idle suspension.",
24331
24342
  "database compute get": "ohmyhost database compute get --project ULID [--environment dev|prod] --json",
24332
24343
  "database write": "ohmyhost database write --project ULID --environment dev|prod --statement-file PATH --idempotency-key KEY [--parameters-json JSON] --yes --json",
24333
24344
  "database query": "ohmyhost database query --project ULID --environment dev|prod --statement SQL [--parameters-json JSON] --json",
@@ -29147,7 +29158,7 @@ function createLocalOhmyhostMcpServer(dependencies) {
29147
29158
  });
29148
29159
  registerManagedSourceTools(server, dependencies);
29149
29160
  registerProductTool(server, dependencies, "database_compute_get", "Read current managed database size, memory, region and compute state without running SQL or waking the database. Shared Dev/Prod resolves to one physical database. A null database means no confirmed managed placement. suspend_timeout_seconds=0 uses the provider default; -1 disables scale to zero. A configured value is not proof that an in-progress resize finished. This read never resizes or changes billing.", external_exports.object({ project_id: identifier2, environment: external_exports.enum(["dev", "prod"]).default("dev") }), (client2, input) => client2.getDatabaseCompute({ projectId: input.project_id, environment: input.environment }));
29150
- registerProductTool(server, dependencies, "database_compute_set", "Select standard or performance compute for an existing database: Free 0.25 CU/1 GB/60-second idle suspension, Paid 0.5 CU/2 GB/60-second idle suspension. First read database_compute_get and explain actual size, metered compute cost, possible brief connection interruption and that shared data changes both Dev and Prod. Require the user's decision before confirm=true. SQL data is preserved. Poll the returned operation every 60 seconds; never submit a second change while it runs. Performance requires active Paid access and selects 1 CU/4 GB/300-second idle suspension at 2.5x Paid-standard compute credits per equal active minute; the longer idle window also consumes more active time. This affects only database compute. Read organization_credits_get for the published rate and active meter first. A successful choice is remembered per physical database; automatic Free downgrades preserve it, and an explicit standard choice clears it. Mixed/uncertain transition hours waive the premium; never multiply raw CU usage again.", external_exports.object({
29161
+ registerProductTool(server, dependencies, "database_compute_set", "Select standard or performance compute for an existing database: Free 0.25 CU/1 GB, Paid 0.5 CU/2 GB. All profiles use provider-default idle suspension (suspend_timeout_seconds=0). First read database_compute_get and explain actual size, metered compute cost, possible brief connection interruption and that shared data changes both Dev and Prod. Require the user's decision before confirm=true. SQL data is preserved. Poll the returned operation every 60 seconds; never submit a second change while it runs. Performance requires active Paid access and selects 1 CU/4 GB at 2.5x Paid-standard compute credits per equal active minute. This affects only database compute. Read organization_credits_get for the published rate and active meter first. A successful choice is remembered per physical database; automatic Free downgrades preserve it, and an explicit standard choice clears it. Mixed/uncertain transition hours waive the premium; never multiply raw CU usage again.", external_exports.object({
29151
29162
  project_id: identifier2,
29152
29163
  environment: external_exports.enum(["dev", "prod"]),
29153
29164
  profile: external_exports.enum(["standard", "performance"]),
@@ -29411,7 +29422,7 @@ function createLocalOhmyhostMcpServer(dependencies) {
29411
29422
  });
29412
29423
  return { revoked: true, key_id: input.key_id };
29413
29424
  }, destructiveAnnotations());
29414
- registerProductTool(server, dependencies, "identity_get", "Get the ohmyho.st customer/agent identity this call acts as: user, organization and, in context, the saved login or OHMYHOST_TOKEN that supplied it. Compare it with the user and organization the customer named before any change. This does not authenticate the hosted application's end users or provision a customer AuthKit tenant; application authentication is the customer's chosen integration.", external_exports.object({}), (client2, _input, signal) => client2.getCurrentIdentity(signal));
29425
+ registerProductTool(server, dependencies, "identity_get", "Get the ohmyho.st customer/agent identity this call acts as: user and account email, scoped organization IDs and names and, in context, the saved login or OHMYHOST_TOKEN that supplied it. Compare it with the user and organization the customer named before any change. This does not authenticate the hosted application's end users or provision a customer AuthKit tenant; application authentication is the customer's chosen integration.", external_exports.object({}), (client2, _input, signal) => client2.getCurrentIdentity(signal));
29415
29426
  registerProductTool(server, dependencies, "project_handle_check", "Check whether a project address is free before offering it to the customer. A handle is one to five lowercase words of letters and digits joined by single hyphens, three to fifty-nine characters, and never a reserved word such as admin, api, dev or www; it becomes <handle>.check.omh.st for Prod and dev-<handle>.check.omh.st for Dev. The answer names why a handle cannot be used and returns free alternatives, so offer one of those instead of guessing again. Check the name here first, then move an existing project onto it with project_handle_set.", external_exports.object({ handle: external_exports.string().min(1).max(120) }), (client2, input) => client2.checkProjectHandle({ handle: input.handle }));
29416
29427
  registerProductTool(server, dependencies, "project_handle_set", "Move a project to an address the customer chose, after project_handle_check said it is free. The Dev and Prod gateways are re-published at the new address and it is stored only once both serve it; the previous address stops answering and anyone may claim it, so a link already shared stops working. Needs the project's current ETag from project_status and one idempotency key; reuse the same key after an uncertain answer. Refused while another operation is running for the project, and refused for an address that is taken, unusable, or the one the project already has. Returns an operation to follow with operation_get.", external_exports.object({
29417
29428
  project_id: identifier2,
@@ -29896,7 +29907,12 @@ function registerManagedSourceTools(server, dependencies) {
29896
29907
  directory: input.directory,
29897
29908
  metadataDirectory: resolveProductCliEnvironment(dependencies.environment).linkDirectory,
29898
29909
  apiOrigin: client2.productApiOrigin ?? resolveProductCliEnvironment(dependencies.environment).apiOrigin,
29899
- identity: { actor_id: current.actor_id, organization_ids: current.organization_ids },
29910
+ identity: {
29911
+ actor_id: current.actor_id,
29912
+ email: current.email,
29913
+ organization_ids: current.organization_ids,
29914
+ organizations: current.organizations
29915
+ },
29900
29916
  projectId: input.project_id,
29901
29917
  request,
29902
29918
  explicitExpectedCommit: input.expected_commit_sha !== void 0,
@@ -29933,7 +29949,12 @@ function registerManagedSourceTools(server, dependencies) {
29933
29949
  directory: input.directory,
29934
29950
  metadataDirectory: resolveProductCliEnvironment(dependencies.environment).linkDirectory,
29935
29951
  apiOrigin: client2.productApiOrigin ?? resolveProductCliEnvironment(dependencies.environment).apiOrigin,
29936
- identity: { actor_id: current.actor_id, organization_ids: current.organization_ids },
29952
+ identity: {
29953
+ actor_id: current.actor_id,
29954
+ email: current.email,
29955
+ organization_ids: current.organization_ids,
29956
+ organizations: current.organizations
29957
+ },
29937
29958
  projectId: input.project_id,
29938
29959
  operationId: input.operation_id,
29939
29960
  api: port(client2),
@@ -29993,7 +30014,9 @@ async function handoverAccount(client2, signal) {
29993
30014
  const report = await client2.getCurrentIdentity(signal);
29994
30015
  const identity = parseCurrentIdentity({
29995
30016
  actor_id: report.actor_id,
29996
- organization_ids: report.organization_ids
30017
+ email: report.email,
30018
+ organization_ids: report.organization_ids,
30019
+ organizations: report.organizations
29997
30020
  });
29998
30021
  const userId = identity.actor_id.startsWith("user:") ? identity.actor_id.slice(5) : "";
29999
30022
  const [organizationId, ...others] = identity.organization_ids;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amerged/ohmyhost-mcp",
3
- "version": "0.1.32",
3
+ "version": "0.1.34",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=22"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ohmyhost/mcp",
3
- "version": "0.1.32",
3
+ "version": "0.1.34",
4
4
  "private": true,
5
5
  "ohmyhost": {
6
6
  "deployment": "production",
@@ -522,7 +522,7 @@ export function createLocalOhmyhostMcpServer(dependencies: LocalOhmyhostMcpDepen
522
522
  server,
523
523
  dependencies,
524
524
  "database_compute_set",
525
- "Select standard or performance compute for an existing database: Free 0.25 CU/1 GB/60-second idle suspension, Paid 0.5 CU/2 GB/60-second idle suspension. First read database_compute_get and explain actual size, metered compute cost, possible brief connection interruption and that shared data changes both Dev and Prod. Require the user's decision before confirm=true. SQL data is preserved. Poll the returned operation every 60 seconds; never submit a second change while it runs. Performance requires active Paid access and selects 1 CU/4 GB/300-second idle suspension at 2.5x Paid-standard compute credits per equal active minute; the longer idle window also consumes more active time. This affects only database compute. Read organization_credits_get for the published rate and active meter first. A successful choice is remembered per physical database; automatic Free downgrades preserve it, and an explicit standard choice clears it. Mixed/uncertain transition hours waive the premium; never multiply raw CU usage again.",
525
+ "Select standard or performance compute for an existing database: Free 0.25 CU/1 GB, Paid 0.5 CU/2 GB. All profiles use provider-default idle suspension (suspend_timeout_seconds=0). First read database_compute_get and explain actual size, metered compute cost, possible brief connection interruption and that shared data changes both Dev and Prod. Require the user's decision before confirm=true. SQL data is preserved. Poll the returned operation every 60 seconds; never submit a second change while it runs. Performance requires active Paid access and selects 1 CU/4 GB at 2.5x Paid-standard compute credits per equal active minute. This affects only database compute. Read organization_credits_get for the published rate and active meter first. A successful choice is remembered per physical database; automatic Free downgrades preserve it, and an explicit standard choice clears it. Mixed/uncertain transition hours waive the premium; never multiply raw CU usage again.",
526
526
  z.object({
527
527
  project_id: identifier,
528
528
  environment: z.enum(["dev", "prod"]),
@@ -1119,7 +1119,7 @@ export function createLocalOhmyhostMcpServer(dependencies: LocalOhmyhostMcpDepen
1119
1119
  server,
1120
1120
  dependencies,
1121
1121
  "identity_get",
1122
- "Get the ohmyho.st customer/agent identity this call acts as: user, organization and, in context, the saved login or OHMYHOST_TOKEN that supplied it. Compare it with the user and organization the customer named before any change. This does not authenticate the hosted application's end users or provision a customer AuthKit tenant; application authentication is the customer's chosen integration.",
1122
+ "Get the ohmyho.st customer/agent identity this call acts as: user and account email, scoped organization IDs and names and, in context, the saved login or OHMYHOST_TOKEN that supplied it. Compare it with the user and organization the customer named before any change. This does not authenticate the hosted application's end users or provision a customer AuthKit tenant; application authentication is the customer's chosen integration.",
1123
1123
  z.object({}),
1124
1124
  (client, _input, signal) => client.getCurrentIdentity(signal),
1125
1125
  );
@@ -2072,7 +2072,12 @@ function registerManagedSourceTools(
2072
2072
  apiOrigin:
2073
2073
  client.productApiOrigin ??
2074
2074
  resolveProductCliEnvironment(dependencies.environment).apiOrigin,
2075
- identity: { actor_id: current.actor_id, organization_ids: current.organization_ids },
2075
+ identity: {
2076
+ actor_id: current.actor_id,
2077
+ email: current.email,
2078
+ organization_ids: current.organization_ids,
2079
+ organizations: current.organizations,
2080
+ },
2076
2081
  projectId: input.project_id,
2077
2082
  request,
2078
2083
  explicitExpectedCommit: input.expected_commit_sha !== undefined,
@@ -2120,7 +2125,12 @@ function registerManagedSourceTools(
2120
2125
  apiOrigin:
2121
2126
  client.productApiOrigin ??
2122
2127
  resolveProductCliEnvironment(dependencies.environment).apiOrigin,
2123
- identity: { actor_id: current.actor_id, organization_ids: current.organization_ids },
2128
+ identity: {
2129
+ actor_id: current.actor_id,
2130
+ email: current.email,
2131
+ organization_ids: current.organization_ids,
2132
+ organizations: current.organizations,
2133
+ },
2124
2134
  projectId: input.project_id,
2125
2135
  operationId: input.operation_id,
2126
2136
  api: port(client),
@@ -2235,7 +2245,9 @@ async function handoverAccount(
2235
2245
  const report = await client.getCurrentIdentity(signal);
2236
2246
  const identity = parseCurrentIdentity({
2237
2247
  actor_id: report.actor_id,
2248
+ email: report.email,
2238
2249
  organization_ids: report.organization_ids,
2250
+ organizations: report.organizations,
2239
2251
  });
2240
2252
  const userId = identity.actor_id.startsWith("user:") ? identity.actor_id.slice(5) : "";
2241
2253
  const [organizationId, ...others] = identity.organization_ids;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ohmyhost/product-cli",
3
- "version": "0.1.32",
3
+ "version": "0.1.34",
4
4
  "private": true,
5
5
  "ohmyhost": {
6
6
  "deployment": "production",
@@ -399,7 +399,7 @@ const HELP_USAGE = Object.freeze({
399
399
  "ohmyhost project handle set --project ULID --handle HANDLE --if-match ETAG --idempotency-key KEY --json (moves the project to a free address; the old one stops working and anyone may claim it)",
400
400
  "database compute set":
401
401
  "ohmyhost database compute set --project ULID --environment dev|prod --profile standard|performance --idempotency-key KEY --yes [--wait] --json\n" +
402
- " standard: Free 0.25 CU/1 GB/60s idle, Paid 0.5 CU/2 GB/60s idle. performance: Paid 1 CU/4 GB/300s idle, 2.5x database compute credits per equal active minute; longer idle time also consumes credits.",
402
+ " standard: Free 0.25 CU/1 GB, Paid 0.5 CU/2 GB. performance: Paid 1 CU/4 GB, 2.5x database compute credits per equal active minute. All profiles use the provider-default idle suspension.",
403
403
  "database compute get":
404
404
  "ohmyhost database compute get --project ULID [--environment dev|prod] --json",
405
405
  "database write":
@@ -63,7 +63,9 @@ export interface SafeProblem {
63
63
 
64
64
  export interface PublicCurrentIdentity {
65
65
  readonly actor_id: string;
66
+ readonly email: string | null;
66
67
  readonly organization_ids: readonly string[];
68
+ readonly organizations: readonly { readonly id: string; readonly name: string }[];
67
69
  }
68
70
 
69
71
  /** One workspace the signed-in user belongs to, with the provider identity a selection needs. */
@@ -635,8 +637,10 @@ export function parseProjectCreditBudget(value: unknown): ProjectCreditBudget {
635
637
  }
636
638
 
637
639
  export const parseCurrentIdentity = (value: unknown): PublicCurrentIdentity => {
638
- const input = exactRecord(value, ["actor_id", "organization_ids"]);
640
+ const input = exactRecord(value, ["actor_id", "email", "organization_ids", "organizations"]);
641
+ const email = input["email"];
639
642
  const organizationIds = input["organization_ids"];
643
+ const organizations = input["organizations"];
640
644
  if (
641
645
  typeof input["actor_id"] !== "string" ||
642
646
  input["actor_id"].length === 0 ||
@@ -645,12 +649,32 @@ export const parseCurrentIdentity = (value: unknown): PublicCurrentIdentity => {
645
649
  const codePoint = character.codePointAt(0) ?? 0;
646
650
  return codePoint <= 31 || codePoint === 127;
647
651
  }) ||
652
+ (email !== null &&
653
+ (!boundedString(email, 3, 254) ||
654
+ !/^[^\s@]+@[^\s@.]+(?:\.[^\s@.]+)+$/u.test(email) ||
655
+ /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u.test(email))) ||
648
656
  !Array.isArray(organizationIds) ||
649
657
  organizationIds.some((organizationId) => !isUlid(organizationId)) ||
650
- new Set(organizationIds).size !== organizationIds.length
658
+ new Set(organizationIds).size !== organizationIds.length ||
659
+ !Array.isArray(organizations) ||
660
+ organizations.length !== organizationIds.length
651
661
  ) {
652
662
  throw new ResponseContractError();
653
663
  }
664
+ organizations.forEach((organization: unknown, index) => {
665
+ const entry = exactRecord(organization, ["id", "name"]);
666
+ if (
667
+ entry["id"] !== organizationIds[index] ||
668
+ !boundedString(entry["name"], 1, 128) ||
669
+ entry["name"].trim() !== entry["name"] ||
670
+ [...entry["name"]].some((character) => {
671
+ const codePoint = character.codePointAt(0) ?? 0;
672
+ return codePoint <= 31 || codePoint === 127;
673
+ })
674
+ ) {
675
+ throw new ResponseContractError();
676
+ }
677
+ });
654
678
  return input as unknown as PublicCurrentIdentity;
655
679
  };
656
680