---
title: "Connect EasyPost to Claude: Manage Multi-Carrier Batches & Rates"
slug: connect-easypost-to-claude-manage-multi-carrier-batches-rates
date: 2026-10-07
author: Riya Sethi
categories: ["AI & Agents"]
excerpt: "Learn how to connect EasyPost to Claude using a managed MCP server. Automate multi-carrier shipments, labels, and tracking with AI agents."
tldr: "Connect EasyPost to Claude using Truto's MCP server. This guide covers setup, handling EasyPost's async batch APIs, executing multi-carrier label generation, and securing AI access."
canonical: https://truto.one/blog/connect-easypost-to-claude-manage-multi-carrier-batches-rates/
---

# Connect EasyPost to Claude: Manage Multi-Carrier Batches & Rates

**EasyPost in Claude, in about a minute.** The best way to connect EasyPost to Claude is Elaichi: connect EasyPost to Elaichi once, then add Elaichi to Claude as a connector. Two steps, about a minute, with a 14-day free trial and no credit card required.

1. **Start your free trial.** Create your Elaichi account. 14 days free, no credit card required.
2. **Connect EasyPost.** Connect EasyPost once in Elaichi. Claude never gets more access than you have.
3. **Add Elaichi to Claude.** In Claude, open Customize, then Connectors, press Add and paste https://api.elaichi.ai/mcp. Sign in and approve.

[Start free on Elaichi, 14 days, no credit card required](https://app.elaichi.ai/signup?utm_source=truto.one&utm_medium=referral&utm_campaign=launchpad&utm_content=post_markdown&utm_term=easypost) · [EasyPost on Elaichi](https://elaichi.ai/connectors/easypost/?utm_source=truto.one&utm_medium=referral&utm_campaign=launchpad&utm_content=post_markdown&utm_term=easypost)

*Building EasyPost into your own product? The guide below is for you.*

---

If your team uses ChatGPT, check out our guide on [/connect-easypost-to-chatgpt-automate-shipping-labels-tracking/](https://truto.one/connect-easypost-to-chatgpt-automate-shipping-labels-tracking/) or explore our broader architectural overview on [/connect-easypost-to-ai-agents-automate-customs-address-validation/](https://truto.one/connect-easypost-to-ai-agents-automate-customs-address-validation/).

If you need to connect EasyPost to Claude to automate multi-carrier shipping logistics, generate labels, track incoming parcels, or manage end-of-day manifests, you need a [Model Context Protocol (MCP) server](https://truto.one/what-is-mcp-model-context-protocol-the-2026-guide-for-saas-pms/). This server acts as the translation layer between Claude's internal tool-calling mechanics and EasyPost's REST APIs. You can either construct and maintain this infrastructure yourself, or use a [managed integration platform like Truto](https://truto.one/managed-mcp-for-claude-full-saas-api-access-without-security-headaches/) to dynamically generate a secure, authenticated MCP server URL.

Giving a Large Language Model (LLM) read and write access to a sprawling logistics ecosystem like EasyPost is an engineering challenge. You have to handle API key lifecycles, map nested JSON schemas to MCP tool definitions, and deal with EasyPost's specific approach to object immutability and asynchronous operations. Every time EasyPost updates an endpoint or deprecates a carrier integration, you have to update your server code, redeploy, and test the integration.

This guide breaks down exactly how to use Truto to generate a secure, managed MCP server for EasyPost, connect it natively to Claude Desktop, and execute complex shipping workflows using natural language.

> Want to give your AI agents secure, authenticated access to EasyPost and 100+ other SaaS APIs? Let's talk about managed MCP architecture.
>
> [Talk to us](https://truto.one/book-a-demo/)

## The Engineering Reality of the EasyPost API

A custom MCP server is a self-hosted integration layer. While the open MCP standard provides a predictable way for models to discover tools, the reality of implementing it against a deeply specialized logistics API like EasyPost is painful. 

If you decide to build a custom MCP server for EasyPost, you own the entire API lifecycle. Here are the specific challenges you will face:

**Strict Object Immutability**
EasyPost relies heavily on immutable objects. Once you create an `Address`, `Parcel`, or `CustomsInfo` object, it cannot be changed. There is no `PATCH /v2/addresses/:id` endpoint. If an LLM attempts to "update" a customer's shipping address to fix a typo, it must be explicitly instructed to create a completely new Address object. Your MCP tools must provide this context in their descriptions, or the LLM will hallucinate update methods that do not exist.

**Asynchronous Batch and Scan Form Processing**
Not all endpoints in the EasyPost API behave like synchronous CRUD operations. When you call the endpoint to create a `Batch` or generate a `ScanForm`, EasyPost enqueues a background job. The immediate API response simply acknowledges the request and returns an object with a state of `creating` or `purchasing`. An LLM cannot simply assume the labels are ready. Your workflow must instruct the AI to poll the specific `get_single_easy_post_batch_by_id` endpoint until the state transitions to a terminal status, or your system must handle webhook callbacks and push the state back into the LLM's context window.

**Strict Rate Limiting and Error Passthrough**
EasyPost enforces strict rate limits, particularly on endpoints that interface with external carrier systems to retrieve live rates. It is critical to note how Truto handles this: Truto does not retry, throttle, or apply backoff on rate limit errors. When the upstream EasyPost API returns an HTTP 429 Too Many Requests error, Truto passes that error directly to the caller. Truto normalizes the upstream rate limit information into standardized headers (`ratelimit-limit`, `ratelimit-remaining`, `ratelimit-reset`) per the IETF specification. The caller - your application or the LLM agent framework - is entirely responsible for observing these headers, implementing retry logic, and applying exponential backoff.

## Creating the EasyPost MCP Server

Truto [dynamically derives MCP tool definitions from the underlying integration's resource schema and documentation records](https://truto.one/openapi-to-mcp-how-mcp-servers-auto-generate-tools-from-api-docs/). You can generate an MCP server for EasyPost using either the Truto UI or the API.

### Method 1: Via the Truto UI

For ad-hoc agent testing or manual configuration, the UI is the fastest path:

1. Log into your Truto environment and navigate to the integrated account page for your EasyPost connection.
2. Click the **MCP Servers** tab.
3. Click **Create MCP Server**.
4. Select your desired configuration (name, allowed methods like `read` or `write`, tag filters, and expiration time).
5. Copy the generated MCP server URL. This URL contains a cryptographically hashed token that authenticates the connection.

### Method 2: Via the API

For programmatic, multi-tenant deployments, generate the MCP server via the Truto API. This validates that tools are available, stores the hashed token in distributed key-value storage, and returns a ready-to-use URL.

**Endpoint:** `POST /integrated-account/:id/mcp`

**Request body:**
```json
{
  "name": "EasyPost Fulfillment Agent",
  "config": {
    "methods": ["read", "write"],
    "tags": ["shipping", "logistics"]
  },
  "expires_at": "2026-12-31T23:59:59Z"
}
```

**Response:**
```json
{
  "id": "mcp_abc123",
  "name": "EasyPost Fulfillment Agent",
  "config": {
    "methods": ["read", "write"],
    "tags": ["shipping", "logistics"]
  },
  "expires_at": "2026-12-31T23:59:59Z",
  "url": "https://api.truto.one/mcp/a1b2c3d4e5f6..."
}
```

## Connecting the MCP Server to Claude

Once you have the Truto MCP server URL, you must connect it to your AI client.

### Option A: Via the Claude Desktop UI

If you are using the consumer-facing Claude Desktop application:

1. Open Claude Desktop.
2. Navigate to **Settings -> Integrations -> Add MCP Server**.
3. Paste the Truto MCP server URL and provide a name (e.g., "EasyPost Logistics").
4. Click **Add**. Claude will perform the JSON-RPC initialization handshake, pull the tool definitions, and immediately make them available in your context window.

*(Note: If your team uses ChatGPT, you can follow a similar path: Settings -> Apps -> Advanced settings -> Developer mode -> Add custom connector).* 

### Option B: Via Manual Configuration File

For programmatic setups or advanced local environments, you can inject the server via Claude's configuration file.

Locate your `claude_desktop_config.json` file. On macOS, this is typically at `~/Library/Application Support/Claude/claude_desktop_config.json`. Add the server configuration using the standard Server-Sent Events (SSE) transport wrapper:

```json
{
  "mcpServers": {
    "easypost": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-sse",
        "https://api.truto.one/mcp/a1b2c3d4e5f6..."
      ]
    }
  }
}
```
Restart Claude Desktop. The model will auto-discover the tools and bind them to its internal context.

## EasyPost Hero Tools for Claude

Truto exposes the entire EasyPost API as LLM-ready tools. We combine query schemas and body schemas into a flat input namespace, simplifying the payload generation for the LLM. Here are the highest-leverage tools for automating shipping operations.

### easy_post_addresses_create_and_verify

Creates an address and validates its deliverability in a single call. This is crucial for avoiding downstream carrier errors. Because addresses are immutable in EasyPost, you must use this tool to generate a completely new address object even if you are just fixing a zip code typo.

**Usage note:** Returns the address object including `id`, `residential` flag, and any `verifications` data. Pass the resulting `id` to the shipment creation tool.

> "I have a customer at 123 Main St, Suite 400, San Francisco, CA 94105. Use `easy_post_addresses_create_and_verify` to validate this address. If it returns verification errors, let me know. If it succeeds, save the address ID for the next step."

### create_a_easy_post_shipment

Creates a shipment object containing the destination address, origin address, and parcel dimensions. EasyPost automatically reaches out to configured carriers and populates the response with available shipping rates.

**Usage note:** Requires a `shipment` object containing `to_address`, `from_address`, and `parcel`. Do not pass rate selections here - this merely stages the shipment and generates rate quotes.

> "Create a new EasyPost shipment. Use origin address ID 'adr_111' and destination address ID 'adr_222'. The parcel weighs 16 ounces and measures 8x6x4 inches. Show me the lowest available rate from the returned rate array."

### easy_post_shipments_list_smartrates

Retrieves time-in-transit predictions for every associated rate on an existing shipment. This is a highly agentic tool - it allows the LLM to make autonomous, logic-based decisions on which carrier to choose based on exact delivery percentiles rather than just looking at the base price.

**Usage note:** Requires `shipment_id`. Only available for US domestic shipments. 

> "Fetch the SmartRates for shipment ID 'shp_999'. I need this package to arrive within 3 days with a 95th percentile confidence. Find the cheapest rate that meets this criteria and tell me the rate ID."

### easy_post_shipments_buy

Purchases the shipping label for an existing shipment using a specific rate ID. This executes the financial transaction against your EasyPost wallet and generates the actual tracking number and printable postage label URL.

**Usage note:** Requires the `id` of the shipment and a `rate_id`. Returns the finalized shipment object including the `tracking_code` and `postage_label` URLs.

> "Buy the shipment 'shp_999' using the USPS Priority rate ID 'rate_444'. Once purchased, return the final tracking number and the PNG URL of the shipping label so I can send it to the warehouse."

### create_a_easy_post_batch

Creates an asynchronous batch process for purchasing labels in bulk. This is essential when fulfilling dozens or hundreds of orders simultaneously. Keep batches under 1,000 shipments to avoid timeout errors during the carrier rating process.

**Usage note:** Batch operations run asynchronously. The initial response will return a state of `creating`. You must poll the batch status using `get_single_easy_post_batch_by_id` before attempting to buy it.

> "Create a new EasyPost batch containing these 50 shipment IDs. Return the batch ID to me, and tell me what its current state is."

### easy_post_batches_create_scan_form

Generates a single carrier manifest (ScanForm) for an entire batch of purchased shipments. This allows the USPS or UPS driver to scan one barcode to accept hundreds of packages, rather than scanning each box individually.

**Usage note:** All shipments in the batch must share the same origin address and carrier account. Like batches, scan form creation is asynchronous.

> "The batch 'batch_777' has finished purchasing. Now, use `easy_post_batches_create_scan_form` to generate an end-of-day manifest for it. Check the status until the form_url is available, then provide me the link."

### create_a_easy_post_tracker

Creates a tracker for a package that was not originally purchased through EasyPost (Bring Your Own Tracking). This allows you to unify all inbound logistics and supplier shipments into the same EasyPost webhook flow.

**Usage note:** Requires a `tracking_code` and `carrier`. EasyPost returns the existing tracker if the same tracking code was submitted within the previous three months.

> "We have an inbound supplier shipment coming via FedEx with tracking number 774123456789. Create a tracker in EasyPost for this package so we can monitor its status. What is the current estimated delivery date?"

For the complete tool inventory, including customs declarations, insurance purchasing, and webhook management, visit the [EasyPost integration page](https://truto.one/integrations/detail/easypost).

## Workflows in Action

Let's look at how an AI agent uses these MCP tools to execute complex, multi-step logistics operations autonomously.

### Workflow 1: Cost-Optimized Order Fulfillment

An e-commerce support agent needs to fulfill a replacement order while balancing shipping speed and cost constraints.

> "I need to ship a 2 lb replacement widget to John Doe at 456 Elm St, Austin TX 78701. Use our standard origin address (adr_origin123). Create the shipment, then evaluate the SmartRates. Find the cheapest option that guarantees delivery within 4 days at the 90th percentile. Buy that rate and give me the tracking link."

1. **Address Verification:** Claude calls `easy_post_addresses_create_and_verify` with the destination string. It successfully creates and verifies the address, noting the ID (`adr_dest456`).
2. **Shipment Staging:** Claude calls `create_a_easy_post_shipment`, passing `from_address: adr_origin123`, `to_address: adr_dest456`, and the parcel weight (32 oz). It receives a shipment ID (`shp_test789`).
3. **Rate Analysis:** Claude calls `easy_post_shipments_list_smartrates` using `shp_test789`. It analyzes the returned JSON array, comparing the `rate` price against the `time_in_transit` percentiles.
4. **Execution:** Claude identifies a UPS Ground rate (`rate_ups999`) that meets the criteria and calls `easy_post_shipments_buy`. It parses the response and hands the tracking URL back to the user.

```mermaid
sequenceDiagram
    participant User as Human Operator
    participant Claude as Claude Agent
    participant Truto as Truto MCP Router
    participant EasyPost as EasyPost API

    User->>Claude: "Ship to Austin, optimize for 4-day delivery"
    Claude->>Truto: "Call tool: easy_post_addresses_create_and_verify"
    Truto->>EasyPost: "POST /v2/addresses"
    EasyPost-->>Truto: "201 Created (adr_dest456)"
    Truto-->>Claude: "Result: Verified Address"
    Claude->>Truto: "Call tool: create_a_easy_post_shipment"
    Truto->>EasyPost: "POST /v2/shipments"
    EasyPost-->>Truto: "201 Created (shp_test789)"
    Truto-->>Claude: "Result: Shipment Staged"
    Claude->>Truto: "Call tool: easy_post_shipments_list_smartrates"
    Truto->>EasyPost: "GET /v2/shipments/shp_test789/smartrates"
    EasyPost-->>Truto: "200 OK (Array of predicted delivery days)"
    Truto-->>Claude: "Result: SmartRates Data"
    Claude->>Truto: "Call tool: easy_post_shipments_buy (rate_ups999)"
    Truto->>EasyPost: "POST /v2/shipments/shp_test789/buy"
    EasyPost-->>Truto: "200 OK (Purchased, tracking URL generated)"
    Truto-->>Claude: "Result: Label and Tracking Data"
    Claude->>User: "Purchased UPS Ground. Tracking URL is attached."
```

### Workflow 2: End-of-Day Manifest Automation

A warehouse manager needs to close out the day's shipments by generating a unified scan form for the USPS driver.

> "Take these 12 shipment IDs [shp_1, shp_2, ... shp_12] that we processed today. Add them to a new batch, buy the batch, and then generate a scan form for the USPS driver. Poll the batch status until the form is ready to print."

1. **Batch Creation:** Claude calls `create_a_easy_post_batch`, passing the array of shipment IDs. It receives a batch ID (`batch_333`).
2. **Batch Execution:** Claude calls `easy_post_batches_buy` to initiate the background purchasing process.
3. **State Polling:** Claude understands the async nature of batches and calls `get_single_easy_post_batch_by_id` several times over the next few seconds until the `state` changes from `purchasing` to `purchased`.
4. **Manifest Generation:** Claude calls `easy_post_batches_create_scan_form`. It receives a new pending state, polls again, and eventually extracts the `form_url` to return to the warehouse manager.

## Security and Access Control

Giving an AI agent access to an API that actively charges a corporate credit card for postage requires strict security boundaries. Truto MCP servers implement several layers of defense to restrict agent capabilities:

* **Method Filtering:** Restrict the server to specific operations. Setting `config.methods: ["read"]` prevents the AI from calling `easy_post_shipments_buy`, allowing it to query tracking statuses and rates without spending money.
* **Tag Filtering:** Scope the server to specific resource domains. Using `config.tags: ["tracking"]` exposes only the tracker endpoints, entirely hiding the shipment and batch tools from the context window.
* **require_api_token_auth:** Enable this flag to force the MCP client to pass a valid Truto API session token. Possession of the MCP URL alone will no longer grant access, preventing unauthorized use if the URL leaks.
* **expires_at:** Assign an ISO timestamp to automatically tear down the server. The distributed key-value storage drops the token, and background alarms sweep the database records, leaving no stale credentials.

## Moving Past Manual Logistics

The gap between natural language intention and physical logistics execution has always been API complexity. By deploying a managed MCP server for EasyPost, you eliminate the need to hand-write schema mappings, handle authentication refreshes, and manually wire JSON-RPC 2.0 endpoints. 

Whether you are building autonomous support agents that refund damaged shipments, internal Slack bots that query inbound tracking statuses, or complex routing systems that leverage SmartRates, Truto's dynamic tool generation provides the structural foundation. Your engineering team can focus on orchestrating the agentic logic, while the infrastructure handles the translation.
