# Persona Matching

> Load audience personas and match them to ad creatives for tailored copy

Canonical URL: https://fa7e86e3d553:3005/tools/personas

> **MCP v3 routing:** The operation names on this page are retained as action-contract references. Do not call them as top-level tools. Pass the former name to `lexsis_discover`, then call the returned router and action with the documented parameters inside `args`.

Tools for loading audience personas and matching them to ad creatives. Use these to tailor page copy to specific customer segments.

---

## list_personas

Get the audience personas for a workspace — vocabulary, pain points, triggers, and demographics. Use these to personalize page copy and design for specific customer segments.

### Parameters

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `workspace_id` | string (UUID) | Yes | The workspace ID to fetch personas for |

### Returns

Array of `PersonaSummary` objects:
```typescript
{
  id: string                 // Persona UUID
  name: string               // Persona name (e.g. "Busy Professional Moms")
  vocabulary: string[]       // Exact words/phrases this persona uses
  pain_points: string[]      // Specific problems this persona faces
  trigger?: string           // Primary trigger that drives purchase
  description?: string       // Rich persona description
  age_range?: string         // Age range (e.g. "25-40")
  location?: string          // Geographic location
  interests: string[]        // Hobbies and interests
  confidence: number         // Persona confidence score (0-1)
  level: string              // Persona detail level
}
```

### Example

```json
{
  "name": "list_personas",
  "arguments": {
    "workspace_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
  }
}
```

**Response:**
```json
[
  {
    "id": "a1b2c3d4-...",
    "name": "Busy Professional Moms",
    "vocabulary": [
      "quick",
      "reliable",
      "family-safe",
      "multitasking",
      "peace of mind"
    ],
    "pain_points": [
      "Limited time for self-care",
      "Need products that work fast",
      "Want clean ingredients for family"
    ],
    "trigger": "Time-saving solutions",
    "description": "Working mothers aged 30-45 balancing career and family...",
    "age_range": "30-45",
    "interests": ["wellness", "efficient routines", "clean beauty"],
    "confidence": 0.87,
    "level": "high"
  }
]
```

### When to Use

- **Before generating a page** to understand your target audiences
- **After analyzing an ad** to match it to the right persona
- **During copy iteration** to refine messaging for specific segments

---

## match_persona_to_ad

Match an analyzed ad creative to the best-fit persona. Returns persona match score + copy adaptations (rewritten headline, subhead, CTA in the persona's vocabulary).

### Parameters

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `ad_analysis` | AdAnalysis object | Yes | AdAnalysis from `analyze_ad_creative` OR your own vision analysis |
| `workspace_id` | string (UUID) | Yes | Workspace ID to load personas from |
| `top_k` | number (1–5) | No | Number of top persona matches to return (default: 1) |

The `ad_analysis` object can be:
- **Output from `analyze_ad_creative`** (if you're a text-only model)
- **Your own vision analysis** (if you're a vision-capable model — just construct the same shape)

### Returns

`PersonaMatch` object (or array if `top_k > 1`):
```typescript
{
  persona: PersonaSummary           // Matched persona with full details
  match_score: number               // Match confidence (0-1)
  match_reasons: string[]           // Why this persona was chosen
  copy_adaptations: {
    hero_headline_suggestion: string   // Rewritten headline in persona's vocabulary
    subhead_suggestion: string         // Subhead addressing persona pain point
    cta_suggestion: string             // CTA in persona's voice
    pain_point_addressed: string       // Specific pain point this resolves
    tone_notes: string                 // Tone guidance (1-2 sentences)
  }
}
```

### Example

```json
{
  "name": "match_persona_to_ad",
  "arguments": {
    "ad_analysis": {
      "headline": "Your Skin, But Better",
      "key_claims": ["Clinically-tested", "72-hour hydration"],
      "tone": "clinical",
      "persona_signals": ["minimal beauty", "clinical results"]
    },
    "workspace_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "top_k": 1
  }
}
```

**Response:**
```json
{
  "persona": {
    "id": "a1b2c3d4-...",
    "name": "Science-Driven Skincare Users",
    "vocabulary": ["clinically-tested", "proven results", "dermatologist"],
    "pain_points": ["Overwhelmed by marketing hype", "Need evidence-based products"]
  },
  "match_score": 0.89,
  "match_reasons": [
    "vocabulary match: \"clinically-tested\"",
    "pain point match: \"proven results\"",
    "tone alignment: clinical/evidence-based"
  ],
  "copy_adaptations": {
    "hero_headline_suggestion": "Clinically-Proven Hydration That Works",
    "subhead_suggestion": "Dermatologist-tested serum with 72-hour moisture lock",
    "cta_suggestion": "See the Science",
    "pain_point_addressed": "Need evidence-based products without marketing hype",
    "tone_notes": "Speak factually with clinical proof. Avoid emotional language. Lead with data and dermatologist validation."
  }
}
```

### When to Use

**Workflow:**
1. **Analyze the ad** (via `analyze_ad_creative` or your own vision analysis)
2. **Match to persona** (this tool)
3. **Use `copy_adaptations`** in page generation — replace generic copy with the persona-tailored suggestions

**Vision-capable models:**
You can skip `analyze_ad_creative` and construct the `AdAnalysis` object directly:
```json
{
  "ad_analysis": {
    "headline": "Get Glowing Skin",
    "key_claims": ["Natural ingredients", "Instant glow"],
    "tone": "playful",
    "persona_signals": ["self-care", "natural beauty"]
  },
  "workspace_id": "..."
}
```

**Text-only models:**
Chain `analyze_ad_creative` → `match_persona_to_ad`:
```typescript
const analysis = await analyze_ad_creative({ ad_format: "image", image_urls: [...] });
const match = await match_persona_to_ad({ ad_analysis: analysis, workspace_id: "..." });
```

---

## Best Practices

1. **Always call `list_personas` first** to understand available segments
2. **Use `top_k: 3`** when you're unsure which persona fits best — compare match scores
3. **Apply `copy_adaptations` faithfully** — they use the persona's exact vocabulary
4. **Chain the workflow**: `analyze_ad_creative` → `match_persona_to_ad` → page generation
5. **Vision-capable models**: Skip `analyze_ad_creative` and pass your own vision analysis to save API calls
