# EasyPost MCP Guide

EasyPost MCP connects AI assistants and agents to your EasyPost account, so you can track packages, look up shipments,
quote rates, and buy labels in plain language. Add the EasyPost app in ChatGPT or Claude and sign in. There is no API key
to copy and nothing to install.

Related:

- [Add EasyPost to ChatGPT](https://chatgpt.com/plugins/plugin_asdk_app_6ace74f020f48191b8c3a4a8f341b807)
- [Add EasyPost to Claude](https://claude.ai/directory/easypost)

Building an agent or using Cursor, Claude Code, Codex, or VS Code? Connect the hosted
[Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server with a production API key. See
[Connect with an API Key](#connect-with-an-api-key).

**Server URL:** `https://app-api.easypost.com/mcp`

  **Production mode:** EasyPost MCP sends all requests in production mode. Labels it buys are real and are paid from
  your postage wallet. Test API keys are not supported.

We want to hear how you use EasyPost MCP. If there is a shipping task you would like an assistant to handle, a tool you
need, or something that didn't work, email [ai@easypost.com](mailto:ai@easypost.com). Your feedback shapes the tools we
add next.

---

## What You Can Do

Support and operations teams can answer shipping questions and ship packages without opening the dashboard, and
developers can inspect an account without writing a script. Paste one of these into your assistant after you connect.

Questions about your account:

- "Which carrier accounts are connected to my EasyPost account?"
- "List my shipments from the last seven days with carrier, service, and cost."
- "Which of my shipments from the past week are still in transit?"
- "Which USPS services can carry a package over 50 pounds?"
- "Do I have any open insurance claims, and what is the status of each?"
- "What is my postage wallet balance?"

You can also ask about one record: "Where is tracking number 9405511899223197428490?" or "Show me shipment
`shp_...`."

Tasks that ship, insure, or refund:

- "Get rates for a 2 lb box from our warehouse to this customer address, and tell me the cheapest option that arrives by
  Friday."
- "Buy the USPS Ground Advantage rate and send me the label."
- "Add $200 of insurance to shipment `shp_...`."
- "Refund the unused label with tracking number 9405511899223197428490."
- "Is this address deliverable?"

---

## Connect from ChatGPT or Claude

The EasyPost app is listed in the ChatGPT and Claude app directories. You sign in with your EasyPost account, so there
is no API key to copy.

1. Open the EasyPost app in ChatGPT or in the
   Claude directory.
2. Select **Connect** and sign in to EasyPost.
3. Approve access on the consent screen.
4. Ask: "Which EasyPost account am I connected to?"

The Claude directory is shared by Claude on the web, desktop, and mobile, so you connect once. To disconnect, remove the
EasyPost app in your ChatGPT or Claude settings.

---

## Connect with an API Key

Use an API key to connect an agent, a coding tool, or your own application. You need:

- An EasyPost account. To buy labels, the account also needs a funded postage wallet or a payment method that refills it.
- A production API key.
- An MCP client that supports remote servers over Streamable HTTP with custom request headers.

---

## Step 1: Set a Production API Key

Sign in to the [EasyPost API Keys page](https://app.easypost.com/account/settings?tab=api-keys) and copy a production
key. Set it as `EASYPOST_API_KEY` in the environment that launches your MCP client.

```shell
# macOS or Linux
EASYPOST_API_KEY="YOUR_EASYPOST_PRODUCTION_API_KEY"; export EASYPOST_API_KEY
```

```shell
# Windows PowerShell
$env:EASYPOST_API_KEY = "YOUR_EASYPOST_PRODUCTION_API_KEY"
```

Do not put the key in the server URL, source control, or an agent prompt.

---

## Step 2: Configure Your MCP Client

Choose the configuration for your client. Each example reads `EASYPOST_API_KEY` from the environment.

### Cursor

[Install EasyPost MCP in Cursor](https://cursor.com/en/install-mcp?name=easypost&config=eyJ1cmwiOiJodHRwczovL2FwcC1hcGkuZWFzeXBvc3QuY29tL21jcCIsImhlYWRlcnMiOnsiQXV0aG9yaXphdGlvbiI6IkJlYXJlciAke2VudjpFQVNZUE9TVF9BUElfS0VZfSJ9fQ%3D%3D),
or add the server manually to `~/.cursor/mcp.json` for all projects or `.cursor/mcp.json` for one project:

```json
{
  "mcpServers": {
    "easypost": {
      "url": "https://app-api.easypost.com/mcp",
      "headers": {
        "Authorization": "Bearer ${env:EASYPOST_API_KEY}"
      }
    }
  }
}
```

Restart Cursor after saving the file.

### Claude Code

Add the server with one command:

```shell
claude mcp add --scope project --transport http easypost \
  https://app-api.easypost.com/mcp \
  --header 'Authorization: Bearer ${EASYPOST_API_KEY}'
```

Use `--scope user` instead of `--scope project` to make the server available in every project.

The command writes `.mcp.json` in the project root. To add it by hand, the equivalent entry is:

```json
{
  "mcpServers": {
    "easypost": {
      "type": "http",
      "url": "https://app-api.easypost.com/mcp",
      "headers": {
        "Authorization": "Bearer ${EASYPOST_API_KEY}"
      }
    }
  }
}
```

Restart Claude Code, then run `claude mcp list` to check the connection.

### Codex

Add the server with the Codex CLI:

```shell
codex mcp add easypost \
  --url https://app-api.easypost.com/mcp \
  --bearer-token-env-var EASYPOST_API_KEY
```

The equivalent `~/.codex/config.toml` entry is:

```shell
[mcp_servers.easypost]
url = "https://app-api.easypost.com/mcp"
bearer_token_env_var = "EASYPOST_API_KEY"
```

### VS Code

Add the server to your user or workspace MCP settings. VS Code prompts for the key and stores it outside the
configuration file:

```json
{
  "servers": {
    "easypost": {
      "type": "http",
      "url": "https://app-api.easypost.com/mcp",
      "headers": {
        "Authorization": "Bearer ${input:easypost_api_key}"
      }
    }
  },
  "inputs": [
    {
      "type": "promptString",
      "id": "easypost_api_key",
      "description": "EasyPost production API key",
      "password": true
    }
  ]
}
```

### OpenAI Responses API

Pass the server and header on the `mcp` tool. The Responses API does not store the header, so send it with every
request:

```python
import os
from openai import OpenAI

client = OpenAI()

response = client.responses.create(
    model="gpt-5",
    tools=[
        {
            "type": "mcp",
            "server_label": "easypost",
            "server_url": "https://app-api.easypost.com/mcp",
            "headers": {
                "Authorization": f"Bearer {os.environ['EASYPOST_API_KEY']}",
            },
        }
    ],
    input="Which carrier accounts are connected to my EasyPost account?",
)

print(response.output_text)
```

### Other MCP Clients

Use these connection settings in any client that supports remote Streamable HTTP servers, including workflow
automation tools with a native MCP client step such as n8n:

| Setting | Value |
|---|---|
| Name | easypost |
| URL | https://app-api.easypost.com/mcp |
| Request header | Authorization: Bearer YOUR_EASYPOST_PRODUCTION_API_KEY |

---

## Step 3: Verify the Connection

Confirm that `easypost` is connected and lists tools in your client. Then ask: "Which EasyPost account am I connected
to?"

The client should call `whoami` and return the user associated with the production API key. Then try one of the
shipping questions above.

---

## Current Tools

EasyPost MCP has 20 tools. Read tools only look up data. Write tools create records, and some of them cost money.

### Read Tools

| Tool | Purpose | API Reference |
|---|---|---|
| whoami | Identifies the connected EasyPost user. Includes the postage wallet balance on the billing account. | [User](https://docs.easypost.com/docs/users) |
| list_payment_methods | Lists the card or bank account brand, last four digits, and priority. Cannot add or change a payment method. | [Billing](https://docs.easypost.com/docs/users/billing#retrieve-payment-methods) |
| list_shipments | Lists Shipments for the connected account. | [Shipment](https://docs.easypost.com/docs/shipments) |
| get_shipment | Retrieves a Shipment with label URLs, stored rates, and a Tracker summary. | [Shipment](https://docs.easypost.com/docs/shipments) |
| list_trackers | Lists Trackers and their current delivery status. | [Tracker](https://docs.easypost.com/docs/trackers) |
| get_tracker | Retrieves a Tracker with its latest scans. | [Tracker](https://docs.easypost.com/docs/trackers) |
| get_address | Retrieves a stored Address by ID. Does not run a new verification. | [Address](https://docs.easypost.com/docs/addresses#retrieve-an-address) |
| list_carrier_accounts | Lists connected carrier accounts without returning credentials. | [CarrierAccount](https://docs.easypost.com/docs/carrier-accounts) |
| carrier_metadata | Describes carrier service levels, packages, shipment options, and supported features. | [Carrier Metadata](https://docs.easypost.com/docs/carrier-metadata) |
| pickups | Retrieves scheduled Pickups. | [Pickup](https://docs.easypost.com/docs/pickups) |
| refunds | Retrieves postage Refund request status. | [Refund](https://docs.easypost.com/docs/refunds) |
| insurances | Retrieves standalone Insurance policies. | [Insurance](https://docs.easypost.com/docs/insurance) |
| claims | Retrieves insurance Claims and their status history. | [Claims](https://docs.easypost.com/docs/insurance/claims) |

### Write Tools

| Tool | Purpose | Cost | API Reference |
|---|---|---|---|
| create_shipment | Quotes rates for one US domestic Shipment. Does not buy a label. Verifies the delivery address. | Address verification is billed. Rating can be metered on a rating subscription. | [Create a Shipment](https://docs.easypost.com/docs/shipments#create-a-shipment) |
| buy_shipment | Buys one rate on a Shipment and returns the label and tracking code. The price must match the quoted rate. | Postage, plus insurance if requested, is debited from the wallet. | [Buy a Shipment](https://docs.easypost.com/docs/shipments#buy-a-shipment) |
| insure_shipment | Adds insurance to a label that was already bought and has no coverage. | Insurance is debited from the wallet. | [Insure a Shipment](https://docs.easypost.com/docs/shipments/shipping-insurance#insure-a-shipment) |
| create_refund | Requests a refund for one unused label, by tracking code. | No charge. | [Create a Refund](https://docs.easypost.com/docs/refunds#create-a-refund) |
| create_tracker | Starts tracking one tracking number that was not bought through EasyPost. | Billed the first time a number is tracked. | [Create a Tracker](https://docs.easypost.com/docs/trackers#create-a-tracker) |
| create_and_verify_address | Checks that an address is deliverable and stores it. | Billed on every call. | [Verify an Address](https://docs.easypost.com/docs/addresses#verify-an-address) |
| smartrate_delivery_date | Estimates the delivery date of each rate on a US domestic Shipment for a planned ship date. | Metered on every call. | [Delivery Date](https://docs.easypost.com/docs/shipments/shipping-smartrate#delivery-date) |

`create_shipment` and `smartrate_delivery_date` work with US domestic shipments only. To ship internationally, use the
EasyPost API.

---

## Buying Labels Safely

Buying a label spends real money, so the tools are built to make mistakes hard:

- **Quoting never buys.** `create_shipment` returns rates. A label is only bought when the assistant calls
  `buy_shipment`.
- **The price has to match.** `buy_shipment` takes the price the user approved and refuses to buy if the rate's price is
  different.
- **Retries don't buy twice.** If a buy times out, calling `buy_shipment` again with the same shipment and rate returns
  the label that was already bought.
- **One label per refund.** `create_refund` takes one tracking code per call.

Many clients ask you to approve a write tool before it runs. Keep that on for `buy_shipment`, `insure_shipment`, and
`create_refund`. These three are marked as destructive, so clients that read MCP tool hints can flag them.

Insurance works in two ways. You can add it when you buy, with the `insurance` amount on `buy_shipment`, or afterwards
with `insure_shipment`. If your account has a default insurance amount, it may cover a shipment that you buy without
setting insurance. To decline coverage, pass `0`.

---

## EasyPost MCP and the API

Use EasyPost MCP for interactive shipping work and agent workflows covered by the current tools. Use the EasyPost API
for application code, webhooks, international shipments, batches, and other high-volume automation.

---

## Data and Security

- The connected EasyPost account determines which records the tools can access.
- Tool responses never include carrier credentials, API keys, recharge settings, or fee rates.
- `whoami` returns the postage wallet balance on the billing account. `list_payment_methods` returns the brand, last
  four digits, and expiry of each card, and the bank name. It cannot add, remove, or change a payment method.
- Responses can include addresses, tracking details, and label URLs. Connect EasyPost only to MCP clients and other MCP
  servers that you trust.
- A production API key can authorize requests outside MCP. Treat it as a secret.

---

## FAQs

**Q: Do I need to install anything?**

No. EasyPost hosts the server. Your client connects to it over HTTPS.

**Q: Does connecting change anything in my EasyPost account?**

Connecting doesn't. The read tools only look up records. The write tools create shipments, buy and insure labels,
request refunds, create trackers, and verify addresses, and some of these are charged to your account. Your client
should ask you before it runs one.

**Q: Can I use a test API key?**

No. EasyPost MCP sends requests in production mode, so it requires a production API key.

**Q: Can I ship internationally?**

Not yet. `create_shipment` quotes US domestic shipments only. Use the EasyPost API for international shipments.

**Q: Can I use the same key in more than one client?**

Yes. EasyPost rate limits apply to the account, not to each client.

**Q: Which clients work?**

ChatGPT and Claude through their app directories, and any MCP client that supports remote servers over Streamable HTTP
with custom request headers.

**Q: How do I request a tool that does not exist yet?**

Email [ai@easypost.com](mailto:ai@easypost.com) with the shipping task you want an agent to complete.

---

## Troubleshooting

| Symptom | What to check |
|---|---|
| No EasyPost tools appear | Confirm the server URL, Streamable HTTP support, and custom header support. Then restart the client. |
| The client reports Authentication required | Confirm that EASYPOST_API_KEY is set in the environment that launched the client and is sent as a Bearer token. |
| The response contains MODE.UNAUTHORIZED | Replace the test key with a production API key. |
| The response contains APIKEY.INACTIVE | The key is disabled. Enable it or create a new one on the API Keys page. |
| buy_shipment refuses with expected_rate does not match | The price changed or the wrong rate was picked. Confirm the price again, or create a new shipment for fresh rates. |
| buy_shipment says the label may already be bought | The buy timed out or the connection dropped. Call buy_shipment again with the same shipment_id and rate_id. Do not create a new shipment, or you may buy a second label. |
| create_shipment returns no rates | Read the messages in the response. They explain why each carrier returned no rate. |

---

## Additional Resources

Related:

- [API Keys](https://docs.easypost.com/docs/api-keys)
- [Rate Limiting](https://docs.easypost.com/guides/rate-limiting-guide)
- [Tracking Guide](https://docs.easypost.com/guides/tracking-guide)
- [EasyPost Status](https://www.easypoststatus.com/)