> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://mpp.dev/api/mcp` to find what you need.

# Official MCP SDK \[Add payments to MCP clients]

Use [`Mppx.create`](/sdk/typescript/client/Mppx.create) to let the [official TypeScript MCP SDK](https://github.com/modelcontextprotocol/typescript-sdk) pay for MCP tools and HTTP requests through MPP. Free calls pass through untouched; when a paid tool or a 402-protected request returns an MPP Challenge, the payment-aware fetch wrapper creates a Credential, retries the call, and returns the result.

## Configure a payment wallet

Choose a local viem account for development or use a Privy wallet when the MCP client runs in production.

### Direct

```bash [terminal]
$ pnpm add mppx viem @modelcontextprotocol/sdk
```

```ts [payments.ts]
import { Mppx, tempo } from 'mppx/client'
import { privateKeyToAccount } from 'viem/accounts'

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`)

Mppx.create({
  methods: [tempo({ account })],
})
```

### Privy

Create an EVM wallet in [Privy](https://dashboard.privy.io), fund its address with pathUSD on Tempo, then store its ID and address with your Privy app credentials. Keep `PRIVY_APP_SECRET` server-side.

:::code-group
```bash [npm]
$ npm install @modelcontextprotocol/sdk @privy-io/node mppx viem
```

```bash [pnpm]
$ pnpm add @modelcontextprotocol/sdk @privy-io/node mppx viem
```

```bash [bun]
$ bun add @modelcontextprotocol/sdk @privy-io/node mppx viem
```
:::

Use `@privy-io/node` version `0.20.0` or later. `createViemAccount` gives `mppx` an account that delegates signing to the Privy wallet.

```ts [payments.ts]
import { PrivyClient } from '@privy-io/node'
import { createViemAccount } from '@privy-io/node/viem'
import { Mppx, tempo } from 'mppx/client'

const privy = new PrivyClient({
  appId: process.env.PRIVY_APP_ID!,
  appSecret: process.env.PRIVY_APP_SECRET!,
})

export const account = createViemAccount(privy, {
  address: process.env.PRIVY_WALLET_ADDRESS as `0x${string}`,
  walletId: process.env.PRIVY_WALLET_ID!,
})

Mppx.create({
  methods: [tempo({ account })],
})
```

## Pay for MCP tools

Create the MCP client after `Mppx.create`. The Streamable HTTP transport uses the payment-aware fetch for both free and paid tool calls.

```ts [client.ts]
import { Client } from '@modelcontextprotocol/sdk/client/index.js'
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'
import './payments'

const client = new Client({
  name: 'mpp-app',
  version: '1.0.0',
})

await client.connect(new StreamableHTTPClientTransport(new URL('<mcp-url>')))

const result = await client.callTool({
  name: 'premium_search',
  arguments: { query: 'tempo' },
})

console.log(result)
```

## Pay for HTTP requests

Call `Mppx.create` before making HTTP requests. It installs the payment-aware fetch, so later `fetch` calls in the same runtime can handle free responses, paid MPP responses, and [x402 payment challenges](/guides/use-mpp-with-x402).

```ts [client.ts]
import './payments'

export async function paidPing() {
  const response = await fetch('https://mpp.dev/api/ping/paid')
  return response.json()
}
```

## Support MPP and x402 clients

Register an EVM method beside your Tempo method when the agent needs to call APIs that support either native MPP or x402 exact. The same payment-aware fetch reads MPP `WWW-Authenticate` Challenges and x402 `PAYMENT-REQUIRED` Challenges, then retries with the matching `Authorization` or `PAYMENT-SIGNATURE` header.

### Direct

```ts [payments.ts]
import { Mppx, evm, tempo } from 'mppx/client'
import { privateKeyToAccount } from 'viem/accounts'

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`)

Mppx.create({
  acceptPaymentPolicy: {
    origins: ['https://api.example.com'],
  },
  methods: [
    // [!code hl:start]
    evm.charge({
      account,
      currencies: [evm.assets.baseSepolia.USDC],
      maxAmount: '1.00',
    }),
    tempo.charge({ account }),
    // [!code hl:end]
  ],
})
```

### Privy

```ts [payments.ts]
import { PrivyClient } from '@privy-io/node'
import { createViemAccount } from '@privy-io/node/viem'
import { Mppx, evm, tempo } from 'mppx/client'

const privy = new PrivyClient({
  appId: process.env.PRIVY_APP_ID!,
  appSecret: process.env.PRIVY_APP_SECRET!,
})

const account = createViemAccount(privy, {
  address: process.env.PRIVY_WALLET_ADDRESS as `0x${string}`,
  walletId: process.env.PRIVY_WALLET_ID!,
})

Mppx.create({
  acceptPaymentPolicy: {
    origins: ['https://api.example.com'],
  },
  methods: [
    // [!code hl:start]
    evm.charge({
      account,
      currencies: [evm.assets.baseSepolia.USDC],
      maxAmount: '1.00',
    }),
    tempo.charge({ account }),
    // [!code hl:end]
  ],
})
```

Use this setup before creating MCP transports or calling `fetch`. MCP tool calls can keep using MPP through the wrapped client, while HTTP calls can pay either native MPP or x402 exact endpoints.

See [build a client for MPP and x402](/guides/use-mpp-with-x402#build-a-client-for-mpp-and-x402) for the shared client flow.

## Manage agent spend

The example above uses a standard viem account. For long-running apps or agents, use scoped access keys when the runtime should pay in the background with spending limits, call scopes, recipient restrictions, and independent revocation.

Create the access key first, then pass the Tempo account into the same setup.

### Accounts SDK

```ts [payments.ts]
Mppx.create({
  methods: [
    tempo({
      account: provider.getAccount(),
      ...provider.getMppxParameters({ accessKey }),
    }),
  ],
})
```

### Privy

Configure spending limits with Privy wallet policies, then use the Privy-backed account from `payments.ts`.

```ts [payments.ts]
import { Mppx, tempo } from 'mppx/client'

Mppx.create({
  methods: [tempo({ account })],
})
```

See [Managing agent spend](/guides/managing-agent-spend) for limits, scopes, recipients, and revocation.
