brand_build_matrix
Generate messaging variants for every persona and buying stage. View the matrix as a grid or edit specific variants by ID to refine core messages.
Instructions
Generate persona x journey stage messaging variants — adapted core messages for every audience at every buying stage. Mode 'generate' creates variants using persona tensions, stage mindsets, and brand perspective. Mode 'view' shows the matrix as a grid. Mode 'edit' refines a specific variant by ID. Requires personas and journey stages in strategy.yaml. Returns variant grid with status tracking (Draft/Active/Retired).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | 'generate' creates messaging variants for every persona × stage; 'view' returns the matrix as a grid; 'edit' updates a specific variant by ID | generate |
| variant_id | No | ID of the variant to edit (required for mode='edit', e.g. MV-001) | |
| answers | No | JSON string with variant fields to update: core_message, tone_shift, proof_points, status (for mode='edit') |
Implementation Reference
- src/tools/brand-build-matrix.ts:581-619 (handler)Main handler function that dispatches to handleGenerate, handleView, or handleEdit based on input.mode
async function handler(input: Params) { const brandDir = new BrandDir(process.cwd()); if (!(await brandDir.exists())) { return buildResponse({ what_happened: "No .brand/ directory found", next_steps: ["Run brand_start first to create a brand system"], data: { error: ERROR_CODES.NOT_INITIALIZED }, }); } switch (input.mode) { case "generate": return handleGenerate(brandDir); case "view": return handleView(brandDir); case "edit": { if (!input.variant_id) { return buildResponse({ what_happened: "Missing required parameter: variant_id", next_steps: ["Provide variant_id (e.g. MV-001) to identify which variant to edit"], data: { error: ERROR_CODES.MISSING_VARIANT_ID }, }); } if (!input.answers) { return buildResponse({ what_happened: "Missing required parameter: answers", next_steps: [ "Provide answers as a JSON string with fields to update: core_message, tone_shift, proof_points, status", ], data: { error: ERROR_CODES.MISSING_ANSWERS }, }); } return handleEdit(brandDir, input.variant_id, input.answers); } } } - Zod schema defining params: mode (enum: generate/view/edit), variant_id (optional string), answers (optional JSON string)
const paramsShape = { mode: z .enum(["generate", "view", "edit"]) .default("generate") .describe( "'generate' creates messaging variants for every persona × stage; 'view' returns the matrix as a grid; 'edit' updates a specific variant by ID" ), variant_id: z .string() .optional() .describe("ID of the variant to edit (required for mode='edit', e.g. MV-001)"), answers: z .string() .optional() .describe( "JSON string with variant fields to update: core_message, tone_shift, proof_points, status (for mode='edit')" ), }; const ParamsSchema = z.object(paramsShape); type Params = z.infer<typeof ParamsSchema>; - src/tools/brand-build-matrix.ts:625-636 (registration)Registers the brand_build_matrix tool with McpServer, binding params schema to handler
export function register(server: McpServer) { server.tool( "brand_build_matrix", "Generate persona x journey stage messaging variants — adapted core messages for every audience at every buying stage. Mode 'generate' creates variants using persona tensions, stage mindsets, and brand perspective. Mode 'view' shows the matrix as a grid. Mode 'edit' refines a specific variant by ID. Requires personas and journey stages in strategy.yaml. Returns variant grid with status tracking (Draft/Active/Retired).", paramsShape, async (args) => { const parsed = safeParseParams(ParamsSchema, args); if (!parsed.success) return parsed.response; return handler(parsed.data); } ); } - src/server.ts:27-88 (registration)Import and registration call in createServer, placing it in Session 4: Content Strategy
import { register as registerBuildMatrix } from "./tools/brand-build-matrix.js"; import { register as registerBuildThemes } from "./tools/brand-build-themes.js"; import { register as registerExport } from "./tools/brand-export.js"; import { register as registerSetLogo } from "./tools/brand-set-logo.js"; import { register as registerFeedback } from "./tools/brand-feedback.js"; import { register as registerAuditContent } from "./tools/brand-audit-content.js"; import { register as registerCheckCompliance } from "./tools/brand-check-compliance.js"; import { register as registerAuditDrift } from "./tools/brand-audit-drift.js"; import { register as registerRuntime } from "./tools/brand-runtime.js"; import { register as registerCheck } from "./tools/brand-check.js"; import { register as registerPreview } from "./tools/brand-preview.js"; import { register as registerExtractVisual } from "./tools/brand-extract-visual.js"; import { register as registerExtractPdf } from "./tools/brand-extract-pdf.js"; import { register as registerResolveConflicts } from "./tools/brand-resolve-conflicts.js"; import { register as registerBrandcodeAuth } from "./tools/brand-brandcode-auth.js"; import { register as registerBrandcodeConnect } from "./tools/brand-brandcode-connect.js"; import { register as registerBrandcodeSync } from "./tools/brand-brandcode-sync.js"; import { register as registerBrandcodeStatus } from "./tools/brand-brandcode-status.js"; import { register as registerBrandcodeLive } from "./tools/brand-brandcode-live.js"; import { register as registerRepoConnect } from "./tools/brand-repo-connect.js"; import { register as registerRepoStatus } from "./tools/brand-repo-status.js"; import { register as registerEnrichSkill } from "./tools/brand-enrich-skill.js"; export function createServer(): McpServer { const server = new McpServer({ name: "brandsystem", version: getVersion(), }); // ── Entry points (register first — agents see these first) ── registerStart(server); // #1: Entry point for new brands registerStatus(server); // #2: "What can I do?" / resume point // ── Session 1: Core Identity ── registerExtractWeb(server); // Extract from website (CSS parsing) registerExtractVisual(server); // Extract from website (headless Chrome + vision) registerExtractSite(server); // Extract from website (multi-page rendered crawl) registerExtractPdf(server); // Extract from PDF guidelines registerResolveConflicts(server); // Compare and resolve source conflicts registerGenerateDesignMd(server); // Generate design-synthesis.json + DESIGN.md registerExtractFigma(server);// Extract from Figma registerSetLogo(server); // Add/replace logo manually registerCompile(server); // Generate tokens + VIM registerClarify(server); // Resolve ambiguous values registerAudit(server); // Validate .brand/ directory registerReport(server); // Generate HTML report registerInit(server); // Low-level init (prefer brand_start) // ── Session 2: Visual Identity ── registerDeepenIdentity(server); registerIngestAssets(server); registerPreflight(server); // ── Session 3: Messaging ── registerExtractMessaging(server); registerCompileMessaging(server); // ── Session 4: Content Strategy ── registerBuildPersonas(server); registerBuildJourney(server); registerBuildThemes(server); registerBuildMatrix(server); - synthesizeCoreMessage - core intelligence that crafts adapted messages per persona × stage using tensions, mindsets, and brand perspective
function synthesizeCoreMessage( persona: Persona, stage: JourneyStage, perspective: { worldview: string; tension: string; resolution: string; positioning: string } | null ): string { const personaLabel = persona.name || persona.role_tag; const tensionPhrase = persona.core_tension; const mindset = stage.buyer_mindset; const goal = stage.content_goal; const narrativeAngle = persona.narrative_emphasis.primary; // Build the adapted message — branch on stage.id for reliable matching const parts: string[] = []; if (stage.id === "first-touch") { // Provocative, tension-as-hook — earn the click, interrupt the scroll parts.push( `${personaLabel} feels this acutely: ${tensionPhrase}.` ); if (perspective) { parts.push( `The angle here is ${perspective.worldview} — reframed for someone whose mindset is: ${mindset}.` ); } else { parts.push( `At this stage, their mindset is: ${mindset}.` ); } parts.push( `Content goal: ${goal}. Lead with ${narrativeAngle} to earn attention.` ); } else if (stage.id === "context-and-meaning") { // Educational, framework-oriented — give them a lens, not a pitch parts.push( `${personaLabel} is past awareness and looking for a framework. Their tension: ${tensionPhrase}.` ); if (perspective) { parts.push( `Introduce ${perspective.worldview} as the lens — help them see the problem differently. Their mindset: ${mindset}.` ); } else { parts.push( `Help them reframe the problem. Their mindset: ${mindset}.` ); } parts.push( `Content goal: ${goal}. Build depth through ${narrativeAngle} — teach, don't sell.` ); } else if (stage.id === "validation-and-proof") { // Evidence-heavy, concrete outcomes, social proof parts.push( `For ${personaLabel}, the core tension is: ${tensionPhrase}.` ); if (perspective) { parts.push( `At this stage they need proof that ${perspective.resolution}. Their mindset: ${mindset}.` ); } else { parts.push( `At this stage they need proof. Their mindset: ${mindset}.` ); } parts.push( `Content goal: ${goal}. Emphasize ${narrativeAngle} with evidence.` ); } else if (stage.id === "decision-support") { // Direct, action-oriented — remove friction, arm the champion parts.push( `${personaLabel} is ready to decide. Their original tension — ${tensionPhrase} — needs a resolution they can defend to stakeholders.` ); if (perspective) { parts.push( `Position: ${perspective.positioning}. Their mindset: ${mindset}.` ); } else { parts.push( `Their mindset: ${mindset}.` ); } parts.push( `Content goal: ${goal}. Use ${narrativeAngle} to close the loop.` ); } else { // Generic fallback for custom stages parts.push( `For ${personaLabel} (${persona.seniority}), the driving tension is: ${tensionPhrase}.` ); if (perspective) { parts.push( `Ground the message in: ${perspective.worldview}. Their mindset at this stage: ${mindset}.` ); } else { parts.push( `Their mindset at this stage: ${mindset}.` ); } parts.push( `Content goal: ${goal}. Narrative emphasis: ${narrativeAngle}.` ); } return parts.join(" "); }