# PieterPost MCP docs
Docs page: https://pieterpost.com/api/docs/mcp
Source: https://pieterpost.com/api/docs/mcp.md
MCP server URL: `https://pieterpost.com/mcp/`
Protocol version: `2025-11-25`
Supported protocol versions: `2025-11-25`, `2025-06-18`, `2025-03-26`, `2024-11-05`
Server version: `2026.05.03.1`

This is the markdown-only reference for agents and MCP clients that connect to PieterPost. Use it for tool descriptions, input types, OAuth details, safety rules, and examples.

## Client setup
PieterPost exposes a remote MCP server with OAuth authorization code, PKCE, dynamic client registration, short-lived bearer tokens, refresh tokens, and revocation.
```json
{
  "allowed_tools": [
    "search",
    "fetch",
    "list_mailbook_contacts",
    "get_mailbook_contact",
    "create_mailbook_contact",
    "update_mailbook_contact",
    "delete_mailbook_contact",
    "quote_order",
    "upload_asset",
    "create_compose_link",
    "create_payment_link",
    "create_checkout_link",
    "create_direct_order",
    "get_wallet",
    "get_order",
    "get_topup",
    "list_topups",
    "create_credit_topup",
    "list_api_keys",
    "create_api_key",
    "revoke_api_key"
  ],
  "require_approval": {
    "never": {
      "read_only": true
    }
  },
  "server_label": "pieterpost",
  "server_url": "https://pieterpost.com/mcp/",
  "type": "mcp"
}
```

## OAuth and metadata
- OAuth issuer: `https://pieterpost.com/mcp/oauth`
- Protected resource metadata: `https://pieterpost.com/.well-known/oauth-protected-resource/mcp/`
- Protected resource convenience URL: `https://pieterpost.com/mcp/.well-known/oauth-protected-resource/`
- Authorization server metadata: `https://pieterpost.com/.well-known/oauth-authorization-server/mcp/oauth/`
- Authorization server issuer-relative metadata: `https://pieterpost.com/mcp/oauth/.well-known/oauth-authorization-server/`
- Dynamic client registration: `https://pieterpost.com/mcp/oauth/register/`
- Token endpoint: `https://pieterpost.com/mcp/oauth/token/`
- Revocation endpoint: `https://pieterpost.com/mcp/oauth/revoke/`
- Bearer challenges use `realm="PieterPost MCP"` and point `resource_metadata` at the protected resource metadata URL.
- Supported scopes: `api:read`, `api:send`, `api:keys`, `mailbook:read`, `mailbook:write`.
- `api:read` permits `search`, `fetch`, `get_wallet`, and `get_order`.
- `api:read` also permits `quote_order`, `get_topup`, and `list_topups`.
- `api:send` permits uploads, compose links, payment links, checkout links, direct orders, and credit top-ups.
- `api:keys` permits listing, creating, and revoking public API keys.
- `mailbook:read` permits listing, searching, and fetching saved Mailbook contacts.
- `mailbook:write` permits creating, updating, and deleting saved Mailbook contacts.

## Safety model
- Test mode is the default for writable tools unless `mode: "live"` is provided.
- Hosted payment and checkout links do not send mail until checkout is paid.
- Live `create_direct_order` sends real mail and spends wallet credits. Only call it after explicit user confirmation, and include `confirmLiveSend: true` plus `maxAmountCents` greater than or equal to the calculated total.
- Before `create_payment_link`, `create_checkout_link`, or `create_direct_order`, review the exact final letter or postcard text in the payload, including line breaks and any template placeholders or recipient customFields.
- API key creation returns the secret once. Existing key secrets cannot be fetched later.
- Uploads accept `fileBase64` or a public HTTPS `fileUrl`; localhost, private network, and metadata host URLs are rejected.
- The example OpenAI configuration skips approval only for `readOnlyHint` tools. Keep host approval enabled for write tools unless the user has explicitly chosen otherwise.
- Use `idempotencyKey` on every create operation. This is especially important for live direct sends, checkout links, and wallet top-ups.

## Mail payload parity
MCP order tools accept the same letter and postcard payloads as the public API, with `idempotencyKey` passed in the tool arguments instead of an HTTP header.
- Letters use `requestType: "letter"` and a `letters` array. Up to 25 letters are allowed per request.
- Each letter can include a `message`, up to 3 `letter-attachment` asset IDs, or both. In letter template mode, `templateMessage` can supply the shared message for each recipient.
- Letter template mode uses `composeMode: "template"`, `templateMessage`, optional `variableKeys`, and recipient `customFields`.
- Letter stamp images use `upload_asset` with `kind: "letter-stamp-image"`, then `stampImageAssetId` on the order tool.
- Postcards use `requestType: "postcard"` and a `postcard` object with `recipient` or `recipients`. Up to 25 postcard recipients are allowed per request.
- Postcards can use the default front image or an uploaded custom one. Custom postcard fronts must be square, with a 1:1 aspect ratio. For a custom front, use `upload_asset` with `kind: "postcard-image"`, then pass the returned asset as `postcard.frontImageAssetId`.
- Hosted checkout tools default to `paymentMethod: "auto"`. For EUR letter or postcard payment links and EUR wallet top-ups, auto offers both card and iDEAL in Stripe Checkout. Pass `paymentMethod: "card"` or `paymentMethod: "ideal"` only when the user explicitly wants one method.
- Recipients can use `addressLines`, or structured address fields such as `streetAddress`, `street`, `number`, `postalCode`, `city`, `state`, and `country`. Free-form address parsing is not performed.
- Metadata accepts up to 20 string, number, or boolean values.

## Mailbook contacts
- Use `list_mailbook_contacts` with a query when the user names a saved contact, for example `Eric`.
- Use `get_mailbook_contact` when you already have a contact id.
- Contact results include a `recipient` object that can be passed directly into `quote_order`, `create_payment_link`, `create_checkout_link`, `create_direct_order`, or `create_compose_link`.
- Use `create_mailbook_contact`, `update_mailbook_contact`, and `delete_mailbook_contact` for contact CRUD. Address input must be structured; free-form address parsing is not performed.
- Example flow: if the user says, `send a postcard to Bart`, call `list_mailbook_contacts` with `query: "Bart"`; if exactly one contact matches, use that contact's `recipient` object in `quote_order`, then continue with `create_payment_link`, `create_compose_link`, `create_checkout_link`, or `create_direct_order` depending on the user's intent and confirmation. If multiple contacts match, ask the user which Bart they mean before creating mail.

## Default live send flow
1. Do not call `create_api_key` unless the user explicitly asked for a public API key. MCP uses internal action keys automatically.
2. Call `quote_order` with the final letter or postcard payload.
3. Review the exact final text that will be sent, including line breaks and any template variables or customFields.
4. Call `create_payment_link` with `mode: "live"` and a stable `idempotencyKey`. `senderEmail` is optional; Stripe Checkout collects the payer email when omitted. `returnUrl` is optional; PieterPost uses a hosted MCP return page when it is omitted, localized by `locale` and labeled as a letter or postcard.
5. Send the returned `paymentLinkUrl` or `checkoutUrl` to the user. PieterPost sends the mail only after Stripe confirms checkout payment.
6. Keep the API/credit path available when the user asks for API keys, wallet credits, top-ups, direct send, or an automated trusted workflow: `get_wallet`, `quote_order`, `create_credit_topup` if needed, then `create_direct_order` after explicit confirmation.

## Tools summary
- `search`: Search PieterPost API docs and the authenticated API account summary, keys, wallets, orders, activity, and MCP connections.
- `fetch`: Fetch a PieterPost API document or account resource returned by the search tool.
- `list_mailbook_contacts`: List or search saved Mailbook contacts for the authenticated PieterPost user. Use query for name, email, or address searches. Each result includes a recipient object that can be passed into letter or postcard payloads.
- `get_mailbook_contact`: Fetch one saved Mailbook contact by id. The result includes a recipient object for letter or postcard payloads.
- `create_mailbook_contact`: Create a saved Mailbook contact for later letter or postcard sending. Requires structured address fields; free-form address parsing is not performed.
- `update_mailbook_contact`: Update a saved Mailbook contact. Provide contactId and only the fields to change; omitted fields keep their existing values.
- `delete_mailbook_contact`: Delete one saved Mailbook contact by id.
- `create_compose_link`: Create a PieterPost compose link for one prepared recipient and optional message. The user reviews, edits, and pays in PieterPost.
- `quote_order`: Validate and price a letter or postcard payload without creating an order. Provide exactly one of letters or postcard. Use this before live direct-send flows to confirm the amount, wallet balance gap, and next action.
- `create_payment_link`: Create a hosted payment link for one-off MCP letter or postcard sending without public API keys or wallet credits. Provide exactly one of letters or postcard. Mail is sent only after checkout is paid. senderEmail is optional; Stripe Checkout collects the payer email when omitted. returnUrl is optional; PieterPost provides a hosted return page when omitted. Review the final message text before creating the link.
- `create_checkout_link`: Create a hosted checkout link for letters or postcards. This is the public-API-compatible name for create_payment_link. Provide exactly one of letters or postcard. Supports bulk letters, letter template mode, custom letter stamps, bulk postcard recipients up to 25 recipients, letter attachments, and optional square 1:1 custom postcard front images. Mail is sent only after checkout is paid. senderEmail is optional for MCP calls; Stripe Checkout collects the payer email when omitted. returnUrl is optional for MCP calls. Review the final message text before creating the link.
- `create_direct_order`: Create a direct-send order paid from wallet credits. Provide exactly one of letters or postcard. Supports bulk letters and postcards with the same payload shape as hosted checkout. Test mode simulates sending. Live mode sends real mail and requires confirmLiveSend=true plus maxAmountCents >= the calculated total. Review the final message text before sending.
- `upload_asset`: Upload a square 1:1 postcard front image, letter attachment, or custom letter stamp for later use in create_checkout_link or create_direct_order. Provide exactly one of fileBase64 or a public HTTPS fileUrl. Returns an assetId that can be passed as postcard.frontImageAssetId, stampImageAssetId, or in a letter attachments array.
- `get_wallet`: Read the API wallet balance and account capability flags for test or live mode.
- `get_order`: Fetch a PieterPost API order by id, including hosted checkout/direct-send status, recipient count, amount, and error details.
- `get_topup`: Fetch a PieterPost wallet top-up by id, including payment status and checkout URL when still pending.
- `list_topups`: List recent PieterPost wallet top-ups for this account. Use mode and currency filters to inspect the active live or test funding history.
- `create_credit_topup`: Create a test credit top-up immediately, or create a live Stripe checkout URL for adding API credits used by direct-send orders. paymentMethod=auto is the default; for EUR top-ups it offers both card and iDEAL. Pass paymentMethod=card or paymentMethod=ideal only when the user wants to force one method.
- `list_api_keys`: List API key metadata for this PieterPost API account. Secrets are never returned.
- `create_api_key`: Create a new PieterPost public API key. The secret is returned once and cannot be recovered later.
- `revoke_api_key`: Revoke an existing PieterPost public API key by id.

## Tool input schemas
The following JSON is the authoritative MCP `tools/list` schema exposed by PieterPost.
The schema is intentionally flattened for Codex-style clients, so allowed values and constraints are described in text instead of unsupported JSON Schema keywords such as `enum`, `format`, or nested unions.
```json
{
  "tools": [
    {
      "annotations": {
        "openWorldHint": false,
        "readOnlyHint": true
      },
      "description": "Search PieterPost API docs and the authenticated API account summary, keys, wallets, orders, activity, and MCP connections.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "query": {
            "description": "Search query.",
            "type": "string"
          }
        },
        "required": [
          "query"
        ],
        "type": "object"
      },
      "name": "search",
      "outputSchema": {
        "additionalProperties": true,
        "type": "object"
      }
    },
    {
      "annotations": {
        "openWorldHint": false,
        "readOnlyHint": true
      },
      "description": "Fetch a PieterPost API document or account resource returned by the search tool.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "id": {
            "description": "Document id returned by search.",
            "type": "string"
          }
        },
        "required": [
          "id"
        ],
        "type": "object"
      },
      "name": "fetch",
      "outputSchema": {
        "additionalProperties": true,
        "type": "object"
      }
    },
    {
      "annotations": {
        "openWorldHint": false,
        "readOnlyHint": true
      },
      "description": "List or search saved Mailbook contacts for the authenticated PieterPost user. Use query for name, email, or address searches. Each result includes a recipient object that can be passed into letter or postcard payloads.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "limit": {
            "description": "Maximum number of contacts to return. Defaults to 25; maximum 100.",
            "type": "number"
          },
          "query": {
            "description": "Optional search query, such as a contact name, email, city, or street.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "name": "list_mailbook_contacts",
      "outputSchema": {
        "additionalProperties": true,
        "type": "object"
      }
    },
    {
      "annotations": {
        "openWorldHint": false,
        "readOnlyHint": true
      },
      "description": "Fetch one saved Mailbook contact by id. The result includes a recipient object for letter or postcard payloads.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "contactId": {
            "description": "Mailbook contact id.",
            "type": "string"
          }
        },
        "required": [
          "contactId"
        ],
        "type": "object"
      },
      "name": "get_mailbook_contact",
      "outputSchema": {
        "additionalProperties": true,
        "type": "object"
      }
    },
    {
      "annotations": {
        "destructiveHint": false,
        "openWorldHint": false,
        "readOnlyHint": false
      },
      "description": "Create a saved Mailbook contact for later letter or postcard sending. Requires structured address fields; free-form address parsing is not performed.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "birthday": {
            "description": "Optional birthday in YYYY-MM-DD format.",
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "displayName": {
            "description": "Saved contact display name.",
            "type": "string"
          },
          "email": {
            "description": "Optional contact email.",
            "type": "string"
          },
          "extra": {
            "description": "Optional address extra line, such as apartment, company, or care-of details.",
            "type": "string"
          },
          "houseNumber": {
            "type": "string"
          },
          "postalCode": {
            "type": "string"
          },
          "state": {
            "description": "State, province, region, or subdivision when applicable.",
            "type": "string"
          },
          "street": {
            "type": "string"
          }
        },
        "required": [
          "displayName",
          "street",
          "houseNumber",
          "postalCode",
          "city",
          "country"
        ],
        "type": "object"
      },
      "name": "create_mailbook_contact",
      "outputSchema": {
        "additionalProperties": true,
        "type": "object"
      }
    },
    {
      "annotations": {
        "destructiveHint": false,
        "openWorldHint": false,
        "readOnlyHint": false
      },
      "description": "Update a saved Mailbook contact. Provide contactId and only the fields to change; omitted fields keep their existing values.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "contactId": {
            "description": "Mailbook contact id.",
            "type": "string"
          },
          "birthday": {
            "description": "Optional birthday in YYYY-MM-DD format.",
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "displayName": {
            "description": "Saved contact display name.",
            "type": "string"
          },
          "email": {
            "description": "Optional contact email.",
            "type": "string"
          },
          "extra": {
            "description": "Optional address extra line, such as apartment, company, or care-of details.",
            "type": "string"
          },
          "houseNumber": {
            "type": "string"
          },
          "postalCode": {
            "type": "string"
          },
          "state": {
            "description": "State, province, region, or subdivision when applicable.",
            "type": "string"
          },
          "street": {
            "type": "string"
          }
        },
        "required": [
          "contactId"
        ],
        "type": "object"
      },
      "name": "update_mailbook_contact",
      "outputSchema": {
        "additionalProperties": true,
        "type": "object"
      }
    },
    {
      "annotations": {
        "destructiveHint": true,
        "openWorldHint": false,
        "readOnlyHint": false
      },
      "description": "Delete one saved Mailbook contact by id.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "contactId": {
            "description": "Mailbook contact id.",
            "type": "string"
          }
        },
        "required": [
          "contactId"
        ],
        "type": "object"
      },
      "name": "delete_mailbook_contact",
      "outputSchema": {
        "additionalProperties": true,
        "type": "object"
      }
    },
    {
      "annotations": {
        "destructiveHint": false,
        "openWorldHint": false,
        "readOnlyHint": false
      },
      "description": "Create a PieterPost compose link for one prepared recipient and optional message. The user reviews, edits, and pays in PieterPost.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "externalId": {
            "description": "Your correlation id for the created order/link.",
            "type": "string"
          },
          "idempotencyKey": {
            "description": "Stable idempotency key for retries. Always include this for create operations, especially in live mode.",
            "type": "string"
          },
          "locale": {
            "description": "Locale. Allowed values: \"de\", \"en\", \"es\", \"fr\", \"it\", or \"nl\".",
            "type": "string"
          },
          "message": {
            "description": "Prepared message. Trimmed to 6,000 characters.",
            "type": "string"
          },
          "metadata": {
            "additionalProperties": true,
            "description": "Up to 20 string, number, or boolean values copied to the order/link.",
            "type": "object"
          },
          "mode": {
            "description": "Mode. Allowed values: \"test\" or \"live\". Defaults to test when omitted.",
            "type": "string"
          },
          "recipient": {
            "additionalProperties": true,
            "description": "Recipient address. Provide name plus addressLines, or name with streetAddress or street plus number, postalCode, city, country, and state when required. Free-form address parsing is not performed.",
            "properties": {
              "addressLines": {
                "description": "Preformatted address lines, excluding the recipient name.",
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "city": {
                "type": "string"
              },
              "country": {
                "type": "string"
              },
              "customFields": {
                "description": "Template variables available when letter or postcard composeMode is template.",
                "additionalProperties": {
                  "type": "string"
                },
                "type": "object"
              },
              "extra": {
                "type": "string"
              },
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "number": {
                "type": "string"
              },
              "postalCode": {
                "type": "string"
              },
              "state": {
                "type": "string"
              },
              "street": {
                "type": "string"
              },
              "streetAddress": {
                "type": "string"
              }
            },
            "required": [
              "name"
            ],
            "type": "object"
          }
        },
        "required": [
          "recipient"
        ],
        "type": "object"
      },
      "name": "create_compose_link",
      "outputSchema": {
        "additionalProperties": false,
        "properties": {
          "expiresAt": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "mode": {
            "const": "compose_link",
            "type": "string"
          },
          "testMode": {
            "type": "boolean"
          },
          "url": {
            "type": "string"
          }
        },
        "required": [
          "expiresAt",
          "id",
          "mode",
          "testMode",
          "url"
        ],
        "type": "object"
      }
    },
    {
      "annotations": {
        "destructiveHint": false,
        "openWorldHint": false,
        "readOnlyHint": true
      },
      "description": "Validate and price a letter or postcard payload without creating an order. Provide exactly one of letters or postcard. Use this before live direct-send flows to confirm the amount, wallet balance gap, and next action.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "composeMode": {
            "description": "Letter compose mode. Allowed values: \"personal\" or \"template\". personal uses each letter.message; template uses templateMessage and recipient customFields to generate each letter.",
            "type": "string"
          },
          "externalId": {
            "description": "Your correlation id for the created order/link.",
            "type": "string"
          },
          "idempotencyKey": {
            "description": "Stable idempotency key for retries. Always include this for create operations, especially in live mode.",
            "type": "string"
          },
          "letters": {
            "description": "Bulk letters. Maximum 25.",
            "items": {
              "additionalProperties": false,
              "description": "One letter for one recipient. In personal mode include a message, uploaded attachments, or both. In template mode, templateMessage can supply the message for every recipient. Destination page limits apply to the combined message and attachment pages.",
              "properties": {
                "attachments": {
                  "description": "Letter attachment asset IDs or upload_asset objects. Assets must be kind letter-attachment.",
                  "items": {
                    "description": "Attachment asset ID string or upload_asset-style object with assetId."
                  },
                  "type": "array"
                },
                "message": {
                  "description": "Letter body. Trimmed to 6,000 characters. Use \\n for line breaks; line breaks are preserved.",
                  "type": "string"
                },
                "recipient": {
                  "additionalProperties": true,
                  "description": "Recipient address. Provide name plus addressLines, or name with streetAddress or street plus number, postalCode, city, country, and state when required. Free-form address parsing is not performed.",
                  "properties": {
                    "addressLines": {
                      "description": "Preformatted address lines, excluding the recipient name.",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "city": {
                      "type": "string"
                    },
                    "country": {
                      "type": "string"
                    },
                    "customFields": {
                      "description": "Template variables available when letter or postcard composeMode is template.",
                      "additionalProperties": {
                        "type": "string"
                      },
                      "type": "object"
                    },
                    "extra": {
                      "type": "string"
                    },
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "number": {
                      "type": "string"
                    },
                    "postalCode": {
                      "type": "string"
                    },
                    "state": {
                      "type": "string"
                    },
                    "street": {
                      "type": "string"
                    },
                    "streetAddress": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "name"
                  ],
                  "type": "object"
                }
              },
              "required": [
                "recipient"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "locale": {
            "description": "Locale. Allowed values: \"de\", \"en\", \"es\", \"fr\", \"it\", or \"nl\".",
            "type": "string"
          },
          "metadata": {
            "additionalProperties": true,
            "description": "Up to 20 string, number, or boolean values copied to the order/link.",
            "type": "object"
          },
          "mode": {
            "description": "Mode. Allowed values: \"test\" or \"live\". Defaults to test when omitted.",
            "type": "string"
          },
          "postcard": {
            "additionalProperties": false,
            "description": "Postcard payload. Provide recipient for one card or recipients for bulk cards up to 25 recipients. Add frontImageAssetId or frontImage when you want a square 1:1 custom front instead of the default one.",
            "properties": {
              "composeMode": {
                "description": "Compose mode. Allowed values: \"personal\" or \"template\". personal sends one message as written; template lets recipient customFields replace variables in supported templates.",
                "type": "string"
              },
              "frontImage": {
                "description": "Optional square 1:1 postcard image asset ID string or upload_asset-style object. Equivalent to frontImageAssetId."
              },
              "frontImageAssetId": {
                "description": "Optional asset ID returned by upload_asset for a square 1:1 postcard-image.",
                "type": "string"
              },
              "message": {
                "description": "Postcard message. Trimmed to 400 characters. Use \\n for line breaks; line breaks are preserved.",
                "type": "string"
              },
              "recipient": {
                "additionalProperties": true,
                "description": "Recipient address. Provide name plus addressLines, or name with streetAddress or street plus number, postalCode, city, country, and state when required. Free-form address parsing is not performed.",
                "properties": {
                  "addressLines": {
                    "description": "Preformatted address lines, excluding the recipient name.",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "city": {
                    "type": "string"
                  },
                  "country": {
                    "type": "string"
                  },
                  "customFields": {
                    "description": "Template variables available when letter or postcard composeMode is template.",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "type": "object"
                  },
                  "extra": {
                    "type": "string"
                  },
                  "id": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "number": {
                    "type": "string"
                  },
                  "postalCode": {
                    "type": "string"
                  },
                  "state": {
                    "type": "string"
                  },
                  "street": {
                    "type": "string"
                  },
                  "streetAddress": {
                    "type": "string"
                  }
                },
                "required": [
                  "name"
                ],
                "type": "object"
              },
              "recipients": {
                "description": "Bulk postcard recipients. Maximum 25.",
                "items": {
                  "additionalProperties": true,
                  "description": "Recipient address. Provide name plus addressLines, or name with streetAddress or street plus number, postalCode, city, country, and state when required. Free-form address parsing is not performed.",
                  "properties": {
                    "addressLines": {
                      "description": "Preformatted address lines, excluding the recipient name.",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "city": {
                      "type": "string"
                    },
                    "country": {
                      "type": "string"
                    },
                    "customFields": {
                      "description": "Template variables available when letter or postcard composeMode is template.",
                      "additionalProperties": {
                        "type": "string"
                      },
                      "type": "object"
                    },
                    "extra": {
                      "type": "string"
                    },
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "number": {
                      "type": "string"
                    },
                    "postalCode": {
                      "type": "string"
                    },
                    "state": {
                      "type": "string"
                    },
                    "street": {
                      "type": "string"
                    },
                    "streetAddress": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "name"
                  ],
                  "type": "object"
                },
                "type": "array"
              },
              "variableKeys": {
                "description": "Template variable keys to use for postcard personalization.",
                "items": {
                  "type": "string"
                },
                "type": "array"
              }
            },
            "type": "object"
          },
          "requestType": {
            "description": "Request type. Allowed values: \"letter\" or \"postcard\". Use letter with letters, or postcard with postcard. If omitted, postcard is inferred when postcard is present.",
            "type": "string"
          },
          "senderEmail": {
            "description": "Optional order contact email. Hosted Stripe Checkout collects the payer email when omitted.",
            "type": "string"
          },
          "stampImage": {
            "description": "Letter stamp image asset ID string or upload_asset-style object. Equivalent to stampImageAssetId."
          },
          "stampImageAssetId": {
            "description": "Asset ID returned by upload_asset for a letter-stamp-image.",
            "type": "string"
          },
          "templateMessage": {
            "description": "Shared letter template used when composeMode is template. Supports {{name}}, {{first_name}}, {{address}}, {{street}}, {{city}}, {{postal_code}}, {{country}}, and recipient customFields. Use \\n for line breaks; line breaks are preserved.",
            "type": "string"
          },
          "variableKeys": {
            "description": "Letter template variable keys used for recipient customFields.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "name": "quote_order",
      "outputSchema": {
        "additionalProperties": false,
        "properties": {
          "accountId": {
            "type": "string"
          },
          "amountCents": {
            "type": "number"
          },
          "approvalStatus": {
            "enum": [
              "pending",
              "approved",
              "rejected"
            ],
            "type": "string"
          },
          "approvedForDirectSend": {
            "type": "boolean"
          },
          "creditsEnabled": {
            "type": "boolean"
          },
          "guidance": {
            "additionalProperties": false,
            "properties": {
              "nextAction": {
                "enum": [
                  "create_payment_link",
                  "create_checkout_link",
                  "create_credit_topup",
                  "create_direct_order"
                ],
                "type": "string"
              },
              "recommendedMaxAmountCents": {
                "type": "number"
              },
              "recommendedTopupAmountCents": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "requiresConfirmLiveSend": {
                "type": "boolean"
              },
              "requiresIdempotencyKey": {
                "type": "boolean"
              },
              "walletDirectSendAlternative": {
                "additionalProperties": false,
                "properties": {
                  "nextAction": {
                    "enum": [
                      "create_credit_topup",
                      "create_direct_order"
                    ],
                    "type": "string"
                  },
                  "recommendedMaxAmountCents": {
                    "type": "number"
                  },
                  "recommendedTopupAmountCents": {
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "requiresConfirmLiveSend": {
                    "type": "boolean"
                  },
                  "requiresIdempotencyKey": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "nextAction",
                  "recommendedMaxAmountCents",
                  "recommendedTopupAmountCents",
                  "requiresConfirmLiveSend",
                  "requiresIdempotencyKey"
                ],
                "type": "object"
              }
            },
            "required": [
              "nextAction",
              "recommendedMaxAmountCents",
              "recommendedTopupAmountCents",
              "requiresConfirmLiveSend",
              "requiresIdempotencyKey",
              "walletDirectSendAlternative"
            ],
            "type": "object"
          },
          "liveEnabled": {
            "type": "boolean"
          },
          "missingBalanceCents": {
            "type": "number"
          },
          "mode": {
            "enum": [
              "test",
              "live"
            ],
            "type": "string"
          },
          "recipientCount": {
            "type": "number"
          },
          "requestType": {
            "enum": [
              "letter",
              "postcard"
            ],
            "type": "string"
          },
          "requiresTopup": {
            "type": "boolean"
          },
          "wallet": {
            "additionalProperties": false,
            "properties": {
              "balanceCents": {
                "type": "number"
              },
              "currency": {
                "enum": [
                  "eur",
                  "usd"
                ],
                "type": "string"
              },
              "mode": {
                "enum": [
                  "test",
                  "live"
                ],
                "type": "string"
              },
              "updatedAt": {
                "type": "string"
              }
            },
            "required": [
              "balanceCents",
              "currency",
              "mode",
              "updatedAt"
            ],
            "type": "object"
          }
        },
        "required": [
          "accountId",
          "amountCents",
          "approvalStatus",
          "approvedForDirectSend",
          "creditsEnabled",
          "guidance",
          "liveEnabled",
          "missingBalanceCents",
          "mode",
          "recipientCount",
          "requestType",
          "requiresTopup",
          "wallet"
        ],
        "type": "object"
      }
    },
    {
      "annotations": {
        "destructiveHint": false,
        "openWorldHint": false,
        "readOnlyHint": false
      },
      "description": "Create a hosted payment link for one-off MCP letter or postcard sending without public API keys or wallet credits. Provide exactly one of letters or postcard. Mail is sent only after checkout is paid. senderEmail is optional; Stripe Checkout collects the payer email when omitted. returnUrl is optional; PieterPost provides a hosted return page when omitted. Review the final message text before creating the link.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "composeMode": {
            "description": "Letter compose mode. Allowed values: \"personal\" or \"template\". personal uses each letter.message; template uses templateMessage and recipient customFields to generate each letter.",
            "type": "string"
          },
          "externalId": {
            "description": "Your correlation id for the created order/link.",
            "type": "string"
          },
          "idempotencyKey": {
            "description": "Stable idempotency key for retries. Always include this for create operations, especially in live mode.",
            "type": "string"
          },
          "letters": {
            "description": "Bulk letters. Maximum 25.",
            "items": {
              "additionalProperties": false,
              "description": "One letter for one recipient. In personal mode include a message, uploaded attachments, or both. In template mode, templateMessage can supply the message for every recipient. Destination page limits apply to the combined message and attachment pages.",
              "properties": {
                "attachments": {
                  "description": "Letter attachment asset IDs or upload_asset objects. Assets must be kind letter-attachment.",
                  "items": {
                    "description": "Attachment asset ID string or upload_asset-style object with assetId."
                  },
                  "type": "array"
                },
                "message": {
                  "description": "Letter body. Trimmed to 6,000 characters. Use \\n for line breaks; line breaks are preserved.",
                  "type": "string"
                },
                "recipient": {
                  "additionalProperties": true,
                  "description": "Recipient address. Provide name plus addressLines, or name with streetAddress or street plus number, postalCode, city, country, and state when required. Free-form address parsing is not performed.",
                  "properties": {
                    "addressLines": {
                      "description": "Preformatted address lines, excluding the recipient name.",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "city": {
                      "type": "string"
                    },
                    "country": {
                      "type": "string"
                    },
                    "customFields": {
                      "description": "Template variables available when letter or postcard composeMode is template.",
                      "additionalProperties": {
                        "type": "string"
                      },
                      "type": "object"
                    },
                    "extra": {
                      "type": "string"
                    },
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "number": {
                      "type": "string"
                    },
                    "postalCode": {
                      "type": "string"
                    },
                    "state": {
                      "type": "string"
                    },
                    "street": {
                      "type": "string"
                    },
                    "streetAddress": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "name"
                  ],
                  "type": "object"
                }
              },
              "required": [
                "recipient"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "locale": {
            "description": "Locale. Allowed values: \"de\", \"en\", \"es\", \"fr\", \"it\", or \"nl\".",
            "type": "string"
          },
          "metadata": {
            "additionalProperties": true,
            "description": "Up to 20 string, number, or boolean values copied to the order/link.",
            "type": "object"
          },
          "mode": {
            "description": "Mode. Allowed values: \"test\" or \"live\". Defaults to test when omitted.",
            "type": "string"
          },
          "postcard": {
            "additionalProperties": false,
            "description": "Postcard payload. Provide recipient for one card or recipients for bulk cards up to 25 recipients. Add frontImageAssetId or frontImage when you want a square 1:1 custom front instead of the default one.",
            "properties": {
              "composeMode": {
                "description": "Compose mode. Allowed values: \"personal\" or \"template\". personal sends one message as written; template lets recipient customFields replace variables in supported templates.",
                "type": "string"
              },
              "frontImage": {
                "description": "Optional square 1:1 postcard image asset ID string or upload_asset-style object. Equivalent to frontImageAssetId."
              },
              "frontImageAssetId": {
                "description": "Optional asset ID returned by upload_asset for a square 1:1 postcard-image.",
                "type": "string"
              },
              "message": {
                "description": "Postcard message. Trimmed to 400 characters. Use \\n for line breaks; line breaks are preserved.",
                "type": "string"
              },
              "recipient": {
                "additionalProperties": true,
                "description": "Recipient address. Provide name plus addressLines, or name with streetAddress or street plus number, postalCode, city, country, and state when required. Free-form address parsing is not performed.",
                "properties": {
                  "addressLines": {
                    "description": "Preformatted address lines, excluding the recipient name.",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "city": {
                    "type": "string"
                  },
                  "country": {
                    "type": "string"
                  },
                  "customFields": {
                    "description": "Template variables available when letter or postcard composeMode is template.",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "type": "object"
                  },
                  "extra": {
                    "type": "string"
                  },
                  "id": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "number": {
                    "type": "string"
                  },
                  "postalCode": {
                    "type": "string"
                  },
                  "state": {
                    "type": "string"
                  },
                  "street": {
                    "type": "string"
                  },
                  "streetAddress": {
                    "type": "string"
                  }
                },
                "required": [
                  "name"
                ],
                "type": "object"
              },
              "recipients": {
                "description": "Bulk postcard recipients. Maximum 25.",
                "items": {
                  "additionalProperties": true,
                  "description": "Recipient address. Provide name plus addressLines, or name with streetAddress or street plus number, postalCode, city, country, and state when required. Free-form address parsing is not performed.",
                  "properties": {
                    "addressLines": {
                      "description": "Preformatted address lines, excluding the recipient name.",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "city": {
                      "type": "string"
                    },
                    "country": {
                      "type": "string"
                    },
                    "customFields": {
                      "description": "Template variables available when letter or postcard composeMode is template.",
                      "additionalProperties": {
                        "type": "string"
                      },
                      "type": "object"
                    },
                    "extra": {
                      "type": "string"
                    },
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "number": {
                      "type": "string"
                    },
                    "postalCode": {
                      "type": "string"
                    },
                    "state": {
                      "type": "string"
                    },
                    "street": {
                      "type": "string"
                    },
                    "streetAddress": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "name"
                  ],
                  "type": "object"
                },
                "type": "array"
              },
              "variableKeys": {
                "description": "Template variable keys to use for postcard personalization.",
                "items": {
                  "type": "string"
                },
                "type": "array"
              }
            },
            "type": "object"
          },
          "requestType": {
            "description": "Request type. Allowed values: \"letter\" or \"postcard\". Use letter with letters, or postcard with postcard. If omitted, postcard is inferred when postcard is present.",
            "type": "string"
          },
          "senderEmail": {
            "description": "Optional order contact email. Hosted Stripe Checkout collects the payer email when omitted.",
            "type": "string"
          },
          "stampImage": {
            "description": "Letter stamp image asset ID string or upload_asset-style object. Equivalent to stampImageAssetId."
          },
          "stampImageAssetId": {
            "description": "Asset ID returned by upload_asset for a letter-stamp-image.",
            "type": "string"
          },
          "templateMessage": {
            "description": "Shared letter template used when composeMode is template. Supports {{name}}, {{first_name}}, {{address}}, {{street}}, {{city}}, {{postal_code}}, {{country}}, and recipient customFields. Use \\n for line breaks; line breaks are preserved.",
            "type": "string"
          },
          "variableKeys": {
            "description": "Letter template variable keys used for recipient customFields.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "paymentMethod": {
            "description": "Stripe-hosted checkout payment method. Allowed values: \"auto\", \"card\", or \"ideal\". auto is the default and offers card plus iDEAL for EUR checkout. ideal is available for EUR letter and postcard checkout links and EUR wallet top-ups.",
            "type": "string"
          },
          "returnUrl": {
            "description": "Optional checkout success/cancel redirect. PieterPost appends checkout=success or checkout=cancelled. Defaults to a PieterPost-hosted MCP return page.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "name": "create_payment_link",
      "outputSchema": {
        "additionalProperties": false,
        "properties": {
          "amountCents": {
            "type": "number"
          },
          "billingMode": {
            "enum": [
              "credits",
              "hosted_checkout"
            ],
            "type": "string"
          },
          "checkoutUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string"
          },
          "currency": {
            "enum": [
              "eur",
              "usd"
            ],
            "type": "string"
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "expiresAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "externalId": {
            "type": [
              "string",
              "null"
            ]
          },
          "fulfilledAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "metadata": {
            "additionalProperties": true,
            "type": "object"
          },
          "orderId": {
            "type": "string"
          },
          "orderRef": {
            "type": "string"
          },
          "paidAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "paymentReference": {
            "type": [
              "string",
              "null"
            ]
          },
          "recipientCount": {
            "type": "number"
          },
          "requestType": {
            "enum": [
              "letter",
              "postcard"
            ],
            "type": "string"
          },
          "senderEmail": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "enum": [
              "draft",
              "checkout_open",
              "paid",
              "queued",
              "fulfilled",
              "failed",
              "cancelled",
              "expired"
            ],
            "type": "string"
          },
          "testMode": {
            "type": "boolean"
          },
          "updatedAt": {
            "type": "string"
          },
          "wallet": {
            "additionalProperties": false,
            "properties": {
              "balanceCents": {
                "type": "number"
              },
              "currency": {
                "enum": [
                  "eur",
                  "usd"
                ],
                "type": "string"
              },
              "mode": {
                "enum": [
                  "test",
                  "live"
                ],
                "type": "string"
              },
              "updatedAt": {
                "type": "string"
              }
            },
            "required": [
              "balanceCents",
              "currency",
              "mode",
              "updatedAt"
            ],
            "type": "object"
          },
          "paymentLinkUrl": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "amountCents",
          "billingMode",
          "checkoutUrl",
          "createdAt",
          "currency",
          "error",
          "expiresAt",
          "externalId",
          "fulfilledAt",
          "metadata",
          "orderId",
          "orderRef",
          "paidAt",
          "paymentReference",
          "recipientCount",
          "requestType",
          "senderEmail",
          "status",
          "testMode",
          "updatedAt",
          "paymentLinkUrl"
        ],
        "type": "object"
      }
    },
    {
      "annotations": {
        "destructiveHint": false,
        "openWorldHint": false,
        "readOnlyHint": false
      },
      "description": "Create a hosted checkout link for letters or postcards. This is the public-API-compatible name for create_payment_link. Provide exactly one of letters or postcard. Supports bulk letters, letter template mode, custom letter stamps, bulk postcard recipients up to 25 recipients, letter attachments, and optional square 1:1 custom postcard front images. Mail is sent only after checkout is paid. senderEmail is optional for MCP calls; Stripe Checkout collects the payer email when omitted. returnUrl is optional for MCP calls. Review the final message text before creating the link.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "composeMode": {
            "description": "Letter compose mode. Allowed values: \"personal\" or \"template\". personal uses each letter.message; template uses templateMessage and recipient customFields to generate each letter.",
            "type": "string"
          },
          "externalId": {
            "description": "Your correlation id for the created order/link.",
            "type": "string"
          },
          "idempotencyKey": {
            "description": "Stable idempotency key for retries. Always include this for create operations, especially in live mode.",
            "type": "string"
          },
          "letters": {
            "description": "Bulk letters. Maximum 25.",
            "items": {
              "additionalProperties": false,
              "description": "One letter for one recipient. In personal mode include a message, uploaded attachments, or both. In template mode, templateMessage can supply the message for every recipient. Destination page limits apply to the combined message and attachment pages.",
              "properties": {
                "attachments": {
                  "description": "Letter attachment asset IDs or upload_asset objects. Assets must be kind letter-attachment.",
                  "items": {
                    "description": "Attachment asset ID string or upload_asset-style object with assetId."
                  },
                  "type": "array"
                },
                "message": {
                  "description": "Letter body. Trimmed to 6,000 characters. Use \\n for line breaks; line breaks are preserved.",
                  "type": "string"
                },
                "recipient": {
                  "additionalProperties": true,
                  "description": "Recipient address. Provide name plus addressLines, or name with streetAddress or street plus number, postalCode, city, country, and state when required. Free-form address parsing is not performed.",
                  "properties": {
                    "addressLines": {
                      "description": "Preformatted address lines, excluding the recipient name.",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "city": {
                      "type": "string"
                    },
                    "country": {
                      "type": "string"
                    },
                    "customFields": {
                      "description": "Template variables available when letter or postcard composeMode is template.",
                      "additionalProperties": {
                        "type": "string"
                      },
                      "type": "object"
                    },
                    "extra": {
                      "type": "string"
                    },
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "number": {
                      "type": "string"
                    },
                    "postalCode": {
                      "type": "string"
                    },
                    "state": {
                      "type": "string"
                    },
                    "street": {
                      "type": "string"
                    },
                    "streetAddress": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "name"
                  ],
                  "type": "object"
                }
              },
              "required": [
                "recipient"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "locale": {
            "description": "Locale. Allowed values: \"de\", \"en\", \"es\", \"fr\", \"it\", or \"nl\".",
            "type": "string"
          },
          "metadata": {
            "additionalProperties": true,
            "description": "Up to 20 string, number, or boolean values copied to the order/link.",
            "type": "object"
          },
          "mode": {
            "description": "Mode. Allowed values: \"test\" or \"live\". Defaults to test when omitted.",
            "type": "string"
          },
          "postcard": {
            "additionalProperties": false,
            "description": "Postcard payload. Provide recipient for one card or recipients for bulk cards up to 25 recipients. Add frontImageAssetId or frontImage when you want a square 1:1 custom front instead of the default one.",
            "properties": {
              "composeMode": {
                "description": "Compose mode. Allowed values: \"personal\" or \"template\". personal sends one message as written; template lets recipient customFields replace variables in supported templates.",
                "type": "string"
              },
              "frontImage": {
                "description": "Optional square 1:1 postcard image asset ID string or upload_asset-style object. Equivalent to frontImageAssetId."
              },
              "frontImageAssetId": {
                "description": "Optional asset ID returned by upload_asset for a square 1:1 postcard-image.",
                "type": "string"
              },
              "message": {
                "description": "Postcard message. Trimmed to 400 characters. Use \\n for line breaks; line breaks are preserved.",
                "type": "string"
              },
              "recipient": {
                "additionalProperties": true,
                "description": "Recipient address. Provide name plus addressLines, or name with streetAddress or street plus number, postalCode, city, country, and state when required. Free-form address parsing is not performed.",
                "properties": {
                  "addressLines": {
                    "description": "Preformatted address lines, excluding the recipient name.",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "city": {
                    "type": "string"
                  },
                  "country": {
                    "type": "string"
                  },
                  "customFields": {
                    "description": "Template variables available when letter or postcard composeMode is template.",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "type": "object"
                  },
                  "extra": {
                    "type": "string"
                  },
                  "id": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "number": {
                    "type": "string"
                  },
                  "postalCode": {
                    "type": "string"
                  },
                  "state": {
                    "type": "string"
                  },
                  "street": {
                    "type": "string"
                  },
                  "streetAddress": {
                    "type": "string"
                  }
                },
                "required": [
                  "name"
                ],
                "type": "object"
              },
              "recipients": {
                "description": "Bulk postcard recipients. Maximum 25.",
                "items": {
                  "additionalProperties": true,
                  "description": "Recipient address. Provide name plus addressLines, or name with streetAddress or street plus number, postalCode, city, country, and state when required. Free-form address parsing is not performed.",
                  "properties": {
                    "addressLines": {
                      "description": "Preformatted address lines, excluding the recipient name.",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "city": {
                      "type": "string"
                    },
                    "country": {
                      "type": "string"
                    },
                    "customFields": {
                      "description": "Template variables available when letter or postcard composeMode is template.",
                      "additionalProperties": {
                        "type": "string"
                      },
                      "type": "object"
                    },
                    "extra": {
                      "type": "string"
                    },
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "number": {
                      "type": "string"
                    },
                    "postalCode": {
                      "type": "string"
                    },
                    "state": {
                      "type": "string"
                    },
                    "street": {
                      "type": "string"
                    },
                    "streetAddress": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "name"
                  ],
                  "type": "object"
                },
                "type": "array"
              },
              "variableKeys": {
                "description": "Template variable keys to use for postcard personalization.",
                "items": {
                  "type": "string"
                },
                "type": "array"
              }
            },
            "type": "object"
          },
          "requestType": {
            "description": "Request type. Allowed values: \"letter\" or \"postcard\". Use letter with letters, or postcard with postcard. If omitted, postcard is inferred when postcard is present.",
            "type": "string"
          },
          "senderEmail": {
            "description": "Optional order contact email. Hosted Stripe Checkout collects the payer email when omitted.",
            "type": "string"
          },
          "stampImage": {
            "description": "Letter stamp image asset ID string or upload_asset-style object. Equivalent to stampImageAssetId."
          },
          "stampImageAssetId": {
            "description": "Asset ID returned by upload_asset for a letter-stamp-image.",
            "type": "string"
          },
          "templateMessage": {
            "description": "Shared letter template used when composeMode is template. Supports {{name}}, {{first_name}}, {{address}}, {{street}}, {{city}}, {{postal_code}}, {{country}}, and recipient customFields. Use \\n for line breaks; line breaks are preserved.",
            "type": "string"
          },
          "variableKeys": {
            "description": "Letter template variable keys used for recipient customFields.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "paymentMethod": {
            "description": "Stripe-hosted checkout payment method. Allowed values: \"auto\", \"card\", or \"ideal\". auto is the default and offers card plus iDEAL for EUR checkout. ideal is available for EUR letter and postcard checkout links and EUR wallet top-ups.",
            "type": "string"
          },
          "returnUrl": {
            "description": "Optional checkout success/cancel redirect. PieterPost appends checkout=success or checkout=cancelled. Defaults to a PieterPost-hosted MCP return page.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "name": "create_checkout_link",
      "outputSchema": {
        "additionalProperties": false,
        "properties": {
          "amountCents": {
            "type": "number"
          },
          "billingMode": {
            "enum": [
              "credits",
              "hosted_checkout"
            ],
            "type": "string"
          },
          "checkoutUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string"
          },
          "currency": {
            "enum": [
              "eur",
              "usd"
            ],
            "type": "string"
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "expiresAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "externalId": {
            "type": [
              "string",
              "null"
            ]
          },
          "fulfilledAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "metadata": {
            "additionalProperties": true,
            "type": "object"
          },
          "orderId": {
            "type": "string"
          },
          "orderRef": {
            "type": "string"
          },
          "paidAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "paymentReference": {
            "type": [
              "string",
              "null"
            ]
          },
          "recipientCount": {
            "type": "number"
          },
          "requestType": {
            "enum": [
              "letter",
              "postcard"
            ],
            "type": "string"
          },
          "senderEmail": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "enum": [
              "draft",
              "checkout_open",
              "paid",
              "queued",
              "fulfilled",
              "failed",
              "cancelled",
              "expired"
            ],
            "type": "string"
          },
          "testMode": {
            "type": "boolean"
          },
          "updatedAt": {
            "type": "string"
          },
          "wallet": {
            "additionalProperties": false,
            "properties": {
              "balanceCents": {
                "type": "number"
              },
              "currency": {
                "enum": [
                  "eur",
                  "usd"
                ],
                "type": "string"
              },
              "mode": {
                "enum": [
                  "test",
                  "live"
                ],
                "type": "string"
              },
              "updatedAt": {
                "type": "string"
              }
            },
            "required": [
              "balanceCents",
              "currency",
              "mode",
              "updatedAt"
            ],
            "type": "object"
          }
        },
        "required": [
          "amountCents",
          "billingMode",
          "checkoutUrl",
          "createdAt",
          "currency",
          "error",
          "expiresAt",
          "externalId",
          "fulfilledAt",
          "metadata",
          "orderId",
          "orderRef",
          "paidAt",
          "paymentReference",
          "recipientCount",
          "requestType",
          "senderEmail",
          "status",
          "testMode",
          "updatedAt"
        ],
        "type": "object"
      }
    },
    {
      "annotations": {
        "destructiveHint": true,
        "openWorldHint": false,
        "readOnlyHint": false
      },
      "description": "Create a direct-send order paid from wallet credits. Provide exactly one of letters or postcard. Supports bulk letters and postcards with the same payload shape as hosted checkout. Test mode simulates sending. Live mode sends real mail and requires confirmLiveSend=true plus maxAmountCents >= the calculated total. Review the final message text before sending.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "composeMode": {
            "description": "Letter compose mode. Allowed values: \"personal\" or \"template\". personal uses each letter.message; template uses templateMessage and recipient customFields to generate each letter.",
            "type": "string"
          },
          "externalId": {
            "description": "Your correlation id for the created order/link.",
            "type": "string"
          },
          "idempotencyKey": {
            "description": "Stable idempotency key for retries. Always include this for create operations, especially in live mode.",
            "type": "string"
          },
          "letters": {
            "description": "Bulk letters. Maximum 25.",
            "items": {
              "additionalProperties": false,
              "description": "One letter for one recipient. In personal mode include a message, uploaded attachments, or both. In template mode, templateMessage can supply the message for every recipient. Destination page limits apply to the combined message and attachment pages.",
              "properties": {
                "attachments": {
                  "description": "Letter attachment asset IDs or upload_asset objects. Assets must be kind letter-attachment.",
                  "items": {
                    "description": "Attachment asset ID string or upload_asset-style object with assetId."
                  },
                  "type": "array"
                },
                "message": {
                  "description": "Letter body. Trimmed to 6,000 characters. Use \\n for line breaks; line breaks are preserved.",
                  "type": "string"
                },
                "recipient": {
                  "additionalProperties": true,
                  "description": "Recipient address. Provide name plus addressLines, or name with streetAddress or street plus number, postalCode, city, country, and state when required. Free-form address parsing is not performed.",
                  "properties": {
                    "addressLines": {
                      "description": "Preformatted address lines, excluding the recipient name.",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "city": {
                      "type": "string"
                    },
                    "country": {
                      "type": "string"
                    },
                    "customFields": {
                      "description": "Template variables available when letter or postcard composeMode is template.",
                      "additionalProperties": {
                        "type": "string"
                      },
                      "type": "object"
                    },
                    "extra": {
                      "type": "string"
                    },
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "number": {
                      "type": "string"
                    },
                    "postalCode": {
                      "type": "string"
                    },
                    "state": {
                      "type": "string"
                    },
                    "street": {
                      "type": "string"
                    },
                    "streetAddress": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "name"
                  ],
                  "type": "object"
                }
              },
              "required": [
                "recipient"
              ],
              "type": "object"
            },
            "type": "array"
          },
          "locale": {
            "description": "Locale. Allowed values: \"de\", \"en\", \"es\", \"fr\", \"it\", or \"nl\".",
            "type": "string"
          },
          "metadata": {
            "additionalProperties": true,
            "description": "Up to 20 string, number, or boolean values copied to the order/link.",
            "type": "object"
          },
          "mode": {
            "description": "Mode. Allowed values: \"test\" or \"live\". Defaults to test when omitted.",
            "type": "string"
          },
          "postcard": {
            "additionalProperties": false,
            "description": "Postcard payload. Provide recipient for one card or recipients for bulk cards up to 25 recipients. Add frontImageAssetId or frontImage when you want a square 1:1 custom front instead of the default one.",
            "properties": {
              "composeMode": {
                "description": "Compose mode. Allowed values: \"personal\" or \"template\". personal sends one message as written; template lets recipient customFields replace variables in supported templates.",
                "type": "string"
              },
              "frontImage": {
                "description": "Optional square 1:1 postcard image asset ID string or upload_asset-style object. Equivalent to frontImageAssetId."
              },
              "frontImageAssetId": {
                "description": "Optional asset ID returned by upload_asset for a square 1:1 postcard-image.",
                "type": "string"
              },
              "message": {
                "description": "Postcard message. Trimmed to 400 characters. Use \\n for line breaks; line breaks are preserved.",
                "type": "string"
              },
              "recipient": {
                "additionalProperties": true,
                "description": "Recipient address. Provide name plus addressLines, or name with streetAddress or street plus number, postalCode, city, country, and state when required. Free-form address parsing is not performed.",
                "properties": {
                  "addressLines": {
                    "description": "Preformatted address lines, excluding the recipient name.",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "city": {
                    "type": "string"
                  },
                  "country": {
                    "type": "string"
                  },
                  "customFields": {
                    "description": "Template variables available when letter or postcard composeMode is template.",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "type": "object"
                  },
                  "extra": {
                    "type": "string"
                  },
                  "id": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "number": {
                    "type": "string"
                  },
                  "postalCode": {
                    "type": "string"
                  },
                  "state": {
                    "type": "string"
                  },
                  "street": {
                    "type": "string"
                  },
                  "streetAddress": {
                    "type": "string"
                  }
                },
                "required": [
                  "name"
                ],
                "type": "object"
              },
              "recipients": {
                "description": "Bulk postcard recipients. Maximum 25.",
                "items": {
                  "additionalProperties": true,
                  "description": "Recipient address. Provide name plus addressLines, or name with streetAddress or street plus number, postalCode, city, country, and state when required. Free-form address parsing is not performed.",
                  "properties": {
                    "addressLines": {
                      "description": "Preformatted address lines, excluding the recipient name.",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "city": {
                      "type": "string"
                    },
                    "country": {
                      "type": "string"
                    },
                    "customFields": {
                      "description": "Template variables available when letter or postcard composeMode is template.",
                      "additionalProperties": {
                        "type": "string"
                      },
                      "type": "object"
                    },
                    "extra": {
                      "type": "string"
                    },
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "number": {
                      "type": "string"
                    },
                    "postalCode": {
                      "type": "string"
                    },
                    "state": {
                      "type": "string"
                    },
                    "street": {
                      "type": "string"
                    },
                    "streetAddress": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "name"
                  ],
                  "type": "object"
                },
                "type": "array"
              },
              "variableKeys": {
                "description": "Template variable keys to use for postcard personalization.",
                "items": {
                  "type": "string"
                },
                "type": "array"
              }
            },
            "type": "object"
          },
          "requestType": {
            "description": "Request type. Allowed values: \"letter\" or \"postcard\". Use letter with letters, or postcard with postcard. If omitted, postcard is inferred when postcard is present.",
            "type": "string"
          },
          "senderEmail": {
            "description": "Optional order contact email. Hosted Stripe Checkout collects the payer email when omitted.",
            "type": "string"
          },
          "stampImage": {
            "description": "Letter stamp image asset ID string or upload_asset-style object. Equivalent to stampImageAssetId."
          },
          "stampImageAssetId": {
            "description": "Asset ID returned by upload_asset for a letter-stamp-image.",
            "type": "string"
          },
          "templateMessage": {
            "description": "Shared letter template used when composeMode is template. Supports {{name}}, {{first_name}}, {{address}}, {{street}}, {{city}}, {{postal_code}}, {{country}}, and recipient customFields. Use \\n for line breaks; line breaks are preserved.",
            "type": "string"
          },
          "variableKeys": {
            "description": "Letter template variable keys used for recipient customFields.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "confirmLiveSend": {
            "description": "Required true for live mode after explicit user confirmation.",
            "type": "boolean"
          },
          "maxAmountCents": {
            "description": "Required for live mode; caps the total spend.",
            "type": "number"
          }
        },
        "type": "object"
      },
      "name": "create_direct_order",
      "outputSchema": {
        "additionalProperties": false,
        "properties": {
          "amountCents": {
            "type": "number"
          },
          "billingMode": {
            "enum": [
              "credits",
              "hosted_checkout"
            ],
            "type": "string"
          },
          "checkoutUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string"
          },
          "currency": {
            "enum": [
              "eur",
              "usd"
            ],
            "type": "string"
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "expiresAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "externalId": {
            "type": [
              "string",
              "null"
            ]
          },
          "fulfilledAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "metadata": {
            "additionalProperties": true,
            "type": "object"
          },
          "orderId": {
            "type": "string"
          },
          "orderRef": {
            "type": "string"
          },
          "paidAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "paymentReference": {
            "type": [
              "string",
              "null"
            ]
          },
          "recipientCount": {
            "type": "number"
          },
          "requestType": {
            "enum": [
              "letter",
              "postcard"
            ],
            "type": "string"
          },
          "senderEmail": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "enum": [
              "draft",
              "checkout_open",
              "paid",
              "queued",
              "fulfilled",
              "failed",
              "cancelled",
              "expired"
            ],
            "type": "string"
          },
          "testMode": {
            "type": "boolean"
          },
          "updatedAt": {
            "type": "string"
          },
          "wallet": {
            "additionalProperties": false,
            "properties": {
              "balanceCents": {
                "type": "number"
              },
              "currency": {
                "enum": [
                  "eur",
                  "usd"
                ],
                "type": "string"
              },
              "mode": {
                "enum": [
                  "test",
                  "live"
                ],
                "type": "string"
              },
              "updatedAt": {
                "type": "string"
              }
            },
            "required": [
              "balanceCents",
              "currency",
              "mode",
              "updatedAt"
            ],
            "type": "object"
          }
        },
        "required": [
          "amountCents",
          "billingMode",
          "checkoutUrl",
          "createdAt",
          "currency",
          "error",
          "expiresAt",
          "externalId",
          "fulfilledAt",
          "metadata",
          "orderId",
          "orderRef",
          "paidAt",
          "paymentReference",
          "recipientCount",
          "requestType",
          "senderEmail",
          "status",
          "testMode",
          "updatedAt"
        ],
        "type": "object"
      }
    },
    {
      "annotations": {
        "destructiveHint": false,
        "openWorldHint": true,
        "readOnlyHint": false
      },
      "description": "Upload a square 1:1 postcard front image, letter attachment, or custom letter stamp for later use in create_checkout_link or create_direct_order. Provide exactly one of fileBase64 or a public HTTPS fileUrl. Returns an assetId that can be passed as postcard.frontImageAssetId, stampImageAssetId, or in a letter attachments array.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "contentType": {
            "description": "Content type. Common values: \"application/pdf\" for letter attachments, or \"image/png\" / \"image/jpeg\" for images.",
            "type": "string"
          },
          "fileBase64": {
            "description": "Base64-encoded file contents.",
            "type": "string"
          },
          "fileName": {
            "description": "Original file name, used for extension validation.",
            "type": "string"
          },
          "fileUrl": {
            "description": "Public HTTPS URL to fetch. Private and localhost URLs are rejected.",
            "type": "string"
          },
          "kind": {
            "description": "Upload kind. Allowed values: \"letter-attachment\", \"letter-stamp-image\", or \"postcard-image\".",
            "type": "string"
          }
        },
        "required": [
          "kind",
          "fileName",
          "contentType"
        ],
        "type": "object"
      },
      "name": "upload_asset",
      "outputSchema": {
        "additionalProperties": true,
        "type": "object"
      }
    },
    {
      "annotations": {
        "destructiveHint": false,
        "openWorldHint": false,
        "readOnlyHint": true
      },
      "description": "Read the API wallet balance and account capability flags for test or live mode.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "currency": {
            "description": "Currency. Allowed values: \"eur\" or \"usd\".",
            "type": "string"
          },
          "mode": {
            "description": "Mode. Allowed values: \"test\" or \"live\". Defaults to test when omitted.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "name": "get_wallet",
      "outputSchema": {
        "additionalProperties": false,
        "properties": {
          "accountId": {
            "type": "string"
          },
          "approvalStatus": {
            "enum": [
              "pending",
              "approved",
              "rejected"
            ],
            "type": "string"
          },
          "approvedForDirectSend": {
            "type": "boolean"
          },
          "creditsEnabled": {
            "type": "boolean"
          },
          "hostedApiEnabled": {
            "type": "boolean"
          },
          "liveEnabled": {
            "type": "boolean"
          },
          "wallet": {
            "additionalProperties": false,
            "properties": {
              "balanceCents": {
                "type": "number"
              },
              "currency": {
                "enum": [
                  "eur",
                  "usd"
                ],
                "type": "string"
              },
              "mode": {
                "enum": [
                  "test",
                  "live"
                ],
                "type": "string"
              },
              "updatedAt": {
                "type": "string"
              }
            },
            "required": [
              "balanceCents",
              "currency",
              "mode",
              "updatedAt"
            ],
            "type": "object"
          }
        },
        "required": [
          "accountId",
          "approvalStatus",
          "approvedForDirectSend",
          "creditsEnabled",
          "hostedApiEnabled",
          "liveEnabled",
          "wallet"
        ],
        "type": "object"
      }
    },
    {
      "annotations": {
        "destructiveHint": false,
        "openWorldHint": false,
        "readOnlyHint": true
      },
      "description": "Fetch a PieterPost API order by id, including hosted checkout/direct-send status, recipient count, amount, and error details.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "mode": {
            "description": "Mode. Allowed values: \"test\" or \"live\". Defaults to test when omitted.",
            "type": "string"
          },
          "orderId": {
            "type": "string"
          }
        },
        "required": [
          "orderId"
        ],
        "type": "object"
      },
      "name": "get_order",
      "outputSchema": {
        "additionalProperties": false,
        "properties": {
          "amountCents": {
            "type": "number"
          },
          "billingMode": {
            "enum": [
              "credits",
              "hosted_checkout"
            ],
            "type": "string"
          },
          "checkoutUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string"
          },
          "currency": {
            "enum": [
              "eur",
              "usd"
            ],
            "type": "string"
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "expiresAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "externalId": {
            "type": [
              "string",
              "null"
            ]
          },
          "fulfilledAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "metadata": {
            "additionalProperties": true,
            "type": "object"
          },
          "orderId": {
            "type": "string"
          },
          "orderRef": {
            "type": "string"
          },
          "paidAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "paymentReference": {
            "type": [
              "string",
              "null"
            ]
          },
          "recipientCount": {
            "type": "number"
          },
          "requestType": {
            "enum": [
              "letter",
              "postcard"
            ],
            "type": "string"
          },
          "senderEmail": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "enum": [
              "draft",
              "checkout_open",
              "paid",
              "queued",
              "fulfilled",
              "failed",
              "cancelled",
              "expired"
            ],
            "type": "string"
          },
          "testMode": {
            "type": "boolean"
          },
          "updatedAt": {
            "type": "string"
          },
          "wallet": {
            "additionalProperties": false,
            "properties": {
              "balanceCents": {
                "type": "number"
              },
              "currency": {
                "enum": [
                  "eur",
                  "usd"
                ],
                "type": "string"
              },
              "mode": {
                "enum": [
                  "test",
                  "live"
                ],
                "type": "string"
              },
              "updatedAt": {
                "type": "string"
              }
            },
            "required": [
              "balanceCents",
              "currency",
              "mode",
              "updatedAt"
            ],
            "type": "object"
          }
        },
        "required": [
          "amountCents",
          "billingMode",
          "checkoutUrl",
          "createdAt",
          "currency",
          "error",
          "expiresAt",
          "externalId",
          "fulfilledAt",
          "metadata",
          "orderId",
          "orderRef",
          "paidAt",
          "paymentReference",
          "recipientCount",
          "requestType",
          "senderEmail",
          "status",
          "testMode",
          "updatedAt"
        ],
        "type": "object"
      }
    },
    {
      "annotations": {
        "destructiveHint": false,
        "openWorldHint": false,
        "readOnlyHint": true
      },
      "description": "Fetch a PieterPost wallet top-up by id, including payment status and checkout URL when still pending.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "mode": {
            "description": "Mode. Allowed values: \"test\" or \"live\". Defaults to test when omitted.",
            "type": "string"
          },
          "topupId": {
            "type": "string"
          }
        },
        "required": [
          "topupId"
        ],
        "type": "object"
      },
      "name": "get_topup",
      "outputSchema": {
        "additionalProperties": false,
        "properties": {
          "amountCents": {
            "type": "number"
          },
          "checkoutUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string"
          },
          "currency": {
            "enum": [
              "eur",
              "usd"
            ],
            "type": "string"
          },
          "paidAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "enum": [
              "pending",
              "paid",
              "cancelled",
              "expired",
              "failed"
            ],
            "type": "string"
          },
          "testMode": {
            "type": "boolean"
          },
          "topupId": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          },
          "wallet": {
            "additionalProperties": false,
            "properties": {
              "balanceCents": {
                "type": "number"
              },
              "currency": {
                "enum": [
                  "eur",
                  "usd"
                ],
                "type": "string"
              },
              "mode": {
                "enum": [
                  "test",
                  "live"
                ],
                "type": "string"
              },
              "updatedAt": {
                "type": "string"
              }
            },
            "required": [
              "balanceCents",
              "currency",
              "mode",
              "updatedAt"
            ],
            "type": "object"
          }
        },
        "required": [
          "amountCents",
          "checkoutUrl",
          "createdAt",
          "currency",
          "paidAt",
          "status",
          "testMode",
          "topupId",
          "updatedAt"
        ],
        "type": "object"
      }
    },
    {
      "annotations": {
        "destructiveHint": false,
        "openWorldHint": false,
        "readOnlyHint": true
      },
      "description": "List recent PieterPost wallet top-ups for this account. Use mode and currency filters to inspect the active live or test funding history.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "currency": {
            "description": "Currency. Allowed values: \"eur\" or \"usd\".",
            "type": "string"
          },
          "limit": {
            "description": "Maximum number of top-ups to return. Typical range is 1 to 20.",
            "type": "number"
          },
          "mode": {
            "description": "Mode. Allowed values: \"test\" or \"live\". Defaults to test when omitted.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "name": "list_topups",
      "outputSchema": {
        "additionalProperties": false,
        "properties": {
          "topups": {
            "items": {
              "additionalProperties": false,
              "properties": {
                "amountCents": {
                  "type": "number"
                },
                "checkoutUrl": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "createdAt": {
                  "type": "string"
                },
                "currency": {
                  "enum": [
                    "eur",
                    "usd"
                  ],
                  "type": "string"
                },
                "paidAt": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "status": {
                  "enum": [
                    "pending",
                    "paid",
                    "cancelled",
                    "expired",
                    "failed"
                  ],
                  "type": "string"
                },
                "testMode": {
                  "type": "boolean"
                },
                "topupId": {
                  "type": "string"
                },
                "updatedAt": {
                  "type": "string"
                },
                "wallet": {
                  "additionalProperties": false,
                  "properties": {
                    "balanceCents": {
                      "type": "number"
                    },
                    "currency": {
                      "enum": [
                        "eur",
                        "usd"
                      ],
                      "type": "string"
                    },
                    "mode": {
                      "enum": [
                        "test",
                        "live"
                      ],
                      "type": "string"
                    },
                    "updatedAt": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "balanceCents",
                    "currency",
                    "mode",
                    "updatedAt"
                  ],
                  "type": "object"
                }
              },
              "required": [
                "amountCents",
                "checkoutUrl",
                "createdAt",
                "currency",
                "paidAt",
                "status",
                "testMode",
                "topupId",
                "updatedAt"
              ],
              "type": "object"
            },
            "type": "array"
          }
        },
        "required": [
          "topups"
        ],
        "type": "object"
      }
    },
    {
      "annotations": {
        "destructiveHint": false,
        "openWorldHint": false,
        "readOnlyHint": false
      },
      "description": "Create a test credit top-up immediately, or create a live Stripe checkout URL for adding API credits used by direct-send orders. paymentMethod=auto is the default; for EUR top-ups it offers both card and iDEAL. Pass paymentMethod=card or paymentMethod=ideal only when the user wants to force one method.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "amountCents": {
            "description": "Top-up amount in cents. Rounded up to whole euros.",
            "type": "number"
          },
          "currency": {
            "description": "Currency. Allowed values: \"eur\" or \"usd\".",
            "type": "string"
          },
          "idempotencyKey": {
            "description": "Stable idempotency key for retries. Always include this for create operations, especially in live mode.",
            "type": "string"
          },
          "metadata": {
            "additionalProperties": true,
            "description": "Up to 20 string, number, or boolean values copied to the order/link.",
            "type": "object"
          },
          "mode": {
            "description": "Mode. Allowed values: \"test\" or \"live\". Defaults to test when omitted.",
            "type": "string"
          },
          "paymentMethod": {
            "description": "Stripe-hosted checkout payment method. Allowed values: \"auto\", \"card\", or \"ideal\". auto is the default and offers card plus iDEAL for EUR checkout. ideal is available for EUR letter and postcard checkout links and EUR wallet top-ups.",
            "type": "string"
          },
          "returnUrl": {
            "description": "Used for live Stripe checkout success/cancel redirects.",
            "type": "string"
          }
        },
        "required": [
          "amountCents"
        ],
        "type": "object"
      },
      "name": "create_credit_topup",
      "outputSchema": {
        "additionalProperties": false,
        "properties": {
          "amountCents": {
            "type": "number"
          },
          "checkoutUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string"
          },
          "currency": {
            "enum": [
              "eur",
              "usd"
            ],
            "type": "string"
          },
          "paidAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "enum": [
              "pending",
              "paid",
              "cancelled",
              "expired",
              "failed"
            ],
            "type": "string"
          },
          "testMode": {
            "type": "boolean"
          },
          "topupId": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          },
          "wallet": {
            "additionalProperties": false,
            "properties": {
              "balanceCents": {
                "type": "number"
              },
              "currency": {
                "enum": [
                  "eur",
                  "usd"
                ],
                "type": "string"
              },
              "mode": {
                "enum": [
                  "test",
                  "live"
                ],
                "type": "string"
              },
              "updatedAt": {
                "type": "string"
              }
            },
            "required": [
              "balanceCents",
              "currency",
              "mode",
              "updatedAt"
            ],
            "type": "object"
          }
        },
        "required": [
          "amountCents",
          "checkoutUrl",
          "createdAt",
          "currency",
          "paidAt",
          "status",
          "testMode",
          "topupId",
          "updatedAt"
        ],
        "type": "object"
      }
    },
    {
      "annotations": {
        "destructiveHint": false,
        "openWorldHint": false,
        "readOnlyHint": true
      },
      "description": "List API key metadata for this PieterPost API account. Secrets are never returned.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {},
        "type": "object"
      },
      "name": "list_api_keys",
      "outputSchema": {
        "additionalProperties": false,
        "properties": {
          "keys": {
            "items": {
              "additionalProperties": false,
              "properties": {
                "createdAt": {
                  "type": "string"
                },
                "id": {
                  "type": "string"
                },
                "lastUsedAt": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "mode": {
                  "enum": [
                    "test",
                    "live"
                  ],
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "revokedAt": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "status": {
                  "enum": [
                    "active",
                    "paused",
                    "revoked"
                  ],
                  "type": "string"
                },
                "tokenLast4": {
                  "type": "string"
                }
              },
              "required": [
                "createdAt",
                "id",
                "lastUsedAt",
                "mode",
                "name",
                "revokedAt",
                "status",
                "tokenLast4"
              ],
              "type": "object"
            },
            "type": "array"
          }
        },
        "required": [
          "keys"
        ],
        "type": "object"
      }
    },
    {
      "annotations": {
        "destructiveHint": false,
        "openWorldHint": false,
        "readOnlyHint": false
      },
      "description": "Create a new PieterPost public API key. The secret is returned once and cannot be recovered later.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "mode": {
            "description": "Mode. Allowed values: \"test\" or \"live\". Defaults to test when omitted.",
            "type": "string"
          },
          "name": {
            "description": "Human-readable key name.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "name": "create_api_key",
      "outputSchema": {
        "additionalProperties": false,
        "properties": {
          "key": {
            "additionalProperties": false,
            "properties": {
              "createdAt": {
                "type": "string"
              },
              "id": {
                "type": "string"
              },
              "lastUsedAt": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "mode": {
                "enum": [
                  "test",
                  "live"
                ],
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "revokedAt": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "status": {
                "enum": [
                  "active",
                  "paused",
                  "revoked"
                ],
                "type": "string"
              },
              "tokenLast4": {
                "type": "string"
              }
            },
            "required": [
              "createdAt",
              "id",
              "lastUsedAt",
              "mode",
              "name",
              "revokedAt",
              "status",
              "tokenLast4"
            ],
            "type": "object"
          },
          "secret": {
            "type": "string"
          },
          "warning": {
            "type": "string"
          }
        },
        "required": [
          "key",
          "secret",
          "warning"
        ],
        "type": "object"
      }
    },
    {
      "annotations": {
        "destructiveHint": true,
        "openWorldHint": false,
        "readOnlyHint": false
      },
      "description": "Revoke an existing PieterPost public API key by id.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "keyId": {
            "type": "string"
          }
        },
        "required": [
          "keyId"
        ],
        "type": "object"
      },
      "name": "revoke_api_key",
      "outputSchema": {
        "additionalProperties": false,
        "properties": {
          "key": {
            "additionalProperties": false,
            "properties": {
              "createdAt": {
                "type": "string"
              },
              "id": {
                "type": "string"
              },
              "lastUsedAt": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "mode": {
                "enum": [
                  "test",
                  "live"
                ],
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "revokedAt": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "status": {
                "enum": [
                  "active",
                  "paused",
                  "revoked"
                ],
                "type": "string"
              },
              "tokenLast4": {
                "type": "string"
              }
            },
            "required": [
              "createdAt",
              "id",
              "lastUsedAt",
              "mode",
              "name",
              "revokedAt",
              "status",
              "tokenLast4"
            ],
            "type": "object"
          },
          "revoked": {
            "type": "boolean"
          }
        },
        "required": [
          "key",
          "revoked"
        ],
        "type": "object"
      }
    }
  ]
}
```

## Example tool arguments
### list_mailbook_contacts before sending to a saved contact
```json
{
  "limit": 5,
  "query": "Bart"
}
```
### quote_order for a postcard to a Mailbook contact
```json
{
  "idempotencyKey": "postcard_bart_2026_05_01_quote",
  "mode": "live",
  "postcard": {
    "message": "Hi Bart,\nA postcard from PieterPost MCP.",
    "recipient": {
      "addressLines": [
        "Keizersgracht 1",
        "1012 AB Amsterdam",
        "Netherlands"
      ],
      "city": "Amsterdam",
      "country": "NL",
      "id": "contact_bart_123",
      "name": "Bart",
      "postalCode": "1012 AB",
      "streetAddress": "Keizersgracht 1"
    }
  },
  "requestType": "postcard"
}
```
### upload_asset for a postcard image
```json
{
  "contentType": "image/jpeg",
  "fileName": "front.jpg",
  "fileUrl": "https://example.com/front.jpg",
  "kind": "postcard-image"
}
```
### quote_order before a live direct-send postcard
```json
{
  "idempotencyKey": "quote_live_postcard_123",
  "locale": "en",
  "mode": "live",
  "postcard": {
    "frontImageAssetId": "asset_postcard_front_123",
    "message": "Bart,\nA postcard from PieterPost MCP.",
    "recipient": {
      "city": "Amsterdam",
      "country": "NL",
      "customFields": {
        "gift_code": "SPRING-10"
      },
      "name": "Pieter Example",
      "postalCode": "1012 AB",
      "streetAddress": "Damrak 1"
    }
  },
  "requestType": "postcard"
}
```
### upload_asset for a letter attachment
```json
{
  "contentType": "application/pdf",
  "fileBase64": "JVBERi0xLjQK...",
  "fileName": "receipt.pdf",
  "kind": "letter-attachment"
}
```
### upload_asset for a letter stamp image
```json
{
  "contentType": "image/png",
  "fileBase64": "iVBORw0KGgo...",
  "fileName": "stamp.png",
  "kind": "letter-stamp-image"
}
```
### create_payment_link for a letter with attachment
```json
{
  "externalId": "invoice_123",
  "idempotencyKey": "invoice_123_checkout",
  "letters": [
    {
      "attachments": [
        "asset_letter_pdf_123"
      ],
      "message": "Thanks for your order. The receipt PDF is enclosed.",
      "recipient": {
        "city": "Amsterdam",
        "country": "NL",
        "customFields": {
          "gift_code": "SPRING-10"
        },
        "name": "Pieter Example",
        "postalCode": "1012 AB",
        "streetAddress": "Damrak 1"
      }
    }
  ],
  "locale": "en",
  "metadata": {
    "customerId": "cus_123"
  },
  "mode": "test",
  "requestType": "letter"
}
```
### create_payment_link for bulk template letters
```json
{
  "composeMode": "template",
  "externalId": "spring_campaign_123",
  "idempotencyKey": "spring_campaign_123_checkout",
  "letters": [
    {
      "recipient": {
        "city": "Amsterdam",
        "country": "NL",
        "customFields": {
          "gift_code": "SPRING-10"
        },
        "name": "Pieter Example",
        "postalCode": "1012 AB",
        "streetAddress": "Damrak 1"
      }
    },
    {
      "recipient": {
        "city": "Amsterdam",
        "country": "NL",
        "customFields": {
          "gift_code": "SPRING-20"
        },
        "name": "Sam Example",
        "postalCode": "1012 AB",
        "streetAddress": "Damrak 1"
      }
    }
  ],
  "locale": "en",
  "mode": "test",
  "requestType": "letter",
  "stampImageAssetId": "asset_stamp_123",
  "templateMessage": "Hi {{first_name}},\nYour spring code is {{gift_code}}.",
  "variableKeys": [
    "gift_code"
  ]
}
```
### create_payment_link for a postcard
```json
{
  "idempotencyKey": "postcard_123_checkout",
  "locale": "en",
  "mode": "test",
  "paymentMethod": "ideal",
  "postcard": {
    "frontImageAssetId": "asset_postcard_front_123",
    "message": "A small card from PieterPost.",
    "recipients": [
      {
        "city": "Amsterdam",
        "country": "NL",
        "customFields": {
          "gift_code": "SPRING-10"
        },
        "name": "Pieter Example",
        "postalCode": "1012 AB",
        "streetAddress": "Damrak 1"
      }
    ]
  },
  "requestType": "postcard"
}
```
### create_direct_order for live wallet-funded mail
```json
{
  "composeMode": "template",
  "externalId": "spring_campaign_123",
  "idempotencyKey": "spring_campaign_123_live_send",
  "letters": [
    {
      "recipient": {
        "city": "Amsterdam",
        "country": "NL",
        "customFields": {
          "gift_code": "SPRING-10"
        },
        "name": "Pieter Example",
        "postalCode": "1012 AB",
        "streetAddress": "Damrak 1"
      }
    },
    {
      "recipient": {
        "city": "Amsterdam",
        "country": "NL",
        "customFields": {
          "gift_code": "SPRING-20"
        },
        "name": "Sam Example",
        "postalCode": "1012 AB",
        "streetAddress": "Damrak 1"
      }
    }
  ],
  "locale": "en",
  "mode": "live",
  "requestType": "letter",
  "stampImageAssetId": "asset_stamp_123",
  "templateMessage": "Hi {{first_name}},\nYour spring code is {{gift_code}}.",
  "variableKeys": [
    "gift_code"
  ],
  "confirmLiveSend": true,
  "maxAmountCents": 2000
}
```
### create_credit_topup
```json
{
  "amountCents": 2500,
  "currency": "eur",
  "idempotencyKey": "credits_2026_04",
  "metadata": {
    "source": "mcp"
  },
  "mode": "live",
  "paymentMethod": "ideal",
  "returnUrl": "https://example.com/topups/return"
}
```
### get_topup
```json
{
  "mode": "live",
  "topupId": "topup_123"
}
```
### list_topups
```json
{
  "currency": "eur",
  "limit": 5,
  "mode": "live"
}
```

## Operational guidance for agents
- Start with `search` or `fetch` when the user asks how PieterPost works or you need account context.
- When the user refers to a saved contact by name, call `list_mailbook_contacts` and confirm the selected recipient if the search returns ambiguous matches.
- For requests like `send this message to Bart`, do not ask for Bart's address first. Search Mailbook for Bart, use the selected `recipient`, then review the final message and continue through the normal quote/send flow.
- Use `quote_order` before the first live letter or postcard so you can confirm the amount, recipient count, and next action.
- For ordinary requests like `send a letter to ...`, default to one-off sending with `create_payment_link`, not wallet credits or public API keys.
- Before any send or hosted checkout handoff, read back and verify the final message text you are placing on the letter or postcard.
- Use `upload_asset` before any order requiring postcard fronts, letter attachments, or custom letter stamps. For postcards, only use square 1:1 custom front images.
- Prefer `create_payment_link` when a payer should review and pay in hosted checkout without API keys or wallet credits. `create_checkout_link` remains available as the API-compatible alias.
- Prefer `create_compose_link` when the user should review or edit a single recipient message in PieterPost.
- Use `get_topup` or `list_topups` to confirm whether a live wallet top-up is still pending or already paid.
- Use `create_direct_order` when the user wants wallet-funded/API-credit sending. For live sends, get explicit confirmation and a maximum spend cap first.
- Use `idempotencyKey` for every create operation that may be retried.