The Mailroom MCP server
Mailroom's MCP server is a stateless streamable-HTTP endpoint that gives an AI agent 16 tools for corporate shipping: quote rates across UPS, FedEx and USPS, buy a label, track it, void it, and manage the prepaid balance that pays for it — inside spending caps a human sets.
Last updated
How to connect
One endpoint, no session to establish. Authenticate with an API key as a bearer token, or with OAuth 2.1 — dynamic client registration lives at /oauth/register, so a client can register itself without a human creating credentials first.
POST https://app.mailroom.software/mcp
Authorization: Bearer mk_test_…
# Stateless streamable HTTP. GET returns 405 — POST only.
# Discovery: https://app.mailroom.software/.well-known/oauth-protected-resourceA mk_test_ key works immediately and costs nothing. See the sandbox for what test keys do differently.
The 16 tools
Two of these spend money — create_shipment buys a real label, and add_funds charges the card on file. Everything else reads state, prepares a purchase, or hands something to a human. Quoting is always free and has no side effects.
| Tool | What it does |
|---|---|
| Shipping | |
get_shipping_rates | Validate the destination and get live rates across the org's enabled carriers. Returns a quoteId valid 15 minutes. Free, no side effects — always call before create_shipment. |
create_shipmentspends money | Buy a label from a quoteId + rateId. Irreversible except by voiding inside the carrier window. May return pending_approval when a human manager must approve first. |
track_shipments | List shipments with status, or get full tracking events for one. Returns labelUrl once status reaches label_created — this is how an agent retrieves its label. |
void_shipment | Void a purchased label and refund per carrier rules. Only inside the carrier void window and before the label is used. |
validate_address | Validate a US address against carrier data. Returns corrections, or candidate addresses when ambiguous. |
search_contacts | Search the organization address book by name or company. Returns saved addresses usable directly as shipTo. |
| Limits | |
request_limit_increase | Ask for a higher cap after a policy_violation. Granted instantly up to the admin-set ceiling; otherwise a human operator reviews it. |
reply_to_limit_request | Answer an operator's follow-up question on a pending cap request, returning it to them for a decision. |
list_limit_requests | List this key's cap requests with status — pending, awaiting_agent, approved, denied, or auto_granted — and the operator Q&A thread. |
| Billing | |
get_billing_status | Read prepaid balance, auto-refill settings, whether a card is on file, and whether live keys are unlocked. |
add_fundsspends money | Charge the card on file to add prepaid balance, $50–$10,000. Takes an idempotencyKey so a retry cannot double-charge. |
check_top_up | Poll a top-up started with add_funds: processing, succeeded, or failed. Balance is credited on succeeded. |
configure_auto_refill | Top up automatically when the balance drops below a threshold. Threshold ≥ $5, refill amount ≥ $50. |
activate_live_key | Mint a live key once card, billing authorization, and positive balance are all in place. Returns the key once; a 402 itemizes whatever is missing. |
| Human handoff | |
get_billing_setup_link | Mint a time-limited URL for a human admin to add a card and authorize balance billing. Card entry is human-only — an agent cannot enter card data. |
get_settings_link | Mint a 1-hour login URL for the human admin to change what an agent cannot: cards, spending policies, approval rules, carriers, keys. Treat it like a password. |
The order the tools go in
Rates first, always. get_shipping_rates validates the destination address and returns a quoteId good for 15 minutes alongside priced options; create_shipment takes that quoteId plus a rateId. The agent therefore cannot buy at a price it has not already seen.
Label creation is asynchronous. create_shipment can return status: draft with no label yet — poll track_shipments by shipment ID until label_created, then fetch labelUrl with the same bearer key. Agent-created shipments raise no Slack notification, so polling is how the agent finds out.
It can also return pending_approval, which means a human manager was notified in Slack and nothing proceeds until they approve.
MCP or REST — the same platform
Every tool maps to a REST endpoint on the same API, with the same keys, caps and audit trail. Use MCP when the agent framework speaks it; use REST when it does not. Nothing is exclusive to either.
- OpenAPI 3.1 spec: /.well-known/openapi.json
- Human-readable API overview: /docs/api
- One request to orient an agent: /llms.txt