Most shipping APIs want a box: length, width, height, weight. People don't have that — they have a thing on the table and a ZIP code to send it to. This server takes the thing.
Describe "a full-size acoustic guitar in its hard case" and it estimates the packed carton, prices it live across three carriers, and hands back services you can actually buy — with the checkout total and, where the carrier publishes one, its own counter price for the same parcel side by side, so you can always show a person both numbers.
What you can ask your assistant
- "How much to ship a 12 lb box from 07922 to 90011?"
- "What would it cost to send a full-size acoustic guitar in a hard case from New Jersey to Los Angeles?"
- "Compare USPS, UPS and FedEx for a 5 lb box, Newark to Chicago — which is cheapest and which is fastest?"
- "Price a 24 × 18 × 12 in box at 22 lb going to 33101, then give me a link to buy the label."
- "Where is my package? Tracking 9400111899561234567890."
- "Did they pay for that label yet? Here is the session id you gave me."
- "What has a 5 lb box to Denver cost over the last few months?"
Tools
| Tool | What it does |
|---|---|
get_parcel_quote | Live rates for one parcel from a US origin, domestic or to Canada, the UK, Germany or Australia, across USPS, UPS and FedEx, plus DHL Express to Germany and Australia. Plain-words description → estimated packed box; or pass exact dimensions and weight to skip the estimate. Returns up to five purchasable services with the checkout total (SMKlog fee inside), the carrier's counter price beside it where one is published, and the delivery window. |
create_checkout_link | Prices the shipment and returns a payment session: the amount, a handoff URL that opens the SMKlog checkout prefilled with this shipment, and a session_id. The human confirms the contents certification and the carrier-adjustment consent there and pays on Stripe. |
get_checkout_status | Where a payment session stands: awaiting_checkout, checkout_started, paid, label_ready (with the tracking number), delivered or refunded. Read from the order record, so it costs no carrier call and never carries names, addresses or emails. Sessions answer for 30 days. |
track_parcel | Delivery status, scan events and the carrier's estimated delivery date for a shipment whose label was bought on smklog.com. Not a universal tracker for arbitrary numbers. |
get_price_index | The monthly SMKlog parcel price index: six common boxes (1–20 lb) from Newark, NJ to five US cities, repriced through the same live pipeline that prices real shipments. Reading it spends no quote allowance. |
Things worth knowing before you wire it in
A quote is a real carrier call and costs real money to produce. Call
get_parcel_quote once per shipment, not once per variation you are curious
about. The server is rate limited per client and will say so plainly rather than
silently degrading.
Origin is the United States. Domestic lanes and US-origin exports. A lane that starts somewhere else is out of scope, and the server will tell you instead of inventing a number.
Prices are checkout totals with the SMKlog fee inside. The fee is itemized only on the checkout receipt; what comes back beside a rate is the carrier's own counter price for the same parcel, where one is published — what the person would pay walking into the carrier's counter instead. The total is what they pay.
Parcels only, one label per box. A shipment past parcel limits or described
as a pallet or freight load comes back as mode: not_a_parcel with no rates:
SMKlog sells parcel labels and does not arrange pallet or freight shipments.
quantity counts units of the item: units that fit one box are priced as that
box, while units that need more than one box — or a quantity above 1 sent with
exact dimensions, which describe one box — come back as mode: multiple_boxes
with no rates, so quote each box on its own.
Nothing here buys a label on its own. create_checkout_link produces a URL;
a human completes the purchase, certifies the contents and consents to carrier
adjustments. An agent cannot spend someone's money through this server.
Connect
{
"mcpServers": {
"smklog": {
"type": "http",
"url": "https://quote-api.smklog.com/mcp"
}
}
}
No key, no OAuth, no signup. Quoting, tracking and the price index are all open.
Over stdio
For a client that only launches local commands — Claude Desktop, Cursor, an MCP inspector, a Docker-based runner — this repository is a thin stdio bridge to the same endpoint. No dependencies, no build step, no keys:
{
"mcpServers": {
"smklog": {
"command": "npx",
"args": ["-y", "github:smklog/parcel-shipping-rates-mcp"]
}
}
}
Or with Docker:
docker build -t smklog-parcel-shipping-rates-mcp https://github.com/smklog/parcel-shipping-rates-mcp.git
docker run -i --rm smklog-parcel-shipping-rates-mcp
The bridge forwards every JSON-RPC message to https://quote-api.smklog.com/mcp
and writes the answer back, one JSON object per line. It also mirrors the
2026-07-28 routing envelope into HTTP headers (MCP-Protocol-Version,
Mcp-Method, Mcp-Name) and, on the legacy path, sends the version
initialize negotiated, so both protocol eras work through it. If the endpoint cannot be
reached it still answers initialize and tools/list from the snapshot shipped
here (initialize.json, tools.json), so you can see what is offered; tool
calls need the network. npm test drives it end to end.
Configuration
The bridge reads three optional environment variables and nothing else:
| Variable | Default | What it does |
|---|---|---|
SMKLOG_MCP_URL | https://quote-api.smklog.com/mcp | Endpoint the bridge forwards to. |
SMKLOG_MCP_TIMEOUT_MS | 90000 (minimum 1000) | Per-request timeout. A quote is a live carrier call and can take half a minute. |
SMKLOG_MCP_DEBUG | unset | 1 writes traffic summaries to stderr; stdout stays clean JSON-RPC. |
{
"mcpServers": {
"smklog": {
"command": "npx",
"args": ["-y", "github:smklog/parcel-shipping-rates-mcp"],
"env": { "SMKLOG_MCP_TIMEOUT_MS": "120000" }
}
}
}
Secrets and keys
There are none to configure. The server takes no API key, token or account, and the bridge reads no credentials. Do not put carrier, payment or other API keys into the client config for this server: nothing reads them, and a config file is the wrong place to keep a secret. Carrier and payment credentials live only on the server side.
Data and privacy
- Quote tools take an item description, postal codes and, optionally, box size and weight. They never ask for street addresses, names, emails or phone numbers. Names, addresses and payment are entered by the person on the smklog.com checkout, not through this server.
- The description and the box are used to price the parcel with the carriers. A recognized item is kept in our product catalog so the next quote for the same item comes out the same.
- Each tool call is logged for 30 days: the tool, the item description, the first three characters of each postal code, the destination country, the client software family, the request's country and the outcome. No IP address, full user agent, street address or contact details are stored for this.
- Rate limits count requests in hourly windows keyed by a one-way SHA-256 hash of the connecting IP (and of IP plus user agent); the address itself is not written.
- Full policy: https://smklog.com/privacy.
Also installable from Smithery
and listed in the official MCP registry
as com.smklog/parcel-shipping-rates.
Other ways in, if MCP is not your transport: OpenAPI · A2A agent card · API docs · llms.txt
Who runs it
SMKlog sells US shipping labels. The same pricing pipeline that answers this server answers the website — there is no separate "API rate". People who are not using an assistant price and buy the same labels in the shipping calculator. Questions, bugs and odd results: [email protected]. Security reports: see SECURITY.md. Changes: CHANGELOG.md.