Developers

MCP Integration Guide

BoxNearby exposes shipping-rate lookups, pickup-point search, and label purchasing as an MCP server, so any MCP-compatible AI agent — Claude, ChatGPT, or your own — can act on a user's behalf through natural language instead of a bespoke integration.

Authentication

Every MCP tool call runs as you — rate lookups, label purchases, and billing are scoped to your account exactly as if you'd used the app directly. There are two ways to connect:

An API key is sent as a standard bearer token:

Authorization: Bearer bnb_mcp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

API keys can be revoked at any time from the same settings screen — a revoked key is rejected immediately.

Connecting

One harmless quirk any real MCP client handles automatically: every tool response arrives as a text/event-stream body rather than plain JSON. The endpoint works with or without a trailing slash (/mcp and /mcp/).

Claude Code

claude mcp add --transport http boxnearby https://yourdomain.com/mcp \
  --header "Authorization: Bearer YOUR_API_KEY"

Or directly in .mcp.json / ~/.claude.json:

{
  "mcpServers": {
    "boxnearby": {
      "type": "http",
      "url": "https://yourdomain.com/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}

claude.ai

Add a custom connector (Settings → Connectors) with the URL https://yourdomain.com/mcp. Leave any OAuth client ID or secret fields blank. You'll be sent to BoxNearby to sign in and click Allow, then returned to claude.ai.

Other clients

Any client that lets you configure a remote HTTP MCP server with a custom header uses the same url + headers shape — Claude Desktop's config file, for example. Clients that support OAuth for remote servers can connect with just the URL.

Tools

get_shipping_rates

Get USPS/UPS home-delivery rate quotes for a package. Call this first to choose a carrier/service pair for create_shipping_label.

ParameterTypeNotes
sender_name, sender_street1, sender_city, sender_state, sender_zipstring
recipient_name, recipient_street1, recipient_city, recipient_state, recipient_zipstring
weight_lb, length_in, width_in, height_innumber

Returns:

{
  "rates": [
    { "carrier": "UPS", "service": "UPSGroundsaverGreaterThan1lb", "price_usd": 11.14, "delivery_days": "5 business days" },
    { "carrier": "USPS (EP)", "service": "GroundAdvantage", "price_usd": 11.69, "delivery_days": "3 business days" }
  ]
}

Rates aren't cached — create_shipping_label re-fetches fresh rates itself, so quotes here are indicative, not locked in.

find_pickup_hubs

Find nearby USPS Post Offices and Smart Lockers.

ParameterTypeNotes
locationstringFree-form address or place name, e.g. "94103" or "123 Main St, San Francisco, CA"
radius_milesintegerDefault 5

Returns {"hubs": [{"id", "name", "type", "address", "distance_miles"}, ...]}.

create_shipping_label

Start purchasing a home-delivery label for a carrier/service pair from get_shipping_rates.

Takes the same sender/recipient/parcel fields as get_shipping_rates, plus carrier and service (must match an option currently available for this exact shipment).

By default, a person pays. Stripe Checkout needs a human to open a URL and enter card details, so the tool returns a checkout link and an order id instead:

{
  "order_id": "205db6a1-cc6c-41ed-a0da-cee4d0d78d32",
  "checkout_url": "https://checkout.stripe.com/c/pay/cs_test_...",
  "amount_usd": 11.14,
  "carrier": "UPS",
  "service": "UPSGroundsaverGreaterThan1lb"
}

Surface checkout_url to the user, then poll get_label_status once they've paid. If the carrier/service pairing no longer matches an available rate, this returns an error asking you to call get_shipping_rates again.

Optionally, charge your membership card. You can turn on Settings → Profile → AI Agent Purchases to let your agent buy labels without a checkout page. It's off by default and uses the card you already pay your membership plan with — there's nothing separate to add (a membership paid from a bank account can't be charged instantly, so switch it to a card first). You set both a maximum per label and a maximum per 24 hours. When a label fits, your card is charged right away and the call returns the finished label ("paid_automatically": true, with label_url and tracking_number). Anything over a limit, or a declined card, simply falls back to the checkout link above, with an auto_pay field explaining why. Every automatic purchase is emailed to you and appears in My Messages, and if the label can't be created you're refunded automatically.

get_label_status

Poll a purchase started with create_shipping_label, given its order_id.

{ "status": "pending", "label_url": null, "tracking_number": null, "error": null }

status progresses pending (awaiting payment) → processing → complete (with label_url/tracking_number) or error (refunded automatically).

Limitations

Questions?

Reach us at support@boxnearby.com.

Get an API key →