Documentation

Documentation / Integrations

MCP (AI assistants)

MCP (Model Context Protocol) lets AI assistants like Claude operate Power Author through a set of structured tools — keyword research, modifier authoring, combination editing, and public hub setup — using a project-bound API key.

What MCP is

MCP is an open protocol for exposing tools and resources to AI assistants. Power Author ships an MCP server at /api/mcp; once you connect it to your assistant of choice, the assistant can call tools like list_combinations, add_keyword, update_combination, and more — exactly the same operations available in the dashboard, just driven by the assistant.

Prerequisites

  • Generate an MCP API key in Workspace Settings → MCP & Tools. You can scope it to a single project (recommended for most workflows) or leave it workspace-wide and pass projectId on each tool call.
  • Add the server to your assistant. The connect card on the same settings page provides ready-to-paste configs for Cursor, Claude Code, and Claude Desktop.
  • Workspace-wide keys: call list_projects first to find the right projectId for the project you want to work in.

Combination public hub workflow

For the underlying concepts — what a hub page is, when to use one, the three layout options, required fields — see Combinations → Public Hub Pages. The MCP tools below are the operational surface.

Which layout to pick

  • grouped (default) — section per IMMEDIATE parent of each article's varying-tag. Best for shallow (1–2 level) role trees, or when you want every L2 visible as its own section.
  • grouped_by_top — section per TOP-LEVEL (L1) ancestor. Best for 3+ level trees (e.g. field → role → niche), so all articles in a field sit together under one section.
  • flat — one grid, no section headings. Best when there's no meaningful grouping or very few articles.

Operations

  • Enable hub: update_combination with { id, publishAsHub: true, slug: "cover-letter-examples", hubNavStyle: "grouped_by_top" }. hubNavStyle defaults to "grouped" when omitted.
  • Switch layout on a published hub: update_combination with { id, hubNavStyle: "grouped_by_top" }. This does NOT call unpublish — the new layout ships on the next Push hub to site or full publish run.
  • Author copy: upsert_combination_hub_copy with { combinationId, languageCode: "en", title, description, metaDescription }. At least one of the three text fields is required; omitted fields are left untouched on update.
  • Read back / verify: get_combination returns core combination columns (including hubNavStyle) plus a translations map keyed by language code. list_combinations returns the same hub fields across every combination in one call — useful for auditing layouts.
  • Disable hub: update_combination with { id, publishAsHub: false }. This triggers a destination unpublish call BEFORE the toggle is persisted; if the unpublish fails, the toggle change is not applied and the tool returns an error.

Modifier descriptions workflow

  • Find candidates: list_modifiers with { groupName: "role", level: 1 } returns all L1 role modifiers, now including their current description for the project's default (source) language.
  • Author one: update_modifier_description with { modifierId, description }. When languageCode is omitted the project's default language is used — matching the typical “set the English description” flow.
  • Author many: bulk_update_modifier_descriptions with { updates: [{ modifierId, description }, ...] }. Recommended for the “describe every L1 role” workflow. Returns per-row success or error.
  • Other locales come from the workspace Translate Taxonomy run; manual writes to non-source locales are allowed but may be overwritten by a later translation run.

Worked example — cover-letter hub grouped by field (L1)

Mirroring the example in Combinations → Public Hub Pages: a cover-letter-examples hub for a job-posting platform whose role tree has three levels (field → role → niche), so we want one section per field. End-to-end as MCP tool calls (the platform stays anonymous):

// 1. Find the combination you want to publish as a hub, and inspect
//    its current settings + copy before changing anything.
list_combinations({})            // returns hubNavStyle on every row
get_combination({ id: 12 })      // detail for the chosen combination

// 2. Enable the hub with the L1 layout in one call. The role tree under
//    this combination has 3 levels, so 'grouped_by_top' (one section per
//    field) is the right pick.
update_combination({
  id: 12,
  publishAsHub: true,
  slug: "cover-letter-examples",
  hubNavStyle: "grouped_by_top"
})

// 3. Author the source-language hub copy (H1, intro, SEO meta).
upsert_combination_hub_copy({
  combinationId: 12,
  languageCode: "en",
  title: "Cover Letter Examples for 1,000+ Roles",
  description: "Browse cover letter examples for over a thousand job titles, organized by field. Each example shows two formats side by side, with notes on when to use each.",
  metaDescription: "Cover letter examples for 1,000+ job titles, organized by field. See traditional and modern formats side by side."
})

// 4. Author one description paragraph per L1 (field) modifier - these
//    render as the intro under each section heading on the hub.
list_modifiers({ groupName: "role", level: 1 })   // returns existing description for source language
bulk_update_modifier_descriptions({
  updates: [
    { modifierId: 101, description: "Healthcare roles spanning patient care, clinical support, and allied health." },
    { modifierId: 102, description: "Engineering roles across software, hardware, and infrastructure." },
    { modifierId: 103, description: "Education roles from early childhood through higher education." }
  ]
})

// 5. Verify before the next publish run.
get_combination({ id: 12 })

// --- Migration variant ---------------------------------------------------
// Switch an EXISTING 'grouped' hub (parent-walk) to 'grouped_by_top' (L1
// buckets). Safe in-place change - no unpublish call. The new layout ships
// on the next 'Push hub to site' or full publish run.

update_combination({ id: 12, hubNavStyle: "grouped_by_top" })

// --- Audit variant -------------------------------------------------------
// See every combination's hub settings in one call (publishAsHub, slug,
// hubNavStyle), then drill in for the ones that need attention.
list_combinations({})

Field reference

  • publishAsHub — boolean toggle on combinations; OFF by default.
  • slug — public hub URL segment on combinations (the path on the destination is /career-advice/{slug} on Specific Resume). Distinct from slugTemplate, which is the per-article URL slug template (e.g. {{role}}-resume-examples).
  • hubNavStyle — one of "grouped" (default; section per IMMEDIATE parent of each article's varying-tag), "grouped_by_top" (section per TOP-LEVEL/L1 ancestor — recommended for 3+ level role trees), or "flat" (single grid, no sections). See the decision aid above and the dedicated Public Hub Pages page.
  • title, description, metaDescription per locale on combination_translations (keyed by (combinationId, languageId)).
  • modifier_translations.description per locale (keyed by (modifierId, languageId)) — the per-section intro paragraph rendered above each L1 bucket on grouped hub pages. There is no description column on modifiers itself.

Caveats & errors

  • Toggling publishAsHub from true to false fires an unpublish call to the destination site BEFORE persisting. If that call fails (network, 5xx, etc.), the toggle change is rolled back and update_combination returns an error so PA's view of the combination matches what the destination is actually serving.
  • REST and MCP share the same upsert helpers under the hood, so dashboard edits and MCP edits cannot drift apart.
  • Source-language descriptions are typically the only ones authored by hand — let the workspace Translate Taxonomy run handle the rest.