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

Generate your own API key from Settings → Profile → API Access after signing in. 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.

Send it as a standard bearer token:

Authorization: Bearer bnb_mcp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

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

Connecting

Two harmless quirks any real MCP client handles automatically: a bare POST /mcp (no trailing slash) redirects to /mcp/, and every tool response arrives as a text/event-stream body rather than plain JSON.

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"
      }
    }
  }
}

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. Some hosted "custom connector" web UIs only expose OAuth for third-party servers rather than a raw bearer-token field; if you hit that, use that client's local config file instead.

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

Payment can't complete inside this call — Stripe Checkout needs a human to open a URL and enter card details. 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.

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) → processingcomplete (with label_url/tracking_number) or error (refunded automatically).

Limitations

Questions?

Reach us at support@airboxship.ai.

Get an API key →