@awesomate/hosting-mcp 0.20.1 → 0.20.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -40190,9 +40190,10 @@ async function knowledgeSources(config3, args) {
40190
40190
  if (args.action === "summary") {
40191
40191
  try {
40192
40192
  const s = await hubGet(config3, "/api/knowledge/sources/summary");
40193
+ const failedJobs = Number(s.failed_jobs_7d ?? 0);
40193
40194
  return {
40194
40195
  ...s,
40195
- note: "Exact whole-library counts. by_kind is what the knowledge base answers from; the paged list is only for browsing individual sources."
40196
+ note: failedJobs > 0 ? `Exact whole-library counts \u2014 BUT ${failedJobs} ingest job(s) FAILED in the last 7 days (last: ${String(s.last_failed_job_at ?? "unknown")}). Those uploads are NOT in the library even though every count here looks clean. Read awesomate_knowledge_sources {action:'jobs', status:'failed'} and tell the user which ingests failed before summarising the library.` : "Exact whole-library counts. by_kind is what the knowledge base answers from; the paged list is only for browsing individual sources."
40196
40197
  };
40197
40198
  } catch (err) {
40198
40199
  if (err instanceof HubApiError && err.status === 404) {
@@ -41535,7 +41536,7 @@ server.registerTool(
41535
41536
  server.registerTool(
41536
41537
  "awesomate_knowledge_sources",
41537
41538
  {
41538
- description: "The knowledge base's content sources. action '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}: use THIS to say what the knowledge base contains. '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?}; 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.",
41539
+ description: "The knowledge base's content sources. action '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?}; 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.",
41539
41540
  inputSchema: {
41540
41541
  action: external_exports.enum(["list", "summary", "add", "remove", "jobs"]),
41541
41542
  url: external_exports.string().url().optional().describe("add: one public page / blog post / YouTube link"),
@@ -41939,10 +41940,11 @@ var KB_UPLOAD_TYPES = {
41939
41940
  ".webp": "image/webp"
41940
41941
  };
41941
41942
  var KB_MAX_UPLOAD_BYTES = 100 * 1024 * 1024;
41943
+ var KB_UNPARSEABLE = /* @__PURE__ */ new Set([".doc", ".docx", ".ppt", ".pptx", ".rtf", ".epub", ".html", ".htm"]);
41942
41944
  server.registerTool(
41943
41945
  "awesomate_knowledge_upload",
41944
41946
  {
41945
- 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, docx, pptx, xlsx, csv, txt, md, epub), audio and video (transcribed), and images. 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; poll awesomate_knowledge_sources {action:'jobs'} until it succeeds, 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.",
41947
+ 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; poll awesomate_knowledge_sources {action:'jobs'} until it succeeds, 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.",
41946
41948
  inputSchema: {
41947
41949
  path: external_exports.string().min(1).max(4096).describe("Path to the file on the user's machine (~ is expanded)"),
41948
41950
  title: external_exports.string().max(300).optional().describe("Display title; defaults to the filename")
@@ -41979,6 +41981,13 @@ server.registerTool(
41979
41981
  );
41980
41982
  }
41981
41983
  const ext = extname(abs).toLowerCase();
41984
+ if (KB_UNPARSEABLE.has(ext)) {
41985
+ return errorResult(
41986
+ new Error(
41987
+ `${basename(abs)} is a format the Knowledge Base cannot parse yet (${ext}). Export it to PDF, or save the text as .md or .txt, and upload that instead. For a web page, add its public URL with awesomate_knowledge_sources {action:'add'} rather than uploading the HTML file.`
41988
+ )
41989
+ );
41990
+ }
41982
41991
  const contentType = KB_UPLOAD_TYPES[ext] ?? "application/octet-stream";
41983
41992
  const filename = title?.trim() ? `${title.trim()}${ext}` : basename(abs);
41984
41993
  const result = await hubUploadFile(requireConfig(), "/api/knowledge/sources", {
@@ -41989,7 +41998,7 @@ server.registerTool(
41989
41998
  return knowledgeResult({
41990
41999
  ...result,
41991
42000
  uploaded: { path: abs, filename, sizeBytes: st.size, contentType },
41992
- note: `Queued \u2014 NOT yet ingested. Poll awesomate_knowledge_sources {action:"jobs"} and read the job's status AND error: a job that fails during processing creates no source row, so summary/failed_sources still look clean and the failure is invisible there. Big media is transcribed and can take a while. Only after the job reports succeeded, verify with awesomate_knowledge_ask before building on it.`
42001
+ note: `Queued \u2014 NOT yet ingested. Poll awesomate_knowledge_sources {action:"jobs"} and read the job's status AND error: a job that fails during processing creates no source row, so summary counts stay clean (only its failed_jobs_7d field shows it). Big media is transcribed and can take a while. Only after the job reports succeeded, verify with awesomate_knowledge_ask before building on it.`
41993
42002
  });
41994
42003
  } catch (err) {
41995
42004
  return knowledgeError(err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awesomate/hosting-mcp",
3
- "version": "0.20.1",
3
+ "version": "0.20.3",
4
4
  "description": "Awesomate MCP server — lets Claude manage your Awesomate WordPress hosting, plan, limits, n8n automations, and build Node/static apps + databases",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -1,5 +1,18 @@
1
1
  {
2
2
  "versions": [
3
+ {
4
+ "version": "0.20.3",
5
+ "highlights": [
6
+ "The Knowledge Base summary now warns when recent uploads failed to ingest - failures used to be invisible unless you checked the jobs list"
7
+ ]
8
+ },
9
+ {
10
+ "version": "0.20.2",
11
+ "highlights": [
12
+ "Plain-text (.txt) and Markdown files now ingest into your Knowledge Base - a bug stopped both from working",
13
+ "Unsupported file types (Word, PowerPoint, EPUB) are refused up front with the fix - export to PDF - instead of failing later"
14
+ ]
15
+ },
3
16
  {
4
17
  "version": "0.20.1",
5
18
  "highlights": [
@@ -41,13 +54,13 @@
41
54
  "highlights": [
42
55
  "Search your knowledge base with filters and ask questions within a slice of your content",
43
56
  "People & entities: your knowledge base now recognises who appears in your content, and you can name and merge them",
44
- "Build AI agents from your own content drafted, tested privately, and published only when you approve"
57
+ "Build AI agents from your own content \u2014 drafted, tested privately, and published only when you approve"
45
58
  ]
46
59
  },
47
60
  {
48
61
  "version": "0.14.0",
49
62
  "highlights": [
50
- "Tools built for business owners, not developers plain-language answers about your account, plan and limits",
63
+ "Tools built for business owners, not developers \u2014 plain-language answers about your account, plan and limits",
51
64
  "New support skill: get help, understand credits, or request a done-for-you build without leaving Claude",
52
65
  "New database skill: Claude picks the right place to keep your data and sets it up for you"
53
66
  ]
@@ -37,6 +37,9 @@ contents never pass through the conversation and a 100 MB PDF costs no context.
37
37
  - A folder path is rejected on purpose — list it, agree the files, then upload.
38
38
  - Public URLs and whole sitemaps stay on `awesomate_knowledge_sources`
39
39
  `{action:'add'}`. Use that for their website; use upload for their disk.
40
+ - **What parses:** pdf, md, txt (documents); csv, tsv, xls, xlsx, json (business data);
41
+ audio, video, images. Word/PowerPoint/RTF/EPUB/HTML files are refused with a
42
+ workaround — export to PDF or save as .md/.txt; a web page goes in by URL.
40
43
 
41
44
  ## 3. Wait for ingestion, and check it actually succeeded
42
45
 
@@ -48,21 +51,25 @@ contents never pass through the conversation and a 100 MB PDF costs no context.
48
51
  processing never creates a source row, so `{action:'summary'}` still reports
49
52
  `failed_sources: 0` and the library total is unchanged. Measured live on
50
53
  2026-09-01: an upload failed with a platform error while summary read
51
- `total: 75, failed_sources: 0`. If you check the summary instead of the job,
52
- a failed ingest looks exactly like one that was never attempted.
54
+ `total: 75, failed_sources: 0`. On current platforms the summary now carries
55
+ `failed_jobs_7d` + `last_failed_job_at` for exactly this reason a nonzero
56
+ value means uploads failed that no other count shows; the field is absent on
57
+ older platforms, so its absence proves nothing.
53
58
 
54
59
  So: read the job's `status` AND its `error`, and relay the error text to the
55
- user. Two real ones seen in the wild, both platform-side configuration rather
56
- than anything wrong with their file:
60
+ user. Real ones seen in the wild, all platform-side rather than anything wrong
61
+ with their file:
57
62
 
58
- - `new row violates row-level security policy for table "documents"` —
59
- document/markdown ingestion is not currently permitted for that tenant.
63
+ - `new row violates row-level security policy for table "documents"` — a
64
+ platform bug in markdown/text ingestion, fixed 2026-09-02. A failed job wrote
65
+ nothing, so once support confirms the fix is deployed the same file can
66
+ simply be re-uploaded.
60
67
  - `transcription_not_configured: DEEPGRAM_API_KEY is not set` — audio/video
61
68
  cannot be transcribed on that deployment yet.
62
69
 
63
- Neither is fixable by the user or by retrying. Say plainly that the upload
64
- reached Awesomate and failed on our side, and raise it with support
65
- (awesomate-support skill) rather than re-uploading and spending allowance again.
70
+ None of these are fixable by the user. Say plainly that the upload reached
71
+ Awesomate and failed on our side, and raise it with support (awesomate-support
72
+ skill) rather than blindly re-uploading and spending allowance again.
66
73
 
67
74
  Then `{action:'summary'}` for the whole-library counts once the job has
68
75
  actually succeeded.