MCP server

AdminUpdated Sep 24, 2026

MCP server

mcp-shippified is a Model Context Protocol server that exposes the Shippified API as tools. With it connected, Claude Desktop, Claude Code, or any other MCP client can list and create orders, check tracking, manage bots and email sources, and set up webhooks, all in your workspace.

It is a thin layer over the TypeScript SDK. Every tool call becomes one REST request authenticated with your API key. It communicates over stdio, so the MCP client starts it as a local subprocess. The current version is 0.2.0.

Important: mcp-shippified is not published to npm. npx mcp-shippified and npm install mcp-shippified will fail or fetch something unrelated. Build it from a checkout of the Shippified repository, or install a tarball you pack yourself.

Install

Requires Node 18 or newer. The build bundles the SDK source from the same repository into one executable file, dist/index.js, so you don't build or install the SDK separately. The MCP protocol library (@modelcontextprotocol/sdk) stays a normal runtime dependency that npm install fetches.

From a checkout

cd shippified/mcp-shippified
npm install
npm run build             # type-checks, then bundles to dist/index.js
./dist/index.js --help

dist/index.js is executable and starts with a node shebang. It accepts two flags:

Flag

Output

--help, -h

Usage and the environment variables it reads.

--version, -v

The version, 0.2.0.

With no flags it waits for JSON-RPC on stdin, which is what an MCP client does when it launches it. Run by hand, it appears to hang. That is expected.

As a tarball

A tarball is a single file you can copy to another machine. npm pack builds first:

cd shippified/mcp-shippified
npm install
npm pack                                        # writes mcp-shippified-0.2.0.tgz
npm install -g ./mcp-shippified-0.2.0.tgz       # puts `mcp-shippified` on your PATH
mcp-shippified --version

npm can't install a package from a subdirectory of a git repository, so a github: URL does not work here.

Configuration

The server reads two environment variables:

Variable

Required

Default

Description

SHIPPIFIED_TOKEN

For every tool except the public ones

none

A Shippified API key (sk_…). A session token also works, but it expires after 14 days.

SHIPPIFIED_BASE_URL

No

https://shippified.net

Instance origin, without /api.

Create a dedicated key for the MCP server under Settings → Developer → API keys, so you can revoke it on its own.

Important: The key gives the agent full access to your workspace, including tools that delete orders, revoke API keys, and create webhook subscriptions. API keys have no scopes, and the server has no read-only mode. Only connect clients you trust, and review tool calls before approving them.

In the configurations below, replace /absolute/path/to/shippified with where you cloned the repository. If you installed the tarball globally, use the command mcp-shippified with no arguments instead of node and the path.

Claude Code

claude mcp add shippified \
  -e SHIPPIFIED_TOKEN="$SHIPPIFIED_API_KEY" \
  -- node /absolute/path/to/shippified/mcp-shippified/dist/index.js

Run claude mcp list to check that the server connects.

Claude Desktop

Edit claude_desktop_config.json. Its location is ~/Library/Application Support/Claude/ on macOS and %APPDATA%\Claude\ on Windows. Then restart Claude Desktop.

{
  "mcpServers": {
    "shippified": {
      "command": "node",
      "args": ["/absolute/path/to/shippified/mcp-shippified/dist/index.js"],
      "env": {
        "SHIPPIFIED_TOKEN": "sk_your_key_here",
        "SHIPPIFIED_BASE_URL": "https://shippified.net"
      }
    }
  }
}

With a global tarball install, use "command": "mcp-shippified" and leave out args.

Other MCP clients

Any client that launches stdio servers works. Configure:

  • Command: node (or mcp-shippified after a global tarball install)

  • Arguments: /absolute/path/to/shippified/mcp-shippified/dist/index.js (none for mcp-shippified)

  • Environment: SHIPPIFIED_TOKEN and, optionally, SHIPPIFIED_BASE_URL

Use absolute paths. Desktop clients often start servers with a minimal PATH and an unexpected working directory. If the client can't find node, give the absolute path to your Node binary.

For development, npm run dev runs the server straight from TypeScript with tsx, without building.

To debug the server outside a client, use the official MCP Inspector:

SHIPPIFIED_TOKEN="$SHIPPIFIED_API_KEY" \
  npx @modelcontextprotocol/inspector \
  node /absolute/path/to/shippified/mcp-shippified/dist/index.js

Tools

The server exposes 49 tools. Each returns the API's JSON response as pretty-printed text.

Public (no token needed)

Tool

Arguments

API call

get_landing_stats

none

GET /api/landing-stats

get_health

none

GET /api/healthz

get_public_profile

username

GET /api/profile/:username

Workspace and orders

Tool

Arguments

API call

get_state

none

GET /api/state

list_orders

status (ordered, canceled, shipped, delivered, issue), store, source, carrier, hasTracking, from, to, q, limit, offset

GET /api/orders

get_order

id

GET /api/orders/:id

create_order

itemSummary (required), store, storeLabel, orderNumber, trackingNumber, carrier, total, costCents, salePriceCents, quantity, productUrl, imageUrl, sku, size, receivedAt, emailSourceId

POST /api/orders

update_order

id, plus salePriceCents (a number, or null to clear), costCents, estimatedDelivery, trackingNumber, carrier, orderNumber, itemSummary, quantity

PATCH /api/orders/:id

delete_order

id

DELETE /api/orders/:id

get_order_tracking

id

GET /api/orders/:id/tracking

refresh_order_tracking

id

POST /api/orders/:id/tracking/refresh

get_carrier_status

none

GET /api/carrier-status

sync_tracking

none

POST /api/orders/sync-tracking

reparse_orders

none

POST /api/orders/reparse

Intake and templates

Tool

Arguments

API call

list_bots

limit, offset

GET /api/bots

get_bot

id

GET /api/bots/:id

create_bot

name (required), templateId, avatar, templateHint, outputWebhook, samplePayload

POST /api/bots

update_bot

id, name, slug, avatar, templateId, templateHint, outputWebhook, samplePayload, type (monitor, dropship, generic)

PATCH /api/bots/:id

delete_bot

id

DELETE /api/bots/:id

list_email_sources

limit, offset

GET /api/email-sources

get_email_source

id

GET /api/email-sources/:id

poll_email_source

id

POST /api/email-sources/:id/poll

rebuild_email_source

id (required), sinceDays (1 to 365, default 30)

POST /api/email-sources/:id/rebuild

import_email

raw, emailSourceId (both required), from

POST /api/email/import

list_templates

none

GET /api/templates (built-in templates only)

list_custom_templates

none

GET /api/templates/custom

detect_template

source (email or webhook) and sample (both required), draft

POST /api/templates/custom/detect

Costs, shares, and billing

Tool

Arguments

API call

list_subscriptions

limit, offset

GET /api/subscriptions (recurring costs)

create_subscription

name, costCents (required), currency, frequency, startDate (defaults to today), endDate, category, notes, active

POST /api/subscriptions

update_subscription

id, plus fields

PATCH /api/subscriptions/:id

delete_subscription

id

DELETE /api/subscriptions/:id

list_shares

none

GET /api/shares

create_share

timeframe (7d, 30d, 90d, ytd, all), includeStats, includeCheckouts

POST /api/shares

delete_share

slug

DELETE /api/shares/:slug

get_billing_usage

none

GET /api/billing/usage

create_billing_checkout

plan (monthly, yearly), successUrl, cancelUrl

POST /api/billing/checkout

create_billing_portal

returnUrl

POST /api/billing/portal

set_timezone

timezone (IANA name)

POST /api/account/timezone

Keys, webhooks, and logs

Tool

Arguments

API call

list_api_keys

none

GET /api/account/api-keys

create_api_key

name

POST /api/account/api-keys (the response contains the raw key)

revoke_api_key

id

DELETE /api/account/api-keys/:id

list_webhook_subscriptions

limit, offset

GET /api/webhook-subscriptions

create_webhook_subscription

url, eventTypes (required), active

POST /api/webhook-subscriptions (the response contains the secret)

update_webhook_subscription

id, url, eventTypes, active

PATCH /api/webhook-subscriptions/:id

delete_webhook_subscription

id

DELETE /api/webhook-subscriptions/:id

test_webhook_subscription

id, eventType (default order.created)

POST /api/webhook-subscriptions/:id/test

rotate_webhook_secret

id

POST /api/webhook-subscriptions/:id/rotate-secret

list_webhook_logs

limit (1 to 500, default 100)

GET /api/webhook-logs

clear_webhook_logs

none

DELETE /api/webhook-logs

How the tools behave

The tool descriptions tell the agent these rules, so it can explain them to you:

  • Status can't be set. Order status comes from parsing and carrier tracking. list_orders offers only the real status values, so a status filter always filters.

  • update_order is fill-missing-only. salePriceCents can always be changed, and null clears it. Every other field is written only when the order has no value yet, and itemSummary only while the order is still "Unparsed order". Adding a tracking number to an ordered order moves it to shipped. Compare the returned order to see what changed.

  • reparse_orders re-runs parsing on the messages Shippified already stored, using the current built-in shapes and your custom templates. Hand-entered values and carrier data are kept. It waits and returns { reparsed, changed, merged, removed, skipped }. Use it after creating or fixing a template.

  • rebuild_email_source is destructive. It re-reads the mailbox and replaces the orders that source produced in the window. It returns right away and runs in the background; check rebuilding and lastRebuild with get_email_source. The mailbox is checked before anything is deleted. Orders you edited and orders that also came in through Discord or manual entry are kept. Forwarding sources return 400, and a rebuild already running returns 409.

  • detect_template is read-only. It shows which template or built-in shape would win for a sample, whether it would be ignored as non-order mail, and the order it would produce. Pass draft to test an unsaved template.

  • import_email creates real orders, through the same pipeline as live mail (allowed senders, Message-ID dedup, plan limit).

  • sync_tracking refreshes up to 50 in-flight orders on carriers with live tracking on the instance and returns { total, refreshed, failed, delivered }. It uses carrier API quota. A background tracker already does this on a schedule, so the agent rarely needs it.

  • get_order_tracking serves a cached answer for up to 5 minutes for packages in transit and 24 hours once delivered. refresh_order_tracking bypasses the cache. Carriers without live tracking on the instance return liveUnavailable: true.

  • create_webhook_subscription rejects URLs that resolve to private or internal addresses. The secret is in the response once. A subscription listed with needsSecretRotation: true gets no deliveries until rotate_webhook_secret runs.

Known differences from the API

  • create_order advertises an eventType argument, but the server doesn't receive it: the tool drops it before calling the API. The order gets the default (order_shipped with a tracking number, otherwise order_placed). To set eventType, call POST /api/orders directly.

  • create_bot doesn't take type. Set it afterwards with update_bot.

  • test_webhook_subscription defaults eventType to order.created, not to the subscription's first event type as the tool description says.

  • The tools don't cover account export and deletion (those need a signed-in session and refuse API keys), per-bot logs, the Inbox, or GET /api/carrier-status.

Errors

API errors come back as tool errors (isError: true) with the text Shippified API <status>: <message>, followed by the full JSON error body when there is one, so fields such as blockedSender or reason reach the agent. For example, a missing or revoked token produces Shippified API 401: Not authenticated. If SHIPPIFIED_TOKEN is unset, authenticated tools fail before any request is sent, with ShippifiedClient: token required for ….

Example prompts

  • "List my orders from the last 7 days that still have no tracking number."

  • "Add a manual order: Example Console Bundle from Best Buy, order BBY01-000000000001, cost $499.99."

  • "Refresh tracking on order ord_mpvu9uim_aeh5t and tell me the latest carrier event."

  • "I just fixed my Hayha template. Re-parse my orders and tell me what changed."

  • "Which template would parse this email? Don't import it."

  • "Create a webhook subscription to https://hooks.example.com/shippified for order.shipped and order.delivered, then send it a test event."

Was this page helpful?
MCP server