MCP Server

The NMI MCP lets your AI coding assistant look up real records in your gateway—customers, payments, subscriptions, plans, products, invoices, and devices—and check which services your API key is ready to use. It runs locally on your machine and talks to the NMI REST API with your own merchant API key.

Use it alongside the NMI Developer Docs MCP: the Developer Docs MCP tells your assistant how the API works, the NMI MCP tells it what your account actually did. Most people connect both.

📘

What the server covers today. The NMI MCP currently provides record lookups and API key readiness checks—the two tools described in Available tools. It doesn't yet cover every NMI product or API, and we plan to expand its coverage to more products and features in future releases. Keep the configuration below unpinned and your assistant picks up new tools as they ship, with no config change.

🔐

Unlike the Developer Docs MCP, this server connects to your NMI account using a merchant API key. It performs read-only lookups—it never creates, modifies, or refunds a transaction—but treat the key as a live credential: give it only the permissions your assistant needs, and never commit it to source control.

What you can do with it

Once connected, your AI assistant can:

  • Look up a record by id—"why did payment 1234567890 decline?"—and read the amount, status, and response codes straight from your gateway instead of asking you to paste them
  • Check readiness before you build—"is my key set up for the Customer Vault and recurring billing?"—so a missing feature surfaces before you've written the integration
  • Ground troubleshooting in real data rather than in a guess about what your account is configured for

Requirements

  • Node.js 18 or later (node --version)
  • A merchant API key—Settings → Security Keys in your gateway. See Getting Your API Keys.
  • An MCP-capable AI tool: Claude Code, Cursor, VS Code, Windsurf, or Claude Desktop

There is nothing to install ahead of time—npx fetches the package the first time your editor starts the server.

Quick Start Guide

Step 1: Configure your editor

Find your tool below and add the config, substituting your own key. Create the file if it doesn't exist.

Run one command—no config file to edit:

claude mcp add USER.GATEWAYNAME \
  --env NMI_MERCHANT_API_KEY=your-merchant-api-key \
  -- npx -y @nmipayments/nmi-mcp

Add --scope user to make it available in every project. Verify with claude mcp list.

Restart your editor after saving.

Step 2: Verify the connection

Open a new chat in your AI tool and try:

  • Which NMI services is my API key ready for?
  • Look up customer 883113718 in my NMI account.
  • What was the response code on payment 1234567890?

The first prompt calls the preflight tool and should come back with a per-service readiness list. If your assistant answers from documentation instead of your account, check that the key is set in the config's env block and restart your editor.

Configuration

VariableRequiredDescription
NMI_MERCHANT_API_KEYYesMerchant API key from Settings → Security Keys.
NMI_ENVIRONMENTNoproduction (default) or sandbox. Controls whether identifying values are masked—see below.
NMI_API_BASE_URLNoOverride the API site root. Defaults to https://secure.nmi.com; set this if your gateway is on a different host. Do not include a trailing /api.
NMI_AGENT_IDNoFixed name for the calling assistant. Usually unnecessary—the server uses the name your editor reports.

How your data is protected

Identifying values in looked-up records are replaced with asterisks before your assistant ever sees them ("first_name": "***", "email": "***@example.com"), so cardholder identity isn't handed to a model. Geographic fields—city, state, country, and postal code—are preserved, because they support address-verification and fraud reasoning without identifying a person on their own.

Masked values are withheld, not changed: the asterisks are what the server returns, not what's stored in your gateway.

Masking is on unless you explicitly set NMI_ENVIRONMENT=sandbox. Any other value—including leaving it unset or misspelling it—masks.

⚠️

Only set NMI_ENVIRONMENT=sandbox when the credentials point at test data. It turns masking off and returns full values.

Available tools

Two tools today. Both are read-only.

fetch_by_type

Looks up one record by type and id.

InputDescription
typeOne of customer, payment, subscription, plan, product, invoice, device
idThe record's identifier. For product, pass the SKU; for device, pass the UUID.

Returns the record plus a found flag. A record that doesn't exist comes back with found: false—that's a valid answer, not an error.

Additional resource types are added over time and become available without any change to your configuration.

preflight

Reports whether the configured API key is ready to use for payments, Customer Vault, invoicing, recurring billing, and mobile, with the individual checks behind each verdict.

📘

preflight evaluates that specific set of services—it is not a full inventory of NMI products or APIs. The response names the services it checked in its scope field, and that set will grow as coverage expands.

Troubleshooting

"Access Denied" or an authentication error on every lookup. The server starts and lists its tools without credentials, so a bad key only shows up when a tool actually runs. Check that NMI_MERCHANT_API_KEY is in the env block of your MCP config (not just in your shell) and that the key has permission for the feature you're querying—the Customer Vault, for example, needs the Customer Vault permission on that key in addition to the feature being enabled on the account.

A lookup returns a 400. The identifier was rejected, not missing. Check you're passing a SKU for product and a UUID for device.

Names and emails come back as ***. That's the masking described above, working as intended.

Your assistant asks for something the server doesn't cover. The two tools above are the current scope. For anything outside it, the NMI Developer Docs MCP gives your assistant the full API reference to work from.

Contacting support. Errors include a ref_id. Quote it when you escalate—it identifies the exact request.

Related


Did this page help you?