# MCP Server

> Connect Claude Code, Cursor, or any MCP client to a local Paymos server and let an agent build your integration with sandbox invoices and simulated payments.

`@paymos/mcp` connects your coding agent to the Paymos sandbox. The local [Model Context Protocol](https://modelcontextprotocol.io) server gives the agent six tools and five documentation resources to create invoices, simulate payments, inspect results, and check webhook signatures while writing your integration.

## Requirements

- Node.js 20 or newer
- A test key pair from [Dashboard → Developer → API Keys](/docs/api-keys.md): `pk_test_…` and `sk_test_…`
- An MCP client that can run a local stdio server

## Connect your client

Run this in your terminal:

```bash
npx -y @paymos/mcp setup
```

Choose the client you use, then enter your test key pair. Secret input is hidden. A webhook secret is optional; add it if you want the agent to verify webhook signatures. Setup can read the same values from `PAYMOS_API_KEY_ID`, `PAYMOS_API_SECRET`, and optional `PAYMOS_WEBHOOK_SECRET` instead.

To choose the client in the command, use `--client`:

```bash
npx -y @paymos/mcp setup --client codex
```

| Client | Value for `--client` | Default configuration |
|---|---|---|
| Codex | `codex` | `$CODEX_HOME/config.toml` or `~/.codex/config.toml` |
| Claude Code | `claude-code` | `~/.claude.json` |
| Claude Desktop | `claude-desktop` | macOS or Windows Claude configuration |
| Kimi CLI | `kimi` | `$KIMI_CODE_HOME/mcp.json` or `~/.kimi-code/mcp.json` |
| Cursor | `cursor` | `~/.cursor/mcp.json` |
| Windsurf | `windsurf` | `~/.codeium/windsurf/mcp_config.json` |
| OpenCode | `opencode` | `OPENCODE_CONFIG` or its user configuration |
| VS Code | `vscode` | `.vscode/mcp.json` in the current directory |
| Another client | `generic` | Supply `--config PATH` |

Use `--config PATH` when your client reads a different file. Claude Desktop also needs an explicit path on operating systems other than macOS and Windows. For Cline, Roo Code, or your own MCP client, find its MCP configuration path and pass it with `--client generic --config PATH`.

The keys go in a separate JSON file at `$XDG_CONFIG_HOME/paymos/mcp/credentials.json`, or `~/.config/paymos/mcp/credentials.json` when `XDG_CONFIG_HOME` is unset. Choose another location with `--credentials-file PATH`. The client configuration receives only `PAYMOS_CREDENTIALS_FILE`, pointing to that file. Keep the credentials file outside your project and version control.

You can inspect a proposed setup before saving it:

```bash
npx -y @paymos/mcp setup --client codex --dry-run
npx -y @paymos/mcp setup --help
```

Dry-run writes no files and does not print secrets. Running setup again with the same data leaves the existing entry in place. If the Paymos entry or credentials file differs, setup stops for you to review it rather than overwriting it. Other MCP servers, comments, model choices, and client settings stay as they are. An older Paymos entry with inline key environment variables is a conflict too; setup does not migrate it automatically.

Restart or reconnect your client after setup, then check that Paymos appears among its MCP servers. Ask the agent to create a sandbox invoice and simulate its payment. The server uses stdio without opening a network listener and calls the Merchant API through the official SDK.

Your client runs the server; your model decides how to use its tools. Kimi CLI is a client with its own configuration. GLM, Kimi, and custom models can use this server through an MCP client when the selected model and client support tool calling. A model name alone does not establish compatibility. For example, [Z.ai documents GLM in Claude Code](https://docs.z.ai/devpack/tool/claude); configure Paymos in that client after setting up the model.

## Configure manually

If you prefer to edit the configuration, create a credentials file outside your project:

```json
{
  "apiKeyId": "pk_test_…",
  "apiSecret": "sk_test_…",
  "webhookSecret": "whsec_…"
}
```

Omit `webhookSecret` if you do not need signature verification. On Unix, run `chmod 600 /absolute/path/credentials.json` after saving the file, using its actual absolute path. On Windows, keep it in your account directory and check its existing access permissions. Replace `/absolute/path/credentials.json` below with the actual path.

### Claude Code, Claude Desktop, Cursor, Windsurf, and generic clients

Add this entry to the client's MCP configuration:

```json
{
  "mcpServers": {
    "paymos": {
      "command": "npx",
      "args": ["-y", "@paymos/mcp"],
      "env": { "PAYMOS_CREDENTIALS_FILE": "/absolute/path/credentials.json" }
    }
  }
}
```

Kimi CLI uses the same format in its `mcp.json`. For Claude Code, a project-level `.mcp.json` is also a manual option. Claude Desktop uses `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS and `%APPDATA%\Claude\claude_desktop_config.json` on Windows. Preserve existing entries when adding Paymos.

### Codex

Add to `config.toml`:

```toml
[mcp_servers.paymos]
command = "npx"
args = ["-y", "@paymos/mcp"]

[mcp_servers.paymos.env]
PAYMOS_CREDENTIALS_FILE = "/absolute/path/credentials.json"
```

### OpenCode

Add to your OpenCode configuration:

```json
{
  "mcp": {
    "paymos": {
      "type": "local",
      "command": ["npx", "-y", "@paymos/mcp"],
      "environment": { "PAYMOS_CREDENTIALS_FILE": "/absolute/path/credentials.json" },
      "enabled": true
    }
  }
}
```

### VS Code

Use `.vscode/mcp.json`:

```json
{
  "servers": {
    "paymos": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@paymos/mcp"],
      "env": { "PAYMOS_CREDENTIALS_FILE": "/absolute/path/credentials.json" }
    }
  }
}
```

### Zed

Setup does not have a Zed adapter. On Unix, add the launcher manually under `context_servers.paymos` in `~/.config/zed/settings.json`; project settings use `.zed/settings.json`. On Windows, open settings in Zed to find the actual `settings.json` file. Use `command`, `args`, and `env` from the generic example.

### Windows launcher

For manual configuration on Windows, replace the launcher with:

```json
"command": "cmd",
"args": ["/d", "/c", "npx", "-y", "@paymos/mcp"]
```

OpenCode instead uses `"command": ["cmd", "/d", "/c", "npx", "-y", "@paymos/mcp"]`. In Codex TOML, use `command = "cmd"` and the same argument array. Setup chooses this launcher automatically on Windows.

The server also accepts `PAYMOS_API_KEY_ID`, `PAYMOS_API_SECRET`, and `PAYMOS_WEBHOOK_SECRET` directly. Existing `--api-key-id` and `--api-secret` flags remain available: environment values take priority over flags, and flags take priority over the credentials file. Avoid putting secrets in command history or project configuration.

## Tools and resources

| Tool | Purpose |
|---|---|
| `create_invoice` | Create a sandbox invoice; idempotent per `external_order_id`; returns `payment_url` |
| `get_invoice` | Read the current invoice state |
| `list_invoices` | Read one cursor page of invoices with filters |
| `cancel_invoice` | Cancel an unpaid invoice and store the reason |
| `simulate_invoice_payment` | Simulate `paid`, `paid_late`, `overpaid`, `underpay`, or `cancel` in the sandbox |
| `verify_webhook_signature` | Verify `X-Webhook-Signature` locally without an API call |

The five resources are `paymos://docs/quick-start`, `paymos://docs/hosted-checkout`, `paymos://docs/webhooks`, `paymos://docs/testing-sandbox`, and `paymos://docs/server-sdks`.

`paid_late` simulates the late-payment case; it does not introduce a new invoice status. See [sandbox testing](/docs/testing.md) for the scenario's behavior.

## Sandbox boundary

Only test key pairs are accepted. Live (`pk_live_`/`sk_live_`) and payout (`rk_…`) keys are refused at setup, startup, and on tool calls. Once you have checked the integration, run your own application with its live keys; the MCP server remains outside production payment paths.

This page covers the local server. Hosted MCP is deferred; it is not an available connection method.

## Next steps

- [Quick start](/docs/quick-start.md) — follow the invoice flow yourself
- [Testing in the sandbox](/docs/testing.md) — choose payment scenarios
- [Server SDKs](/docs/server-sdks.md) — build the application around an SDK
- [Webhooks](/docs/webhooks.md) — handle events and verify signatures
