@awesomate/hosting-mcp 0.52.0 → 0.53.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/dist/index.js CHANGED
@@ -42804,17 +42804,19 @@ var crmAttribute = external_exports.object({
42804
42804
  choices: external_exports.array(external_exports.string().max(100)).max(200).optional().describe("required for choice / choices"),
42805
42805
  required: external_exports.boolean().optional(),
42806
42806
  sensitivity: external_exports.enum(["ordinary", "personal", "sensitive"]).optional().describe("sensitive values are never readable by AI"),
42807
- readable_by_ai: external_exports.boolean().optional().describe("default false: only readable attributes reach awesomate_crm_rows")
42807
+ readable_by_ai: external_exports.boolean().optional().describe("default false: only readable attributes reach awesomate_crm_rows"),
42808
+ visible_to: external_exports.array(external_exports.string().max(31)).max(10).nullable().optional().describe("which of an app's signed-in roles see it, e.g. ['staff']; leave out for everyone who can read the record")
42808
42809
  });
42809
42810
  server.registerTool(
42810
42811
  "awesomate_crm_kinds",
42811
42812
  {
42812
42813
  annotations: annotate("awesomate_crm_kinds", MUTATING),
42813
- description: "The kinds of app data in the client's own database (the tables an app keeps: jobs, memos, bookings, messages), created directly from here on Support Plus and above. action 'list': every kind with its attributes and links. 'define' {key, label?, label_plural?, attributes, links?}: a new kind; links: [{key, to, label?, required?}] where to is 'contact' or a kind already made, and each shows as <key>_id. 'add_attribute' {kind, attribute}. 'archive_attribute' {kind, key}: leaves the views, values kept. 'archive' {kind}: kept, restorable. No migration and no SQL: a kind is registry rows plus generated views. Business things whose values must be traced to a source (a property, an installed system) are 'tracked' kinds the owner accepts in the hub; they are refused here. Mark an attribute readable_by_ai only when the owner wants Claude and agents to see it, and never for anything sensitive. 'set_access' {kind, access} (or access on define): who among the people signed in to the account's apps (awesomate_crm_apps) may read and change records of this kind, by their role: {read: {<role>: <rule>}, write: {<role>: <rule>}}. A rule is all, none, own (records they created), or linked:<link path ending at a contact> (linked:customer: jobs whose customer is them; linked:job.customer: memos on their jobs), joined with |. A role with no rule gets nothing; the default lets owner and staff do everything and members nothing. A write must leave the record inside the person's rule. Confirm the design with the user before defining: a kind is part of their data, not scratch space.",
42814
+ description: "The kinds of app data in the client's own database (the tables an app keeps: jobs, memos, bookings, messages), created directly from here on Support Plus and above. action 'list': every kind with its attributes and links. 'define' {key, label?, label_plural?, attributes, links?}: a new kind; links: [{key, to, label?, required?}] where to is 'contact' or a kind already made, and each shows as <key>_id. 'add_attribute' {kind, attribute}. 'archive_attribute' {kind, key}: leaves the views, values kept. 'set_visibility' {kind, key, visible_to}: which of an app's signed-in roles see that attribute (['staff'] for a cost or an internal note on a customer's job; null for everyone who can read the record; [] for none of them). Others read it as null and cannot write it; the database enforces it, and the account, Claude and hooks always see every attribute. 'archive' {kind}: kept, restorable. No migration and no SQL: a kind is registry rows plus generated views. Business things whose values must be traced to a source (a property, an installed system) are 'tracked' kinds the owner accepts in the hub; they are refused here. Mark an attribute readable_by_ai only when the owner wants Claude and agents to see it, and never for anything sensitive. 'set_access' {kind, access} (or access on define): who among the people signed in to the account's apps (awesomate_crm_apps) may read and change records of this kind, by their role: {read: {<role>: <rule>}, write: {<role>: <rule>}}. A rule is all, none, own (records they created), or linked:<link path ending at a contact> (linked:customer: jobs whose customer is them; linked:job.customer: memos on their jobs), joined with |. A role with no rule gets nothing; the default lets owner and staff do everything and members nothing. A write must leave the record inside the person's rule. Confirm the design with the user before defining: a kind is part of their data, not scratch space.",
42814
42815
  inputSchema: {
42815
- action: external_exports.enum(["list", "define", "add_attribute", "archive_attribute", "archive", "set_access"]),
42816
- kind: external_exports.string().max(41).optional().describe("the kind to change (add_attribute, archive_attribute, archive, set_access)"),
42817
- key: external_exports.string().max(41).optional().describe("define: the new kind; archive_attribute: the attribute"),
42816
+ action: external_exports.enum(["list", "define", "add_attribute", "archive_attribute", "archive", "set_access", "set_visibility"]),
42817
+ kind: external_exports.string().max(41).optional().describe("the kind to change (add_attribute, archive_attribute, archive, set_access, set_visibility)"),
42818
+ key: external_exports.string().max(41).optional().describe("define: the new kind; archive_attribute, set_visibility: the attribute"),
42819
+ visible_to: external_exports.array(external_exports.string().max(31)).max(10).nullable().optional().describe("set_visibility: the roles that see it, or null for everyone"),
42818
42820
  label: external_exports.string().max(80).optional(),
42819
42821
  label_plural: external_exports.string().max(80).optional(),
42820
42822
  attributes: external_exports.array(crmAttribute).max(60).optional(),
@@ -42826,7 +42828,7 @@ server.registerTool(
42826
42828
  }).optional().describe("define / set_access: {read: {<role>: <rule>}, write: {<role>: <rule>}}")
42827
42829
  }
42828
42830
  },
42829
- async ({ action, kind, key, label, label_plural, attributes, links, attribute, access }) => {
42831
+ async ({ action, kind, key, label, label_plural, attributes, links, attribute, access, visible_to }) => {
42830
42832
  try {
42831
42833
  const cfg = requireConfig();
42832
42834
  if (action === "list") return textResult(await hubGet(cfg, "/api/my-crm/v1/kinds"));
@@ -42840,6 +42842,10 @@ server.registerTool(
42840
42842
  return textResult(await hubPut(cfg, `/api/my-crm/v1/kinds/${k}/access`, { access }));
42841
42843
  }
42842
42844
  if (action === "add_attribute") return textResult(await hubPost(cfg, `/api/my-crm/v1/kinds/${k}/attributes`, { attribute }));
42845
+ if (action === "set_visibility") {
42846
+ if (!key || visible_to === void 0) return errorResult(new Error("set_visibility needs key (the attribute) and visible_to (a list of roles, or null for everyone)."));
42847
+ return textResult(await hubPut(cfg, `/api/my-crm/v1/kinds/${k}/attributes/${encodeURIComponent(key)}/visibility`, { visible_to }));
42848
+ }
42843
42849
  if (action === "archive_attribute") {
42844
42850
  if (!key) return errorResult(new Error("archive_attribute needs key, the attribute."));
42845
42851
  return textResult(await hubDelete(cfg, `/api/my-crm/v1/kinds/${k}/attributes/${encodeURIComponent(key)}`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awesomate/hosting-mcp",
3
- "version": "0.52.0",
3
+ "version": "0.53.0",
4
4
  "description": "Awesomate MCP server — lets Claude manage your Awesomate WordPress hosting, plan, limits, n8n automations, and build Node/static apps + databases",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -1,5 +1,12 @@
1
1
  {
2
2
  "versions": [
3
+ {
4
+ "version": "0.53.0",
5
+ "highlights": [
6
+ "Fields only your team sees: mark an attribute visible to staff only (awesomate_crm_kinds, set_visibility), such as the cost behind a quote or an internal note on a job. Customers signed in to your portal read it as empty and cannot change it",
7
+ "Your own database enforces it, not the portal's code, and Bree, answering as the customer, never sees it either. You and Claude always see every field"
8
+ ]
9
+ },
3
10
  {
4
11
  "version": "0.52.0",
5
12
  "highlights": [
@@ -44,8 +44,13 @@ Ask, one or two at a time:
44
44
 
45
45
  - **Link the thing to the customer's contact.** That link is what "their own" means.
46
46
  - Mark an attribute `readable_by_ai` only when the owner wants Claude and AI assistants to see
47
- it. Never for anything sensitive. App people see every attribute of a record they may read;
48
- `readable_by_ai` is only about AI.
47
+ it. Never for anything sensitive. `readable_by_ai` is only about AI.
48
+ - **Fields only the team sees** (a cost, an internal note): give the attribute
49
+ `visible_to: ['staff']` when defining it, or later with `awesomate_crm_kinds
50
+ {action:'set_visibility'}`. Customers read it as null and cannot write it; the database
51
+ enforces it, and so does what the assistant sees. Without `visible_to`, everyone who can read
52
+ the record sees the attribute. Don't make such an attribute `required` on a kind customers
53
+ create, or they cannot create one.
49
54
  - Show the owner the design ("A job has a title, a status and a quote, and belongs to a
50
55
  customer. Messages hang off a job.") and get a yes first.
51
56