> **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.

# Vercel AI SDK \[Add payments to agents and tools]

Use [`Mppx.create`](/sdk/typescript/client/Mppx.create) to let a [Vercel AI SDK agent](https://ai-sdk.dev/docs/agents/overview) 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 wrapped client 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 agent runs in production.

### Direct

```bash [terminal]
$ pnpm add mppx viem ai @ai-sdk/mcp zod
```

```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 @ai-sdk/mcp @privy-io/node ai mppx viem zod
```

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

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

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 AI SDK MCP transport uses the payment-aware fetch for both free and paid tool calls.

```ts [agent.ts]
import { createMCPClient } from '@ai-sdk/mcp'
import { generateText } from 'ai'
import { yourProvider } from 'your-custom-provider'

const mcp = await createMCPClient({
  transport: {
    type: 'http',
    url: '<mcp-url>',
  },
})

const { toolResults } = await generateText({
  model: yourProvider('your-model-id'),
  prompt: 'Call the MCP tool.',
  tools: await mcp.tools(),
  toolChoice: 'required',
})

console.log(toolResults)
await mcp.close()
```

## Pay for HTTP requests

Define a normal AI SDK tool and call `fetch` inside `execute`. Because `Mppx.create` ran first, the HTTP request is payment-aware.

```ts [agent.ts]
import { generateText, tool } from 'ai'
import { yourProvider } from 'your-custom-provider'
import { z } from 'zod'

const { toolResults } = await generateText({
  model: yourProvider('your-model-id'),
  prompt: 'Call paidPing.',
  tools: {
    paidPing: tool({
      description: 'Call a paid MPP HTTP endpoint.',
      inputSchema: z.object({}),
      execute: async () => {
        const response = await fetch('https://mpp.dev/api/ping/paid')
        return response.json()
      },
    }),
  },
  toolChoice: { type: 'tool', toolName: 'paidPing' },
})

console.log(toolResults)
```

The `tempo({ account })` helper used above supports Tempo [charge](/payment-methods/tempo/charge) and [session](/payment-methods/tempo/session) challenges.

## 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.
