---
name: mindset-postmark-email-connection
description: Use when a Mindset (mindset.ai) agent should send email through Postmark, through the mindset-admin MCP server, for example to email a person the link to a form. Sets up a Postmark connection, or reuses one the Org already has. Use whenever the user wants an agent to send email, email them a link, or connect Postmark.
metadata:
  title: Let an agent send email with Postmark
  blurb: A Postmark connection a Mindset agent sends email through, from a sender you verified.
  group: Examples
  order: 3
  docs: connect-a-system, connections-and-operations
  checked: 28ab3d642
  updated: 2026-10-26
---

# Let an agent send email with Postmark

The user wants a Mindset agent to send email. Postmark is an email-sending service; the account is the user's own, so they create it and verify their sender address. You do the Mindset side. The general method for an HTTP connection lives on the platform: read `get_information` topics `authoring:connection`, `authoring:connection:register` and `authoring:connection:api` and follow them. This skill adds only what is particular to Postmark. If the platform has a topic `authoring:connection:provider:postmark`, read it first and prefer it where the two differ.

## 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.

## 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`.

## 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 build anything

1. Tell the user which Org and Environment you're in (every reply from the server names them), and build only where they asked.
2. Call `list_resources` with `type: "connection"` and look for one whose `url` is `https://api.postmarkapp.com`. If one exists, offer to reuse it by name: ask for no keys, check it has a `send_email` operation that isn't waiting for approval, and ask which sender address to use.
3. Otherwise ask: do they have a Postmark account, is their organization happy to use Postmark (some teams approve new suppliers first), and which address at their own domain the email should come from.

## The Postmark side, one step at a time

1. Sign up or log in at **postmarkapp.com**.
2. Open **Servers** and pick or create one, named for what it's for.
3. Verify the sender under **Sender Signatures**: a single address (they click the confirmation email), or the whole domain (DNS records; better for production).
4. Open the server's **API Tokens** tab. The **Server API token** is the one secret you need. It isn't the Account API token.

Say this up front: until Postmark approves a new account, it may only send to addresses at the sender's own domain.

## The Mindset side

1. Capture the Server API token with `request_capture`, field `token`, with a label that tells the person which token to paste.
2. Create the connection with `create_resource`, `type: "connection"`: `adapter: "api_key"`, `type: "rest_api"`, `kind: "tools"`, `url: "https://api.postmarkapp.com"`, and `config: {"token": {"secretRef": "<the returned ref>"}, "headerName": "X-Postmark-Server-Token"}`. Don't publish it yet.
3. Register `get_server` (`GET /server`, a read with no parameters) once the person has entered the token. A read is tested live as it's registered, so it fails until then. Publishing calls it too, so a pass proves the token as well as the host.
4. Register `send_email`: `POST /email`, a write. Parameters: `From` (body, required, `Name <address>` with a verified sender), `To` (body, required, one recipient), `Subject` (body, required), `TextBody` (body, required), `HtmlBody` (body, optional), and `MessageStream` (body, optional, `outbound` is Postmark's default transactional stream).
5. Publish last, and tell the user which grade came back.
6. Once the connection is published, give the agent `send_email`; until then the platform refuses the grant. `get_information` topic `authoring:connection:operations` names the three acts that takes, and why a write may wait for an admin's approval.

## Writing the emails

- Keep the email to the link and a line of context, and put the detail on the page the link opens. Email gets forwarded, and whoever holds a link can answer it.
- Say how long the link stays open. Send one email per person, with one address in `To`.

## Read more

https://docs.mindset.ai/docs/connect-a-system.md explains HTTP connections for people.

## Done means

The user has received a real test email from the verified sender, and the agent holds `send_email`. Send the test with `test_resource` in `invoke` mode, to an address the user gives you; it asks for a go-ahead first, as `authoring:connection_operation` describes. "Published" isn't done.
