@awesomate/hosting-mcp 0.22.3 → 0.24.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 +160 -36
- package/package.json +1 -1
- package/skill/awesomate-support/SKILL.md +41 -16
package/dist/index.js
CHANGED
|
@@ -40857,10 +40857,85 @@ ${JSON.stringify(details, null, 2)}`;
|
|
|
40857
40857
|
}
|
|
40858
40858
|
return { content: [{ type: "text", text }], isError: true };
|
|
40859
40859
|
}
|
|
40860
|
-
var READ_ONLY = { readOnlyHint: true };
|
|
40861
|
-
var
|
|
40860
|
+
var READ_ONLY = { readOnlyHint: true, destructiveHint: false };
|
|
40861
|
+
var MUTATING = { readOnlyHint: false, destructiveHint: false };
|
|
40862
|
+
var DESTRUCTIVE = { readOnlyHint: false, destructiveHint: true };
|
|
40863
|
+
var TITLES = {
|
|
40864
|
+
awesomate_whoami: "Check connected account",
|
|
40865
|
+
awesomate_get_context: "Get account context",
|
|
40866
|
+
awesomate_get_hosting_status: "Get hosting status",
|
|
40867
|
+
awesomate_get_hosting_account: "Get hosting account",
|
|
40868
|
+
awesomate_list_sites: "List WordPress sites",
|
|
40869
|
+
awesomate_list_domains: "List domains",
|
|
40870
|
+
awesomate_get_limits: "Get plan limits",
|
|
40871
|
+
awesomate_get_plan_features: "Get plan features",
|
|
40872
|
+
awesomate_dashboard_metrics: "Get dashboard metrics",
|
|
40873
|
+
awesomate_account_report: "Get account report",
|
|
40874
|
+
awesomate_privacy_settings: "Get privacy settings",
|
|
40875
|
+
awesomate_app_list: "List apps",
|
|
40876
|
+
awesomate_app_context: "Get apps context",
|
|
40877
|
+
awesomate_n8n_context: "Get n8n context",
|
|
40878
|
+
awesomate_n8n_storage: "Get n8n storage usage",
|
|
40879
|
+
awesomate_dns_check: "Check domain DNS",
|
|
40880
|
+
awesomate_site_uptime: "Get site uptime",
|
|
40881
|
+
awesomate_notifications: "Account notifications",
|
|
40882
|
+
awesomate_support: "Get support help",
|
|
40883
|
+
// Destructive: rmSync/writeFileSync under ~/.claude/skills overwrites files
|
|
40884
|
+
// on the user's own machine, so it must always prompt.
|
|
40885
|
+
awesomate_skill_update: "Update Awesomate skills",
|
|
40886
|
+
awesomate_site_create: "Create WordPress site",
|
|
40887
|
+
awesomate_site_audit: "Audit site for SEO and AEO",
|
|
40888
|
+
awesomate_uninstall_site: "Delete WordPress site",
|
|
40889
|
+
awesomate_snapshot_site: "Snapshot site",
|
|
40890
|
+
awesomate_list_snapshots: "List site snapshots",
|
|
40891
|
+
awesomate_rollback_site: "Roll site back to snapshot",
|
|
40892
|
+
awesomate_site_staging_create: "Create staging site",
|
|
40893
|
+
awesomate_site_staging_promote: "Publish staging to live",
|
|
40894
|
+
awesomate_site_staging_discard: "Discard staging site",
|
|
40895
|
+
awesomate_domain_add: "Add custom domain",
|
|
40896
|
+
awesomate_run_wp_cli: "Run WP-CLI command",
|
|
40897
|
+
awesomate_wp_post: "Manage WordPress posts",
|
|
40898
|
+
awesomate_wp_media_import: "Import media to WordPress",
|
|
40899
|
+
awesomate_wp_settings: "Change WordPress settings",
|
|
40900
|
+
awesomate_app_create: "Create app",
|
|
40901
|
+
awesomate_app_get: "Get app details",
|
|
40902
|
+
awesomate_app_scaffold: "Get app scaffold guide",
|
|
40903
|
+
awesomate_app_deploy_info: "Get app deploy briefing",
|
|
40904
|
+
awesomate_app_health: "Check app health",
|
|
40905
|
+
awesomate_app_set_env: "Set app secret",
|
|
40906
|
+
awesomate_app_provision_db: "Add database to app",
|
|
40907
|
+
awesomate_n8n_workflows: "List n8n workflows",
|
|
40908
|
+
awesomate_n8n_inspect: "Inspect n8n workflow",
|
|
40909
|
+
awesomate_n8n_executions: "List n8n executions",
|
|
40910
|
+
awesomate_n8n_errors: "Get n8n errors",
|
|
40911
|
+
awesomate_n8n_findings: "Get n8n findings",
|
|
40912
|
+
awesomate_n8n_kpis: "Get n8n KPIs",
|
|
40913
|
+
awesomate_n8n_node_docs: "Get n8n node docs",
|
|
40914
|
+
awesomate_n8n_deploy: "Deploy n8n workflow",
|
|
40915
|
+
awesomate_n8n_test: "Test-fire n8n workflow",
|
|
40916
|
+
awesomate_n8n_datatable_write: "Write to n8n data table",
|
|
40917
|
+
awesomate_n8n_attach_to_app: "Attach n8n to app",
|
|
40918
|
+
awesomate_n8n_provision_pg: "Provision Postgres for n8n",
|
|
40919
|
+
awesomate_request_build: "Request a build from Awesomate",
|
|
40920
|
+
awesomate_knowledge_status: "Get Knowledge Base status",
|
|
40921
|
+
awesomate_knowledge_provision: "Enable Knowledge Base",
|
|
40922
|
+
awesomate_knowledge_search: "Search Knowledge Base",
|
|
40923
|
+
awesomate_knowledge_ask: "Ask the Knowledge Base",
|
|
40924
|
+
awesomate_knowledge_sources: "Manage knowledge sources",
|
|
40925
|
+
awesomate_knowledge_upload: "Upload file to Knowledge Base",
|
|
40926
|
+
awesomate_knowledge_agent: "Configure knowledge agent",
|
|
40927
|
+
awesomate_knowledge_agents: "Manage knowledge agents",
|
|
40928
|
+
awesomate_knowledge_collections: "Manage knowledge collections",
|
|
40929
|
+
awesomate_knowledge_people: "Manage knowledge entities",
|
|
40930
|
+
awesomate_knowledge_data: "Query knowledge data warehouse"
|
|
40931
|
+
};
|
|
40932
|
+
function annotate(name, kind) {
|
|
40933
|
+
const title = TITLES[name];
|
|
40934
|
+
if (!title) throw new Error(`No TITLES entry for tool "${name}" \u2014 add one before registering it.`);
|
|
40935
|
+
return { title, ...kind };
|
|
40936
|
+
}
|
|
40862
40937
|
function readTool(name, description, path) {
|
|
40863
|
-
server.registerTool(name, { description, inputSchema: {}, annotations: READ_ONLY }, async () => {
|
|
40938
|
+
server.registerTool(name, { description, inputSchema: {}, annotations: annotate(name, READ_ONLY) }, async () => {
|
|
40864
40939
|
try {
|
|
40865
40940
|
return textResult(await hubGet(requireConfig(), path));
|
|
40866
40941
|
} catch (err) {
|
|
@@ -40871,7 +40946,7 @@ function readTool(name, description, path) {
|
|
|
40871
40946
|
server.registerTool(
|
|
40872
40947
|
"awesomate_whoami",
|
|
40873
40948
|
{
|
|
40874
|
-
annotations: READ_ONLY,
|
|
40949
|
+
annotations: annotate("awesomate_whoami", READ_ONLY),
|
|
40875
40950
|
description: "Zero-network identity check: which Awesomate account this session is connected to (slug, plan, token expiry) and WHY (env var, project pin file, sole profile, or default). Call it after connecting, after switching folders, and any time the account in play matters \u2014 if the slug is not the account the user expects, STOP and fix the pin/connection before doing any work.",
|
|
40876
40951
|
inputSchema: {}
|
|
40877
40952
|
},
|
|
@@ -40895,7 +40970,7 @@ server.registerTool(
|
|
|
40895
40970
|
server.registerTool(
|
|
40896
40971
|
"awesomate_get_context",
|
|
40897
40972
|
{
|
|
40898
|
-
annotations: READ_ONLY,
|
|
40973
|
+
annotations: annotate("awesomate_get_context", READ_ONLY),
|
|
40899
40974
|
description: "THE session entry point \u2014 call it FIRST, before any domain context. Returns the connected account: plan, capabilities, limits, scopes, token expiry, cPanel routing, PLUS `attention` ({unreadNotifications, erroringWorkflows7d, patExpiresInDays} \u2014 null means unknown, never zero; when something is non-zero, mention it to the user in one line before starting the asked task), `latestMcpVersion` (if serverVersion still lags it after a restart, the npx cache is stale \u2014 remedy: rm -rf ~/.npm/_npx, then restart), and `skill` ({updateAvailable, staleSkills, whatsNew} \u2014 if updateAvailable, mention ONCE with a whatsNew line, offer awesomate_skill_update, never mid-task). If the token is near expiry (patExpiresInDays < 7), re-running Connect Claude Code from hub.awesomate.ai/claude refreshes skills AND renews the token in one go.",
|
|
40900
40975
|
inputSchema: {}
|
|
40901
40976
|
},
|
|
@@ -40916,7 +40991,7 @@ readTool(
|
|
|
40916
40991
|
server.registerTool(
|
|
40917
40992
|
"awesomate_n8n_deploy",
|
|
40918
40993
|
{
|
|
40919
|
-
annotations: DESTRUCTIVE,
|
|
40994
|
+
annotations: annotate("awesomate_n8n_deploy", DESTRUCTIVE),
|
|
40920
40995
|
description: "Workflow lifecycle writes on the client's n8n, all consent-gated and audited server-side. Actions: 'validate' (structural + n8n-mcp check of workflowJson \u2014 ALWAYS validate before create_draft), 'create_draft' (creates an INACTIVE '[CLI] ' workflow tagged awm:client-cli; returns its webhook URLs), 'activate'/'deactivate' (activation strips the [CLI] prefix; production webhooks respond only while active; agency-managed workflows are refused), 'promote' (swaps a TESTED draft into the live workflow IN PLACE \u2014 live id + webhookIds preserved so external callers keep working; pass workflowId=the LIVE id and draftId=the tested draft; the draft is archived '[promoted <date>]'; response includes operationId for rollback), 'rollback' (restore a promote's pre-swap state \u2014 pass operationId), 'update_draft' (replace an INACTIVE self-built draft's full JSON in place \u2014 pass workflowId + workflowJson; live workflows are refused, use the promote path), 'delete_draft' (inactive self-built drafts only). Get explicit user approval before activate, promote, rollback, and delete_draft. 429 quota_exceeded = daily plan limit; 403 consent_required \u2192 send user to settingsUrl; 409 n8n_credential_invalid = the user's OWN n8n rejected the stored API key (NOT a hub outage \u2014 reads and validate keep working because they never touch their instance): tell them to create a new API key in their n8n under Settings \u2192 n8n API, paste it into their Awesomate account at hub.awesomate.ai/n8n/settings, then retry.",
|
|
40921
40996
|
inputSchema: {
|
|
40922
40997
|
action: external_exports.enum(["validate", "create_draft", "update_draft", "activate", "deactivate", "promote", "rollback", "delete_draft"]),
|
|
@@ -40972,6 +41047,7 @@ server.registerTool(
|
|
|
40972
41047
|
server.registerTool(
|
|
40973
41048
|
"awesomate_n8n_test",
|
|
40974
41049
|
{
|
|
41050
|
+
annotations: annotate("awesomate_n8n_test", MUTATING),
|
|
40975
41051
|
description: "Fire a synthetic test payload at an ACTIVE self-built workflow's production webhook and get back the webhook response plus the executionId it caused (then poll GET /api/my-n8n/executions/:id for node-by-node results). Sends the X-Awesomate-Test header. Real side effects DO run (emails actually send) \u2014 warn the user, use their own address, prefix subjects with [TEST]. Only works on awm:client-cli-tagged workflows.",
|
|
40976
41052
|
inputSchema: {
|
|
40977
41053
|
workflowId: external_exports.string(),
|
|
@@ -40991,7 +41067,7 @@ server.registerTool(
|
|
|
40991
41067
|
server.registerTool(
|
|
40992
41068
|
"awesomate_n8n_workflows",
|
|
40993
41069
|
{
|
|
40994
|
-
annotations: READ_ONLY,
|
|
41070
|
+
annotations: annotate("awesomate_n8n_workflows", READ_ONLY),
|
|
40995
41071
|
description: "The client's workflows. No id \u2192 EVERY workflow as a node-level summary in one call (nodeCount, nodeTypes, triggers, usesAi, communityNodes, dates; ?active filter + pagination) \u2014 use this for the session's world picture instead of fetching workflows one by one. With id \u2192 that workflow's JSON: detail 'full' (default \u2014 nodes with parameters, connections, settings) or 'structure' (nodes WITHOUT parameters + connections \u2014 cheap shape check for big workflows). 403 consent_required \u2192 send the user to settingsUrl and re-check.",
|
|
40996
41072
|
inputSchema: {
|
|
40997
41073
|
id: external_exports.string().optional().describe("Workflow id for a single-workflow read; omit for the all-workflows summary"),
|
|
@@ -41027,7 +41103,7 @@ server.registerTool(
|
|
|
41027
41103
|
server.registerTool(
|
|
41028
41104
|
"awesomate_n8n_inspect",
|
|
41029
41105
|
{
|
|
41030
|
-
annotations: READ_ONLY,
|
|
41106
|
+
annotations: annotate("awesomate_n8n_inspect", READ_ONLY),
|
|
41031
41107
|
description: `Instance inventory reads, one tool: 'nodes' (distinct node types in use, counts, versions, community/AI flags), 'datatables' (tables + columns + row counts), 'datatable_rows' (pass datatableId; limit \u2264 100), 'possibilities' (facts for "what could I automate": connected services with live-usage cross-check, unused connections, top nodes, AI tools [null = unknown, not none], community packages, counts \u2014 YOU turn these into suggestions, grounded only in what's actually there), 'credentials' (names/types/inferred service \u2014 never secrets), 'variables' ($vars keys). All consent-gated server-side; 403 consent_required \u2192 settingsUrl.`,
|
|
41032
41108
|
inputSchema: {
|
|
41033
41109
|
what: external_exports.enum(["nodes", "datatables", "datatable_rows", "possibilities", "credentials", "variables"]),
|
|
@@ -41059,7 +41135,7 @@ server.registerTool(
|
|
|
41059
41135
|
server.registerTool(
|
|
41060
41136
|
"awesomate_n8n_executions",
|
|
41061
41137
|
{
|
|
41062
|
-
annotations: READ_ONLY,
|
|
41138
|
+
annotations: annotate("awesomate_n8n_executions", READ_ONLY),
|
|
41063
41139
|
description: "Execution reads. workflowId \u2192 recent executions of that workflow. executionId \u2192 detail with errorSummary \u2014 trust errorSummary.failingNode only when confident:true (structural decode; also carries errorType/code/lastNodeExecuted); when confident:false it came from a heuristic and may name a node that does not exist \u2014 verify against the workflow before editing anything. executionId + debug:true \u2192 node-by-node decode (statuses, timings, errors, 2 example items per node) \u2014 the best failure-diagnosis view; needs the 'error content analysis' privacy toggle (403 consent_required \u2192 settingsUrl), and responses with tooLarge:true mean the payload exceeded 15MB \u2014 fall back to the non-debug detail. For 'what is failing across ALL my workflows', use awesomate_n8n_errors instead.",
|
|
41064
41140
|
inputSchema: {
|
|
41065
41141
|
workflowId: external_exports.string().optional(),
|
|
@@ -41088,7 +41164,7 @@ server.registerTool(
|
|
|
41088
41164
|
server.registerTool(
|
|
41089
41165
|
"awesomate_n8n_node_docs",
|
|
41090
41166
|
{
|
|
41091
|
-
annotations: READ_ONLY,
|
|
41167
|
+
annotations: annotate("awesomate_n8n_node_docs", READ_ONLY),
|
|
41092
41168
|
description: "Live n8n documentation, 500+ nodes + 2,500+ community templates \u2014 ALWAYS prefer this over memory for node schemas and typeVersions. tools: search_nodes {query}, get_node {nodeType \u2014 full form like 'n8n-nodes-base.gmail' works, add detail:'full' for everything}, search_templates {query} / get_template {templateId} (real importable community workflows \u2014 great starting points), validate_node {nodeType, config}, tools_documentation {}. Works on every plan, no consent needed. 503 node_catalog_unavailable \u2192 use the skill's references/vendor/ files instead; 422 catalog_tool_error \u2192 YOUR args were wrong (message says why), the catalog is fine.",
|
|
41093
41169
|
inputSchema: {
|
|
41094
41170
|
tool: external_exports.enum(["search_nodes", "get_node", "search_templates", "get_template", "validate_node", "tools_documentation"]),
|
|
@@ -41106,7 +41182,7 @@ server.registerTool(
|
|
|
41106
41182
|
server.registerTool(
|
|
41107
41183
|
"awesomate_n8n_datatable_write",
|
|
41108
41184
|
{
|
|
41109
|
-
annotations: DESTRUCTIVE,
|
|
41185
|
+
annotations: annotate("awesomate_n8n_datatable_write", DESTRUCTIVE),
|
|
41110
41186
|
description: "Datatable writes (Support Plus+, consent-gated, audited). 'create' {name, columns:[{name,type?}], workflowId?} \u2014 ALWAYS pass workflowId when the table serves a specific workflow (datatables resolve PER PROJECT at runtime; workflowId threads that workflow's project; a projectWarning in the response means pass it). 'add_column' {tableId, name, type?} \u2014 needs the 'direct database writes' privacy toggle; names: letters/digits/underscores only. 'insert' {tableId, rows:[...]} (\u2264100), 'update' {tableId, filter, data}, 'delete_rows' {tableId, filter \u2014 REQUIRED, there is no delete-all}. Writes only work on tables created through Claude Code (403 not_self_created otherwise \u2014 agency tables are off limits). Get explicit user approval before delete_rows.",
|
|
41111
41187
|
inputSchema: {
|
|
41112
41188
|
action: external_exports.enum(["create", "add_column", "insert", "update", "delete_rows"]),
|
|
@@ -41141,6 +41217,7 @@ server.registerTool(
|
|
|
41141
41217
|
server.registerTool(
|
|
41142
41218
|
"awesomate_skill_update",
|
|
41143
41219
|
{
|
|
41220
|
+
annotations: annotate("awesomate_skill_update", DESTRUCTIVE),
|
|
41144
41221
|
description: "The one-step updater for the locally installed Awesomate skills \u2014 run when any response stamp or awesomate_get_context reports an update ready. Refreshes ALL bundled skills in ~/.claude/skills from this (always-latest) server package, removes files newer bundles no longer ship, re-stamps versions, and returns per-skill from\u2192to plus what's-new lines and the exact restart step. New skill content applies from the NEXT Claude Code session; finish the current task first, then hand the user the restart instruction verbatim.",
|
|
41145
41222
|
inputSchema: {}
|
|
41146
41223
|
},
|
|
@@ -41173,17 +41250,33 @@ server.registerTool(
|
|
|
41173
41250
|
server.registerTool(
|
|
41174
41251
|
"awesomate_support",
|
|
41175
41252
|
{
|
|
41176
|
-
|
|
41253
|
+
annotations: annotate("awesomate_support", MUTATING),
|
|
41254
|
+
description: "Help the user with the service itself \u2014 questions, being stuck, or reaching a human. **action 'ask' {q} is the FIRST thing to try for any question about Awesomate** \u2014 it answers from Awesomate's own Knowledge Base with numbered citations, works on every plan, and composes across articles rather than matching titles; relay its answer and cite the source URLs. If it returns no_answer:true the grounding gate declined, so offer a ticket instead of guessing; if degraded:true the Knowledge Base was unavailable and you are looking at keyword matches, so do not present them as a verified answer. action 'faq' {q} searches the published help library (answer FROM the results; never invent policy or pricing). action 'help_docs' {q} searches the full Help Centre articles live \u2014 use when the FAQ has no good answer, and cite the returned article URLs. action 'create_ticket' {subject, message, category} opens a support ticket \u2014 draft it in the user's words, SHOW it, and get an explicit yes before sending; it emails the Awesomate team and returns a portal URL. **`category` is REQUIRED and must name what the ticket is actually about \u2014 'Other' is refused.** Ticket access splits by SUBJECT, not by plan: reporting a problem with AWESOMATE ITSELF ('Infrastructure fault' \u2014 site down, instance unreachable, provisioning or SSL failure; 'Claude/MCP connectivity' \u2014 pairing fails, token rejected, tools erroring) and 'Account/billing' work on EVERY plan. Asking for help USING the products ('Workflow not running', 'Workflow error', 'New automation request', 'How-to question') needs Support Plus or above and returns 403 upgrade_required below it \u2014 when that happens, answer from 'faq'/'help_docs' instead and relay the upgrade honestly; do NOT relabel the ticket as a fault to get through. action 'list_tickets' shows their tickets and status. Use the awesomate-support skill for the full flow. Not for building \u2014 route n8n work to awesomate-n8n and hosting to awesomate-hosting.",
|
|
41177
41255
|
inputSchema: {
|
|
41178
|
-
action: external_exports.enum(["faq", "help_docs", "create_ticket", "list_tickets"]),
|
|
41179
|
-
q: external_exports.string().optional().describe("faq and help_docs: the question or topic"),
|
|
41256
|
+
action: external_exports.enum(["ask", "faq", "help_docs", "create_ticket", "list_tickets"]),
|
|
41257
|
+
q: external_exports.string().optional().describe("ask, faq and help_docs: the question or topic"),
|
|
41180
41258
|
subject: external_exports.string().optional().describe("create_ticket only"),
|
|
41181
|
-
message: external_exports.string().optional().describe("create_ticket only: the body, in the user's words")
|
|
41259
|
+
message: external_exports.string().optional().describe("create_ticket only: the body, in the user's words"),
|
|
41260
|
+
category: external_exports.enum([
|
|
41261
|
+
"Infrastructure fault",
|
|
41262
|
+
"Claude/MCP connectivity",
|
|
41263
|
+
"Workflow not running",
|
|
41264
|
+
"Workflow error",
|
|
41265
|
+
"New automation request",
|
|
41266
|
+
"Account/billing",
|
|
41267
|
+
"How-to question"
|
|
41268
|
+
]).optional().describe(
|
|
41269
|
+
"create_ticket: REQUIRED. What the ticket is about. The first two and Account/billing work on every plan; the rest need Support Plus or above."
|
|
41270
|
+
)
|
|
41182
41271
|
}
|
|
41183
41272
|
},
|
|
41184
|
-
async ({ action, q, subject, message }) => {
|
|
41273
|
+
async ({ action, q, subject, message, category }) => {
|
|
41185
41274
|
try {
|
|
41186
41275
|
const cfg = requireConfig();
|
|
41276
|
+
if (action === "ask") {
|
|
41277
|
+
if (!q) return errorResult(new Error("ask needs q"));
|
|
41278
|
+
return textResult(await hubGet(cfg, `/api/help/ask?q=${encodeURIComponent(q)}`));
|
|
41279
|
+
}
|
|
41187
41280
|
if (action === "faq") {
|
|
41188
41281
|
return textResult(await hubGet(cfg, `/api/help/faq${q ? `?q=${encodeURIComponent(q)}` : ""}`));
|
|
41189
41282
|
}
|
|
@@ -41195,7 +41288,14 @@ server.registerTool(
|
|
|
41195
41288
|
return textResult(await hubGet(cfg, "/api/support/tickets"));
|
|
41196
41289
|
}
|
|
41197
41290
|
if (!subject || !message) return errorResult(new Error("create_ticket needs subject and message"));
|
|
41198
|
-
|
|
41291
|
+
if (!category) {
|
|
41292
|
+
return errorResult(
|
|
41293
|
+
new Error(
|
|
41294
|
+
'create_ticket needs a category naming what the ticket is about. Use "Infrastructure fault" or "Claude/MCP connectivity" when the problem is with Awesomate itself, "Account/billing" for money, and the workflow/how-to categories (Support Plus and above) for help using the products.'
|
|
41295
|
+
)
|
|
41296
|
+
);
|
|
41297
|
+
}
|
|
41298
|
+
return textResult(await hubPost(cfg, "/api/support/tickets", { subject, body_text: message, category }));
|
|
41199
41299
|
} catch (err) {
|
|
41200
41300
|
return errorResult(err);
|
|
41201
41301
|
}
|
|
@@ -41204,7 +41304,7 @@ server.registerTool(
|
|
|
41204
41304
|
server.registerTool(
|
|
41205
41305
|
"awesomate_request_build",
|
|
41206
41306
|
{
|
|
41207
|
-
annotations: DESTRUCTIVE,
|
|
41307
|
+
annotations: annotate("awesomate_request_build", DESTRUCTIVE),
|
|
41208
41308
|
description: "Submit a DONE-FOR-YOU automation request \u2014 the Awesomate team builds it, for clients who'd rather not build it themselves or whose request is beyond what you can build here. This SPENDS 1 CREDIT ($100). Two steps, always: call WITHOUT confirmCredit first \u2014 it returns the cost and the user's available balance and spends nothing; state both to the user in plain words, get an explicit yes, THEN call again with confirmCredit:true. Needs a wizard-enabled plan (Pro/Embedded) \u2014 a Support Plus user gets upgrade_required, relay it honestly. On success returns a tracking URL (progress shows on My Automations).",
|
|
41209
41309
|
inputSchema: {
|
|
41210
41310
|
title: external_exports.string().describe("Short name for the automation"),
|
|
@@ -41224,7 +41324,8 @@ server.registerTool(
|
|
|
41224
41324
|
server.registerTool(
|
|
41225
41325
|
"awesomate_site_create",
|
|
41226
41326
|
{
|
|
41227
|
-
|
|
41327
|
+
annotations: annotate("awesomate_site_create", MUTATING),
|
|
41328
|
+
description: "Create a WordPress site on the user's hosting. **Needs Support Plus or above from Claude** \u2014 on Essentials this returns 403 `upgrade_required` ALWAYS, not only at a cap, because building hosting from a machine token is a Support Plus capability; the Essentials site itself is real and is created by the user in the hub at hub.awesomate.ai/sites, so offer that path first rather than leading with the upgrade. Plan COUNT limits are enforced separately (403 with an upgrade hint at the cap; 409 means WordPress already exists at that domain). Ask 'live or dev?' first per the awesomate-hosting skill. Omit `domain` and the next free siteN.{primary} subdomain is chosen for you. ASYNC and returns only {success:true} \u2014 no domain, no admin details: poll awesomate_list_sites to learn the name, and expect HTTPS to refuse connections for a minute or two while AutoSSL issues even though the site is already serving over http. See 'After creating a site' in the skill.",
|
|
41228
41329
|
inputSchema: {
|
|
41229
41330
|
domain: external_exports.string().optional().describe("Custom domain if they have one; omit for a default *.awesomate.site subdomain"),
|
|
41230
41331
|
siteTitle: external_exports.string().optional(),
|
|
@@ -41242,7 +41343,8 @@ server.registerTool(
|
|
|
41242
41343
|
server.registerTool(
|
|
41243
41344
|
"awesomate_domain_add",
|
|
41244
41345
|
{
|
|
41245
|
-
|
|
41346
|
+
annotations: annotate("awesomate_domain_add", MUTATING),
|
|
41347
|
+
description: "Add a custom domain to the user's hosting account. Returns the DNS steps they need to complete at their registrar. **Needs Support Plus or above from Claude** \u2014 Essentials gets 403 `upgrade_required` even though its plan DOES include one custom domain, because adding it from a machine token is Support Plus; tell them it takes two clicks at hub.awesomate.ai/sites/domains instead. Plan COUNT limits are enforced separately on top.",
|
|
41246
41348
|
inputSchema: { domain: external_exports.string().describe("The domain to add, e.g. example.com") }
|
|
41247
41349
|
},
|
|
41248
41350
|
async ({ domain }) => {
|
|
@@ -41256,7 +41358,8 @@ server.registerTool(
|
|
|
41256
41358
|
server.registerTool(
|
|
41257
41359
|
"awesomate_run_wp_cli",
|
|
41258
41360
|
{
|
|
41259
|
-
|
|
41361
|
+
annotations: annotate("awesomate_run_wp_cli", DESTRUCTIVE),
|
|
41362
|
+
description: "Run an allowlisted WP-CLI command on one of the user's WordPress sites (plugin/theme list+activate+update, cache flush, option get/update, post/media/menu/comment/user list). **Needs Support Plus or above** \u2014 the whole route is behind the write gate, so even the READS (option get, plugin list) return 403 `upgrade_required` on Essentials. ARGUMENTS CANNOT CONTAIN SPACES (letters, digits and -_./=:@+, only) \u2014 so a site title, tagline or any multi-word value is impossible here: use awesomate_wp_settings for those, and awesomate_wp_post for post/page content. Installs accept wp.org SLUGS only \u2014 never URLs. args is the command as an array, e.g. ['plugin','list'] or ['plugin','install','wordpress-seo','--activate']. A 400 wp_cli_not_allowed means that command isn't permitted; a 502 wp_cli_unavailable is a temporary server-side issue, not your command.",
|
|
41260
41363
|
inputSchema: {
|
|
41261
41364
|
domain: external_exports.string().describe("The site domain"),
|
|
41262
41365
|
args: external_exports.array(external_exports.string()).describe("WP-CLI args, e.g. ['plugin','list']")
|
|
@@ -41273,7 +41376,7 @@ server.registerTool(
|
|
|
41273
41376
|
server.registerTool(
|
|
41274
41377
|
"awesomate_uninstall_site",
|
|
41275
41378
|
{
|
|
41276
|
-
annotations: DESTRUCTIVE,
|
|
41379
|
+
annotations: annotate("awesomate_uninstall_site", DESTRUCTIVE),
|
|
41277
41380
|
description: "Permanently delete a WordPress site (files + database). IRREVERSIBLE \u2014 snapshot first if the user might want it back, and always get explicit confirmation. You MUST pass confirm equal to the exact domain, or the hub refuses. Support Plus+.",
|
|
41278
41381
|
inputSchema: {
|
|
41279
41382
|
domain: external_exports.string().describe("The site domain to delete"),
|
|
@@ -41291,6 +41394,7 @@ server.registerTool(
|
|
|
41291
41394
|
server.registerTool(
|
|
41292
41395
|
"awesomate_app_provision_db",
|
|
41293
41396
|
{
|
|
41397
|
+
annotations: annotate("awesomate_app_provision_db", MUTATING),
|
|
41294
41398
|
description: "Add a Postgres database to an EXISTING Node app that doesn't have one \u2014 one DB per environment, with DATABASE_URL injected into each app environment (restart/redeploy to pick it up). The password is set server-side and never returned. Support Plus+; static apps and apps that already have a DB are refused. Use the awesomate-database skill's decision tree first \u2014 a simple list an automation reads/writes is often better as an n8n data table.",
|
|
41295
41399
|
inputSchema: { appId: external_exports.number().int().positive().describe("The app id from awesomate_app_list / _get") }
|
|
41296
41400
|
},
|
|
@@ -41350,7 +41454,7 @@ var PLAN_LADDER_FALLBACK = {
|
|
|
41350
41454
|
server.registerTool(
|
|
41351
41455
|
"awesomate_get_plan_features",
|
|
41352
41456
|
{
|
|
41353
|
-
annotations: READ_ONLY,
|
|
41457
|
+
annotations: annotate("awesomate_get_plan_features", READ_ONLY),
|
|
41354
41458
|
description: "The Awesomate plan ladder: what each plan includes for hosting (WordPress sites, custom domains, hosted apps, cPanel, shell/Claude Code access) and which plans are purchasable. Fetched live from the hub (single source of truth) with a static fallback. Use to explain what an upgrade unlocks; live per-account usage comes from awesomate_get_limits.",
|
|
41355
41459
|
inputSchema: {}
|
|
41356
41460
|
},
|
|
@@ -41372,6 +41476,7 @@ server.registerTool(
|
|
|
41372
41476
|
server.registerTool(
|
|
41373
41477
|
"awesomate_snapshot_site",
|
|
41374
41478
|
{
|
|
41479
|
+
annotations: annotate("awesomate_snapshot_site", MUTATING),
|
|
41375
41480
|
description: "Snapshot a WordPress site (files + database) BEFORE any risky change \u2014 an AI edit, a deploy, a plugin/theme/core update. Returns a snapshotId you can roll back to. ALWAYS snapshot before mutating a live site. Requires shell access (Support Plus+).",
|
|
41376
41481
|
inputSchema: {
|
|
41377
41482
|
domain: external_exports.string().describe("The site domain (as shown by awesomate_list_sites), e.g. mysite.awesomate.site"),
|
|
@@ -41391,7 +41496,7 @@ server.registerTool(
|
|
|
41391
41496
|
server.registerTool(
|
|
41392
41497
|
"awesomate_list_snapshots",
|
|
41393
41498
|
{
|
|
41394
|
-
annotations: READ_ONLY,
|
|
41499
|
+
annotations: annotate("awesomate_list_snapshots", READ_ONLY),
|
|
41395
41500
|
description: "List a site\u2019s available snapshots (newest first) with their ids, timestamps, and reasons. Requires shell access (Support Plus+).",
|
|
41396
41501
|
inputSchema: { domain: external_exports.string().describe("The site domain") }
|
|
41397
41502
|
},
|
|
@@ -41406,7 +41511,7 @@ server.registerTool(
|
|
|
41406
41511
|
server.registerTool(
|
|
41407
41512
|
"awesomate_rollback_site",
|
|
41408
41513
|
{
|
|
41409
|
-
annotations: DESTRUCTIVE,
|
|
41514
|
+
annotations: annotate("awesomate_rollback_site", DESTRUCTIVE),
|
|
41410
41515
|
description: "Restore a site to a previous snapshot (files + database). The current state is auto-snapshotted first, so a rollback is itself reversible (see preRollbackSnapshotId in the result). Confirm with the user before rolling back \u2014 it overwrites the live site. Requires shell access (Support Plus+).",
|
|
41411
41516
|
inputSchema: {
|
|
41412
41517
|
domain: external_exports.string().describe("The site domain"),
|
|
@@ -41426,6 +41531,7 @@ server.registerTool(
|
|
|
41426
41531
|
server.registerTool(
|
|
41427
41532
|
"awesomate_site_staging_create",
|
|
41428
41533
|
{
|
|
41534
|
+
annotations: annotate("awesomate_site_staging_create", MUTATING),
|
|
41429
41535
|
description: "Create a staging copy of a WordPress site on the client's private awesomate.dev address (files + database cloned, URLs rewritten). Use this BEFORE making user-facing changes so the user can review at the staging URL first \u2014 post to dev, review, then awesomate_site_staging_promote. The staging site is hidden from search engines and AI crawlers by policy; anyone with the link can view it. One staging copy per site \u2014 a 409 with code 'staging_exists' means promote or discard the existing one first. Cloning can take a few minutes on large sites. Requires shell access (Support Plus+).",
|
|
41430
41536
|
inputSchema: {
|
|
41431
41537
|
domain: external_exports.string().describe("The LIVE site domain (as shown by awesomate_list_sites), e.g. mysite.awesomate.site")
|
|
@@ -41444,7 +41550,7 @@ server.registerTool(
|
|
|
41444
41550
|
server.registerTool(
|
|
41445
41551
|
"awesomate_site_staging_promote",
|
|
41446
41552
|
{
|
|
41447
|
-
annotations: DESTRUCTIVE,
|
|
41553
|
+
annotations: annotate("awesomate_site_staging_promote", DESTRUCTIVE),
|
|
41448
41554
|
description: "Publish the staging copy to the LIVE site (overwrites live files + database with staging). The live site is auto-snapshotted first \u2014 the result includes preSnapshotId, which awesomate_rollback_site can restore if anything looks wrong. **Confirm with the user before promoting \u2014 it replaces the live site.** Requires shell access (Support Plus+).",
|
|
41449
41555
|
inputSchema: {
|
|
41450
41556
|
domain: external_exports.string().describe("The LIVE site domain whose staging copy should go live")
|
|
@@ -41463,7 +41569,7 @@ server.registerTool(
|
|
|
41463
41569
|
server.registerTool(
|
|
41464
41570
|
"awesomate_site_staging_discard",
|
|
41465
41571
|
{
|
|
41466
|
-
annotations: DESTRUCTIVE,
|
|
41572
|
+
annotations: annotate("awesomate_site_staging_discard", DESTRUCTIVE),
|
|
41467
41573
|
description: "Delete the staging copy of a site (staging WP install + its awesomate.dev address; the live site is untouched). **Confirm with the user before discarding \u2014 unpromoted staging changes are lost.** Requires shell access (Support Plus+).",
|
|
41468
41574
|
inputSchema: {
|
|
41469
41575
|
domain: external_exports.string().describe("The LIVE site domain whose staging copy should be discarded")
|
|
@@ -41492,7 +41598,7 @@ readTool(
|
|
|
41492
41598
|
server.registerTool(
|
|
41493
41599
|
"awesomate_app_get",
|
|
41494
41600
|
{
|
|
41495
|
-
annotations: READ_ONLY,
|
|
41601
|
+
annotations: annotate("awesomate_app_get", READ_ONLY),
|
|
41496
41602
|
description: "Get one app plus its environments (subdomains, ports, db engine/name, deploy + health state). Poll this after awesomate_app_create \u2014 status goes provisioning \u2192 active | failed (read provision_error on failure).",
|
|
41497
41603
|
inputSchema: { appId: external_exports.number().int().positive().describe("The app id from awesomate_app_list / _create") }
|
|
41498
41604
|
},
|
|
@@ -41507,6 +41613,7 @@ server.registerTool(
|
|
|
41507
41613
|
server.registerTool(
|
|
41508
41614
|
"awesomate_app_create",
|
|
41509
41615
|
{
|
|
41616
|
+
annotations: annotate("awesomate_app_create", MUTATING),
|
|
41510
41617
|
description: "Provision a new app on the client's cPanel account. Choose the stack deliberately (see the awesomate-app-builder skill): kind 'static' = a single fast landing/lead page served straight from the docroot (no DB, no server process \u2014 pick this for brochure/landing/lead-capture); kind 'node' = a dynamic app with a backend + database (logins, custom logic, an API). Pick the template by job \u2014 'node-auth-sync' (user accounts/logins, MySQL), 'node-crud-postgres' (structured data without logins: trackers/dashboards \u2014 ready-made CRUD + UI, Postgres), 'node-api-only' (webhooks/integrations/glue, no DB wiring), 'static-landing' (marketing/lead page). If dbEngine is omitted the template's native engine is used (node-crud-postgres \u2192 postgres). Returns 202 immediately with an appId + subdomain(s); poll awesomate_app_get until status=active, then fetch the starter files with awesomate_app_scaffold. Requires apps:write (Support Plus+) \u2014 a 403 means offer an upgrade. Plans also cap the NUMBER of apps (Support Plus 5, Pro 20 \u2014 check awesomate_get_limits.dimensions.apps first): a 409 with code 'app_limit' means the cap is reached \u2014 do NOT retry; tell the user their allowance is full and surface the recommendedPlan/deepLink from the error. Get the user's confirmation on the stack + name before calling.",
|
|
41511
41618
|
inputSchema: {
|
|
41512
41619
|
appSlug: external_exports.string().regex(/^[a-z][a-z0-9]{1,15}$/).describe("2-16 chars, starts with a letter, lowercase alphanumeric \u2014 used for subdomains + db names"),
|
|
@@ -41528,7 +41635,7 @@ server.registerTool(
|
|
|
41528
41635
|
server.registerTool(
|
|
41529
41636
|
"awesomate_app_scaffold",
|
|
41530
41637
|
{
|
|
41531
|
-
annotations: READ_ONLY,
|
|
41638
|
+
annotations: annotate("awesomate_app_scaffold", READ_ONLY),
|
|
41532
41639
|
description: "Fetch the app's starter files (its template rendered against the live app metadata \u2014 subdomains, control-plane URL, repo \u2014 with placeholders already substituted). Call after awesomate_app_create reaches status=active: write each returned file into a fresh local project folder at its relative path, then run npm install (Node apps) and follow the bundled CLAUDE.md. This is how the starter code gets onto the user's machine \u2014 don't reconstruct templates by hand.",
|
|
41533
41640
|
inputSchema: { appId: external_exports.number().int().positive().describe("The app id from awesomate_app_create / _list") }
|
|
41534
41641
|
},
|
|
@@ -41543,6 +41650,7 @@ server.registerTool(
|
|
|
41543
41650
|
server.registerTool(
|
|
41544
41651
|
"awesomate_app_deploy_info",
|
|
41545
41652
|
{
|
|
41653
|
+
annotations: annotate("awesomate_app_deploy_info", READ_ONLY),
|
|
41546
41654
|
description: "READ-ONLY deploy briefing \u2014 this never deploys anything (deploys happen via git push). Reports how to deploy an app, its per-env targets, last-deploy/health state, and how to promote (dev\u2192staging\u2192main) or roll back (git revert + push). Node apps deploy via git push (dev/staging/main \u2192 GitHub Actions \u2192 cPanel). Use the awesomate-github skill to wire push-to-deploy the first time.",
|
|
41547
41655
|
inputSchema: { appId: external_exports.number().int().positive().describe("The app id") }
|
|
41548
41656
|
},
|
|
@@ -41557,6 +41665,7 @@ server.registerTool(
|
|
|
41557
41665
|
server.registerTool(
|
|
41558
41666
|
"awesomate_app_set_env",
|
|
41559
41667
|
{
|
|
41668
|
+
annotations: annotate("awesomate_app_set_env", MUTATING),
|
|
41560
41669
|
description: "Store an API key / secret for a Node app environment: it's encrypted in the hub AND injected into the app's .env (0600) then the app restarts. ALWAYS use this instead of putting a secret in code, a committed file, or leaving it in the chat. NEVER echo the value back \u2014 confirm with the key name only. If the user pastes a key in chat, store it here and tell them (per the awesomate-credentials skill) it should be rotated since it passed through the transcript. Node apps only (static sites have no server env).",
|
|
41561
41670
|
inputSchema: {
|
|
41562
41671
|
appId: external_exports.number().int().positive().describe("The app id"),
|
|
@@ -41576,6 +41685,7 @@ server.registerTool(
|
|
|
41576
41685
|
server.registerTool(
|
|
41577
41686
|
"awesomate_n8n_attach_to_app",
|
|
41578
41687
|
{
|
|
41688
|
+
annotations: annotate("awesomate_n8n_attach_to_app", MUTATING),
|
|
41579
41689
|
description: "Wire an app to call the user's own n8n as a backend. Give it the app + a webhook URL you already created/tested/promoted on their n8n (via awesomate_n8n_deploy \u2014 create_draft returns the webhook URL, and promote preserves it). It stores N8N_WEBHOOK_URL + a generated N8N_WEBHOOK_SECRET on the app (encrypted + injected) and RETURNS the secret so you can add a matching `X-Awesomate-Webhook-Secret` header check to the n8n workflow (so the webhook isn't world-callable). The app then calls it via src/lib/n8n.ts callWorkflow(). Node apps only. Only reach for this when the job needs an external app/credential or AI the user already has in n8n \u2014 not for pure in-app logic.",
|
|
41580
41690
|
inputSchema: {
|
|
41581
41691
|
appId: external_exports.number().int().positive().describe("The app id"),
|
|
@@ -41594,7 +41704,7 @@ server.registerTool(
|
|
|
41594
41704
|
server.registerTool(
|
|
41595
41705
|
"awesomate_app_health",
|
|
41596
41706
|
{
|
|
41597
|
-
annotations: READ_ONLY,
|
|
41707
|
+
annotations: annotate("awesomate_app_health", READ_ONLY),
|
|
41598
41708
|
description: "Probe an app's environments live and report health. Node envs hit /api/ready (200 = deployed + DB up + migrations applied); static hits the root. An env that isn't deployed yet reports unreachable \u2014 expected, not a failure. Use after a deploy to confirm it came up, or when the user says something's down.",
|
|
41599
41709
|
inputSchema: { appId: external_exports.number().int().positive().describe("The app id") }
|
|
41600
41710
|
},
|
|
@@ -41609,6 +41719,7 @@ server.registerTool(
|
|
|
41609
41719
|
server.registerTool(
|
|
41610
41720
|
"awesomate_n8n_provision_pg",
|
|
41611
41721
|
{
|
|
41722
|
+
annotations: annotate("awesomate_n8n_provision_pg", MUTATING),
|
|
41612
41723
|
description: "Provision a NEW Postgres database on the user's own Awesomate cPanel hosting and wire it into their n8n as a ready-to-use `postgres` credential their workflows can select. This is a WRITE that creates real infrastructure \u2014 get explicit user approval first. Requires: their n8n builder access (Support Plus+, allow_client_cli_builds) AND the allow_pg_writes consent (403 consent_required \u2192 send them to settingsUrl); AND an Awesomate cPanel hosting account (409 hosting_required otherwise). Limited to 2/day. Returns the new credential id + name, the database/user, and the password ONCE (it lives in the n8n credential, never stored by Awesomate \u2014 tell the user to note or rotate it). After this, build the workflow selecting the returned Postgres credential.",
|
|
41613
41724
|
inputSchema: {}
|
|
41614
41725
|
},
|
|
@@ -41642,7 +41753,7 @@ ${scrubKeyMaterial(message)}` }],
|
|
|
41642
41753
|
server.registerTool(
|
|
41643
41754
|
"awesomate_knowledge_status",
|
|
41644
41755
|
{
|
|
41645
|
-
annotations: READ_ONLY,
|
|
41756
|
+
annotations: annotate("awesomate_knowledge_status", READ_ONLY),
|
|
41646
41757
|
description: "Call FIRST for any Knowledge Base work. The account's knowledge tenant state (provisioning/active/suspended), plan entitlement, consent flag, month-to-date usage vs included quota, and purchased packs. upgrade_required:true \u2192 relay the included upsell copy + billing link honestly, do NOT retry. available:false \u2192 this hub doesn't serve Knowledge Base yet (kill switch / old hub) \u2014 also not retryable. Reads work on every plan.",
|
|
41647
41758
|
inputSchema: {}
|
|
41648
41759
|
},
|
|
@@ -41657,6 +41768,7 @@ server.registerTool(
|
|
|
41657
41768
|
server.registerTool(
|
|
41658
41769
|
"awesomate_knowledge_provision",
|
|
41659
41770
|
{
|
|
41771
|
+
annotations: annotate("awesomate_knowledge_provision", MUTATING),
|
|
41660
41772
|
description: "Enable the Knowledge Base for this account (creates their isolated tenant on the Awesomate knowledge platform and wires the n8n credential). Idempotent \u2014 safe to re-call; a pending:true response means provisioning continues in the background: poll awesomate_knowledge_status. consent_required \u2192 send the user to Settings \u2192 Privacy (they must flip it themselves), re-check, then retry. upgrade_required \u2192 relay the upsell, don't retry. Get the user's explicit go-ahead before enabling.",
|
|
41661
41773
|
inputSchema: {}
|
|
41662
41774
|
},
|
|
@@ -41671,6 +41783,7 @@ server.registerTool(
|
|
|
41671
41783
|
server.registerTool(
|
|
41672
41784
|
"awesomate_knowledge_sources",
|
|
41673
41785
|
{
|
|
41786
|
+
annotations: annotate("awesomate_knowledge_sources", MUTATING),
|
|
41674
41787
|
description: "The knowledge base's content sources \u2014 the LIBRARY. action 'search' {q?, kind?, visibility?, tags?, collectionIds?, cursor?, limit?} \u2014 find sources by title/tag substring and metadata filters (instant, free; for CONTENT search use awesomate_knowledge_search); each row carries visibility (private|internal|public \u2014 who may retrieve it, ENFORCED), tags and collections. 'tag' {sourceId, tags} \u2014 REPLACE a source's free-form tags. 'set_visibility' {sourceId|sourceIds, visibility, confirm?} \u2014 change who may retrieve the source(s); 'public' is irreversible once fetched, so it needs the user's explicit agreement and their account slug as confirm. 'move' {sourceId|sourceIds, collectionIds?, removeCollectionIds?} \u2014 add to / remove from collections. 'sync_rules' / 'sync_rule_create' {pathPrefix, includeGlobs?, visibility?, tags?, collectionIds?, onFileRemoved?} / 'sync_rule_delete' {ruleId} / 'sync_run' / 'sync_state' \u2014 keep a folder of the account's File Manager (their n8n file system: public/, private/, temp/) synced into the knowledge base, so files their workflows write become searchable; a public rule needs confirm. 'list' \u2014 ONE page of sources, most recently ingested first (default 50, max 200 via limit): read `page.has_more`/`next_cursor` and pass cursor to continue \u2014 a page is never the whole library. 'summary' \u2014 exact whole-library counts {total, by_kind, chunks, indexed_chunks, failed_sources, failed_jobs_7d}: use THIS to say what the knowledge base contains, and if failed_jobs_7d > 0 say so \u2014 those ingests are missing from every other count. 'jobs' \u2014 ingest job statuses (optional status filter: queued|running|succeeded|failed). 'add' \u2014 ingest a public page {url} or a whole site {sitemap, since?}, optionally with visibility (default private), tags and collectionIds; ALWAYS get explicit approval first (ingest costs money and counts against quota), for a local FILE on the user's machine use awesomate_knowledge_upload instead (it streams the file from disk; this tool takes URLs only). A pack_required response means the allowance is exhausted: NOTHING was purchased \u2014 present the pack price (1 credit = $100) and let the user buy from the hub if they want it. 'remove' {sourceId} \u2014 deletes the source AND its indexed content; explicit approval required.",
|
|
41675
41788
|
inputSchema: {
|
|
41676
41789
|
action: external_exports.enum(["list", "summary", "add", "remove", "jobs", "search", "tag", "set_visibility", "move", "sync_rules", "sync_rule_create", "sync_rule_delete", "sync_run", "sync_state"]),
|
|
@@ -41708,7 +41821,7 @@ server.registerTool(
|
|
|
41708
41821
|
server.registerTool(
|
|
41709
41822
|
"awesomate_knowledge_search",
|
|
41710
41823
|
{
|
|
41711
|
-
annotations: READ_ONLY,
|
|
41824
|
+
annotations: annotate("awesomate_knowledge_search", READ_ONLY),
|
|
41712
41825
|
description: "Instant search over the knowledge library with live facet counts: the fastest way to see WHAT is in there and to find the exact video moment, book page, dataset or web section. Returns hits (title, kind, locator like t=612-640 or p.42, snippet with **matched words**, score) plus facets {kind, year, category, author, people, places, topics} whose counts describe the current filters: repeat a facet value to OR within it, combine facets to AND. include_media adds presigned url/poster_url to hits: they expire in minutes, use immediately, never store. Keyword-only and free (no answer quota); for a verified ANSWER use awesomate_knowledge_ask, optionally with the same filters. Citations from awesomate_knowledge_ask carry NO media URLs \u2014 when a cited source is an image/video and the user wants to SEE it, re-query here with include_media (ideally filtered by its doc id). The returned url/poster_url expire in minutes: fine to show in chat, never safe to embed in a page \u2014 see the awesomate-knowledge skill's showing-media.md.",
|
|
41713
41826
|
inputSchema: {
|
|
41714
41827
|
q: external_exports.string().max(2e3).optional().describe("Search words; empty lists the library filtered by the facets"),
|
|
@@ -41736,6 +41849,7 @@ server.registerTool(
|
|
|
41736
41849
|
server.registerTool(
|
|
41737
41850
|
"awesomate_knowledge_ask",
|
|
41738
41851
|
{
|
|
41852
|
+
annotations: annotate("awesomate_knowledge_ask", READ_ONLY),
|
|
41739
41853
|
description: `Ask the account's knowledge base a question and get the VERIFIED answer with numbered sources (title, locator, url) \u2014 the test surface for 'is my content in there and answering well'. Read BOTH status and grounded. grounded:true \u2192 present the answer with its numbered sources. grounded:false (status ok but ZERO sources) \u2192 the agent answered from MODEL MEMORY, not their content: say their content does not cover it, never present it as an answer from their knowledge base, never build on it. The default workspace agent is not strict-grounded, so this is common \u2014 anything customer-facing should use a purpose-built agent (awesomate_knowledge_agents) with strict grounding. no_results / failed_validation (not_in_verified_content:true) \u2192 the verified content has no answer: relay that honestly (use configured_fallback), never fill the gap from memory \u2014 an honest "it doesn't know" is the feature working. error (platform_error:true) \u2192 the platform itself failed (model/API/infra): NOT a content gap \u2014 never tell the user their content lacks the answer; retry once, then awesomate_support. Counts against the monthly answers quota.`,
|
|
41740
41854
|
inputSchema: {
|
|
41741
41855
|
question: external_exports.string().min(1).max(2e3),
|
|
@@ -41763,6 +41877,7 @@ server.registerTool(
|
|
|
41763
41877
|
server.registerTool(
|
|
41764
41878
|
"awesomate_knowledge_agent",
|
|
41765
41879
|
{
|
|
41880
|
+
annotations: annotate("awesomate_knowledge_agent", MUTATING),
|
|
41766
41881
|
description: "The knowledge agent's configuration. action 'get' \u2014 persona, no-answer fallback message, model tier, allowed datasets, indexed counts. 'set' \u2014 change any of those on the LIVE agent that answers real customers: read the current values first, show the user exactly what will change, get explicit approval, then call; the response echoes the change \u2014 read it back to confirm. model_tier 'opus' is plan-gated (Embedded) \u2014 relay upgrade_required honestly.",
|
|
41767
41882
|
inputSchema: {
|
|
41768
41883
|
action: external_exports.enum(["get", "set"]),
|
|
@@ -41790,6 +41905,7 @@ server.registerTool(
|
|
|
41790
41905
|
server.registerTool(
|
|
41791
41906
|
"awesomate_knowledge_agents",
|
|
41792
41907
|
{
|
|
41908
|
+
annotations: annotate("awesomate_knowledge_agents", MUTATING),
|
|
41793
41909
|
description: "The agent builder (multi-agent; the older awesomate_knowledge_agent tool is the single workspace default). action 'list' \u2014 every agent with status (draft/published vN/suspended). 'get' {agentId} \u2014 full config incl. system message and scope. 'create' {goal} \u2014 AI drafts the whole setup (instructions, scope, tone, test questions) from the account's own content and saves it as a PRIVATE DRAFT (never live, nothing lost); or {name} for a blank draft. 'test' {agentId, message, sessionId?} \u2014 chat with the DRAFT config: free, unmetered, the right way to check behaviour before going live. 'publish' {agentId} \u2014 makes the draft LIVE immediately for every key bound to the agent: get the user's explicit approval first, and read the version back. Editing fields, policies, API keys and the request log live in the hub UI (Knowledge \u2192 Agents); keys are shown once there and never pass through this tool.",
|
|
41794
41910
|
inputSchema: {
|
|
41795
41911
|
action: external_exports.enum(["list", "get", "create", "publish", "test"]),
|
|
@@ -41812,6 +41928,7 @@ server.registerTool(
|
|
|
41812
41928
|
server.registerTool(
|
|
41813
41929
|
"awesomate_knowledge_collections",
|
|
41814
41930
|
{
|
|
41931
|
+
annotations: annotate("awesomate_knowledge_collections", MUTATING),
|
|
41815
41932
|
description: "Collections: named sets of knowledge sources with a default audience \u2014 the unit a chatbot is scoped to (agent scope.tags ['collection:<collection_id>']). action 'list' \u2014 every collection with source counts by visibility. 'create' {slug, name, description?, defaultVisibility?} \u2014 defaultVisibility only pre-fills NEW sources' visibility; each source keeps its own. 'get' {collectionId}. 'update' {collectionId, slug?|name?|description?|defaultVisibility?}. 'delete' {collectionId} \u2014 removes the collection; the sources survive (explicit approval first). 'add'/'remove' {collectionId, sourceIds} \u2014 membership. A source may be in several collections. A PUBLIC chatbot over a collection whose sources are all private answers nothing \u2014 check visibility (awesomate_knowledge_sources search) before building on one.",
|
|
41816
41933
|
inputSchema: {
|
|
41817
41934
|
action: external_exports.enum(["list", "create", "get", "update", "delete", "add", "remove"]),
|
|
@@ -41834,6 +41951,7 @@ server.registerTool(
|
|
|
41834
41951
|
server.registerTool(
|
|
41835
41952
|
"awesomate_knowledge_people",
|
|
41836
41953
|
{
|
|
41954
|
+
annotations: annotate("awesomate_knowledge_people", MUTATING),
|
|
41837
41955
|
description: "The people, places and topics the knowledge base has recognised \u2014 so 'everything about X' and 'who appears with X' answer with citations. action 'list' {status?: named|unknown|hidden|all, cursor?} \u2014 people with counts (unnamed rows carry an opaque handle, NEVER a name; do not guess who they are); 'get' {personId} \u2014 aliases, co-mentions and witness sources; 'aliases' \u2014 pending alias suggestions (text names that probably refer to a known entity); 'rename' {personId, displayName} \u2014 only a name the USER gave, after they confirm which cluster (face/mention counts + sources), then read the result back; 'hide'/'unhide' {personId}; 'merge' {personId, intoPersonId} \u2014 explicit approval first, faces and aliases move and the source entry is hidden; 'decide' {kind, aliasNorm, decision: accept|reject, entityId? | createPersonName?} \u2014 explicit approval first, alias identity is (kind, aliasNorm); 'resolve' \u2014 re-run entity resolution: counts toward the ingestion allowance, so ask first. list/aliases/resolve return available:false when the platform hasn't enabled the layer yet \u2014 relay that honestly, don't retry. Photos of people are only viewable on the hub Knowledge \u2192 People page.",
|
|
41838
41956
|
inputSchema: {
|
|
41839
41957
|
action: external_exports.enum(["list", "get", "rename", "hide", "unhide", "merge", "aliases", "decide", "resolve"]),
|
|
@@ -41860,6 +41978,7 @@ server.registerTool(
|
|
|
41860
41978
|
server.registerTool(
|
|
41861
41979
|
"awesomate_knowledge_data",
|
|
41862
41980
|
{
|
|
41981
|
+
annotations: annotate("awesomate_knowledge_data", MUTATING),
|
|
41863
41982
|
description: "The knowledge platform's business-data warehouse (Pro+). action 'metrics' \u2014 headline numbers for the data tab. 'datasets' \u2014 the datasets imported and their columns: read this FIRST, measures/dimensions must name real columns. 'imports' \u2014 import job statuses. 'query' {dataset, measures:[{column, agg}], plus optional dimensions/filters passed through} \u2014 answer QUANTITATIVE questions from the user's own imported business data (revenue by month, top customers); read-only, results come back as rows to present honestly. New data is imported in the hub UI, not here.",
|
|
41864
41983
|
inputSchema: {
|
|
41865
41984
|
action: external_exports.enum(["metrics", "datasets", "imports", "query"]),
|
|
@@ -41887,7 +42006,7 @@ server.registerTool(
|
|
|
41887
42006
|
server.registerTool(
|
|
41888
42007
|
"awesomate_n8n_kpis",
|
|
41889
42008
|
{
|
|
41890
|
-
annotations: READ_ONLY,
|
|
42009
|
+
annotations: annotate("awesomate_n8n_kpis", READ_ONLY),
|
|
41891
42010
|
description: "Automation KPIs from the hub's monitoring: executions, error rate, avg + p95 duration, time saved, 7-day-vs-prior deltas. No workflowId \u2192 the whole instance (the headline numbers for any report). With workflowId \u2192 that workflow, plus last_error_at and clean_days. Needs the 'aggregate monitoring' privacy toggle (on by default). Pair with awesomate_n8n_errors for what is failing and awesomate_site_uptime for the hosting side.",
|
|
41892
42011
|
inputSchema: { workflowId: external_exports.string().max(64).optional() }
|
|
41893
42012
|
},
|
|
@@ -41904,7 +42023,7 @@ server.registerTool(
|
|
|
41904
42023
|
server.registerTool(
|
|
41905
42024
|
"awesomate_n8n_errors",
|
|
41906
42025
|
{
|
|
41907
|
-
annotations: READ_ONLY,
|
|
42026
|
+
annotations: annotate("awesomate_n8n_errors", READ_ONLY),
|
|
41908
42027
|
description: "What is broken across the WHOLE instance \u2014 error events grouped by fingerprint (category, workflow, node, occurrences, first/last seen), newest first. THE first call when the user says 'something is failing' or at the start of an n8n session (a quick 7-day sweep; stay silent when it's clean). Counts and categories only \u2014 drill into a specific failure with awesomate_n8n_executions. days defaults to 30 (max 90).",
|
|
41909
42028
|
inputSchema: {
|
|
41910
42029
|
days: external_exports.number().int().min(1).max(90).optional(),
|
|
@@ -41930,7 +42049,7 @@ readTool(
|
|
|
41930
42049
|
server.registerTool(
|
|
41931
42050
|
"awesomate_n8n_findings",
|
|
41932
42051
|
{
|
|
41933
|
-
annotations: READ_ONLY,
|
|
42052
|
+
annotations: annotate("awesomate_n8n_findings", READ_ONLY),
|
|
41934
42053
|
description: "Findings from Awesomate's automated error analyzer for THIS account (Pro/Embedded + the 'Enable AI Error Diagnosis' privacy toggle (n8n \u2192 Settings \u2192 Privacy)): severity, workflow, occurrences, a plain-language clientSummary, needsClientAction (something only the user can fix \u2014 expired logins, third-party quotas), and fixReady (a reviewed fix is prepared \u2014 raise it with awesomate_support to have it applied). Read-only. An empty list on a healthy instance is the good state, not an error.",
|
|
41935
42054
|
inputSchema: { limit: external_exports.number().int().min(1).max(100).optional() }
|
|
41936
42055
|
},
|
|
@@ -41971,6 +42090,7 @@ readTool(
|
|
|
41971
42090
|
server.registerTool(
|
|
41972
42091
|
"awesomate_notifications",
|
|
41973
42092
|
{
|
|
42093
|
+
annotations: annotate("awesomate_notifications", MUTATING),
|
|
41974
42094
|
description: "The account's hub notification bell \u2014 the only channel where Awesomate pushes to the client: knowledge quota warnings (80%/100%), 'your quote is ready', support-access events. action 'list' {limit?} \u2192 notifications + unread count (surface unread ones once per session, in one line). 'read' {id} / 'read_all' \u2192 mark seen after you've relayed them. Not for sending anything.",
|
|
41975
42095
|
inputSchema: {
|
|
41976
42096
|
action: external_exports.enum(["list", "read", "read_all"]),
|
|
@@ -41998,6 +42118,7 @@ server.registerTool(
|
|
|
41998
42118
|
server.registerTool(
|
|
41999
42119
|
"awesomate_wp_post",
|
|
42000
42120
|
{
|
|
42121
|
+
annotations: annotate("awesomate_wp_post", MUTATING),
|
|
42001
42122
|
description: "Create, update or read a WordPress post/page on the user's own Awesomate-hosted site \u2014 titles and content with spaces/HTML are fine (unlike awesomate_run_wp_cli). 'create' {domain, title, content?, status?, postType?: post|page, excerpt?, slug?} \u2014 lands as a DRAFT unless status:'publish' is explicit; never publish content the user hasn't seen or approved. 'update' {domain, postId, any of title/content/excerpt/slug/status}. 'get' {domain, postId, includeContent?}. Writes need Support Plus+ and are audited; snapshot the site first (awesomate_snapshot_site) before the session's first content change on a live site. Find post ids via awesomate_run_wp_cli ['post','list'].",
|
|
42002
42123
|
inputSchema: {
|
|
42003
42124
|
action: external_exports.enum(["create", "update", "get"]),
|
|
@@ -42046,7 +42167,7 @@ server.registerTool(
|
|
|
42046
42167
|
domain: external_exports.string().min(3).max(253).describe("a domain on the user's own hosting account"),
|
|
42047
42168
|
path: external_exports.string().max(400).optional().describe("page path to audit, default /")
|
|
42048
42169
|
},
|
|
42049
|
-
annotations: READ_ONLY
|
|
42170
|
+
annotations: annotate("awesomate_site_audit", READ_ONLY)
|
|
42050
42171
|
},
|
|
42051
42172
|
async ({ domain, path }) => {
|
|
42052
42173
|
try {
|
|
@@ -42061,6 +42182,7 @@ server.registerTool(
|
|
|
42061
42182
|
server.registerTool(
|
|
42062
42183
|
"awesomate_wp_media_import",
|
|
42063
42184
|
{
|
|
42185
|
+
annotations: annotate("awesomate_wp_media_import", MUTATING),
|
|
42064
42186
|
description: "Import ONE media item into the user's WordPress media library by https URL (Support Plus+, audited). Returns the attachmentId to reference from posts. URLs only \u2014 this cannot read local files; for a local file, upload it somewhere reachable first or use wp-admin. Ask before importing anything the user didn't explicitly provide.",
|
|
42065
42187
|
inputSchema: {
|
|
42066
42188
|
domain: external_exports.string().min(3).max(253),
|
|
@@ -42080,6 +42202,7 @@ server.registerTool(
|
|
|
42080
42202
|
server.registerTool(
|
|
42081
42203
|
"awesomate_wp_settings",
|
|
42082
42204
|
{
|
|
42205
|
+
annotations: annotate("awesomate_wp_settings", DESTRUCTIVE),
|
|
42083
42206
|
description: `Change a WordPress site's core settings \u2014 THE tool for "change my site title" / tagline. Use this, never awesomate_run_wp_cli, for any value containing spaces: that tool's argument gate rejects spaces outright, so \`option update blogname "My Business Name"\` cannot work there. Fields (send only what you're changing): title, tagline, timezone (IANA, e.g. Australia/Sydney), dateFormat, timeFormat, postsPerPage (1-100), searchEngineVisible (false hides the site from search engines \u2014 confirm before setting it). Support Plus+ and audited; flushes the object cache so the change shows. Snapshot first with awesomate_snapshot_site if this is the session's first change to a live site.`,
|
|
42084
42207
|
inputSchema: {
|
|
42085
42208
|
domain: external_exports.string().min(3).max(253).describe("The site domain, e.g. mybusiness.awesomate.site"),
|
|
@@ -42134,6 +42257,7 @@ var KB_UNPARSEABLE = /* @__PURE__ */ new Set([".doc", ".docx", ".ppt", ".pptx",
|
|
|
42134
42257
|
server.registerTool(
|
|
42135
42258
|
"awesomate_knowledge_upload",
|
|
42136
42259
|
{
|
|
42260
|
+
annotations: annotate("awesomate_knowledge_upload", MUTATING),
|
|
42137
42261
|
description: "Ingest ONE file from the user's own computer into their Knowledge Base (Pro+). Pass a LOCAL PATH \u2014 this server runs on their machine and streams the file to the hub itself, so the file contents never pass through the conversation. Handles documents (pdf, md, txt), business data (csv, tsv, xls, xlsx, json), audio and video (transcribed), and images. Word/PowerPoint/RTF/EPUB files are NOT parseable yet \u2014 the tool refuses them with the workaround (export to PDF, or save as .md/.txt). Max 100 MB per file; bigger media goes through the hub's Knowledge \u2192 Sources page. INGESTING COSTS MONEY and counts against the monthly allowance, so ALWAYS get explicit approval for the specific file(s) first and say what it will consume. For several files, call once per file and report progress \u2014 do not loop silently. Returns a job with its live status; poll awesomate_knowledge_sources {action:'jobs'} until it succeeds (a duplicate upload replays the earlier job \u2014 a response already reading succeeded needs no polling), then probe the content with awesomate_knowledge_ask before building anything on it. A pack_required response means the allowance is exhausted: nothing was ingested and nothing was purchased.",
|
|
42138
42262
|
inputSchema: {
|
|
42139
42263
|
path: external_exports.string().min(1).max(4096).optional().describe("Path to the file on the user's machine (~ is expanded). Omit when using fromFilesPath."),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@awesomate/hosting-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.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",
|
|
@@ -28,36 +28,61 @@ what's actually spendable once credits promised to builds in flight are
|
|
|
28
28
|
set aside — rather than the raw balance.) Never quote a plan, price, or
|
|
29
29
|
balance from memory.
|
|
30
30
|
|
|
31
|
-
## 1.
|
|
31
|
+
## 1. Ask the Knowledge Base first
|
|
32
32
|
|
|
33
33
|
For any "how do I", "why does", "what is" question about the service:
|
|
34
34
|
|
|
35
|
-
1. Call `awesomate_support {action:'
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
35
|
+
1. Call `awesomate_support {action:'ask', q:'<their question>'}`. This is
|
|
36
|
+
Awesomate's own Knowledge Base answering from Awesomate's own content,
|
|
37
|
+
with numbered citations. It works on every plan.
|
|
38
|
+
2. Read the response's `source` and `degraded` fields before you answer —
|
|
39
|
+
they are the difference between three very different situations:
|
|
40
|
+
|
|
41
|
+
- `source:'knowledge_base'`, `no_answer:false` → a grounded answer.
|
|
42
|
+
Relay it in your own plain words and give the citation URLs.
|
|
43
|
+
- `source:'knowledge_base'`, `no_answer:true` → the grounding gate
|
|
44
|
+
declined, because the answer is not in our content. **Do not fill the
|
|
45
|
+
gap yourself.** Offer a ticket (§2).
|
|
46
|
+
- `degraded:true` → the Knowledge Base was unavailable or is not
|
|
47
|
+
switched on, and you are looking at keyword matches from `faq` and
|
|
48
|
+
`docs` instead. Useful, but **never present them as a verified
|
|
49
|
+
answer**, and say the search was limited if it matters.
|
|
50
|
+
|
|
51
|
+
3. Only if `ask` came back thin do you need `faq` or `help_docs` directly.
|
|
52
|
+
Both remain available and behave as before, and `help_centre_url` in
|
|
53
|
+
any response is always safe to offer for browsing.
|
|
54
|
+
4. Cite nothing the tools didn't say. No invented policy, no guessed
|
|
55
|
+
pricing, no remembered plan limits.
|
|
47
56
|
|
|
48
57
|
## 2. Ticket flow — talking to a human
|
|
49
58
|
|
|
50
59
|
When the user wants a human, or §1 came up empty:
|
|
51
60
|
|
|
61
|
+
**First, what is this ticket about?** Access splits by SUBJECT, not by
|
|
62
|
+
plan, and you must pass a `category` naming it. `Other` is refused.
|
|
63
|
+
|
|
64
|
+
| The problem is | category | Who can raise it |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| Our platform is broken: site down, n8n unreachable, provisioning or SSL failed, the hub is erroring | `Infrastructure fault` | **every plan** |
|
|
67
|
+
| They cannot connect or use Claude: pairing fails, the token is rejected, tools error | `Claude/MCP connectivity` | **every plan** |
|
|
68
|
+
| Money: invoices, plans, credits, refunds | `Account/billing` | **every plan** |
|
|
69
|
+
| Help USING n8n, their website, or the Knowledge Base | `Workflow not running`, `Workflow error`, `New automation request`, `How-to question` | **Support Plus and above** |
|
|
70
|
+
|
|
71
|
+
Choose the category that is actually true. If a product-help ticket comes
|
|
72
|
+
back `403 upgrade_required`, answer from §1 instead and relay the upgrade
|
|
73
|
+
honestly — **never relabel a workflow question as an outage to get it
|
|
74
|
+
through.** That is lying to your own support team about the state of the
|
|
75
|
+
platform, and it puts a false fault report in front of an engineer.
|
|
76
|
+
|
|
52
77
|
1. Draft the ticket in the USER'S words — their description of the problem,
|
|
53
78
|
what they were trying to do, what happened. Add context you observed
|
|
54
79
|
(which site/app, what you already tried) in one short paragraph. No
|
|
55
80
|
stack traces, no jargon dumps.
|
|
56
81
|
2. Show the full draft (subject + message) and ask plainly: "Send this to
|
|
57
82
|
the Awesomate team?" NEVER call `create_ticket` without an explicit yes.
|
|
58
|
-
3. On yes: `awesomate_support {action:'create_ticket', subject, message
|
|
59
|
-
Confirm: "Sent. The team replies by email, usually within a
|
|
60
|
-
day."
|
|
83
|
+
3. On yes: `awesomate_support {action:'create_ticket', subject, message,
|
|
84
|
+
category}`. Confirm: "Sent. The team replies by email, usually within a
|
|
85
|
+
business day."
|
|
61
86
|
4. Later, "any update on my ticket?" →
|
|
62
87
|
`awesomate_support {action:'list_tickets'}` and report each ticket's
|
|
63
88
|
status in one line.
|