@awesomate/hosting-mcp 0.61.1 → 0.63.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 +2 -2
- package/package.json +1 -1
- package/skill/CHANGELOG.json +12 -0
- package/skill/awesomate-app-builder/SKILL.md +15 -0
- package/skill/awesomate-app-builder/references/design-system.md +68 -0
- package/skill/awesomate-email/SKILL.md +5 -0
- package/skill/awesomate-hosting/SKILL.md +15 -0
- package/skill/awesomate-portals/SKILL.md +42 -2
package/dist/index.js
CHANGED
|
@@ -42923,7 +42923,7 @@ server.registerTool(
|
|
|
42923
42923
|
"awesomate_crm_types",
|
|
42924
42924
|
{
|
|
42925
42925
|
annotations: annotate("awesomate_crm_types", READ_ONLY),
|
|
42926
|
-
description: "TypeScript for the client's readable contact data, for a project that uses @awesomate/sdk: one interface per kind (only the fields the owner marked readable by AI), choice fields as literal unions, and an augmentation that types db.query('contact', ...) once the file is imported. Returns {file, content}: write content to that file in the project (or tell the user to run `npx @awesomate/sdk types`). Regenerate after the owner changes fields. No people's details are in it, only column names and types.",
|
|
42926
|
+
description: "TypeScript for the client's readable contact data, for a project that uses @awesomate/sdk: one interface per kind (only the fields the owner marked readable by AI), choice fields as literal unions, and an augmentation that types db.query('contact', ...) once the file is imported. Returns {file, content}: write content to that file in the project (or tell the user to run `npx @awesomate/sdk types`). Regenerate after the owner changes fields. No people's details are in it, only column names and types. SDK docs: https://hub.awesomate.ai/docs/sdk/ (all of them as one text file: https://hub.awesomate.ai/docs/sdk/llms-full.txt).",
|
|
42927
42927
|
inputSchema: {}
|
|
42928
42928
|
},
|
|
42929
42929
|
async () => {
|
|
@@ -43030,7 +43030,7 @@ server.registerTool(
|
|
|
43030
43030
|
"awesomate_crm_apps",
|
|
43031
43031
|
{
|
|
43032
43032
|
annotations: annotate("awesomate_crm_apps", MUTATING),
|
|
43033
|
-
description: "The account's own apps (a client portal, a members' app) whose users sign in by email link and then read and change only what each kind's access rules allow them (awesomate_crm_kinds set_access). Pro and above to create or change; reading is every plan. action 'list': each app with its publishable key, allowed origins, sign-up mode and default role. action 'create' {name, allowed_origins, sign_up?, default_role?}: name appears in the sign-in email; allowed_origins are the exact origins the app runs on (https://portal.example.com; http://localhost:5173 for development; capacitor://localhost for the mobile shell), with no path and no wildcard; sign_up 'invite' (default: only people added with awesomate_crm_app_users) or 'open' (anyone who uses the email link gets the default role). action 'update' {app_id, ...any of those, status?}: status 'disabled' signs everyone out of that app and stops its server keys; voice_agent_id names the account's agent that signed-in people talk to by voice (Talk to the agent: @awesomate/sdk voiceAgent() and voiceSession() with the hub's AwesomateAgent widget; the agent greets them by name and, when the app's assistant is set up, knows the 10 most recent conversations they can see, read as them; the app's origin must also be listed under the agent's 'Where your app runs'), null takes it away. The publishable key (pk_...) is not a secret: it goes in the app's browser code, with @awesomate/sdk. Never put the account's own token (amt_pat_...) in browser code. Confirm origins and sign-up mode with the user: open sign-up lets strangers in under the default role. action 'customer_lookup' {app_id, roles?}: which roles in that app may look customers up (name, email and phone, by search or id, with @awesomate/sdk lookupCustomers) and so put a record under any customer, not only themselves. Without roles it reads the setting; roles ['staff'] switches it on for staff; [] switches it off. Never the app's default role (the one customers sign in with): that would show every customer to every other customer, and the hub refuses it. Off until the owner asks for it. SERVER KEYS (ak_...), for the app's own server or an n8n workflow, used with @awesomate/sdk createClient({ token: <key> }) or as a Bearer token on https://hub.awesomate.ai/api/sdk/v1/server: action 'keys' {app_id} lists them (never the secrets); 'create_key' {app_id, name, access: 'read'|'write', kinds?} makes one (kinds leaves it to those kinds, 'contact' to read contacts; leave it out for every kind) and returns the key ONCE: put it straight into the app server's environment (awesomate_app_set_env for an app hosted with us) and never into browser code, a repository or a reply to the user. For an n8n workflow pass n8n_credential: true instead (prefer it): the hub puts the key into a Header Auth credential 'Awesomate app key: <name>' on their n8n (Authorization: Bearer, usable only towards the hub) and returns only its id and name, so the key never passes through you. 'revoke_key' {app_id, key_id} stops it at once, and removes a credential the hub made. A key reads every attribute of an app kind, contacts only as you read them, and writes need Support Plus and above. Prefer the narrowest key: read unless the server writes, and only the kinds it uses.",
|
|
43033
|
+
description: "The account's own apps (a client portal, a members' app) whose users sign in by email link and then read and change only what each kind's access rules allow them (awesomate_crm_kinds set_access). Pro and above to create or change; reading is every plan. action 'list': each app with its publishable key, allowed origins, sign-up mode and default role. action 'create' {name, allowed_origins, sign_up?, default_role?}: name appears in the sign-in email; allowed_origins are the exact origins the app runs on (https://portal.example.com; http://localhost:5173 for development; capacitor://localhost for the mobile shell), with no path and no wildcard; sign_up 'invite' (default: only people added with awesomate_crm_app_users) or 'open' (anyone who uses the email link gets the default role). action 'update' {app_id, ...any of those, status?}: status 'disabled' signs everyone out of that app and stops its server keys; voice_agent_id names the account's agent that signed-in people talk to by voice (Talk to the agent: @awesomate/sdk voiceAgent() and voiceSession() with the hub's AwesomateAgent widget; the agent greets them by name and, when the app's assistant is set up, knows the 10 most recent conversations they can see, read as them; the app's origin must also be listed under the agent's 'Where your app runs'), null takes it away. The publishable key (pk_...) is not a secret: it goes in the app's browser code, with @awesomate/sdk. Never put the account's own token (amt_pat_...) in browser code. SDK docs, with a tutorial that builds a customer portal: https://hub.awesomate.ai/docs/sdk/ (as one text file for you: https://hub.awesomate.ai/docs/sdk/llms-full.txt). Confirm origins and sign-up mode with the user: open sign-up lets strangers in under the default role. action 'customer_lookup' {app_id, roles?}: which roles in that app may look customers up (name, email and phone, by search or id, with @awesomate/sdk lookupCustomers) and so put a record under any customer, not only themselves. Without roles it reads the setting; roles ['staff'] switches it on for staff; [] switches it off. Never the app's default role (the one customers sign in with): that would show every customer to every other customer, and the hub refuses it. Off until the owner asks for it. SERVER KEYS (ak_...), for the app's own server or an n8n workflow, used with @awesomate/sdk createClient({ token: <key> }) or as a Bearer token on https://hub.awesomate.ai/api/sdk/v1/server: action 'keys' {app_id} lists them (never the secrets); 'create_key' {app_id, name, access: 'read'|'write', kinds?} makes one (kinds leaves it to those kinds, 'contact' to read contacts; leave it out for every kind) and returns the key ONCE: put it straight into the app server's environment (awesomate_app_set_env for an app hosted with us) and never into browser code, a repository or a reply to the user. For an n8n workflow pass n8n_credential: true instead (prefer it): the hub puts the key into a Header Auth credential 'Awesomate app key: <name>' on their n8n (Authorization: Bearer, usable only towards the hub) and returns only its id and name, so the key never passes through you. 'revoke_key' {app_id, key_id} stops it at once, and removes a credential the hub made. A key reads every attribute of an app kind, contacts only as you read them, and writes need Support Plus and above. Prefer the narrowest key: read unless the server writes, and only the kinds it uses.",
|
|
43034
43034
|
inputSchema: {
|
|
43035
43035
|
action: external_exports.enum(["list", "create", "update", "keys", "create_key", "revoke_key", "customer_lookup"]),
|
|
43036
43036
|
app_id: external_exports.string().max(48).optional().describe("update, keys, create_key, revoke_key, customer_lookup: the app"),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@awesomate/hosting-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.63.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",
|
package/skill/CHANGELOG.json
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"versions": [
|
|
3
|
+
{
|
|
4
|
+
"version": "0.63.0",
|
|
5
|
+
"highlights": [
|
|
6
|
+
"Before building anything people will see, Claude asks about your brand design system: it uses yours in Claude Design, or offers to make one from your business details, so your apps, pages and emails all look like you. You can save its name and link on Your business"
|
|
7
|
+
]
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"version": "0.62.0",
|
|
11
|
+
"highlights": [
|
|
12
|
+
"Claude points you to the new SDK docs at hub.awesomate.ai/docs/sdk when you build a portal or an app, and the portal skill now covers letting customers accept a quote, who's here and typing, and talking by voice"
|
|
13
|
+
]
|
|
14
|
+
},
|
|
3
15
|
{
|
|
4
16
|
"version": "0.61.1",
|
|
5
17
|
"highlights": [
|
|
@@ -37,6 +37,21 @@ own hosting) but you should always confirm the **stack + name** before creating.
|
|
|
37
37
|
voice, logo, colours and contact details. Use them rather than inventing
|
|
38
38
|
placeholders; confirm anything marked *suggestion* with the owner first.
|
|
39
39
|
|
|
40
|
+
### Brand design system first (strongly recommended)
|
|
41
|
+
|
|
42
|
+
Before you build anything people will see, find the business's brand design system:
|
|
43
|
+
|
|
44
|
+
1. `awesomate_business` shows **Design system** and **Design system link** when the owner has
|
|
45
|
+
saved them.
|
|
46
|
+
2. If it is in Claude Design, connect to it with `/design-sync` (the owner may need `/design-login`
|
|
47
|
+
once) and build with its tokens and components.
|
|
48
|
+
3. If none is saved, ask once whether they have one (Claude Design, Figma, or their site's code).
|
|
49
|
+
4. If they don't, offer to make one from their colours, fonts, logo and voice, and put it in Claude
|
|
50
|
+
Design with `/design-sync`.
|
|
51
|
+
5. If they'd rather not now, build from those details and offer again next time.
|
|
52
|
+
|
|
53
|
+
What makes a good one, and the tokens to start from: [references/design-system.md](references/design-system.md).
|
|
54
|
+
|
|
40
55
|
## 1. Decide the stack (do this before building)
|
|
41
56
|
|
|
42
57
|
Read [references/stack-decision.md](references/stack-decision.md) — it's the
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# The brand design system: find it, connect it, or make one
|
|
2
|
+
|
|
3
|
+
A brand design system keeps a business's colours, type, components and layout rules in one place,
|
|
4
|
+
so everything built for it looks like the same business. Claude Design holds them (claude.ai/design,
|
|
5
|
+
Settings, Design systems). It checks its own work against the design system, and `/design-sync` in
|
|
6
|
+
Claude Code keeps a project's code and the design system in step. Asking for the design system
|
|
7
|
+
before building is strongly recommended. It is never a reason to refuse to build.
|
|
8
|
+
|
|
9
|
+
## Before you build anything people will see
|
|
10
|
+
|
|
11
|
+
1. **Look it up.** `awesomate_business` shows **Design system** and **Design system link** when the
|
|
12
|
+
owner has saved them on Your business in the hub.
|
|
13
|
+
2. **It's in Claude Design.** Connect this project to it with `/design-sync`. The owner may need to
|
|
14
|
+
run `/design-login` once first. Build with its tokens and components, not with new ones.
|
|
15
|
+
3. **Nothing is saved.** Ask once: "Do you have a brand design system, in Claude Design, Figma, or
|
|
16
|
+
your website's code?" If they do, connect it, and suggest they save its name and link on Your
|
|
17
|
+
business so the next build finds it straight away.
|
|
18
|
+
4. **They have none.** Offer to make one. Put the tokens in this project, built from the business's
|
|
19
|
+
own details (colours, fonts, logo, voice from `awesomate_business`): a `tokens.css` of CSS
|
|
20
|
+
variables plus the few components the app needs. Then `/design-sync` puts it in Claude Design as
|
|
21
|
+
their design system. Tell them to save its name and link on Your business.
|
|
22
|
+
5. **They'd rather not now.** Build from the business's colours, fonts and logo, and offer again
|
|
23
|
+
next time. Never make the build wait for a design system.
|
|
24
|
+
|
|
25
|
+
Follow Anthropic's `/design-sync` for how the sync itself works. Don't describe it from memory.
|
|
26
|
+
|
|
27
|
+
## What a good brand design system has
|
|
28
|
+
|
|
29
|
+
Check the system you connect or create against these eight points, and say in one line what is
|
|
30
|
+
missing:
|
|
31
|
+
|
|
32
|
+
1. **One idea**, rooted in the business's place or story: its town, its building, its trade, its people.
|
|
33
|
+
2. **Type first.** One expressive face for headings and one neutral face for text. Generic system
|
|
34
|
+
fonts are not a display face.
|
|
35
|
+
3. **Colour with a rule.** A tight trio (a near-black, one brand colour, a near-white), or small
|
|
36
|
+
palettes that never mix. Large areas use off-black and off-white, not pure black and white.
|
|
37
|
+
4. **The name at hero scale.** The wordmark large, over an image or a flat colour.
|
|
38
|
+
5. **A system the owner can run:**
|
|
39
|
+
- a type scale for phone and desktop;
|
|
40
|
+
- spacing;
|
|
41
|
+
- corner radii, with pills for buttons and tags;
|
|
42
|
+
- which colours go together;
|
|
43
|
+
- card and list patterns.
|
|
44
|
+
6. **One piece of motion** that expresses the idea, not scattered effects.
|
|
45
|
+
7. **Voice.** Two or three lines on how it sounds, and real copy, never placeholder text.
|
|
46
|
+
8. **Accessible.** AA contrast for text, and buttons and links at least 44 px to tap.
|
|
47
|
+
|
|
48
|
+
## Tokens to start from
|
|
49
|
+
|
|
50
|
+
When you make one from the business's details, name the variables so a person can read them:
|
|
51
|
+
|
|
52
|
+
```css
|
|
53
|
+
:root {
|
|
54
|
+
--brand-ink: #1a1a1a; /* text and dark surfaces */
|
|
55
|
+
--brand-paper: #f7f5f0; /* page background */
|
|
56
|
+
--brand-accent: #e9484d; /* the one brand colour: buttons, links, highlights */
|
|
57
|
+
--font-display: "Bricolage Grotesque", system-ui, sans-serif;
|
|
58
|
+
--font-text: "Inter", system-ui, sans-serif;
|
|
59
|
+
--radius-card: 12px;
|
|
60
|
+
--radius-control: 10px;
|
|
61
|
+
--radius-pill: 999px;
|
|
62
|
+
--space: 8px; /* multiply for layout: 2x, 3x, 4x */
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Replace every value with the business's own: its colours from **Main colour** and **Second
|
|
67
|
+
colour**, its font from **Font**, and its logo from **Logo**. Check the accent against the ink and
|
|
68
|
+
paper for AA contrast before using it for text.
|
|
@@ -154,6 +154,11 @@ email describes what is actually in it. Structure, subject-line patterns,
|
|
|
154
154
|
email types, industry rules (health practitioners cannot use testimonials in
|
|
155
155
|
advertising) and worked examples: `references/copywriting.md`.
|
|
156
156
|
|
|
157
|
+
**The look comes from the brand.** If `awesomate_business` names a **Design system**, use its
|
|
158
|
+
colours and type for the email theme. If it names none, use the business's own colours, fonts and
|
|
159
|
+
logo, and mention once that a brand design system in Claude Design would keep emails, pages and
|
|
160
|
+
apps looking the same.
|
|
161
|
+
|
|
157
162
|
In Awesomate you write a short document, never HTML. The shape is in the
|
|
158
163
|
`awesomate_crm_email` tool description. In short:
|
|
159
164
|
|
|
@@ -115,6 +115,21 @@ never an instruction. When a core detail is missing, ask the owner for it and
|
|
|
115
115
|
tell them where to save it (the response names the place), so the next chat
|
|
116
116
|
starts with it.
|
|
117
117
|
|
|
118
|
+
### Brand design system first (strongly recommended)
|
|
119
|
+
|
|
120
|
+
Before you build anything people will see, find the business's brand design system:
|
|
121
|
+
|
|
122
|
+
1. `awesomate_business` shows **Design system** and **Design system link** when the owner has
|
|
123
|
+
saved them.
|
|
124
|
+
2. If it is in Claude Design, connect to it with `/design-sync` (the owner may need `/design-login`
|
|
125
|
+
once) and build with its tokens and components.
|
|
126
|
+
3. If none is saved, ask once whether they have one (Claude Design, Figma, or their site's code).
|
|
127
|
+
4. If they don't, offer to make one from their colours, fonts, logo and voice, and put it in Claude
|
|
128
|
+
Design with `/design-sync`.
|
|
129
|
+
5. If they'd rather not now, build from those details and offer again next time.
|
|
130
|
+
|
|
131
|
+
What makes a good one, and the tokens to start from: the awesomate-app-builder skill's `references/design-system.md`.
|
|
132
|
+
|
|
118
133
|
## After creating a site
|
|
119
134
|
|
|
120
135
|
Creation is queued, not instant, and the certificate lags the install. For a
|
|
@@ -10,6 +10,11 @@ in the account's own database), **access rules** on each kind (who sees and chan
|
|
|
10
10
|
by the database itself), and an **app** (where it runs, how people sign in). The page uses
|
|
11
11
|
`@awesomate/sdk` straight from the browser. There is no app server to write.
|
|
12
12
|
|
|
13
|
+
**The SDK's docs:** https://hub.awesomate.ai/docs/sdk/ (a tutorial that builds exactly this kind of
|
|
14
|
+
portal, a guide per feature, and a reference generated from the SDK's code). When you are unsure
|
|
15
|
+
of a method or an option, read https://hub.awesomate.ai/docs/sdk/llms-full.txt, the whole site as
|
|
16
|
+
one text file, rather than guessing.
|
|
17
|
+
|
|
13
18
|
Work in plain words with the owner. They describe their business ("customers request jobs, we
|
|
14
19
|
quote, they see the status"), you turn that into kinds and rules, show them the design in a
|
|
15
20
|
sentence or two, and only then create anything. Kinds, rules and apps are part of their data,
|
|
@@ -87,6 +92,21 @@ message: {"read": {"member": "linked:job.customer", "staff": "all"}, "write": {"
|
|
|
87
92
|
their contact by email. Staff get `role: 'staff'`. No email is sent; they ask for a link on the
|
|
88
93
|
page.
|
|
89
94
|
|
|
95
|
+
### Brand design system first (strongly recommended)
|
|
96
|
+
|
|
97
|
+
Before you build anything people will see, find the business's brand design system:
|
|
98
|
+
|
|
99
|
+
1. `awesomate_business` shows **Design system** and **Design system link** when the owner has
|
|
100
|
+
saved them.
|
|
101
|
+
2. If it is in Claude Design, connect to it with `/design-sync` (the owner may need `/design-login`
|
|
102
|
+
once) and build with its tokens and components.
|
|
103
|
+
3. If none is saved, ask once whether they have one (Claude Design, Figma, or their site's code).
|
|
104
|
+
4. If they don't, offer to make one from their colours, fonts, logo and voice, and put it in Claude
|
|
105
|
+
Design with `/design-sync`.
|
|
106
|
+
5. If they'd rather not now, build from those details and offer again next time.
|
|
107
|
+
|
|
108
|
+
What makes a good one, and the tokens to start from: the awesomate-app-builder skill's `references/design-system.md`.
|
|
109
|
+
|
|
90
110
|
## 5. Build the page
|
|
91
111
|
|
|
92
112
|
Any static page works (host it with the awesomate-app-builder skill, `kind: 'static'`). The SDK
|
|
@@ -94,7 +114,7 @@ loads from a CDN, or from npm in a Vite app:
|
|
|
94
114
|
|
|
95
115
|
```html
|
|
96
116
|
<script type="module">
|
|
97
|
-
import { createAppClient } from 'https://cdn.jsdelivr.net/npm/@awesomate/sdk@0.
|
|
117
|
+
import { createAppClient, AwesomateError } from 'https://cdn.jsdelivr.net/npm/@awesomate/sdk@0.13/+esm';
|
|
98
118
|
const app = createAppClient({ publishableKey: 'pk_...' });
|
|
99
119
|
|
|
100
120
|
// The email link signs them in by itself (also when it opens in a tab already on this page).
|
|
@@ -138,7 +158,27 @@ lists the two staff-only kinds it needs (`assistant_thread`, `assistant_draft`)
|
|
|
138
158
|
agent (awesomate-knowledge skill) so she can answer questions about the business. Confirm the
|
|
139
159
|
name and the default mode with the owner: switching it on lets an AI reply to their customers.
|
|
140
160
|
|
|
141
|
-
##
|
|
161
|
+
## 6a. Optional: things customers may do that their rule does not allow
|
|
162
|
+
|
|
163
|
+
Accepting a quote is the usual one: customers can't edit a job, but they should be able to accept
|
|
164
|
+
its quote. Save a write recipe (`awesomate_crm_recipes {action:'save'}`) whose steps do exactly
|
|
165
|
+
that, then open it to their role (`{action:'run_by', key, roles:['member']}`). The page runs it
|
|
166
|
+
with `await app.call('accept_quote', { job: jobId })`. The database checks every step against
|
|
167
|
+
the recipe as saved, and the job must be one they can read. Guide:
|
|
168
|
+
https://hub.awesomate.ai/docs/sdk/guides/customer-actions/
|
|
169
|
+
|
|
170
|
+
## 6b. Optional: who's here, and talking by voice
|
|
171
|
+
|
|
172
|
+
- `const room = app.here(jobId, (people) => render(people))` shows who else has the job open and
|
|
173
|
+
who is typing (`room.typing(true)` on input, `room.leave()` on close). Guide:
|
|
174
|
+
https://hub.awesomate.ai/docs/sdk/guides/who-is-here/
|
|
175
|
+
- Voice: pick one of the account's agents for the app (`awesomate_crm_apps {action:'update',
|
|
176
|
+
app_id, voice_agent_id}`; the agent needs In your app switched on and the page's address under
|
|
177
|
+
its "Where your app runs"). The page loads the hub's widget and mounts it with
|
|
178
|
+
`agentId: await app.voiceAgent()` and `session: () => app.voiceSession()`. Guide:
|
|
179
|
+
https://hub.awesomate.ai/docs/sdk/guides/voice/
|
|
180
|
+
|
|
181
|
+
## 6c. Optional: reply emails
|
|
142
182
|
|
|
143
183
|
`awesomate_crm_notifications {action:'set', app_id, notifications: {enabled: true, thread_link: 'job'}}`
|
|
144
184
|
emails the other side of a conversation when someone writes there and they are not in the app:
|