persona_update
Change the sections, the age range or the slug of a persona. The revision that the agent read stops it from overwriting a change that it did not see.
Ask for a change to a persona. The agent changes only the parts that you name.
“The Loyalists say ‘my daily trainer’. Add that to their language.”
The agent reads the persona with persona_get, and then calls persona_update. You then see the new language, and the other sections as they were.
The job guide Describe a brand shows each step of the job.
Reference
Update a persona. Pass base_revision (from persona_get) — the update is rejected if the persona changed since you read it. Only the fields you pass are changed; pass null for a section or age bound to clear it. Optionally rename the slug handle.
Input
| Argument | Type | Required | Description |
|---|---|---|---|
age_max |
integer, 0 to 120 or null | no | New upper age bound. Pass null to clear it (“and older”). |
age_min |
integer, 0 to 120 or null | no | New lower age bound. Pass null to clear it (“and younger”). |
base_revision |
integer | yes | The revision you last read via persona_get. Guards against overwriting a concurrent edit. |
brand_name |
string | yes | The slug of the brand that owns the persona. |
description |
string | no | New one-line summary. |
frictions |
string or null | no | New objections and barriers. Pass null to clear the section. |
language |
string or null | no | New voice-of-customer wording — the audience’s own words, not a locale. Pass null to clear the section. |
motivations |
string or null | no | New jobs, triggers and outcomes. Pass null to clear the section. |
name |
string | no | New display name. |
persona_name |
string | yes | The current persona slug identifying which to update. |
profile |
string or null | no | New description of who they are. Pass null to clear the section. |
slug |
string | no | Optional new slug handle (a deliberate rename); normalized to kebab-case. Callers of the old handle must be updated. |
Output
A successful call returns this object in structuredContent.
| Field | Type | Always present | Description |
|---|---|---|---|
persona |
object | yes | The persona in full. |
persona.ageMax |
integer, 0 to 120 or null | yes | The highest age of the audience. null when the range has no upper bound. |
persona.ageMin |
integer, 0 to 120 or null | yes | The lowest age of the audience. null when the range has no lower bound. |
persona.brandId |
string | yes | The brand that owns the persona (brd_…). |
persona.createdAt |
number | yes | Milliseconds since the Unix epoch, in UTC. |
persona.createdBy |
string | yes | The user who created the record (usr_…). |
persona.description |
string | yes | One line about the persona. An agent picks a persona on it. |
persona.frictions |
string or null | yes | What stops the audience: objections, doubts, perceived risk. Markdown. null when the section is not written. |
persona.id |
string | yes | The id of the persona (psn_…). |
persona.language |
string or null | yes | The words that the audience uses for the problem. It is not a locale. Markdown. null when the section is not written. |
persona.motivations |
string or null | yes | What the audience wants: jobs to be done, triggers, outcomes. Markdown. null when the section is not written. |
persona.name |
string | yes | The display name. |
persona.profile |
string or null | yes | Who the audience is: life stage, situation, role. Markdown. null when the section is not written. |
persona.revision |
number | yes | The version of the record. Each change adds 1. Send it as base_revision to update or delete the record. |
persona.slug |
string | yes | The handle of the persona. It is unique in its brand, not in the organization. The tools take it as persona_name. |
persona.updatedAt |
number or null | yes | Milliseconds since the Unix epoch, in UTC. null until the first change. |
Failure codes
A failed call has isError set, and structuredContent.error holds one of these codes. Errors describes the shape of a failed call.
not_foundinvalid_sluginvalid_age_rangerevision_mismatchslug_conflictforbiddeninvalid_requestinternal_error
Scope
The token must hold brand:write. Auth & scopes lists each scope.
Annotations
A client reads these hints. A hint that the tool does not declare has the default value of the MCP specification.
- Writes. The tool can change data.
- Destructive. The tool can make a change that you cannot undo. A client can ask you to confirm before it calls the tool.
- Not idempotent. A second call with the same arguments can change more.
- Closed world. The tool reads and writes the data of AdCrunch only.
Example
The arguments:
{
"base_revision": 1,
"brand_name": "acme",
"language": "They say \"my daily trainer\" and \"I got 900 out of the last pair\". They ask about the drop and the stack, never about the technology.",
"motivations": "They want the same shoe again, and proof that it is the same. A resole keeps them running on a pair they trust.",
"persona_name": "loyalists",
"profile": "Runners of 40 to 80 kilometres a week, ten years in, with one pair in rotation and one on the shelf."
}
The result, in structuredContent:
{
"persona": {
"ageMax": 45,
"ageMin": 28,
"brandId": "brd_6a9c33",
"createdAt": 1790000000000,
"createdBy": "usr_4d8b12",
"description": "Runners who already own a pair, and who buy the next one without looking at another brand.",
"frictions": "They fear the new model is worse than the one they know. A change of sole or of last reads to them as a risk, not as progress.",
"language": "They say \"my daily trainer\" and \"I got 900 out of the last pair\". They ask about the drop and the stack, never about the technology.",
"motivations": "They want the same shoe again, and proof that it is the same. A resole keeps them running on a pair they trust.",
"profile": "Runners of 40 to 80 kilometres a week, ten years in, with one pair in rotation and one on the shelf.",
"id": "psn_8c4a20",
"name": "Loyalists",
"revision": 2,
"slug": "loyalists",
"updatedAt": 1790086400000
}
}