Skip to main content
Glama

klarna-mcp: an MCP server for Klarna's merchant APIs

A small Model Context Protocol server that gives Claude, Cursor, Claude Code and any other MCP client access to Klarna's merchant APIs: orders, captures, refunds, payouts, settlement transactions, disputes and payment sessions.

It is read-only by default. Write tools (capture, refund, extend authorization, cancel, release) exist, but they are not even registered unless you set KLARNA_ENABLE_WRITES=true.

Built by Walma AI. There is a longer write-up in our guide: Klarna MCP. For how e-commerce teams use servers like this one, see AI for e-commerce.

Unofficial. This project is not made, endorsed or supported by Klarna, and is not affiliated with Klarna Bank AB. "Klarna" is a trademark of Klarna Bank AB, used here only to describe which API the server talks to.

Status: built against Klarna's documented API; not yet verified against a live Klarna environment. Try it on the playground first and please report anything that does not match.

Tools

All money amounts, in and out, are integers in minor units of the currency: 10000 means 100.00 SEK, EUR or USD.

Read tools (always available)

Tool

Klarna endpoint

What it does

get_order

GET /ordermanagement/v1/orders/{order_id}

Order status, amounts (authorized, captured, refunded, remaining), expiry, lines, captures and refunds

list_captures

GET /ordermanagement/v1/orders/{order_id}/captures

All captures on an order

get_capture

GET /ordermanagement/v1/orders/{order_id}/captures/{capture_id}

One capture

get_refund

GET /ordermanagement/v1/orders/{order_id}/refunds/{refund_id}

One refund (all refunds are listed on the order)

list_payouts

GET /settlements/v1/payouts

Payouts with totals, by date range and currency, paginated

get_payout

GET /settlements/v1/payouts/{payment_reference}

One payout by the reference on your bank statement

get_payout_summary

GET /settlements/v1/payouts/summary

Totals per currency for a date range

list_transactions

GET /settlements/v1/transactions

Settlement transactions by payout and/or order, paginated

get_payout_report_csv

GET /settlements/v1/reports/payout-with-transactions

One payout with its transactions, as CSV text

get_payouts_summary_report_csv

GET /settlements/v1/reports/payouts-summary-with-transactions

All payouts and transactions in a date range, as CSV text

list_disputes

GET /v4/payment/disputes

Disputes by order, state, reason, reference and dates, cursor-paginated

get_dispute

GET /v4/payment/disputes/{payment_dispute_id}

One dispute with its requests and deadlines

get_payment_session

GET /payments/v1/sessions/{session_id}

A Klarna Payments session (never creates or updates one)

Write tools (only with KLARNA_ENABLE_WRITES=true)

Tool

Klarna endpoint

Annotation

capture_order

POST /ordermanagement/v1/orders/{order_id}/captures

destructive

refund_order

POST /ordermanagement/v1/orders/{order_id}/refunds

destructive

extend_authorization_time

POST /ordermanagement/v1/orders/{order_id}/extend-authorization-time

not destructive

cancel_order

POST /ordermanagement/v1/orders/{order_id}/cancel

destructive

release_remaining_authorization

POST /ordermanagement/v1/orders/{order_id}/release-remaining-authorization

destructive

Read tools carry readOnlyHint: true. Write tools carry readOnlyHint: false, and every write that moves money or cannot be undone carries destructiveHint: true, so clients that honour annotations ask before running them. Capture is marked destructive too: it is an additive call in API terms, but it charges a customer.

Related MCP server: Shopify MCP Server

Safety model

  1. Read-only unless you say otherwise. Without KLARNA_ENABLE_WRITES=true (exactly true) the write tools do not exist on the server, so the model cannot call them, whatever the prompt says.

  2. Playground first. KLARNA_ENV defaults to playground. Point it at production only after you have watched the tools behave on test orders.

  3. Idempotency on every write. Each write sends a Klarna-Idempotency-Key header. The tool generates one if you do not pass it and returns it in the result; retry a failed or timed-out write with the same idempotency_key and Klarna executes it at most once (Klarna keeps keys for 24 hours).

  4. Credentials stay out of the conversation. They are read from the environment and sent only in the Authorization header. Error messages are built from Klarna's error_code, error_messages and correlation_id, and anything that looks like a credential is redacted before it reaches the model.

  5. Use a dedicated credential. Create a separate API credential for the agent in the Klarna Merchant Portal so you can revoke it on its own.

Setup

1. Get API credentials

In the Klarna Merchant Portal, create an API credential for the environment you want. Klarna's keys say which one they belong to: klarna_test_api_... is for the playground, klarna_live_api_... for production. When you create the credential, Klarna shows a username (a UUID) next to the API key; use the username as KLARNA_USERNAME and the API key as KLARNA_PASSWORD, or set only KLARNA_API_KEY.

2. Install

The package is not on npm. Clone and build it:

git clone https://github.com/Walma-Labs/klarna-mcp.git
cd klarna-mcp
npm install
npm run build

This gives you dist/stdio.js. Node 20 or newer is required.

3. Configure

Variable

Default

Meaning

KLARNA_USERNAME

API credential username

KLARNA_PASSWORD

API credential password (the API key or shared secret)

KLARNA_API_KEY

Alternative to the two above: a klarna_<live|test>_api_... key, sent as Authorization: Basic <API key> as Klarna documents it

KLARNA_REGION

eu

eu, na or oc

KLARNA_ENV

playground

playground or production

KLARNA_ENABLE_WRITES

off

true registers the write tools

Region and environment map to Klarna's documented hosts:

Production

Playground

eu

https://api.klarna.com

https://api.playground.klarna.com

na

https://api-na.klarna.com

https://api-na.playground.klarna.com

oc

https://api-oc.klarna.com

https://api-oc.playground.klarna.com

4. Add it to your client

Use the absolute path to your clone.

Claude Code

claude mcp add --transport stdio klarna \
  -e KLARNA_USERNAME=your-username \
  -e KLARNA_PASSWORD=your-password \
  -e KLARNA_REGION=eu \
  -e KLARNA_ENV=playground \
  -- node /absolute/path/to/klarna-mcp/dist/stdio.js

Add -e KLARNA_ENABLE_WRITES=true only when you want the write tools.

Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "klarna": {
      "command": "node",
      "args": ["/Users/you/klarna-mcp/dist/stdio.js"],
      "env": {
        "KLARNA_USERNAME": "your-username",
        "KLARNA_PASSWORD": "your-password",
        "KLARNA_REGION": "eu",
        "KLARNA_ENV": "playground"
      }
    }
  }
}

Cursor (.cursor/mcp.json or ~/.cursor/mcp.json)

{
  "mcpServers": {
    "klarna": {
      "command": "node",
      "args": ["/Users/you/klarna-mcp/dist/stdio.js"],
      "env": {
        "KLARNA_USERNAME": "your-username",
        "KLARNA_PASSWORD": "your-password",
        "KLARNA_REGION": "eu",
        "KLARNA_ENV": "playground"
      }
    }
  }
}

Desktop clients do not expand ~ or inherit your shell's PATH, so use absolute paths (and the absolute path to node if it is not found).

Running it as a remote server

dist/http.js is a stateless streamable-HTTP entrypoint for hosting the server centrally. It listens on PORT (default 8080) with a /healthz endpoint and has no auth of its own: anyone who reaches the port uses your Klarna credentials. Only run it behind a gateway that authenticates callers. Programmatic hosts can import { createKlarnaServer } from "klarna-mcp" and mount it on any transport.

Using it

Example prompts for an e-commerce or finance team:

  • "Show me order <klarna order id>: what is authorized, what is captured, and when does the authorization expire?"

  • "Sum up our Klarna payouts for September per currency: sales, fees, returns and what actually hit the bank."

  • "Get payout <payment reference> and list its transactions. Which fees and returns are in it?"

  • "Which settlement transactions belong to order <klarna order id>, and in which payout did the sale land?"

  • "List open disputes created in the last 30 days, grouped by reason, and tell me which deadlines are closest."

  • "Download the payout report CSV for <payment reference> and reconcile it against this export from our shop."

  • With writes on, on the playground: "Capture 450.00 SEK of order <id> for the two lines that shipped today, with DHL tracking number 123."

Things to tell the agent:

  • Order ids are Klarna's order ids, not your shop's order number. Your number is merchant_reference1 on the order.

  • Settlements dates are date-times. A bare date means midnight, so ask for 2026-09-30T23:59:59Z to include the last day.

  • Transactions have no date filter in Klarna's API. Find the payouts for a period first, then list transactions per payout.

  • Disputes need enrollment. Klarna's Disputes API v4 requires your merchant account to be enrolled; an empty list can mean you are not. Klarna's v4 reference lists only the EU hosts.

Development

npm install
npm run build && npm test
KLARNA_USERNAME=... KLARNA_PASSWORD=... node dist/stdio.js

Tests drive the real MCP wire and the real HTTP client against a mocked fetch, so they need no network or credentials. Try the server interactively with the MCP Inspector:

npx @modelcontextprotocol/inspector node dist/stdio.js

Sources

Every endpoint, field and header comes from Klarna's published API reference:

Left out on purpose: the PDF settlement reports (binary), order updates (amount, lines, addresses, references, shipping info), due-date extensions and customer send-outs, dispute responses and evidence uploads, and creating payment sessions or orders.

License

MIT. Copyright (c) 2026 Walma AI AB.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables Claude to query Stripe data—customers, charges, subscriptions, invoices, balance, events, and more—through 17 read-oriented tools, with optional write protections and a read-only default for remote deployments.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Connects Claude, ChatGPT, Cursor, or any MCP client to a Shopify store, enabling read-only access to themes, Liquid files, catalogue data, and store configuration through 122 tools.
    1
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables sellers to interact with Amazon Selling Partner API and Advertising API data—orders, inventory, pricing, ads, reports, and more—through MCP clients like Claude and Cursor.
    MIT