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

114 lines (91 loc) • 5.64 kB
# People, places and topics — the entity layer The platform builds one identity per person, place and topic across all of the tenant's media (face clusters from photos/video, text names from posts, books and transcripts). That is what lets `/v1/answer` handle "everything about X", "who appears most often with X" and "what connects X and Y" with citations. The user curates it — naming, merging, hiding, and deciding alias suggestions — through `awesomate_knowledge_people` or the hub's Knowledge → People page. The hub stores none of this; every call is a live read of platform metadata (ids, counts, titles, locators — never photos, never document text). ## Probe first `list`, `aliases` and `resolve` check `GET /api/knowledge/entities` before anything else. `available: false` means the platform has not enabled the layer for this tenant yet. Say so plainly ("people and connections aren't switched on for your knowledge base yet — nothing to do on your side"), do not retry, and carry on with sources/ask. When it IS available the result carries `counts` (named, unnamed, aliases pending, places, topics), `last_resolution_at` and `resolution_job`. ## What a person looks like ``` { person_id, handle, display_name | null, status: named|unknown|hidden, face_count, text_mentions, docs, aliases } ``` - `display_name: null` + `status: 'unknown'` is an **unnamed face cluster**. `handle` (e.g. `unknownBB0007`) is an opaque per-tenant label — it is NOT a name, and nothing about it tells you who the person is. - `get {personId}` adds `aliases[]` (text forms already linked), `co_mentions[]` (`{entity_id, kind, label, shared_docs}`) and `docs[]` — the witness sources, rendered for the user as `[n] title — (locator)` with the kind. - Photos of a cluster exist only on the hub page. You cannot see them; the user can. When they want to identify someone, send them there. ## Naming a person — the rules 1. **Only a name the user gives.** Never infer identity from a handle, from co-mentions, from an alias suggestion's confidence, or from your own knowledge of who "probably" appears in this content. 2. **Confirm the cluster before the name lands.** Show the counts and the witness sources from `get` and ask "is this the person you mean?" — two unnamed clusters can both be "the guy in the blue shirt". If the user is working from photos, they confirm on the hub page and give you the `handle` or `person_id`. 3. **`rename {personId, displayName}`**, then read `person.display_name` and `relabelled` back. The platform propagates the name into facets and queues a resolution; the agent answers with it after the next reindex. 4. A rename on an already-named person replaces the name everywhere. Same confirmation. ## Merging duplicates Two entries for one real person (a face cluster and a text-only person, or two clusters the face pipeline split). `merge {personId, intoPersonId}` moves every face and alias of `personId` onto `intoPersonId` and hides the source. Before calling: name both entries to the user with their counts, say which one survives, and get an explicit yes — reversal is a support request. Read `faces_moved` / `aliases_moved` back afterwards. Never merge into a hidden person; never merge a person into themselves (the tool refuses). ## Hiding `hide {personId}` removes a person from answers (their sources stay indexed); `unhide` brings them back. Reversible, so a confirmation sentence is enough. Hidden people are listed with `status: 'hidden'`. ## Alias suggestions `aliases` lists pending suggestions: a text form the content uses (`alias`, normalised as `alias_norm`) that the platform thinks refers to a known entity (`suggested_entity_id`, `suggested_label`, `confidence`), with `sample_docs` as evidence and `mention_count`. **Identity is the pair `(kind, alias_norm)` — there is no alias id.** Present alias → suggested match → confidence → a sample title or two, then act ONLY on the user's word: - `decide {kind, aliasNorm, decision: 'accept', entityId}` — link it to the suggested (or another known) entity. - `decide {…, decision: 'accept', createPersonName}` — the alias is a real person nobody has a cluster for yet; creates them (person kind only). - `decide {…, decision: 'reject'}` — stays plain text, not suggested again. Mentions re-link on the next resolution, so counts move after a short delay. ## Re-running resolution `resolve` re-scans the content for people/places/topics, applies the user's names and decisions (which are never undone by a re-run), and refreshes the connections. It runs in the background and **counts toward the ingestion allowance** — ask first. `202 queued` starts one; `200 running` means one is already in flight and nothing new was started. A `resolution_job` that has been `running` for over an hour is stuck — say so and offer `awesomate_support`. ## Answering "who appears with X" Once people are named, `awesomate_knowledge_ask` handles relationship questions ("who appears most often with Dale?", "what connects Dale and Fiji?") with citations to the witnessing photos/posts. Pass names exactly as the user says them. If the answer names nobody, check `list` — the people involved may still be unnamed clusters, which the platform never names in an answer. ## What never happens here - No guessing identities, no "this is probably …". - No photos through these tools; no document text either. - No rename / merge / decide / resolve without the user's explicit approval. - No retry loop on `available: false` — it is a state, not an error.