Agent Skills / maison-knowledge
Install this skill alone, or read it below. Raw file: SKILL.md · references/tools.md
npx skills add https://docs.maison-labs.com --skill maison-knowledgeMaison — Knowledge base
Manage what a hotel's concierge knows: website and document knowledge sources (add, sync, rescrape, disable/reactivate, follow a run and its log and report, rediscover booking links, versions, download, large uploads), curated Q&A pairs (add, update, publish, unpublish, delete, version history), unanswered-question gaps (list, detect, answer, dismiss, reopen) and knowledge quality runs (deduplicate, consistency check, their reports). Use when a hotel's answers are missing, wrong or stale, or when adding new content.
Part of the Maison public API. Read the maison-public-api skill first for authentication, discovery and transport details (https://docs.maison-labs.com/skills/maison-public-api/SKILL.md).
When to use
- Add a page or site to a hotel's knowledge —
add_website_source. - Upload a PDF/brochure/policy —
add_document_source(≤ 64 KiB inline asbytesBase64). - Upload a document over 64 KiB —
create_document_upload, PUT the file to itsurlwith itsheaders, thenadd_document_source(oradd_document_version) with theuploadId. - Take a source out of the agent's knowledge without losing it —
disable_source; undo withreactivate_source. - Follow a scrape, sync or ingestion —
list_source_runs(the source'sidfromlist_knowledge_sources), thenget_source_run_logswithafter: lastSequntilfinished;get_website_scrapefor the step-by-step view of a website run. - Read what a finished website scrape or sync changed —
get_source_run_report(the run'ssessionId): the report inline, orformat: "pdf"for a download link to the PDF the report email attaches. - A hotel changed booking engine —
discover_booking_links(no full rescrape). - Fix a specific wrong answer —
list_qa_pairswithsearch, thenupdate_qa_pair. - Find what guests asked that the concierge could not answer —
list_knowledge_gaps, thenanswer_knowledge_gap. - Find conflicting or duplicate answers —
check_knowledge_consistencyordeduplicate_knowledge(each returns asessionId), thenget_knowledge_quality_rununtilfinishedfor the report;list_knowledge_quality_runsfor past runs.
Before you start
- Send
x-api-key: <key>on every call; the key only reaches/api/v1. GET /api/v1/tools(or MCPtools/list) returns the tools THIS key may run — if a tool below is missing there, you lack a grant; do not retry it.- Client-scoped tools take
clientId(a hotel id).whoamilists the ids you can act on.
Tools
| Tool | What it does | REST | Needs |
|---|---|---|---|
add_document_source | Add a document (PDF, DOCX, etc.) as a knowledge source and queue its ingestion. | POST /api/v1/client/{clientId}/source/document | document-source WRITE (client); plan: document-source |
add_document_version | Upload a new version of an existing document source and queue its ingestion. | POST /api/v1/client/{clientId}/source/document/{documentId}/version | document-source WRITE (client); plan: document-source |
add_qa_pairs | Create one or more Q&A pairs. | POST /api/v1/client/{clientId}/qapairs | qa-editor WRITE (client) |
add_website_source | Add a website as a knowledge source for a hotel and queue its first scrape. | POST /api/v1/client/{clientId}/source/website | document-source WRITE (client); plan: document-source; composite of set_source_sync_schedule |
answer_knowledge_gap | Answer an open knowledge gap and mark it ANSWERED. | POST /api/v1/client/{clientId}/knowledgegap/{gapId}/answer | qa-editor WRITE (client); plan: unanswered-questions |
check_knowledge_consistency | Start a consistency-check run: a pipeline task that checks Q&A pairs for answers that conflict or are ambiguous. | POST /api/v1/client/{clientId}/qapairs/consistencycheck | consistency-check EXECUTE (client); plan: consistency-check |
create_document_upload | Get a presigned URL to upload a document larger than the 64 KiB inline limit (up to 50 MiB). | POST /api/v1/client/{clientId}/source/document/upload | document-source WRITE (client); plan: document-source |
deduplicate_knowledge | Start a deduplication run: a pipeline task that finds and merges near-duplicate Q&A pairs in the knowledge base, optionally with a similarityThreshold (0–1) and batchSize. | POST /api/v1/client/{clientId}/qapairs/deduplicate | deduplication EXECUTE (client); plan: deduplication |
delete_document_version | Soft-delete a non-current version of a document. | DELETE /api/v1/client/{clientId}/source/document/{documentId}/version/{version} | document-source WRITE (client); plan: document-source; destructive |
delete_qa_pairs | Soft-delete one or more Q&A pairs by id. | POST /api/v1/client/{clientId}/qapairs/delete | qa-editor WRITE (client); destructive |
detect_knowledge_gaps | Start a manual knowledge-gap detection run for a hotel and return at once (202 { queued: true }); the run analyses recent guest chats in the background and inserts or updates gap records. | POST /api/v1/client/{clientId}/knowledgegaps/detect | clients EXECUTE (client); plan: unanswered-questions |
disable_source | Disable a website (kind: website) or document (kind: document) source: it stays linked with its history, its answers are frozen (the agent stops using them; they cannot be edited, published or deleted) and it is left out of syncs. | POST /api/v1/client/{clientId}/source/{kind}/{sourceId}/disable | document-source WRITE (client); plan: document-source; destructive |
discover_booking_links | Re-run booking-link discovery for one website source without a full re-scrape — after the hotel changed booking engine, say. | POST /api/v1/client/{clientId}/source/website/{websiteId}/bookinglinks | document-source EXECUTE (client); plan: document-source |
dismiss_knowledge_gap | Mark an open knowledge gap as DISMISSED without creating a Q&A pair; 404 unknown, 409 already resolved. | POST /api/v1/client/{clientId}/knowledgegap/{gapId}/dismiss | qa-editor WRITE (client); plan: unanswered-questions |
download_document | Download a document source. | GET /api/v1/client/{clientId}/source/document/{documentId}/download | document-source READ (client); plan: document-source; read-only |
get_knowledge_quality_run | One deduplication or consistency-check run (a sessionId from deduplicate_knowledge, check_knowledge_consistency or list_knowledge_quality_runs) with its full report: for a consistency check each conflict and ambiguity (the questions involved, why, and the Q&A pair ids when known); for a deduplication the answer counts at each stage. | GET /api/v1/client/{clientId}/knowledge/quality/run/{sessionId} | test-session READ (client); plan: test-session; read-only |
get_qa_counts | Active, deleted and total Q&A pair counts for a hotel's knowledge base. | GET /api/v1/client/{clientId}/qapairs/counts | qa-editor READ (client); read-only |
get_qa_pair | Fetch a single Q&A pair by id. | GET /api/v1/client/{clientId}/qapair/{qaId} | clients READ (client); read-only |
get_source_run_logs | The log lines of one knowledge-source run (a sessionId from list_source_runs), oldest first, after line after (its seq; omit for the start). | GET /api/v1/client/{clientId}/source/run/{sessionId}/logs | document-source READ (client); plan: document-source; read-only |
get_source_run_report | The report of one website scrape or sync run (a sessionId from list_source_runs): with format: "json" (default) the stored report (summary, added, updated, deleted, merged, conflicts, unreadable, failedUpdates, needsRescrape), generatedAt and pdfUrl, a download link for the PDF version valid for 15 minutes (null when no PDF was stored); with format: "pdf" only the download url and its expiresAt. | GET /api/v1/client/{clientId}/source/run/{sessionId}/report | document-source READ (client); plan: document-source; read-only |
get_website_scrape | The latest scrape or sync of a linked website source, told step by step: status, the running step, countable progress, a bounded message log and stalled/stopped state; scrape: null when it never ran. | GET /api/v1/client/{clientId}/source/website/{websiteId}/scrape | document-source READ (client); plan: document-source; read-only |
list_document_versions | List all versions of a document source, newest first. | GET /api/v1/client/{clientId}/source/document/{documentId}/versions | document-source READ (client); plan: document-source; read-only |
list_knowledge_gaps | List unanswered questions detected in guest chat sessions, ordered by occurrence count. | GET /api/v1/client/{clientId}/knowledgegaps | clients READ (client); plan: unanswered-questions; read-only |
list_knowledge_quality_runs | The hotel's deduplication and consistency-check runs, newest first: each with its kind, status, steps, countable progress, who started it, its headline and, once reported, the report's summary and counts (conflicts and ambiguities, or answers before, after and removed). | GET /api/v1/client/{clientId}/knowledge/quality/runs | test-session READ (client); plan: test-session; read-only |
list_knowledge_sources | List every website and document knowledge source attached to a hotel, including scrape/sync status, schedule and current version. | GET /api/v1/client/{clientId}/sources | document-source READ (client); plan: document-source; read-only |
list_qa_pairs | Page through the Q&A knowledge base for a hotel with optional text search, source and origin filters, a creation-time window, publish-state filter, exact ids and sort. | GET /api/v1/client/{clientId}/qapairs | clients READ (client); read-only |
list_qa_versions | Page through the version history of a Q&A pair (DynamoDB-backed audit log), newest first. | GET /api/v1/client/{clientId}/qapair/{qaId}/versions | clients READ (client), qa-editor READ (client); read-only |
list_source_runs | The runs of one knowledge source, newest first: website scrapes and syncs or document ingestions, each with its steps, countable progress, who started it and its headline. | GET /api/v1/client/{clientId}/source/{sourceId}/runs | document-source READ (client); plan: document-source; read-only |
publish_qa_pairs | Publish one or more Q&A pairs so the chat agent uses them. | POST /api/v1/client/{clientId}/qapairs/publish | qa-editor WRITE (client) |
reactivate_source | Reactivate a disabled website or document source: its answers come back exactly as they were before disable_source, and syncs and rescrapes are allowed again. | POST /api/v1/client/{clientId}/source/{kind}/{sourceId}/reactivate | document-source WRITE (client); plan: document-source |
remove_source | Permanently remove a website (kind: website) or document (kind: document) source from a hotel. | DELETE /api/v1/client/{clientId}/source/{kind}/{sourceId} | document-source WRITE (client); plan: document-source; destructive |
rename_document_source | Change the display name of a document source without changing its content or version. | PATCH /api/v1/client/{clientId}/source/document/{documentId} | document-source WRITE (client); plan: document-source |
reopen_knowledge_gap | Move an answered or dismissed knowledge gap back to OPEN, clearing its resolution (the Q&A pair that answered it is kept). | POST /api/v1/client/{clientId}/knowledgegap/{gapId}/reopen | qa-editor WRITE (client); plan: unanswered-questions |
restore_document_version | Restore a previous version of a document source by creating a new version with the old content, then re-queueing ingestion. | POST /api/v1/client/{clientId}/source/document/{documentId}/version/{version}/restore | document-source WRITE (client); plan: document-source |
restore_qa_version | Restore a Q&A pair to a previous version by copying its question and answer into a new update. | POST /api/v1/client/{clientId}/qapair/{qaId}/version/{version}/restore | clients READ (client), qa-editor WRITE (client) |
scrape_website_source | Queue an immediate scrape of a specific website source. | POST /api/v1/client/{clientId}/source/website/{websiteId}/scrape | document-source EXECUTE (client); plan: document-source |
set_main_website_source | Mark a website source as the main knowledge website for the hotel. | PATCH /api/v1/client/{clientId}/source/website/{websiteId}/main | document-source WRITE (client); plan: document-source |
set_source_sync_schedule | Change the automatic sync schedule for a website source (NONE, DAILY, WEEKLY, BI_WEEKLY, MONTHLY). | PATCH /api/v1/client/{clientId}/source/website/{websiteId}/schedule | document-source WRITE (client), schedules WRITE (global); plan: document-source |
sync_source | Queue an on-demand sync for a website (kind: website) or document (kind: document) source. | POST /api/v1/client/{clientId}/source/{kind}/{sourceId}/sync | document-source EXECUTE (client); plan: document-source |
unpublish_qa_pairs | Unpublish one or more Q&A pairs so the agent no longer uses them without deleting them. | POST /api/v1/client/{clientId}/qapairs/unpublish | qa-editor WRITE (client) |
update_qa_pair | Change the question, the answer or both of an existing Q&A pair. | PUT /api/v1/client/{clientId}/qapair/{qaId} | qa-editor WRITE (client) |
Full input fields for every tool: references/tools.md.
Recommended workflows
Add content and make it live
add_website_source(domain URL) oradd_document_source(name, filename, mimeType, andbytesBase64or anuploadIdfromcreate_document_upload).- Ingestion is queued;
list_knowledge_sourcesshowsscrapeStatus/lastSuccessfulIngestAtwhen it has landed. - For hand-written facts use
add_qa_pairs— new pairs are published on creation;unpublish_qa_pairstakes one out of answers without deleting it (unpublished pairs are not used).
Close knowledge gaps
detect_knowledge_gapsanswers 202{ queued: true }at once; polllist_knowledge_gaps(itslastSession) withstatus: "OPEN".- For each gap:
answer_knowledge_gapwith ananswer(optionally a rewordedquestion) to create the Q&A pair — live at once, new pairs are stored published — or withqaIdto link a pair that already answers it (nothing is created, its publish state is unchanged);dismiss_knowledge_gapwhen it is noise (gapIdsdismisses many in one call);reopen_knowledge_gapto undo either. - Run
deduplicate_knowledgeandcheck_knowledge_consistencyafter a large import; read each report withget_knowledge_quality_runand fix the conflicting pairs withupdate_qa_pair.
Tips
- Q&A versions are kept:
list_qa_versions+restore_qa_versionundo a bad edit. set_main_website_sourcemarks the website that also drives the preview site;set_source_sync_scheduleis Maison-staff only.
Pitfalls
- A
sync_sourceon a document re-ingests the stored file; ascrape_website_sourcefetches the live site. Do not confuse them. list_qa_pairscan return 503 when semantic search is down — retry later rather than concluding the knowledge base is empty.- Inline base64 uploads over 64 KiB are rejected with 413
too_large— usecreate_document_upload. download_documentreturnsbytesBase64up to 64 KiB, elsedownloadUrl+expiresAt(15 minutes).update_qa_pairtakesquestion,answeror both; the field left out keeps its stored value.sync_source/scrape_website_source/discover_booking_linksanswer 409 for a disabled source —reactivate_sourcefirst.add_website_sourcewith asyncScheduleother than NONE needs Maison-staffschedulesWRITE (403 otherwise, nothing created).
Calling conventions
Same tool, three transports — pick whichever your runtime already speaks. Always send x-api-key.
# REST
curl -X POST "https://maison-labs.com/api/v1/client/<clientId>/source/document" -H "x-api-key: $MAISON_API_KEY" -H "content-type: application/json" -d '{ "name": …, "filename": …, "mimeType": … }'// MCP (https://maison-labs.com/mcp, Streamable HTTP): tools/call
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "add_document_source", "arguments": { "name": …, "filename": …, "mimeType": … } } }// A2A (https://maison-labs.com/a2a): tasks/send with a data part
{ "jsonrpc": "2.0", "id": 1, "method": "tasks/send", "params": { "message": { "role": "user", "parts": [{ "type": "data", "data": { "tool": "add_document_source", "input": { "name": …, "filename": …, "mimeType": … } } }] } } }Errors are the same everywhere: 401 no/invalid key; 403 forbidden with details.missing (the grants you lack — fall back to the composite's parts or stop); 403 not_entitled (the hotel's plan lacks the feature); 404, 409, 413 too_large, 503. Inputs that fail validation return 400 invalid_input with the Zod issues — fix and retry once.