# Brand Wiki: agent guide

Crawls a brand website to build an entity map, brand wiki, evidence claims and schema, then links them to ListeningMind search demand to produce an action plan, entity gaps, coverage and page signals. GEO/AEO teams use it to fix content so AI answers describe the brand correctly. Demand data exists for Korea, Japan and the US; demand and category context can also be imported from Intent KG runs.

## Connect
- MCP: `https://daas-wiki.listeningmind.ai/mcp` (Streamable HTTP). Start with `app_guide`.
- Browser agents: tools are registered on every page through WebMCP (`document.modelContext`).
- REST: `https://daas-wiki.listeningmind.ai/.well-known/openapi.json`

## Approval
- read and action tools run at once.
- run and delete tools need a person's approval. Over MCP the tool returns `confirm_url`; show it to the person, then call `confirmation_status` with the token until state is done.
- In the browser the page shows the person a confirm box.

## Workflow
1. `create_project` (action): Create a project for the brand site.
2. `discover_urls` (action): Collect candidate URLs from sitemaps and links.
3. `update_crawl_settings` (action): Adjust crawl scope such as max pages if needed.
4. `crawl_pages` (run): Crawl the selected pages.
5. `start_entity_analysis` (run): Start the entity, wiki and claim analysis.
6. `get_analysis_status` (read): Poll until the analysis is done.
7. `get_analysis` (read): Read the entity map and wiki.
8. `get_kg_link` (read): See whether a category Intent KG is linked (0 credits).
9. `import_demand_from_ontology` (action): If a KG exists, import demand keywords from it (0 credits).
10. `fetch_demand_live` (run): Otherwise fetch demand live from ListeningMind (spends credits).
11. `import_category_context` (action): Import the KG's category knowledge as wiki context.
12. `start_action_plan` (run): Build the action plan linking demand to entities.
13. `get_action_plan_status` (read): Poll until the plan is done.
14. `start_entity_gap` (run): Find missing entities and facts.
15. `get_entity_gap_status` (read): Poll until the gap analysis is done.
16. `start_coverage` (run): Evaluate coverage of AI questions.
17. `get_coverage` (read): Read the coverage report.
18. `start_page_signals` (run): Score per-page AI-readability signals.
19. `get_page_signals` (read): Read the page signals.
20. `generate_entity_page` (run): Draft canonical pages for entities that need them.
21. `get_project` (read): Read the full result bundle.
22. `export_project` (read): Export wiki, JSON-LD, llms.txt or CSV.

## Inputs
Brand site URL (required), brand name, market (KR/JP/US...), language, industry, max pages to crawl. Optional: demand keywords as CSV/JSON, a KG topic.

## Outputs
Entity map (core, supporting, context), wiki page per entity, claims with source URLs, JSON-LD, demand keywords, action plan, entity gaps, coverage report, page signals, draft entity pages, a brand MCP server, exports (md, json, csv, jsonld, llms.txt).

## Cost and time
Crawling costs no credits. Analysis, action plan, gaps, coverage, page signals and page generation use server LLM calls (scale with page count; amounts not reported). Live demand fetch uses up to 5 cluster_finder calls plus keyword_info for about 120 keywords; a new KG build costs 20k-50k credits. Importing from an existing KG costs 0 credits.

## Limits
Results are stored on the server (project folder); nothing is kept only in the browser (only the UI language is in localStorage). ListeningMind demand exists only for KR, JP and US; other markets are refused with unsupported-market. Analysis-type jobs run in the background and return 409 already-running if the same job is running. Status reads report state under status.state. Each project also exposes a brand MCP server at POST /api/projects/{id}/mcp (JSON-RPC 2.0); its search_market tool spends credits. No auth (internal network).

## Method (how the analysis works)
1. Create a project for the brand site, gather URLs from sitemaps and links, and judge AI crawler access from robots.txt.
2. Crawl the selected pages and store their text.
3. Run the AI analysis: entity map (core, supporting, context), brand wiki pages, claims with source URLs and schema.
4. Attach demand keywords: import them from an Intent KG run (0 credits), fetch them live from ListeningMind, or import your own.
5. Build the action plan linking demand to entities, then entity gaps, coverage of AI questions and per-page signals.
6. Draft canonical pages for entities that need them and export the wiki, JSON-LD, llms.txt or CSV.

## Reading the result
- analysis.entities, analysis.wikiPages and analysis.claims are the core; every claim carries a source URL, so you can check what the site actually supports.
- actionPlan.actionItems maps demand keywords to entities and content actions; start the work from there.
- entityGap.gaps lists entities and facts the brand should cover but does not.
- The coverage report (get_coverage) shows how well the site covers the questions AI assistants would ask; pageSignals.overallScore and the page signals score structure, schema, entity clarity and demand fit.
- connector.items is the demand data behind the plan (keyword, intent, CEP, monthly volume, trend).

## Requests this app answers well
- Crawl our brand site and build the entity map and brand wiki that AI assistants read
- Find the entities and facts that have search demand but are missing from our site
- Create llms.txt and JSON-LD for our brand site
- Make a content action plan for our site based on demand keywords in Japan

## Continue in another app
- [GEO Audit](https://daas-geo.listeningmind.ai/llms.txt) (MCP `https://daas-geo.listeningmind.ai/mcp`): When page signals or coverage show weak pages, or after editing pages from the action plan. Carry: The URLs of low-scoring pages (up to 5 per audit) and the brand's main category keyword as the topic.
- [Prompt Builder](https://daas-prompt.listeningmind.ai/llms.txt) (MCP `https://daas-prompt.listeningmind.ai/mcp`): When you want to measure, after the content work, whether ChatGPT and Gemini mention and recommend the brand. Carry: The brand name as own brand and the category keyword used for demand as the keyword.

## Using the screens (browser agents)
- `describe_screen`: menus, tabs, fields and buttons of the current screen, and what the page is for
- `go_to`: open a menu or page of this app by its label or path
- `fill_field`: type a value into a field by its label (never presses run; runs go through the run tools, which ask the person)
- `read_this_page`: the text and ids of what the person is looking at

## The ListeningMind apps (same account, same tools, call any of them)
Each app has `/mcp`, `/llms.txt`, `/agents.md` and WebMCP on its pages. `family_apps` and `recommend_app` return this list with addresses.
- [ACO](https://daas-aco.listeningmind.ai/llms.txt): Diagnoses whether a product detail page can be cited by AI answers and used by shopping agents (MCP `https://daas-aco.listeningmind.ai/mcp`)
- [AOO](https://daas-aoo.listeningmind.ai/llms.txt): Measures whether AI agents can get real tasks done on a website (MCP `https://daas-aoo.listeningmind.ai/mcp`)
- [Brand Finder](https://daas-brand.listeningmind.ai/llms.txt): Which brands lead search by generation or field, and what their brand assets are (MCP `https://daas-brand.listeningmind.ai/mcp`)
- [Brand Naming Agent](https://daas-naming.listeningmind.ai/llms.txt): Creates and checks brand name candidates grounded in search data (MCP `https://daas-naming.listeningmind.ai/mcp`)
- [CEP Finder](https://daas-cep.listeningmind.ai/llms.txt): In which situations do people start looking for this category (category entry point map) (MCP `https://daas-cep.listeningmind.ai/mcp`)
- [Creative Finder](https://daas-creative.listeningmind.ai/llms.txt): Finds purchase situations (CEP) in search data and drafts a creative, an image and a video for each (MCP `https://daas-creative.listeningmind.ai/mcp`)
- [Demand Forecast](https://daas-forecast.listeningmind.ai/llms.txt): What category demand looks like in the next 3-6 months and when to launch or campaign (MCP `https://daas-forecast.listeningmind.ai/mcp`)
- [Funnel Leak Finder](https://daas-funnel.listeningmind.ai/llms.txt): Where category search journeys leak to competitors (MCP `https://daas-funnel.listeningmind.ai/mcp`)
- [GEO Audit](https://daas-geo.listeningmind.ai/llms.txt): Checks whether a web page is ready to be read and cited by search engines and AI answer engines (MCP `https://daas-geo.listeningmind.ai/mcp`)
- [ICSS](https://daas-icss.listeningmind.ai/llms.txt): Synthetic consumer panel conditioned on search intent, for surveys and FGDs (MCP `https://daas-icss.listeningmind.ai/mcp`)
- [Intent KG](https://daas-intent.listeningmind.ai/llms.txt): What people look for about a topic, why, and how they choose (Intent Knowledge Graph) (MCP `https://daas-intent.listeningmind.ai/mcp`)
- [Prompt Builder](https://daas-prompt.listeningmind.ai/llms.txt): Finds what consumers ask AI and builds managed brand prompts with AI visibility (MCP `https://daas-prompt.listeningmind.ai/mcp`)
- [Pulse Finder](https://daas-pulse.listeningmind.ai/llms.txt): What is rising in search for a gender and age segment right now (MCP `https://daas-pulse.listeningmind.ai/mcp`)
- [Smart Store Suite](https://daas-store.listeningmind.ai/llms.txt): Which Smart Store products to grow, and how to rewrite their titles and detail pages in searchers' words (MCP `https://daas-store.listeningmind.ai/mcp`)
- [Taste Finder](https://daas-taste.listeningmind.ai/llms.txt): In what sensory and emotional words do people choose this (consumer taste report from search data) (MCP `https://daas-taste.listeningmind.ai/mcp`)
- [ListeningMind Data API](https://daas.listeningmind.ai/llms.txt): the search data behind every app (MCP `https://daas.listeningmind.ai/mcp`) · [glossary](https://daas.listeningmind.ai/en/glossary) · [all apps](https://daas.listeningmind.ai/en/apps)

## All tools
### list_projects
Lists all brand wiki projects: {projects:[{projectId, brandName, domain, seedUrl, language, country, industry, crawlSettings, status, createdAt, updatedAt}]}. status moves created -> discovered -> crawling -> crawled -> analyzed. Read only, free. Usually followed by: get_project.
`GET /api/projects`

### create_project
Creates a project for one brand website. Only seedUrl is required; brandName defaults to the host name, language and country are normalized (empty language is detected from content later). Returns {project} with projectId (HTTP 201). Changes saved data in the app; no credits. Usually followed by: discover_urls.
`POST /api/projects`
- `seedUrl` (required): Brand site URL to start from, e.g. https://www.example.com/.
- `brandName`: Brand name used in analysis prompts, wiki titles and the brand MCP; defaults to the host name.
- `country`: Market. Decides which ListeningMind market demand data comes from (only KR, JP, US have data; others are refused for demand) and the default language. Empty = guessed from domain TLD and language. Names like 한국 or kr are normalized.
- `language`: Preferred report language. Empty = market default or detected. Note: the analysis decides the output language from the crawled pages first (html lang majority, then script), and uses this setting only when pages give no clear signal.
- `industry`: Industry text given to the analysis as context, e.g. B2B SaaS.
- `maxPages`: Max pages to crawl. More pages give more entities and claims and longer analysis. Default from settings (80 unless changed).
- `maxDepth`: Max link depth for discovery (default from settings, 3).
- `competitors`: Competitor names.
- `priorityCategories`: Priority categories.
- `includePaths`: Only crawl these path prefixes.
- `excludePaths`: Skip these path prefixes (default from settings).
- `respectRobots`: Respect robots.txt (default true).
- `includeNoindex`: Also keep noindex pages (default false).

### get_project
Returns everything stored for a project: {project, discovery, pages, analysis (entities, wiki pages, claims, schema), connector (demand keywords), actionPlan, entityGap, generatedPages, pageSignals, categoryContext}. Can be large. Read only, free.
`GET /api/projects/{project_id}`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.

### update_crawl_settings
Updates crawl settings of a project before crawling. maxPages is clamped to 1-1000 and maxDepth to 1-10. Returns {project}. Changes saved data in the app; no credits.
`PATCH /api/projects/{project_id}`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.
- `crawlSettings` (required): {maxPages 1-1000, maxDepth 1-10, includePaths: [string], excludePaths: [string]}; send only what changes. The UI sends maxPages right before crawling.

### delete_project
Deletes a project and all its data. Returns {ok:true}. Deletes data. A person approves it first.
`DELETE /api/projects/{project_id}`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.

### discover_urls
Collects candidate URLs from the site's sitemaps and links and reads robots.txt to judge AI crawler access. Pass robotsOnly='1' to only re-read robots.txt for an existing discovery. Returns {discovery:{urls:[{url, included, ...}], ...}}. Changes saved data in the app; no credits. Time: 10 seconds to a few minutes. Usually followed by: crawl_pages.
`POST /api/projects/{project_id}/discover`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.
- `robotsOnly`: '1' = only refresh robots.txt access, keep the URL list.

### crawl_pages
Crawls pages and stores their text. With no urls it crawls every discovered URL marked included (capped by maxPages). Waits until done (up to 5 minutes). Returns {crawled, successful, failed}. Spends ListeningMind Data API credits or paid model calls. Over MCP a person approves it first (you get a confirm link); in the browser the page asks the person. Cost: free (no credits); fetches the brand's site. Time: up to 5 minutes. Usually followed by: start_entity_analysis.
`POST /api/projects/{project_id}/crawl`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.
- `urls`: Specific URLs to crawl; omit to crawl the included discovered URLs.

### start_entity_analysis
Starts the AI analysis of the crawled pages: entity map (core, supporting, context), brand wiki pages, evidence claims and schema. Runs in the background; returns {started:true} or 409 {reason:'already-running'}. Poll get_analysis_status. Spends ListeningMind Data API credits or paid model calls. Over MCP a person approves it first (you get a confirm link); in the browser the page asks the person. Cost: paid LLM calls on the server (Gemini, OpenAI, Anthropic or MiniMax, whichever key is set); no Data API credits. Time: 1-10 minutes depending on page count. Usually followed by: get_analysis_status.
`POST /api/projects/{project_id}/analyze`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.

### get_analysis_status
Returns {status:{state (idle, running, done, error), startedAt, finishedAt, message, progress:{pagesCited, totalPages, entities, elapsedSec}}, claudeAvailable}. Repeat until state is done or error. Read only, free. Waits up to about 45 s for 'status.state' to reach done, error, idle; call again if not done. Usually followed by: get_analysis.
`GET /api/projects/{project_id}/analyze`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.

### get_analysis
Returns {analysis}: entities with types, layers, descriptions, CEPs, attributes and evidence; brand wiki pages; claims with source URLs; review status. null before analysis. Read only, free.
`GET /api/projects/{project_id}/analysis`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.

### save_analysis
Replaces the whole analysis object, as the in-app editor does when you edit an entity or wiki page or change review status. Send the full analysis from get_analysis with your edits. Returns {ok:true}. Changes saved data in the app; no credits.
`PUT /api/projects/{project_id}/analysis`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.
- `analysis` (required): Full analysis object (same shape as get_analysis.analysis).

### get_demand_data
Returns the project's demand connector: {connector:{source, importedAt, items:[{keyword, intent, cep, monthlyVolume, trend, relatedEntity, note}]}} or null. Read only, free.
`GET /api/projects/{project_id}/connector`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.

### import_demand_data
Saves demand keywords you already have. Send exactly one of items, csv (header keyword,volume,intent,cep,trend,note; Korean headers also work) or json (a JSON string of an array or {items}). Replaces the current connector. Returns {connector}. Changes saved data in the app; no credits.
`PUT /api/projects/{project_id}/connector`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.
- `items`: Demand items [{keyword, monthlyVolume, intent, cep, trend, relatedEntity, note}].
- `csv`: CSV text with a header row.
- `json`: JSON text: an array of items or {items:[...]}.
- `source`: Source label (default listeningmind).

### check_live_demand_fetch
Tells whether the server can fetch demand directly from ListeningMind for this project: {available, market:{code, name, gl}, marketSupported, message}. Only KR, JP and US markets have data. Read only, free. Usually followed by: fetch_demand_live.
`GET /api/projects/{project_id}/connector/fetch-direct`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.

### fetch_demand_live
Server calls the ListeningMind Data API: expands related keywords from up to 5 seed keywords (cluster_finder rels), then gets volume and trend for up to about 120 candidates (keyword_info), keeps those with volume, and saves them as the demand connector. Returns {imported, source}; 409 no-credentials or unsupported-market. Spends ListeningMind Data API credits or paid model calls. Over MCP a person approves it first (you get a confirm link); in the browser the page asks the person. Cost: ListeningMind Data API credits: up to 5 cluster_finder calls plus keyword_info for up to about 120 keywords. Time: up to 2 minutes. Usually followed by: start_action_plan.
`POST /api/projects/{project_id}/connector/fetch-direct`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.

### prepare_demand_handoff
Writes a FETCH-LM.md instruction file into the project folder and returns {command, gl, market, marketSupported, seeds} so a Claude Code session with the ListeningMind MCP can collect demand and write connector.json. No credits by itself. Changes saved data in the app; no credits.
`POST /api/projects/{project_id}/connector/fetch`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.

### list_ontology_runs_for_demand
Lists existing Intent KG (topic ontology) runs that can be imported as demand data, optionally filtered by topic text and market. Returns {runs:[{runId, topic, gl, ...}]}. Never builds. Read only, free.
`GET /api/projects/{project_id}/connector/fetch-ontology`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.
- `q`: Topic text filter.
- `gl`: Market code.

### import_demand_from_ontology
Imports the decision layer of one existing Intent KG run as the project's demand connector. Give runId, or topic (+gl) to match a run. Never builds a new run. Returns {imported, connector, stats}; 404 no-match when no run exists. Changes saved data in the app; no credits. Usually followed by: start_action_plan.
`POST /api/projects/{project_id}/connector/fetch-ontology`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.
- `runId`: KG run id.
- `topic`: Topic to match when runId is not given.
- `gl`: Market code for topic matching.
- `cap`: Max demand items to import (server default when omitted).

### start_action_plan
Builds the action plan that maps demand keywords to entities and content actions. Needs an analysis and demand data. Runs in the background; returns {started:true}. Poll get_action_plan_status, then read actionPlan from get_project. Spends ListeningMind Data API credits or paid model calls. Over MCP a person approves it first (you get a confirm link); in the browser the page asks the person. Cost: paid LLM calls on the server (Gemini, OpenAI, Anthropic or MiniMax, whichever key is set); no Data API credits. Time: 1-5 minutes. Usually followed by: get_action_plan_status.
`POST /api/projects/{project_id}/actionplan`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.

### get_action_plan_status
Returns {status:{state, message, ...}, claudeAvailable}. Repeat until done or error; the plan itself is in get_project.actionPlan. Read only, free. Waits up to about 45 s for 'status.state' to reach done, error, idle; call again if not done. Usually followed by: get_project.
`GET /api/projects/{project_id}/actionplan`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.

### save_action_plan
Saves the full action plan after edits such as changing an action item's status. Send the full actionPlan object. Returns {ok:true}. Changes saved data in the app; no credits.
`PUT /api/projects/{project_id}/actionplan`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.
- `actionPlan` (required): Full actionPlan object (from get_project).

### start_entity_gap
Finds entities and facts the brand should cover but does not (uses demand data as a hint if present). Needs an analysis. Background job; returns {started:true}. Poll get_entity_gap_status, then read entityGap from get_project. Spends ListeningMind Data API credits or paid model calls. Over MCP a person approves it first (you get a confirm link); in the browser the page asks the person. Cost: paid LLM calls on the server (Gemini, OpenAI, Anthropic or MiniMax, whichever key is set); no Data API credits. Time: 1-5 minutes. Usually followed by: get_entity_gap_status.
`POST /api/projects/{project_id}/entitygap`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.

### get_entity_gap_status
Returns {status:{state, message, ...}, claudeAvailable}. Repeat until done or error. Read only, free. Waits up to about 45 s for 'status.state' to reach done, error, idle; call again if not done. Usually followed by: get_project.
`GET /api/projects/{project_id}/entitygap`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.

### save_entity_gap
Saves the full entity gap report after edits such as a gap status toggle. Returns {ok:true}. Changes saved data in the app; no credits.
`PUT /api/projects/{project_id}/entitygap`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.
- `entityGap` (required): Full entityGap report (from get_project).

### start_coverage
Checks how well the site covers the entities and demand (questions AI assistants would ask). Needs an analysis. Background job; returns {started:true}. Poll get_coverage. Spends ListeningMind Data API credits or paid model calls. Over MCP a person approves it first (you get a confirm link); in the browser the page asks the person. Cost: paid LLM calls on the server (Gemini, OpenAI, Anthropic or MiniMax, whichever key is set); no Data API credits. Time: 1-5 minutes. Usually followed by: get_coverage.
`POST /api/projects/{project_id}/coverage`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.

### get_coverage
Returns {status:{state, message}, report, claudeAvailable}. Repeat until state is done or error; report holds the coverage result. Read only, free. Waits up to about 45 s for 'status.state' to reach done, error, idle; call again if not done.
`GET /api/projects/{project_id}/coverage`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.

### start_page_signals
Scores crawled pages for AI-readability signals (structure, schema, entity clarity, demand fit). Needs analysis and crawled pages. Background job; returns {started:true}. Poll get_page_signals. Spends ListeningMind Data API credits or paid model calls. Over MCP a person approves it first (you get a confirm link); in the browser the page asks the person. Cost: paid LLM calls on the server (Gemini, OpenAI, Anthropic or MiniMax, whichever key is set); no Data API credits. Time: 1-5 minutes. Usually followed by: get_page_signals.
`POST /api/projects/{project_id}/page-signals`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.

### get_page_signals
Returns {status:{state, message}, report, claudeAvailable}. Repeat until state is done or error. Read only, free. Waits up to about 45 s for 'status.state' to reach done, error, idle; call again if not done.
`GET /api/projects/{project_id}/page-signals`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.

### generate_entity_page
Generates a draft canonical page (text and schema) for one entity of the analysis. Background job; returns {started:true}. Poll get_page_generation_status; the result appears in get_project.generatedPages. Spends ListeningMind Data API credits or paid model calls. Over MCP a person approves it first (you get a confirm link); in the browser the page asks the person. Cost: paid LLM calls on the server (Gemini, OpenAI, Anthropic or MiniMax, whichever key is set); no Data API credits. Time: about 1-3 minutes. Usually followed by: get_page_generation_status.
`POST /api/projects/{project_id}/generate-page`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.
- `entityId` (required): Entity id from the analysis.

### get_page_generation_status
Returns {status, aiAvailable}. status describes the current or last page generation job (state, entityId, message). Repeat until done or error. Read only, free. Waits up to about 45 s for 'status.state' to reach done, error, idle; call again if not done. Usually followed by: get_project.
`GET /api/projects/{project_id}/generate-page`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.

### list_ontology_runs_for_context
Lists existing Intent KG runs whose knowledge layer can be imported as category context for the wiki. Returns {runs}. Never builds. Read only, free.
`GET /api/projects/{project_id}/wiki/fetch-ontology-context`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.
- `q`: Topic text filter.
- `gl`: Market code.

### import_category_context
Imports one KG run's knowledge layer (conventions, heuristics, trade-offs, benchmarks, pitfalls) as the project's category context, cited at the bottom of wiki pages. Give runId, or topic (+gl). Returns {imported, context, stats}. Changes saved data in the app; no credits.
`POST /api/projects/{project_id}/wiki/fetch-ontology-context`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.
- `runId`: KG run id.
- `topic`: Topic to match when runId is not given.
- `gl`: Market code for topic matching.
- `cap`: Max context items to import (server default when omitted).

### get_kg_link
Returns the project's link to the Intent KG: matched run digest (run_id, topic, type counts), candidates and any build in progress. refresh='1' re-matches automatically; topic (+gl) matches a given topic. 0 credits. Read only, free.
`GET /api/projects/{project_id}/kg`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.
- `refresh`: '1' = ignore the cached link and match again.
- `topic`: Topic to match.
- `gl`: Market code.

### match_kg_topic
Matches the project to an existing KG run for the given topic and saves the link. Returns {link}. 0 credits. Changes saved data in the app; no credits.
`POST /api/projects/{project_id}/kg`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.
- `topic` (required): Topic to match.
- `gl`: Market code.

### request_kg_build
Asks the Intent KG app to build a new topic graph for this project (sends build:true and confirm:true). Returns {link} with link.building.jobId; poll get_kg_build. Spends ListeningMind Data API credits or paid model calls. Over MCP a person approves it first (you get a confirm link); in the browser the page asks the person. Cost: about 20,000-50,000 Data API credits per build. Time: several minutes. Usually followed by: get_kg_build.
`POST /api/projects/{project_id}/kg`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.
- `topic` (required): Topic to build.
- `gl`: Market code.

### get_kg_build
Returns {job:{status, ...}, link}. When status is done the link is refreshed to the new run. Repeat until done or error. Read only, free. Waits up to about 45 s for 'job.status' to reach done, error; call again if not done.
`GET /api/projects/{project_id}/kg`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.
- `poll` (required): Build job id from request_kg_build (link.building.jobId).

### ask_dual_demo
Answers one question twice: from internal brand knowledge only, and from brand knowledge plus live ListeningMind search demand for the most related entity. Returns {internal, combined, evidence:{wiki, market}}. Spends ListeningMind Data API credits or paid model calls. Over MCP a person approves it first (you get a confirm link); in the browser the page asks the person. Cost: 2 paid LLM calls plus ListeningMind Data API credits (cluster_finder rels and keyword_info for up to 40 keywords). Time: 10-60 seconds.
`POST /api/projects/{project_id}/mcp-demo`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.
- `question` (required): Question about the brand.

### get_brand_mcp_info
Describes the per-project brand knowledge MCP server (JSON-RPC 2.0 over POST to the same path): service name, transport, endpoint and tool names (search_wiki, list_entities, read_entity, search_market, gap_report, category_kg). Read only, free.
`GET /api/projects/{project_id}/mcp`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.

### export_project
Downloads project data. format: markdown (wiki), json (whole bundle), entities-csv, claims-csv, jsonld (schema.org), llms-txt, connector (demand JSON), connector-csv. Sent as an attachment. Read only, free.
`GET /api/projects/{project_id}/export`
- `project_id` (required): Project id (12 hex chars) from list_projects or create_project.
- `format`: Export format.

### get_settings
Returns {settings:{defaultMaxPages, defaultMaxDepth, defaultExcludePaths, respectRobots}} applied to new projects. Read only, free.
`GET /api/settings`

### update_settings
Updates defaults for new projects. defaultMaxPages is clamped to 1-1000 and defaultMaxDepth to 1-10. Returns {settings}. Changes saved data in the app; no credits.
`PUT /api/settings`
- `defaultMaxPages`: Default max pages.
- `defaultMaxDepth`: Default max depth.
- `defaultExcludePaths`: Default excluded path prefixes.
- `respectRobots`: Respect robots.txt by default.

