---
name: mindset-build-agent
description: Use when creating or changing an AI agent in Mindset (mindset.ai) through the mindset-admin MCP server. Turns a spec, prompt file, Claude skill or plain description into an agent with its prompt fields, model, resources and script, then handles versions, activation, rollback and where the agent can be reached (Hub, embedded, schedules, other agents).
metadata:
  title: Build an agent
  blurb: Creates or changes an agent, with its instructions, model, tools and where it can be reached.
  group: Mindset MCP
  order: 1
  docs: build-an-agent, turn-a-skill-or-spec-into-an-agent, change-something-thats-already-live, versions-and-going-live
  checked: d671041b6
  updated: 2026-10-19
---

# Build a Mindset agent from a spec, prompt or skill

When you finish, the agent exists in the person's environment with its prompt fields, model, resources and (if it needs one) script, one version is active, and it can be reached exactly where the person chose and nowhere else. To check how it behaves, or to work out why it misbehaves, use the `mindset-test-agent` skill.

## Mindset in brief

Mindset is a hosted platform for building, running and governing AI agents. An **agent** is configuration, not code: a prompt, a model, and the resources it may use. Those resources are **scripts** (steps that must wait or happen in order), **functions** (fixed steps with one right answer), **widgets** and **connections** (the only way data enters or leaves). People manage all of it in the Studio, a web app, or through Mindset's MCP servers.

## Where you are building: host, org, environment

Every Mindset call names three things. Get all three from the person before you write code or call a tool. Never guess or invent them.

| Value | What it is | Where the person finds it |
|---|---|---|
| **Host** | The Mindset deployment their org lives on, for example `https://eu.mindset.ai` | The address bar when they're signed in to the Studio, or an agent's **Embed** tab |
| **Org slug** | Their company's account. The org is the isolation boundary: members, model keys, settings and audit sit here, and one org can never see into another | An agent's **Embed** tab, or the address under **Settings → Systems → Connect an AI client** |
| **Environment slug** | A named partition inside the org, such as Sandbox, Test or Production | An agent's **Embed** tab, or the same address. The **Environment** switcher in the Studio shows which one is current |

How environments behave:

- **Agents, scripts, functions, connections, triggers, schedules, conversations, runs and API keys each belong to exactly one environment** and can't see anything in another.
- **Every org starts with one environment, Sandbox, whose slug is `original`.** A slug never changes, even when the environment is renamed. Use the slug, never the display name.
- **Nothing copies between environments.** To promote a change from Test to Production, make the same change again in Production.
- **Don't create an environment to hold your work.** Environments can't be deleted, and they're for stages such as Test and Production, not for projects. Work in the environment the person names. Create one only if the person asks you to.
- **Members, model keys and org settings are shared by every environment.** Changing an org setting changes it everywhere.

## Credentials for building in Mindset: sign in, never a key

You build inside Mindset through the **`mindset-admin` MCP server**. The person signs in with their own Mindset account in a browser, and they must be an org admin. There is no key or token, so never ask the person for one.

- **The server address names one environment**: `<host>/api/v1/orgs/<org-slug>/envs/<environment-slug>/mcp`. Every call goes to that environment unless the tool call passes `envSlug` to point that one call at another environment. Org-level tools refuse an `envSlug`.
- **No tool takes a secret value.** When a connection needs a credential, call `request_capture`. It returns a reference and a capture URL. Give the person the URL to open and paste the value into themselves, then use the reference. Capture links expire after 15 minutes. For a system that signs in with OAuth, `authorize_connection` returns a sign-in link the person opens the same way, and it expires after 10 minutes. If a link has expired, request a new one. Never ask the person to paste a credential into the conversation, even if they offer.
- **Errors come back structured.** Read `code` and `context` and act on them. Don't retry blind.

## Before you start

This skill works through the `mindset-admin` MCP server. Check that its tools (for example `get_information`) are available to you. If they aren't, set the server up first, following the `mindset-mcp` skill or https://docs.mindset.ai/docs/work-from-claude-code.md, then come back here.

Call `get_information` with no arguments for the platform's own topic index. Its guidance is current for the platform you're connected to. Where it and this skill disagree, follow `get_information`.

## Ask the person for

- The source: the spec, prompt file or skill, in full. Read all of it before you plan anything.
- Who uses the agent and how: people in the org (the Hub), the person's own product (embedded), another agent, a schedule, a trigger, or the person's backend.
- Which systems it reads and which it changes. Get every write named: "it registers a supplier query" and nothing else.
- The model, if they have a preference, and the reply language if it isn't the org's.
- Whether the agent already exists and people use it. That decides how you save changes (step 4).

## Decide what goes where

The server doesn't make this choice for you. Most of a skill or spec becomes prompt text. Move a part out of the prompt only when the prompt can't hold it reliably.

| What the source says | Where it goes |
|---|---|
| What the agent is for, in a sentence or two | `purpose` |
| Identity, tone, how it behaves | `personality` |
| Domain and audience context | `background` |
| Rules it must follow | `policyRules`. These are instructions to the model. Mindset doesn't enforce them |
| How replies are shaped | `outputFormatting` |
| A one-line blurb for cards and lists | `description`. It never enters the prompt |
| Steps that must wait for an answer or happen in order, where skipping ahead would be wrong | A **script**, covering only those steps. The rest stays in the prompt |
| A definition with one right answer ("material means over $500 or over 5% of the PO"), a calculation, or the same action repeated per item in a list | A **function**. If a phrase would need a definition before someone else could apply it the same way every time, it belongs in a function |
| Reading or changing data in another system | **Operations** on a connection |

Limits to plan around:

- **Each prompt field, and `description`, holds at most 2,000 characters.** Longer is refused, not truncated. Condense, and tell the person what you shortened. The full text isn't kept anywhere else.
- **The script language refuses some shapes on purpose:** a route back to an earlier phase, repeating an action once per item in a list (use a function), and a model named per phase.
- **Some things don't come across at all.** A skill's bundled code or data files, steps that read files on someone's computer, logging into a website and clicking through it, and any system the org has no connection to. List these for the person before you build.

For the invoice exceptions agent: the prompt says what it does and how to talk to finance, the gather, assess, prepare, close order is a short script, "compare the invoice to its PO line by line" is the `invoice-comparison` function, and `get_invoice`, `get_purchase_order_for_invoice` and `register_supplier_query` are operations on the finance connection.

## Step 1: take stock of what exists

1. Call `get_information` with `topic='what-is-this-platform'` if you haven't this session.
2. Call `list_agents` with a `search` to check the agent doesn't already exist. Change an existing agent instead of creating a second.
3. Call `list_resources` for connections, functions and widgets. Judge a connection by what it reaches (its host or server), not its name. A connection named `Q3 spend review` may already reach the finance system.
4. Anything missing must exist before the agent can use it. Build a connection with the `mindset-connect` skill and a function with the `mindset-function` skill, then come back and attach it.

## Step 2: create the agent

Call `create_agent` with `name`, the five prompt fields (`purpose`, `personality`, `background`, `policyRules`, `outputFormatting`), `description` and `llmModel`.

- **Always send `idempotencyKey`. If the call fails, retry with the same key.** A failed create may have committed, and a new key makes a second agent, with a `-2` handle.
- **A key means one intent.** Re-sending a key with different fields returns the original agent and reports success while your changes are ignored. Edit with `update_agent`.
- **Leave out `availability`.** A new agent starts with version 1 saved, nothing active and every surface off, so only org admins can reach it. Leave it that way until the person has looked at it.
- **`llmModel` only takes models in the platform's catalog**, and only models the org can run are served: those its own provider keys cover, or on a self-hosted deployment, the instance key. A model that isn't served is refused, never quietly swapped.
- `handle` is optional and derived from the name. If you give one, it's a lowercase slug: letters, digits and single hyphens.
- **The reply language isn't a create field.** Set it afterward with `update_agent` `replyLanguage`, for example `{ mode: "specified", language: "British English" }`, in the call that activates it (step 4).

## Step 3: give it resources and a script

Set resources with `update_agent` and `resources`, keyed by type: `connections`, `connection_operations`, `functions`, `widgets` and `agents` (other agents it can hand work to). Each value is the complete list for that type, as ids or @handles.

- A type you name is replaced wholesale. A type you leave out is left alone. An empty array detaches everything of that type.
- Give the smallest set the agent needs. Anyone who can reach the agent can use everything it holds.
- An operation must be offered to agents before you can attach it. You can enable a read operation (`govern_tool`). You can attach a write that is waiting for approval: it runs nothing until a person approves it in the Studio, on the connection's **Operations** tab, and then reaches the agent with no new version. Tell the person. Never attach the whole connection to get round an approval.
- For a script, call `find_examples` and then `create_resource` with type `script` and an explicit `handle` (a script takes no `idempotencyKey`, and a retried create is refused as `handle_taken`). Bind it with `update_agent` `scriptId`. A script belongs to one agent.
- To read back what the agent holds, use `agent_config_admin` with verb `describe_resources`. Never answer that from the prompt text.

## Step 4: save as a version, then activate or stage

Every `update_agent` call that changes a prompt field, the name, the model, the reply language, resources, the script or schedules mints a new configuration version, and must carry `activation`. Leave it out and the call is refused.

Which value to send depends on whether a version of this agent is already active.

- **Never been active** (you just created it): send `activation: "activate"`. Nobody is using it yet.
- **Already active** (people may be using it): send `activation: "stage"`. Then tell the person "saved as version 7, not live yet", and that they activate it on the agent's **Versions & Availability** tab. Never put a change in front of an agent's users on your own initiative, however small, and even when every surface is off.

Name versions by the number `update_agent` returns, never by uuid. Changing several fields in one call makes one version, which reads better in the history.

Activation can be refused:

- `operations_untested`: the version puts new script text live and the script calls an operation with no successful call on record in this environment. Run the script's test parameters (see `mindset-test-agent`), then activate again. `overrideUntested` exists, but pass it only when the person has chosen it themselves, naming each operation. It's recorded under their name and the operations stay untested.
- `operation_awaiting_approval`: the script text it puts live calls an operation still waiting for a person's approval. No override covers it. A person approves it in the Studio, then run the script's test parameters.
- `version_resource_unreachable`: a resource the version uses is switched off or no longer offered to agents. Clear that and try again. An operation waiting for approval doesn't block activation.
- `version_resource_gone`: a resource it uses was deleted. That version can't run again. Save a new one.
- `resource_not_granted`: the version, or a resource change, removes a resource the agent's script uses. Keep it, or change the script first.

## Step 5: choose where it can be reached

Availability is outside versions. `update_agent` with `availability` applies at once and mints nothing. Name only the surfaces you're changing.

| Key | Screen label | Lets in |
|---|---|---|
| `hub` | **The Hub** | Every member of the org, in that environment, in the Hub and from their own AI client |
| `embed` | **Embedded in your own product** | The person's own app, through the SDK |
| `delegation` | **Other agents** | Another agent handing this one a task |
| `schedules` | **Schedules** | A schedule set on the agent |
| `triggers` | **Triggers** | An outside tool calling a trigger's URL |
| `api` | **Outside systems** | A backend calling with an org API key |
| `links` | **People sent a link** | A person the agent's script sends a conversation link to |

Rules:

- **Turn on only what your own wiring needs:** `delegation` for a helper another agent hands work to, `schedules` or `triggers` if the person asked for them, `links` if the script sends a person a link to answer in.
- **Never turn on `hub`, `embed` or `api` on your own.** They let people and outside systems in, so the person decides.
- **The Hub shares with everyone in the org.** There's no per-person list. Before ticking it, put it to the person as "this lets everyone in the org do X to Y". If a write shouldn't be everyone's, keep it off this agent.
- **`available: true` is the screen's switch.** With no surface ticked yet, it ticks every one, and the person unticks what they don't want.
- **An agent is reachable only when** a version is active, it's switched on, and at least one surface is ticked. Ticking a surface on an agent with no active version records the intent; calls are refused with `no_version_in_force` until you activate.
- **A page with no backend can sign visitors in.** That needs `hub` ticked as well as `embed`, the org's self-signup on (`org_domain_admin` verb `set_self_signup`) and the website allowed (`add_allowed_website`). Those are the person's decisions too.

In your reply, name every surface you turned on and why, and every agent you left unavailable.

## Versions, rollback and lost wording

- `agent_config_versions`: `list` (every version with its number and wording), `read`, `compare` (role by role, with the computed `diff`), `activate`, `delete` (never the active one or the only one).
- **Rollback is `activate` on an older version.** It restores that version's resources too, so anything attached since is dropped. After rolling back, pass that version as `update_agent` `baseVersion` on every edit, or your next edit builds on the newer version and brings it back.
- A version records which functions and widgets the agent uses, not which version of each. Roll a function or widget back with `activate_resource_version`. That tool refuses a script: pin a script's text with `update_agent` `scriptVersionId`.
- A wording someone thinks they lost is in `list_agent_prompt_history`. It's read only: put the text back through `update_agent`.

## Rules

- Work in the environment the server address names, or the `envSlug` the person gives. Never create an environment for this work.
- Confirm with the person before `delete_agent`. It can't be undone. To take an agent out of use, `archive_agent` or switch availability off.
- Never put a credential, key or token in a prompt field. Credentials belong on connections, through `request_capture`.
- A rule that must hold every time doesn't belong only in `policyRules`. Make it a script condition, a function, or leave the operation off the agent. A rule about what the agent says can only live in `policyRules`: cover it with an acceptance test (the `mindset-test-agent` skill).
- Report what you couldn't convert, what you shortened, and which version is active.

## Check it works

1. `get_agent` and confirm the prompt fields and model. It doesn't show the reply language: read that with `agent_config_versions` verb `read`.
2. `agent_config_admin` verb `assignment_health`. `unusable` names resources that won't become tools, `configNotLive` means staged changes aren't live, and `scriptResources` names script phases that use something the agent no longer holds.
3. `list_agents` with `available: false` lists agents nobody can reach. Expect yours there until the person opens a surface.
4. Talk to it with `call_agent`. An org admin can call an agent that's unavailable, and the person can try it on the agent's **Chat** tab in the Studio. To try a staged version, pass its uuid as `configVersionId`. That version's writes are refused (`write_not_agreed`) until `agent_config_versions` verb `writes` shows its write list, you tell the person, and on their go-ahead you call `agree_writes`. If `call_agent` returns `working`, don't call again. Read the reply later with `conversation_fetch`, noun `message`, filtered by the `conversationId` it returned.
5. Then test its behavior with the `mindset-test-agent` skill.

## When it fails

| What you see | Cause and fix |
|---|---|
| `update_agent` refused, naming `activation` | The edit mints a version. Add `activation` per step 4 |
| A prompt field refused as too long | Over 2,000 characters. Condense it, or move ordered steps into a script |
| `llmModel` refused | Not in the catalog, or not served for this org. Pick another, or the person adds a provider key |
| A handle ending in `-2` | A create was retried with a new key. Archive the duplicate |
| `no_version_in_force` | No version is active. Activate one |
| `agent_not_available_here` | The surface isn't ticked. The message names which |
| `operations_untested` | Run the script's test parameters, then activate. See step 4 |
| `version_resource_unreachable` or `version_resource_gone` | A resource the version uses is switched off or deleted. See step 4 |
| `operation_awaiting_approval` | A script step calls a write still waiting for approval. A person approves it, then test and activate |
| `resource_not_granted` on activation | The change removes a resource the script uses. Keep it, or change the script first |
| The agent says it can't use a resource you attached | The version holding it is staged, not active. `assignment_health` shows `configNotLive` |
| An edit after a rollback brought back newer changes | It built on the latest version. Pass `baseVersion` |
| A write operation stays un-enabled | It's waiting for a person to approve it in the Studio |

## Read more

Fetch these as Markdown when you need more than this skill gives you. If one disagrees with this skill, the page is newer: follow it.

- https://docs.mindset.ai/docs/turn-a-skill-or-spec-into-an-agent.md: read when converting a skill or spec, for what doesn't come across and what to check in a plan.
- https://docs.mindset.ai/docs/build-an-agent.md: read for each prompt field, where an agent can be reached, and why it shows **Unavailable**.
- https://docs.mindset.ai/docs/write-a-script.md: read before you give the agent a script.
- https://docs.mindset.ai/docs/build-a-function.md: read when a definition or calculation should be a function.
- https://docs.mindset.ai/docs/change-something-thats-already-live.md: read for versions that can't be activated, comparing and rollback.
- https://docs.mindset.ai/docs/versions-and-going-live.md: read for when each kind of change reaches people.
- https://docs.mindset.ai/docs/approve-what-an-agent-can-do.md: read when a write operation needs approval.
