UNPKG

@awesomate/hosting-mcp

Version:

Awesomate MCP server — lets Claude manage your Awesomate WordPress hosting, plan, limits, n8n automations, and build Node/static apps + databases

229 lines (203 loc) • 22.1 kB
--- name: awesomate-knowledge description: Turn the user's own content into a verified Knowledge Base their AI agents answer from, with citations. Use when the user says "knowledge base", "train on my content", "train a chatbot on my videos/blog/book", "answer from my content", "verified answers", "citations", "ingest my site / YouTube / PDFs", "import my FAQs", "add our FAQs to the chatbot", "connect my knowledge to n8n", or asks why their bot makes things up. The Knowledge Base and text ingest work on every plan; video, audio and scanned-document OCR need Pro; a public website chat is on every plan. Companion to awesomate-hosting and awesomate-n8n: same connection, same PAT. --- # Awesomate Knowledge Base — verified answers from Claude Code The user's content (videos, podcasts, blog posts, books, socials) becomes an isolated knowledge tenant on the Awesomate knowledge platform. Their AI agents then answer ONLY from that content, with a numbered citation for every claim — no evidence means an honest "I don't know". That refusal is the product working, never a bug to paper over. Most users are business owners: plain words, one question at a time, report outcomes ("your bot now answers from your book, here's a cited example"), never jargon like "tenant" or "SSE". **Routing rule:** live facts about THEIR knowledge base come from the tools; semantics (citations, quotas, ingest formats) come from the references; the platform's answer beats anything you remember. ## 0. First run (every session) 1. `awesomate_whoami` — every knowledge tool acts on whichever ACCOUNT this folder resolves to. Wrong slug → stop and fix the pin/connection first. Watch the `account:` stamp on every response. 2. Check `features.knowledge` (and `features.agents` before building agents) in `awesomate_get_context`. `available: false` → relay its `message` in one line and stop; never retry, never offer Knowledge or agents work. Every knowledge tool answers `feature_unavailable` with that sentence too. No `features` block (an older hub) or no entry: carry on as before, never read that as unavailable. 3. `awesomate_knowledge_status`: cache the result: - `available: false` → this hub doesn't serve Knowledge Base yet. Say so honestly, don't retry, offer `awesomate_support` for the timeline. - `upgrade_required: true` → relay the included upsell copy + billing link once, honestly, then help within what reads allow. Never retry into the gate. - `consent.knowledge_platform_enabled: false` → the user must turn it on themselves: **Settings → Features** (hub.awesomate.ai/settings?tab=features), the **Knowledge** row, then the second line under it, **"Use your content for Knowledge"**. Say plainly that switching on the Knowledge feature itself is NOT this consent: it is the separate line beneath it. It is not on the Privacy tab any more (an owner who was sent there switched on the Knowledge feature and four unrelated Privacy toggles before finding it). You cannot flip it for them, and there is no tool that can. If you're unsure which toggle is blocking (or a knowledge call 403s), call `awesomate_privacy_settings` — it reads which consents are on or off and names the one that's stopping you. Explain what it consents to (their selected content is indexed in Sydney, kept isolated to their account, deletable any time; turning it off suspends the Knowledge Base immediately), wait, re-check. - `tenant: null` or `status: 'provisioning'` → not enabled yet / still building; `usage` → month-to-date vs `usage.included` quota. 3. Only then design: what content exists, what's already ingested, what the user wants the bot to answer. For "what's ingested" use `awesomate_knowledge_sources {action:'summary'}` (exact `total` + `by_kind`; falls back to `status.usage.sources_total`, a floor when `sources_total_truncated:true`). `{action:'list'}` returns ONE page — the most recently ingested first (default 50, `limit` up to 200) — read `page.kinds_on_this_page` / `page.has_more` and follow `next_cursor`; never describe the library from a single page. 4. Writing an agent's instructions, greeting or "no answer" message? Call `awesomate_business` for the business's name, who it serves and its voice, and write them in. Confirm anything marked *suggestion* with the owner. ## 1. Tools | Task | Tool | |---|---| | Tenant state, plan gate, consent, quota, packs (CALL FIRST) | `awesomate_knowledge_status` | | Enable the knowledge base (idempotent; 202 = keep polling status) | `awesomate_knowledge_provision` | | The LIBRARY: search by title/tag/collection/visibility, list, add url·sitemap (with visibility, tags, collections), tag, rename (uploaded titles arrive slugified), set visibility (public needs the slug typed), move between collections, remove, ingest jobs and `job_retry` for a failed one, one source by id (`get`), counts per audience (`visibility_summary`), connected video libraries (`video_connections`) | `awesomate_knowledge_sources` | | A whole Vimeo or Wistia library import: how far it has got, its quote and transcription price, which videos failed (`video_imports`, with `importId` and `itemState` for one import). READ ONLY: connecting a library (the provider's token) and starting, pausing or cancelling an import (transcription is charged) are the owner's, in the hub at Knowledge, Video library | `awesomate_knowledge_sources` | | Collections — named sets of sources a chatbot is scoped to: list / create / update / delete / add / remove members | `awesomate_knowledge_collections` | | FAQs: sets of question-and-answer entries, imported as drafts, published with ONE owner yes, edited one answer at a time; read FAQs from a page, pasted text or a local file without saving (`import_page`, `import_text`, `import_file`); one `set` or `entry` ([faqs.md](references/faqs.md)) | `awesomate_knowledge_faq` | | Questions the public assistant couldn't answer: read why, publish the owner's answer with ONE yes, close similar ones in one go; inbox counts (`questions_summary`); the owner's daily email about them (`email_settings`, `email_settings_set` only when they ask) ([faqs.md](references/faqs.md)) | `awesomate_knowledge_faq` (`questions`, `question`, `answer`) | | Keep a File Manager folder (their n8n file system) synced into the knowledge base: `sync_rules` / `sync_rule_create` / `sync_rule_update` (change it, or `enabled:false` to switch it off) / `sync_rule_delete` / `sync_run` / `sync_state` on the sources tool; one file at a time via `awesomate_knowledge_upload {fromFilesPath}` (a spreadsheet needs `kind`, a folder rule `sheetKind`) | `awesomate_knowledge_sources`, `awesomate_knowledge_upload` | | Instant search with facet counts (find WHAT is in there: moments, pages, datasets; free) | `awesomate_knowledge_search` | | Ask a question → verified answer + numbered sources (accepts the same facet `filters` to ask within a slice) | `awesomate_knowledge_ask` | | Agent persona, fallback message and model tier: get and set (the single workspace default). Every account answers on Gemini Flash (`flash`) until the owner picks another; Claude Sonnet is a choice on any plan, Claude Opus on Embedded. Which model answers ONE live agent is its `effective_model` on `awesomate_knowledge_agents` list/get (absent while it is off, paused or has changes not live yet) | `awesomate_knowledge_agent` | | Agent BUILDER: list / get / create (AI-drafted from their content, saved as a private draft; pass `audience:'public'` for anything customers will talk to; it then answers from sources marked public ONLY; ALWAYS scope it to the right collection with `collectionIds` and check `kinds`, since a drafted scope can read every collection, and relay the `warning` it returns) / update (edit the draft's instructions, grounding, no-answer message, audience and collection scope; nothing changes for callers until publish) / test the draft (ignores audience: NOT what the public sees) / visitor_test (the PUBLISHED agent as a website visitor gets it) / publish, suspend, resume, delete (explicit approval first) / `logs`, `answer_rates`, `where_used` / `ai_key_status`, `models` (read only: the AI key is saved in the hub) / customer-group access policies (`policies`, `policy_create`, `policy_update`, `policy_delete`, `policy_suspend`, `policy_resume`) | `awesomate_knowledge_agents` | | People, places, topics: list / name / hide / merge / alias suggestions / re-run resolution / look one up by name (`explore`), who appears with it (`related`), open the passage behind a citation (`evidence`) | `awesomate_knowledge_people` | | Business-data warehouse: `metrics` / `datasets` / `query` / `imports`: answer quantitative questions from their own imported business data (query is free-form but read-only); one `dataset`, `dataset_update` (name, column decisions), one `import`, and `import_action` (approve, reject, withdraw with confirm, reimport, answer), each after the owner's yes | `awesomate_knowledge_data` | | Refresh these skills from the latest package | `awesomate_skill_update` | Local FILES (PDFs, Markdown, videos on disk) go through `awesomate_knowledge_upload` below, which streams them from disk so their contents never enter the conversation. The owner can also use the hub's Knowledge → Sources upload page themselves (100 MB per file; bigger media by URL). Formats + caps: [ingestion-sources.md](references/ingestion-sources.md). **`awesomate_knowledge_upload {path, title?, kind?}`** — ingest ONE file from the user's own computer. Pass a local path; the server streams it from disk, so file contents never pass through the conversation. 100 MB max, one call per file, explicit approval first (it spends allowance). URLs and sitemaps stay on `awesomate_knowledge_sources`. A spreadsheet (csv, tsv, xls, xlsx, xlsm, json) needs `kind`: `sheet` for rows a customer asks about (price lists, fee tables, timetables), `data-import` for totals and trends (job or invoice history). Ask when it is not obvious; never guess. ## 2. References — read on demand | When | Read | |---|---| | **"Train this on my files and put a chat on my site"** — the full path | [from-your-files.md](references/from-your-files.md) | | **"Import my FAQs"**, from their website, a spreadsheet or typed in; keeping them current | [faqs.md](references/faqs.md) | | **"What couldn't my chatbot answer?"**, "improve my assistant", unanswered questions | [faqs.md](references/faqs.md) § Questions | | Showing a cited image or video (and why a built page breaks); sharing a whole video with a permanent link or embed code | [showing-media.md](references/showing-media.md) | | Choosing/adding sources, estimating ingest cost & time | [ingestion-sources.md](references/ingestion-sources.md) | | Explaining citations, refusals, "verified" semantics | [citations-and-grounding.md](references/citations-and-grounding.md) | | Wiring the knowledge base into n8n agents | [n8n-connection.md](references/n8n-connection.md) | | Quotas, allowances, Ingestion Packs, overage | [quotas-and-packs.md](references/quotas-and-packs.md) | | Naming people, merging duplicates, alias suggestions, "who appears with X" | [people-and-entities.md](references/people-and-entities.md) | ## 3. The onboarding loop 1. Inventory their public content (site, blog, YouTube, books) — with them. **Start with their FAQ** if they have one: it is already questions customers ask, answered in their own words, so a public assistant is useful on day one ([faqs.md](references/faqs.md)). Never upload a Q&A spreadsheet as it is: turn it into the FAQ Markdown file, which keeps every answer word for word and citable. 2. Propose sources with a rough cost/time estimate ([ingestion-sources.md](references/ingestion-sources.md)) and get EXPLICIT approval — ingest spends real money and quota. 3. Queue sources (`add`), then poll `{action:'jobs'}` until succeeded; explain "searchable in minutes for pages, longer for media". 4. Probe with ~5 real questions via `awesomate_knowledge_ask` — show the citations, and show one out-of-scope question refusing (that's the feature). 5. Connect to n8n via the bundle ([n8n-connection.md](references/n8n-connection.md)) — never hand-build the credential. Two natural follow-ons, each one sentence when the moment fits: - **The same content should feed SEO.** What makes a good knowledge source (a services page, an FAQ, an about page) is exactly what `llms.txt` and AI discoverability need on their public site — route to the **awesomate-seo** skill. - **"Ask my knowledge base on a schedule" / "build me reports"** — that's the weekly-pulse recipe in the **awesomate-n8n** skill (`references/recurring-reports.md`); knowledge usage joins the report via `awesomate_knowledge_status`. ## 4. REST fallback (no `awesomate_knowledge_*` tools loaded, or an action with no tool) Auth exactly as the awesomate-hosting skill: `Authorization: Bearer <pat>` from `~/.awesomate/credentials.json` against `<apiBase>` — never echo the PAT. Rotating the n8n key, buying a pack and deleting the WHOLE knowledge base deliberately have NO tool: they're consequential enough to route through explicit REST calls (or the hub) the user has just approved. Deleting ONE source is `awesomate_knowledge_sources {action:'remove'}` and deleting an agent is `awesomate_knowledge_agents {action:'delete', confirm:true}`, both after the owner's yes. | Action | Endpoint | |---|---| | Status / provision / sources / jobs / agent | `GET\|POST /api/knowledge/{status,provision,sources,jobs,agent}` (tool equivalents) | | Ask the knowledge base | `POST /api/knowledge/chat` `{question, session?}` — **returns SSE (`text/event-stream`), NOT JSON.** `JSON.parse` of the body yields `null` and reading `.status` off it throws. Concatenate `event: answer` data lines; the single `event: meta` line carries the verdict `{status, sources, score}`. | | Whole-library counts | `GET /api/knowledge/sources/summary` — a PATH. **`?action=summary` is NOT a thing:** it returns 200 with a plain source list, so `.total` is `undefined` and any count derived from it silently becomes 0 or NaN. | | Faceted search (what `awesomate_knowledge_search` calls) | `GET /api/knowledge/explore?q=…` + the same facet params. **Add `&include=media` to get `url`/`poster_url` on image/video hits** — without it you get titles with nothing to display. | | Business-data warehouse (what `awesomate_knowledge_data` calls: metrics, datasets, `dataset`, `dataset_update`, imports, `import`, `import_action`, query) | `GET /api/knowledge/data/{metrics,datasets,datasets/:id,imports,imports/:id}` · `PATCH /api/knowledge/data/datasets/:id` · `POST /api/knowledge/data/imports/:id/:action` · `POST /api/knowledge/data/query` (read-only SQL) | | Agent builder (what `awesomate_knowledge_agents` calls) | `GET\|POST /api/knowledge/agents` · `GET\|PATCH\|DELETE /api/knowledge/agents/:agent_id` · `POST /api/knowledge/agents/:agent_id/{publish,suspend,resume}` · `GET /api/knowledge/agents/{logs,answer-rates,where-used}` · `GET\|POST /api/knowledge/agents/policies` · `GET\|PATCH\|DELETE /api/knowledge/agents/policies/:policy_id` · `POST /api/knowledge/agents/policies/:policy_id/{suspend,resume}` | | **Test a DRAFT agent** (`action:'test'`) | `POST /api/knowledge/agents/:agent_id/chat` `{message, session_id?}`. There is **no** `/test` endpoint — guessing one returns 404. It ignores the agent's audience. | | **Ask the PUBLISHED agent as a visitor** (`action:'visitor_test'`) | `POST /api/knowledge/agents/:agent_id/visitor-chat` `{message (max 2000), session_id?}`. Every plan; an unanswered question lands in the Questions inbox. | | **Website chat key** (`action:'website_key'`, `website_keys`, `revoke_website_key`; owner only, every plan) | `POST /api/knowledge/agents/keys` `{class:'p', agent_id, allowed_origins (https only, no path or wildcard), label?, request_id?, monthly_answer_cap?}` returns the key ONCE with its `monthly_answer_cap`; with no cap the hub sets half the account's monthly answers at that moment, and a key's cap cannot be changed later (a new limit is a new key). The tool refuses an agent that is not published, not public-audience, or paused. List with `GET /api/knowledge/agents/keys` (class `p`), revoke with `DELETE /api/knowledge/agents/keys/:key_id`. Every one only after the owner's yes. | | **The website chat's code: every attribute it reads** | `<script src="…/widget/v1.js" data-key="amk_p_…" data-agent="<agent id>" …>` before `</body>`. Required: `data-key` (the website key; or `data-token` for a short-lived u token your own server mints for a signed-in member) and `data-agent`. Optional: `data-title` (the header, "Ask us" when left out), `data-sub` (one line under the title; offer it only where `features.website_subtitle` is available), `data-greeting` (first message), `data-placeholder` (the hint in the box), `data-accent` (#hex), `data-position` (`right`\|`left`), `data-mode` (`bubble`\|`inline`), `data-target` (CSS selector the inline panel goes in), `data-height` (inline height, e.g. `620px`), `data-theme` (`auto`\|`light`\|`dark`), `data-sources` (`on` shows numbered sources; hidden otherwise), `data-media` (`off` stops players), `data-session-suffix` (two chats on one page). Never set `data-api`. The hub's look editor writes title, sub, accent, greeting, position, theme and sources; `website_key` writes title and sub (`title`, `subtitle`). | | Entity layer probe (`available` false = not enabled yet, stop) | `GET /api/knowledge/entities` | | People list / detail | `GET /api/knowledge/people?status=named\|unknown\|hidden\|all` · `GET /api/knowledge/people/:id` — returns `{people, next_cursor}` and **no `counts` key**. | | Entity COUNTS + availability | `GET /api/knowledge/entities` → `{available, counts: {...}}` — counts are nested under `counts`. Reading `people.counts?.x ?? 0` prints a confident row of zeros next to data that plainly exists. | | Name or hide/unhide a person (after approval) | `PATCH /api/knowledge/people/:id` `{display_name}` or `{status: "hidden"\|"unknown"}` | | Merge two people (after approval; source is hidden) | `POST /api/knowledge/people/:id/merge` `{into_person_id}` | | Alias suggestions / decision (identity = kind + alias_norm) | `GET /api/knowledge/entities/aliases?status=pending` · `POST /api/knowledge/entities/aliases/decision` `{kind, alias_norm, decision, entity_id? \| create_person?}` | | Re-run entity resolution (counts toward ingestion; after approval) | `POST /api/knowledge/entities/resolve` | | Rotate the n8n query key (after approval) | `POST /api/knowledge/keys/rotate` | | Buy an Ingestion Pack (1 credit = $100; after an explicit yes) | `POST /api/knowledge/packs` `{pack}` + `Idempotency-Key` header | | Delete a source (approval + it deletes indexed content; `awesomate_knowledge_sources` `remove`) | `DELETE /api/knowledge/sources/:id` | | Delete the WHOLE knowledge base | hub UI only (owner types the account slug) — never via PAT | | Fleet/admin views (Awesomate team) | `/api/fleet/knowledge/*` — admin JWT, not a client PAT | **The two chat endpoints take OPPOSITE field names, and both reject unknown keys.** Learning one shape and applying it to the other is a guaranteed `400`: | Endpoint | Body | |---|---| | `POST /api/knowledge/chat` — ask the knowledge base | `{question, session?, filters?}` | | `POST /api/knowledge/agents/:id/chat` — test a draft agent | `{message, session_id?, filters?}` | `question` vs `message`, `session` vs `session_id`. Both are strict objects, so sending both spellings to be safe fails too — as does **camelCase**: `{message, sessionId}` is a 400, and so is an extra `{draft: true}`. Going direct, use snake_case and send nothing the schema does not name. (The MCP tool parameters are camelCase — `sessionId`, `agentId` — because the tool translates for you.) Measured on a real first-time session (2026-09-01): fourteen `400`s and one `404` were spent rediscovering exactly this. ## 5. Hard rules - **Never ask for, paste, or echo an API key** — not the platform key, not the PAT, not "just to test". Key handling is the hub's job (rotate via REST above); new secrets go through the awesomate-credentials / secret-drop flow. - **Never present an uncited answer as verified.** If `awesomate_knowledge_ask` returns anything but `status: 'ok'` with sources, the verified content has no answer — say exactly that. - **Explicit approval before anything that costs:** every ingest (media especially — transcription is the big line), and any Ingestion Pack. A `pack_required` response purchases NOTHING — state the price (1 credit = $100), get a clear yes, then the user buys via the hub or the REST call. - **Approval before deleting sources** — removal also deletes the indexed content behind live answers. - **Caution on the live agent:** before `awesomate_knowledge_agent {action:'set'}`, read the current config, show exactly what will change, get approval, and read the response back to confirm. Real customers are talking to this agent. - **Respect quota honesty:** at/over quota, explain the numbers from `status.usage` — never silently retry or work around a 402/429. - **Never guess who a person is.** An unnamed person is an opaque handle plus counts; the only names you may attach are ones the USER gives, after they have confirmed WHICH cluster (face count, mention count, the witness sources from `get`). Photos are on the hub's Knowledge → People page, not in these tools. Full rules: [people-and-entities.md](references/people-and-entities.md). - **Approval before rename, merge, alias decisions and re-running resolution** — renames change what every answer says, merges hide an entry and move its faces/aliases (reversal is a support request), and a resolution run spends ingestion allowance. Read the result back each time.