npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

envia-mcp

v0.2.0

Published

MCP server and client library for Envia.com shipping API — quote, label, track, and cancel shipments across 170+ carriers in 18 countries

Readme


What's Inside

Two exports, one package:

| Export | Import | Use Case | |--------|--------|----------| | MCP Server | envia-mcp | AI agents (Claude Code, Claude Desktop, Cursor) interact with Envia via natural language | | Client Library | envia-mcp/client | Node.js/TypeScript apps call the Envia API directly with full type safety | | Type Definitions | envia-mcp/types | Zod schemas and TypeScript types for all API entities |

Supported Countries

Americas

| Country | Code | Carriers | Notable Carriers | |---------|:----:|:--------:|-----------------| | Mexico | MX | 34 | DHL, FedEx, Estafeta, Paquetexpress, UPS | | United States | US | 33 | FedEx, UPS, USPS, DHL, Sendle, LSO | | Colombia | CO | 16 | FedEx, DHL, Coordinadora, Servientrega, TCC | | Argentina | AR | 12 | Andreani, Correo Argentino, FedEx, DHL, OCA | | Brazil | BR | 11 | Correios, FedEx, DHL, Jadlog, Loggi | | Chile | CL | 10 | Chilexpress, Correos Chile, FedEx, DHL, Starken | | Guatemala | GT | 7 | Cargo Expreso, DHL, Telomando | | Canada | CA | 4 | Canada Post, Canpar, DHL, Purolator | | Uruguay | UY | 3 | DHL, Treggo | | Peru | PE | 1 | Olva |

Europe, Asia & Oceania

| Country | Code | Carriers | Notable Carriers | |---------|:----:|:--------:|-----------------| | Spain | ES | 16 | Correos, DHL, FedEx, GLS, SEUR, UPS | | India | IN | 9 | BlueDart, Delhivery, FedEx, Aramex, Xpressbees | | France | FR | 4 | Chronopost, Mondial Relay, UPS | | Italy | IT | 4 | Poste Italiane, BRT, InPost, UPS | | Australia | AU | 3 | Aramex, FedEx, Sendle | | Hong Kong | HK | 1 | FedEx | | Japan | JP | 1 | — | | China | CN | 1 | — |

Envia adds carriers and countries over time. Use envia_get_carriers to get the current list.


Quick Start

As an MCP Server

The server connects to Envia's sandbox by default — no real charges, safe to experiment.

Add to your Claude Code config (.mcp.json):

{
  "mcpServers": {
    "envia": {
      "command": "node",
      "args": ["/path/to/envia-mcp/dist/index.js"],
      "env": {
        "ENVIA_API_KEY": "your-sandbox-api-key"
      }
    }
  }
}

Or, if installed globally via npm:

{
  "mcpServers": {
    "envia": {
      "command": "npx",
      "args": ["envia-mcp"],
      "env": {
        "ENVIA_API_KEY": "your-sandbox-api-key"
      }
    }
  }
}

As a Client Library

import { EnviaClient } from 'envia-mcp/client';

// Sandbox (default — safe for testing)
const client = new EnviaClient({
  apiKey: process.env.ENVIA_API_KEY!,
  shippingUrl: 'https://api-test.envia.com',
  queriesUrl: 'https://queries-test.envia.com',
  geocodesUrl: 'https://geocodes.envia.com',
});

// Get rates from all carriers, sorted by price
const quotes = await client.getQuotesAllCarriers(origin, destination, packages);

// Purchase a label (charges your prepaid balance in USD)
const label = await client.createLabel(origin, destination, packages, 'fedex', 'ground');

// Track a shipment
const tracking = await client.trackShipments(['TRACK123']);

MCP Tools

The server exposes 11 tools that AI agents can call:

| Tool | Description | Destructive | |------|-------------|:-----------:| | envia_quote | Get shipping rates from all carriers for a route | | | envia_create_label | Purchase a shipping label (charges USD balance) | Yes | | envia_track | Track one or more shipments by tracking number | | | envia_cancel | Cancel a shipment and request refund | Yes | | envia_validate_zipcode | Validate a postal code and get address info | | | envia_get_carriers | List available carriers for a country | | | envia_get_services | List services for a specific carrier | | | envia_shipment_history | Get shipment history for a given month/year | | | envia_schedule_pickup | Schedule a carrier pickup | Yes | | envia_classify_hscode | Classify product description into HS code for customs | | | envia_lookup_city | Look up cities by name, get postal codes (no auth) | |

All tools return both Markdown (for display) and structured data (for programmatic use).

MCP Resources

7 documentation resources provide AI agents with context about the Envia API:

| URI | Content | |-----|---------| | envia://docs/overview | API hosts, auth model, sandbox vs production | | envia://docs/address-format-mx | Mexican address fields, state codes, colonia mapping | | envia://docs/carriers | 34 carriers, service counts, weight limits | | envia://docs/rate-response | Price breakdown, MXN currency, additional charges | | envia://docs/label-response | USD currency, permanent label URLs, no idempotency | | envia://docs/errors | Error codes and how to handle them | | envia://docs/international | International shipping guide: HS codes, commercial invoices, currency, duties |

MCP Prompts

4 workflow prompts guide agents through multi-step tasks:

| Prompt | What It Does | |--------|-------------| | diagnose-shipment | Investigate tracking status, identify stuck/failed shipments | | compare-rates | Quote all carriers for a route, compare price vs speed | | verify-address | Validate a postal code, return neighborhoods and coordinates | | prepare-international-shipment | Step-by-step international shipment workflow |


Client API

The EnviaClient class provides typed methods for every Envia operation:

import { EnviaClient } from 'envia-mcp/client';

const client = new EnviaClient({ apiKey, shippingUrl, queriesUrl, geocodesUrl });

| Method | Returns | Description | |--------|---------|-------------| | getQuotes(origin, dest, packages, carrier) | RateQuoteItem[] | Rates from one carrier | | getQuotesAllCarriers(origin, dest, packages) | RateQuoteItem[] | Fan-out to all carriers, sorted by price | | createLabel(origin, dest, packages, carrier, service) | LabelItem | Purchase a shipping label | | trackShipments(trackingNumbers) | TrackingItem[] | Track one or more shipments | | cancelShipment(carrier, trackingNumber) | CancellationItem | Cancel and request refund | | validateZipCode(postalCode, countryCode?) | PostalCodeItem[] | Validate postal code (no auth needed) | | getCarriers(countryCode?) | Carrier[] | List available carriers | | getServices(carrier, countryCode?) | CarrierService[] | List services for a carrier | | getShipmentHistory(month, year) | ShipmentHistoryItem[] | Get shipment history for a month | | schedulePickup(request) | PickupResult | Schedule a carrier pickup | | classifyHsCode(description, options?) | HsCodeClassification | Classify product into HS code | | generateCommercialInvoice(request) | CommercialInvoiceResult | Generate commercial invoice for customs | | lookupCity(city, countryCode?) | CityLookupItem[] | Look up cities by name, get postal codes | | getAvailableCarriers(countryCode?, international?) | AvailableCarrier[] | List carriers with availability details |


Envia API Gotchas

Things that will bite you if you're not careful:

| Gotcha | Details | |--------|---------| | phone_code differs | Country code string for quotes (e.g. "MX"), dialing code for labels (e.g. "52") | | Quotes are MXN, labels are USD | Prepaid balance is denominated in USD | | Labels are NOT idempotent | Duplicate call = double charge, different tracking number | | Sandbox geocodes is DOWN | Always use production geocodes.envia.com | | Carrier is required per quote | The client fans out automatically, but the raw API needs one carrier per call | | Track by tracking number | shipmentId does NOT work as a tracking key |


Configuration

The MCP server reads configuration from environment variables:

| Variable | Required | Default | Description | |----------|:--------:|---------|-------------| | ENVIA_API_KEY | Yes | — | Your Envia.com API key | | ENVIA_SHIPPING_URL | | https://api-test.envia.com | Shipping API base URL | | ENVIA_QUERIES_URL | | https://queries-test.envia.com | Queries API base URL | | ENVIA_GEOCODES_URL | | https://geocodes.envia.com | Geocodes API base URL |

Sandbox vs Production

The server defaults to Envia's sandbox environment. This is intentional.

The envia_create_label tool purchases real shipping labels — it costs money and is not idempotent (calling it twice creates two labels with different tracking numbers, charged twice). AI agents can trigger this tool multiple times during a conversation, and there is no undo. Defaulting to sandbox prevents accidental charges during development, testing, and experimentation.

This follows industry best practice: Supabase MCP recommends "never connect to production"; Stripe separates test/live keys; Slack MCP disables destructive operations by default.

Switching to production

To use the live Envia API, set the URL environment variables to production hosts:

{
  "mcpServers": {
    "envia": {
      "command": "node",
      "args": ["/path/to/envia-mcp/dist/index.js"],
      "env": {
        "ENVIA_API_KEY": "your-production-api-key",
        "ENVIA_SHIPPING_URL": "https://api.envia.com",
        "ENVIA_QUERIES_URL": "https://queries.envia.com"
      }
    }
  }
}

Important notes:

  • Sandbox and production use separate API keys — a sandbox key won't work on production and vice versa
  • Geocodes (geocodes.envia.com) always uses production — the sandbox geocodes endpoint is down (503)
  • The server logs (sandbox) or (PRODUCTION) on startup so you always know which environment you're hitting

Currency

The Envia API defaults to USD when the currency field is omitted from requests. This is a common source of confusion for Latin American users who expect MXN (or their local currency). The official @envia/envia-mcp server inherits this behavior, silently quoting and charging in USD.

Our implementation defaults to MXN. You can override this globally or per call:

// Default: MXN
const client = new EnviaClient({ apiKey, shippingUrl, queriesUrl, geocodesUrl });

// Override globally (e.g., for Colombia)
const client = new EnviaClient({
  apiKey,
  shippingUrl,
  queriesUrl,
  geocodesUrl,
  defaultCurrency: 'COP',
});

// Override per call via the currency parameter
const quotes = await client.getQuotesAllCarriers(origin, destination, packages, {
  currency: 'USD',
});

The MCP server also defaults to MXN. Set ENVIA_DEFAULT_CURRENCY to change it.


HTTP Features

The client includes production-grade HTTP handling:

  • SSRF protection — hostname allowlist restricts requests to known Envia API domains only
  • Retry with exponential backoff — failed requests retry up to 3 times with increasing delays
  • Retry-After header support — respects server-requested cooldown periods before retrying

Comparison with @envia/envia-mcp

Envia maintains an official MCP server at @envia/envia-mcp. Here is a factual comparison:

| Feature | envia-mcp (this project) | @envia/envia-mcp (official) | |---------|--------------------------|----------------------------| | Typed TypeScript client library | Yes | No | | Configurable currency default | Yes (MXN default) | No (USD default) | | Zod response validation | Yes | No | | Structured MCP output (data + Markdown) | Yes | No | | Sandbox geocodes fallback | Yes | No | | SSRF protection (hostname allowlist) | Yes | No | | Retry with exponential backoff | Yes | No | | Official Envia branding | No | Yes | | Sandbox by default | Yes | Yes | | 10+ MCP tools | Yes (11) | Yes |

Known issues in the official server:

  • Missing settings object on label creation causes HTTP 400 errors
  • Defaults to USD instead of MXN, which is unexpected for the primary market (Mexico)

Development

# Clone and install
git clone https://github.com/amak07/envia-mcp.git
cd envia-mcp
npm.cmd install

# Build
npm.cmd run build

# Type check
npm.cmd run typecheck

# Run tests (30 unit tests, mocked API)
npm.cmd run test:run

# Dev mode (watch + restart)
npm.cmd run dev

Project Structure

src/
  index.ts          # MCP server entry point (shebang, stdio transport)
  client.ts         # EnviaClient class (standalone, no MCP dependency)
  types.ts          # Zod schemas + TypeScript types for all API entities
  utils.ts          # HTTP helpers, error handling, formatting
  constants.ts      # API URLs, character limits, response format
  tools/
    quote.ts        # envia_quote — fan-out rate quoting
    create-label.ts # envia_create_label — label purchase
    track.ts        # envia_track — shipment tracking
    cancel.ts       # envia_cancel — shipment cancellation
    validate-zipcode.ts  # envia_validate_zipcode — postal code lookup
    get-carriers.ts # envia_get_carriers — carrier directory
    get-services.ts # envia_get_services — service catalog
    index.ts        # Barrel — registerAllTools()
  resources/
    index.ts        # 6 inline documentation resources
  prompts/
    index.ts        # 3 workflow prompts
  client.test.ts    # 30 unit tests (mocked fetch)
tests/
  fixtures/         # Real API response snapshots (JSON)

Tech Stack

  • TypeScript with strict mode
  • MCP SDK @modelcontextprotocol/sdk 1.27+
  • Zod for runtime schema validation
  • Native fetch (Node.js 18+ built-in, no axios)
  • Vitest for unit testing
  • ESM ("type": "module")

License

MIT