> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wisepilot.app/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Tool Reference

> The 8 explore/query domains and 4 atomic orchestration tools that power WisePilot's MCP surface — for Claude, ChatGPT, and any MCP-compatible client.

WisePilot exposes its full surface area through **8 domain pairs** (`{domain}_explore` + `{domain}_query`) plus **4 atomic orchestration tools**. This is the recommended way to use the MCP server from Claude, ChatGPT projects, or any MCP client — the agent discovers operations dynamically rather than memorizing 100+ individual tool names.

<Note>
  The legacy atomic tools (e.g. `get_conversation_metrics`, `list_assets`, `list_ad_creatives`) are still registered and continue to work. New integrations should prefer the explore/query pattern below — it scales better as we add capabilities.
</Note>

## How It Works

Every domain has the same two tools:

1. **`{domain}_explore`** — browse what's available. Returns a category list with operation counts. Drill into a category to see operations with full param schemas + examples.
2. **`{domain}_query`** — execute one operation. Takes `{ operation, params }`.

```bash theme={null}
# 1. See what the metrics domain offers
metrics_explore()

# 2. Drill into one category
metrics_explore({ category: "engagement" })

# 3. Execute an operation
metrics_query({
  operation: "conversation",
  params: { website_id: "abc-123", period: "30d" }
})
```

The agent only needs to remember 16 tool names (8 explore + 8 query) rather than 100+ atomic tools, and discovery is self-documenting.

## The 8 Domains

<CardGroup cols={2}>
  <Card title="intelligence" icon="brain">
    Lifecycle state, work items, content opportunities, AI insights, hypothesis test runs, confirmed learnings, pattern candidates, attribution rollups, runner stats. **12 ops across 4 categories.**
  </Card>

  <Card title="metrics" icon="chart-line">
    GHL conversations / appointments / revenue, Google + Meta Ads, GSC, GA4, GBP, content/CTA performance, client snapshot. **22 ops across 6 categories.**
  </Card>

  <Card title="ads" icon="bullhorn">
    Google Ads + Meta Ads catalog and performance: creatives, ad sets, keywords, search terms, daily timeseries, summaries. **10 ops across 3 categories.**
  </Card>

  <Card title="content" icon="file-lines">
    Library reads: assets, blogs, CTAs, nurture sequences, sequence steps, entities, opportunities, full-text search. **10 ops across 4 categories.**
  </Card>

  <Card title="brand" icon="palette">
    Brand position, guidelines, ICPs, hooks & angles, messaging learnings, operating profile, design tokens, color palettes, image styles, brand subjects. **10 ops across 2 categories.**
  </Card>

  <Card title="ghl" icon="comments">
    GHL CRM browse: conversations + messages, appointments, pipeline stages, opportunities. **5 ops across 3 categories.**
  </Card>

  <Card title="seo_research" icon="magnifying-glass">
    Ahrefs-backed: keyword ideas, bulk metrics, SERP analysis, competitor keywords. *Each call consumes Ahrefs credits.* **4 ops across 2 categories.**
  </Card>

  <Card title="integration" icon="plug">
    Connection state (WordPress, GHL, ad platforms), GHL agents/prompts/KBs/contacts, ad campaigns, sync trigger. **7 ops across 4 categories.**
  </Card>
</CardGroup>

## The 4 Atomic Orchestration Tools

These are stateful or composed actions that don't fit the "browse + execute" pattern.

### `dispatch_lifecycle`

Open or resume a content lifecycle session. Given a content type and intent, returns a chat session id, the current step, the chat hint for that step, and a deep-link URL.

```ts theme={null}
dispatch_lifecycle({
  entity_type: "blog",
  intent: "create",
  inputs: { title: "Outdoor wedding venues", primary_keyword: "wedding venue houston" }
})
// → { session_id, current_step, chat_hint, deep_link_url }
```

**Intents:** `create` (new entity), `edit` (resume edit lifecycle), `optimize` (ad ops), `review` (approval review), `approve` (approval gate).

**Permission:** `write_staging` (or `approve` for `intent: "approve"`).

***

### `promote_learning`

Promote a `pattern_candidate` to a durable `confirmed_learning`. Human-in-the-loop step at the end of the hypothesis-iteration pipeline.

```ts theme={null}
promote_learning({
  pattern_candidate_id: "uuid-here",
  summary: "Hooks that lead with 'the moment' outperform feature-led hooks by 35-50% on Meta carousel ads."
})
// → { confirmed_learning_id, pattern_candidate_id, ... }
```

**Guards:** `win_count >= 2`, `avg_confidence >= 0.6`, no active duplicate (overrideable).

**Permission:** `approve`.

***

### `request_wp_engineer_work`

File an engineering task into the unified inbox under `label='engineer_work'`. Use this when the agent identifies a problem requiring WP / theme / plugin / infra changes (not a content edit).

```ts theme={null}
request_wp_engineer_work({
  title: "Tracking pixel missing on /pricing",
  description: "Confirmed via GTM preview that the meta_lead_pixel is not firing on /pricing. We need to add it to the page template before launch...",
  priority: "high",
  area: "tracking",
  reference_url: "https://example.com/pricing"
})
// → { work_item_id, label: "engineer_work", priority, area }
```

**Permission:** `write_staging`.

***

### `get_image_brief`

Composed read returning a brand-aligned brief that any image-gen client (ChatGPT's built-in image gen, Claude's image renderer) can hand off. Bundles brand position + design tokens + color palette + image style + brand subjects + suggested prompt prefix + do/don't lists.

```ts theme={null}
get_image_brief({
  intent: "Hero for a blog about outdoor wedding venues in Houston",
  preset: "blog_hero"  // square | portrait | landscape | story | meta_feed | meta_story | blog_hero
})
// → { intent, dimensions, brand_position, design_tokens, color_palette, image_style, brand_subjects, do, dont, prompt_prefix }
```

For **server-side** image generation (lifecycle-attached, persisted), use the legacy `generate_image` tool.

**Permission:** `read`.

## Permission Scopes

API keys carry one or more permissions. Each operation declares which it requires; the MCP server returns `403 PERMISSION_DENIED` when missing.

| Permission      | Use cases                                                                                                                                   |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `read`          | All `_explore` calls and read-only `_query` operations.                                                                                     |
| `write_staging` | Create / update entities in staging state — e.g. `intelligence_query` `create_work_item`, `dispatch_lifecycle`, `request_wp_engineer_work`. |
| `push`          | Actions that change external systems — e.g. `integration_query` `trigger_sync`, the legacy `push_to_platform_rest`.                         |
| `approve`       | Approval / promotion gates — e.g. `promote_learning`, approving work items via `dispatch_lifecycle({intent:"approve"})`.                    |

Existing pre-v1 keys are auto-granted all four permissions for backward compatibility. New keys can be scoped to a subset (read-only, write-staging-no-approve, etc).

## Authentication

The MCP endpoint at `https://ai.wisepilot.app/api/v1/mcp` accepts:

* **OAuth 2.1 + PKCE** — Claude.ai, Claude Desktop, Claude Code use this. Identity-tied, automatic refresh.
* **API key (Bearer)** — ChatGPT projects, custom MCP clients, scripts. `Authorization: Bearer cr_...`. Created in **Settings → API Keys**.

API keys can also carry an `expires_at` and a monthly image-gen budget counter, both enforced at the middleware layer.

## Common Patterns

### Discovery before execution

When unsure which operation to call, always `_explore` first.

```bash theme={null}
# Explore overview → pick a category → drill in → execute
metrics_explore()
metrics_explore({ category: "seo" })
metrics_query({ operation: "gsc_pages", params: { website_id, period: "30d", limit: 50 } })
```

### Date ranges (metrics, ads, ghl)

All time-bounded operations accept the same shape:

```ts theme={null}
{
  period: "today" | "7d" | "30d" | "90d" | "mtd" | "ytd"  // default 30d
  // OR
  start_date: "2026-04-01",
  end_date: "2026-04-15"  // overrides period
}
```

### Pagination

`limit` + `offset` on every list-style op. Defaults to `50` items, max `200` for most operations. SEO research and image briefs cap differently — see explore output for per-op limits.

### Error shapes

Every error returns a structured payload the LLM can parse:

```json theme={null}
{
  "error": "limit: must be an integer",
  "code": "INVALID_PARAMS",
  "field": "limit"
}
```

Common codes: `INVALID_PARAMS`, `UNKNOWN_OPERATION`, `PERMISSION_DENIED`, `MISSING_WEBSITE_SCOPE`, `FORBIDDEN_WEBSITE`, `RATE_LIMIT_EXCEEDED`, `API_KEY_EXPIRED`.

## Migration from atomic tools

If you have an existing integration using the per-tool API (e.g. `get_conversation_metrics`, `list_ad_creatives`):

| Old atomic tool            | New equivalent                                      |
| -------------------------- | --------------------------------------------------- |
| `get_conversation_metrics` | `metrics_query({operation:"conversation"})`         |
| `get_appointment_metrics`  | `metrics_query({operation:"appointment"})`          |
| `get_revenue_metrics`      | `metrics_query({operation:"revenue"})`              |
| `get_gsc_pages`            | `metrics_query({operation:"gsc_pages"})`            |
| `get_gsc_queries`          | `metrics_query({operation:"gsc_queries"})`          |
| `list_assets`              | `content_query({operation:"assets"})`               |
| `get_asset_detail`         | `content_query({operation:"asset_detail"})`         |
| `list_ad_creatives`        | `ads_query({operation:"creatives"})`                |
| `get_brand_position`       | `brand_query({operation:"position"})`               |
| `get_design_tokens`        | `brand_query({operation:"design_tokens"})`          |
| `list_conversations`       | `ghl_query({operation:"list"})`                     |
| `get_keyword_ideas`        | `seo_research_query({operation:"keyword_ideas"})`   |
| `get_work_items`           | `intelligence_query({operation:"work_items"})`      |
| `get_lifecycle_status`     | `intelligence_query({operation:"lifecycle_state"})` |
| `trigger_integration_sync` | `integration_query({operation:"trigger_sync"})`     |

The legacy tools remain registered — there's no rush. Migrate when you're updating the integration anyway.

## Reference

* **Strategy doc:** `docs/mcp-tool-surface-strategy.md` (rationale, design decisions, future domains)
* **Reference implementation:** `/Code/base-microservices/apps/open-data/` — the proven explore/query pattern this is based on
* **Source:** `src/features/public-api/server/mcp/router/` (generic dispatcher) and `src/features/public-api/server/mcp/domains/*` (one folder per domain)
