MCP Server

The Lifepeaks MCP server exposes part of the v2 API as tools, a resource, and prompts that any MCP-compatible AI agent can use. Each tool does exactly what the matching REST endpoint does, with the same scope and the same validation.

Three areas are covered: headless commerce reads and order creation, branded gift-card PDF templates, and configuration of the Lifepeaks-hosted order page.

Payment confirmation, capture, refunds, and negotiated settlement are deliberately not exposed as tools. Those decisions stay with your own server against the REST API.

Connecting

The MCP endpoint speaks JSON-RPC over streamable HTTP:

text
https://api.lifepeaks.dk/mcp

All requests require a Bearer API key in the Authorization header:

text
Authorization: Bearer lp_live_<your-key>

The tool list depends on the key. The server registers only the tools the presented key holds the scope for, so an agent with a read-only key never sees a write tool at all. A key with no matching scope connects successfully and sees an empty tool list.

Write tools additionally require the key to be attributable to a credential record, which every key issued through POST /v2/api-keys or the admin UI is.

Install

Claude Code — one command, with the key supplied as a header:

bash
claude mcp add --transport http lifepeaks https://api.lifepeaks.dk/mcp \
  --header "Authorization: Bearer lp_live_<your-key>"

Cursor and VS Code install from a deep link. Both carry the endpoint plus a placeholder Authorization header — after installing, replace lp_live_<your-key> with your own key in the client's MCP settings.

Any other MCP client:

bash
npx add-mcp https://api.lifepeaks.dk/mcp

add-mcp registers the endpoint only, so add the Authorization header in that client's MCP configuration afterwards. Without it every call returns 401.

Available tools

Headless commerce

ToolScope requiredDescription
commerce_list_productscatalog:readList every product the company sells — its variable-value gift card, its experiences, its events and its special offers — with the limits, prices and fees of each, plus how a card can be delivered, what a buyer may add to it, and the terms
commerce_list_pickup_pointscatalog:readFind the courier's collection points near one postcode, for a postal order
commerce_create_quotequotes:createCalculate an authoritative quote for one value gift-card line, or for up to twenty lines of one other family
commerce_get_orderorders:readRead canonical order, payment, and fulfillment state
commerce_create_orderorders:createCreate an unpaid order — this never confirms payment
commerce_create_checkoutcheckout:createCreate a Lifepeaks-hosted QuickPay checkout for an unpaid order

Amounts in these tools are whole numbers of the smallest unit of the currency, exactly as in the REST API: 50000 is DKK 500.00. Whole numbers of the smallest unit avoid rounding errors.

Every product family is read, priced and ordered here. commerce_list_products answers with the same catalog GET /v2/products returns, so an agent can discover a gcv_ experience, an evt_ event or an so_ special offer and the option a buyer wants. commerce_create_quote and commerce_create_order take the same lines the HTTP routes take, under the same rules: every line but a value one names a product_option_id and never an amount, a request carries one value line or one to twenty lines of a single other family, families are never mixed, an option appears once, and one order issues at most 1000 items. Both also take the same delivery object, and commerce_create_quote needs it whenever the buyer is posting the card: a postal quote sent without it reports shipping of 0, and the order then charges up to DKK 175,00 more. Price the selection with commerce_create_quote before creating the order, so the user approves a total Lifepeaks calculated. See Quote and order lines for every rule and the exact 422 a broken line gets.

Read fee_basis before totalling anything. It is per_line for gift cards, experiences and special offers, and per_ticket for events. An agent that assumes one fee per line quotes a two-seat event line short by a whole ticket fee.

An event line carries what the organiser asked for. commerce_create_quote and commerce_create_order accept an optional ticket object on an event line: comment, code, collection_point_id and address. Each one is conditional on something the product publishes — the event's comment.available and the option's requires.code, requires.address and requires.collection_point — so read the product and send only what it asks for. A collection point is an epp_<n> from the event's own event.collection_points and is not what commerce_list_pickup_points answers with; those are courier collection points for posting a gift card. address and collection_point_id are alternatives, and one event takes one comment however many lines name it.

A special offer publishes what the voucher is worth. redemption_value on an offer option is what the issued voucher can be spent on, and it is not always what the buyer pays: an offer configured to redeem at the regular price sells at amount and redeems at regular_amount. Tell the user redemption_value when describing what they are getting.

A business buyer goes in sender.company. commerce_create_order takes the buyer's own company there — name and vat_number always, and street, postcode, city, country as an all-or-nothing set. It is on the sender alone; the recipient schema has no company, because the company an envelope is addressed to is delivery.address.company_name and a different thing. A product whose company_required is true, or an event whose event.requires.company is true, refuses an order without it under sender_company_required. Never invent a VAT number.

A discount code is a plain string, and Lifepeaks does the arithmetic. commerce_create_quote and commerce_create_order take discount_code; there is nowhere for an agent to put a discount amount, deliberately. The answer comes back as amounts.discount, a positive figure that is subtracted, and a top-level discount object naming the code and its percentage. total is subtotaldiscount + fees + shipping. A code never reduces fees, never applies to an event ticket or a special offer, and a shipping code comes off amounts.shipping while leaving amounts.discount at 0.

A quote reserves nothing. commerce_create_order locks the option rows and re-checks stock, minimums, maximums and capacity before it writes, so an agent that quoted a last seat can still be refused at the order. Re-quote before asking the user to pay.

Neither an event ticket nor a special offer can be posted. delivery.method of postal on such an order is refused, and their shipping is always 0.

Delivery and the greeting are read before the order, not guessed at, and they come back with the product. Each entry commerce_list_products answers carries delivery_methods — which of sender_email, recipient_email and postal the company actually offers, what each costs, and which of them can be scheduled — and personalization, which says how long a greeting may be and which pictures the company offers for the greeting page. An empty designs list means there is nothing to choose. There is no second tool for either: one product call is everything an agent needs to describe a whole order, and one list cannot fall out of step with another. commerce_create_order then carries the user's answers as greeting and delivery on the order body. See How the card is delivered.

commerce_list_pickup_points is the one delivery fact not already on the product, because collection points open, close and move. It is a live call to the courier and is rate-limited, so ask for points once the user has given a postcode rather than exploring. Its country is a two-letter ISO 3166-1 code; a country name is refused rather than guessed at.

How fast a posted card travels is on the product too. A company that posts its own cards publishes a priorities list of spri_<n> speeds on its postal method, and commerce_create_order names one as delivery.shipping_priority. The key is absent whenever there is no genuine choice, and sending a priority then is refused rather than ignored, so read the product before offering the option. Omitting it charges the cheapest, which is the price destinations[] already publishes.

Marketing consent is recorded, never assumed. commerce_create_order takes the same marketing_consent object the HTTP body takes, so an agent can carry a user's answer onto the order. Send it only when the user was actually shown a consent sentence and acted on it, and put that sentence in consent_text verbatim — it is the evidence, so it must never be composed or paraphrased. Omit the object when nobody was asked. See Marketing consent.

A buyer's own photograph cannot be uploaded over MCP. The protocol has no way to carry the bytes, so greeting.image over MCP names one of the company's own pictures with design_id, or an upload_id that an HTTP client already finalized. An agent with neither should send a message with "source": "none" rather than invent an id.

Branded gift-card PDF templates

ToolScope requiredDescription
pdf_templates_get_currentpdf_templates:readRead the template in force for a locale (defaults to da-DK); optional lang
pdf_templates_listpdf_templates:readList stored template versions; optional lang narrows to one locale
pdf_templates_getpdf_templates:readRead one template version
pdf_templates_previewpdf_templates:readGet a controlled preview URL, with no storage details
pdf_templates_create_upload_intentpdf_templates:writeCreate a short-lived upload target bound to a checksum and a size. The type is always application/pdf and is not an argument
pdf_templates_finalizepdf_templates:writeValidate an uploaded file into one immutable version
pdf_templates_publishpdf_templates:writeSelect a validated version for future orders
pdf_templates_revert_to_defaultpdf_templates:writeGo back to the company-branded default for a locale

Hosted order page

ToolScope requiredDescription
orderpage_get_currentorderpage:readRead the live configuration and published revision metadata; optional lang
orderpage_list_fieldsorderpage:readList every writable field with its type and constraints
orderpage_list_revisionsorderpage:readList draft, published, and archived revisions; optional lang narrows to one locale
orderpage_get_revisionorderpage:readRead one revision, including its fields and ETag
orderpage_preview_draftorderpage:readPreview a draft without touching the live page
orderpage_create_draftorderpage:writeStart a draft — the live page is unchanged
orderpage_update_draftorderpage:writeEdit a draft using its exact ETag
orderpage_publish_draftorderpage:writePublish a reviewed draft to the live page

Resource

Resource URIScope requiredDescription
orderpage://schemaorderpage:readThe writable field catalog as a structured resource

Built-in prompts

PromptAppears when the key canPurpose
build_headless_checkoutReach any commerce toolThe safe catalog-to-checkout workflow for a partner storefront
customize_order_pageRead the order pageThe draft-review-publish workflow for the hosted page

Writes are gated and idempotent

Every write tool takes an idempotency_key — a stable string of 16 to 255 characters that you generate once per logical action and reuse on retry, exactly like the Idempotency-Key header in REST.

Most write tools additionally take confirm, which must be true. Send it only after the user has explicitly approved that specific side effect; an unconfirmed call returns an error instead of acting. The gated tools are commerce_create_order, commerce_create_checkout, pdf_templates_publish, pdf_templates_revert_to_default, orderpage_update_draft, and orderpage_publish_draft.

Order-page workflow

Changing the hosted page goes through a draft, so nothing reaches buyers until it is published:

  1. orderpage_list_fields — discover which fields exist, their types, maximum lengths, and whether they support per-locale values.
  2. orderpage_get_current — read what is live today.
  3. orderpage_create_draft — start a draft with an idempotency_key, optionally naming a lang, a name, and a from_revision_id to branch from a published revision rather than from the live page. Keep the returned id and etag.
  4. orderpage_update_draft — send revision_id, a fields object, the exact etag from the last read, an idempotency_key, and confirm: true. Each edit returns a new ETag; use it for the next one.
  5. orderpage_preview_draft — review the exact payload the page would render.
  6. orderpage_publish_draft — publish with the newest etag, a fresh idempotency_key, and confirm: true.

orderpage_update_draft input shape

json
{
  "revision_id": "opr_7c1e93a4b60d48f2a5e7c081b3d92f64",
  "fields": {
    "orderform_company_box_bg": "#2d3a8c",
    "orderform_signup_text": "Tilmeld dig eksklusive fordele"
  },
  "etag": "\"opr_7c1e93a4b60d48f2a5e7c081b3d92f64:v1\"",
  "idempotency_key": "orderpage_draft_edit_018f4f37b949",
  "confirm": true
}

Send only the fields you intend to change. Unknown fields, wrong types, and over-length values are rejected and nothing is written.

Fields marked i18n: true hold one value per locale. Choose the locale when you create the draft with lang; a draft covers a single locale, so translating a page means one draft per locale.

Error handling

A rejected write returns a runtime error carrying a JSON payload. The common causes are:

  • A field name that is not in the catalog from orderpage_list_fields.
  • A value of the wrong type — a string where bool is expected, for example.
  • A value longer than the field's max.
  • A stale etag, meaning someone else edited the draft. Re-read the revision, reconcile, and retry with its new ETag.
  • A missing or false confirm on a gated write.

Relationship to the REST API

The tools and the REST endpoints act on the same data, so the two can be mixed freely. Three differences are worth knowing:

  • The MCP server does not manage API keys. Use POST /v2/api-keys for that.
  • The MCP server always acts on the key's own company. The company selector is REST-only, in the query string or in a write body alike, so an agency working on an assigned company's order page uses GET/PATCH /v2/order-page?company=<slug> instead.
  • Payment and money operations are REST-only. There is no MCP tool for confirming payment, capturing, refunding, or settling.

Skill file

The full skill definition for AI agents is published on this site: