Een Model Context Protocol (MCP) server voor de PostNL API. Maak zendingen aan, genereer barcodes, volg pakketten, bereken bezorgdata en vind afhaalpunten — allemaal via natuurlijke taal in je AI-app.
Let op: Dit is een onofficieel, community-onderhouden project en is niet verbonden aan of goedgekeurd door PostNL.
A community-built Model Context Protocol (MCP) server for the PostNL API. Create shipments, generate barcodes, track parcels, calculate delivery dates, and find pickup locations — all through natural language via any MCP-compatible AI client.
Note: This is an unofficial, community-maintained project and is not affiliated with or endorsed by PostNL.
Je hoeft deze repo niet te clonen.
- Zorg dat Node.js 20+ is geïnstalleerd (je AI-app draait
npxop je machine) - Haal PostNL API-gegevens op (zie API Key Setup)
- Voeg de server toe als MCP server in je AI-app (kopieer onderstaande configuratie)
- Stel vragen in gewoon Nederlands (zie Voorbeelden)
You do not need to clone this repo.
- Make sure Node.js 20+ is installed (your AI app will run
npxon your machine) - Get PostNL credentials (see API Key Setup)
- Add this as an MCP server in your AI app (copy/paste config below)
- Ask plain-language shipping/tracking questions (see Example Usage)
Cowork runs inside Claude Desktop and uses the same connected MCP servers and permissions.
- Open your Claude Desktop MCP config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\\Claude\\claude_desktop_config.json
- macOS:
- Add this server entry (or merge into existing
mcpServers):
{
"mcpServers": {
"postnl-mcp": {
"command": "npx",
"args": ["-y", "postnl-mcp"],
"env": {
"POSTNL_API_KEY": "your-api-key",
"POSTNL_CUSTOMER_CODE": "your-customer-code",
"POSTNL_CUSTOMER_NUMBER": "your-customer-number"
}
}
}
}- Restart Claude Desktop
Most MCP apps have an "Add MCP Server" screen where you can fill in:
- Command:
npx - Args:
-y postnl-mcp - Env:
POSTNL_API_KEY=...,POSTNL_CUSTOMER_CODE=...,POSTNL_CUSTOMER_NUMBER=...
If your app wants JSON, paste this and adapt the top-level key name to your client (common keys are mcpServers, servers, or context_servers):
{
"<servers-key>": {
"postnl-mcp": {
"command": "npx",
"args": ["-y", "postnl-mcp"],
"env": {
"POSTNL_API_KEY": "your-api-key",
"POSTNL_CUSTOMER_CODE": "your-customer-code",
"POSTNL_CUSTOMER_NUMBER": "your-customer-number"
}
}
}
}- Error:
Missing required env varsor startup validation errors.- Fix: add
POSTNL_API_KEY,POSTNL_CUSTOMER_CODE, andPOSTNL_CUSTOMER_NUMBERto serverenvand restart your app.
- Fix: add
- Error:
npx: command not foundor server fails to start.- Fix: install Node.js 20+ and restart your app.
- Connected but API calls fail with
401/403or empty business data.- Fix: verify PostNL API subscriptions for the tools you use (see Required API Subscriptions).
- 7 tools across 4 categories covering the PostNL Shipping APIs
- Barcode generation for domestic (3S), mailbox (2S), EU (CC/CP/CD/CF), and international (LA/RI/UE) shipments
- Shipment creation with shipping label generation (PDF or ZPL format)
- Parcel tracking with full status history and event timeline
- Delivery date calculation with origin country and postal code support
- Delivery timeframes with evening delivery and Sunday sorting options
- Location finder — search PostNL pickup/drop-off points by postal code, city, or coordinates
- Input validation via Zod schemas on every tool for safe, predictable operations
- Response caching with configurable TTL and automatic invalidation on writes
- Rate limit handling with exponential backoff and
Retry-Afterheader support - Toolset filtering to expose only the tool categories you need
- Docker support for containerized deployment via GHCR
- Actionable error messages with context-aware recovery suggestions
Advanced setup and supported clients (expand)
This MCP server is not tied to one coding agent. It works with any MCP-compatible client or agent runtime that can start a stdio MCP server.
| Client / runtime | Docs |
|---|---|
| Claude Code | MCP in Claude Code |
| Anthropic API (Messages API) | Remote MCP servers |
| Codex CLI (OpenAI) | Codex CLI docs |
| Gemini CLI (Google) | Gemini CLI MCP server docs |
| VS Code (Copilot) | Use MCP servers in VS Code |
| Claude Desktop | MCP in Claude Desktop |
| Cursor | Cursor docs |
| Windsurf | Windsurf MCP docs |
| Cline | Cline MCP docs |
| Zed | Zed context servers docs |
| Any other MCP host | Use command/args/env from Generic MCP Server Config |
Claude currently has multiple MCP-related concepts that are easy to mix up:
- Local MCP servers (Claude Desktop): defined in
claude_desktop_config.jsonand started on your machine (docs). - Cowork: reuses the MCP servers connected in Claude Desktop (docs).
- Connectors: remote MCP integrations managed in Claude (docs).
- Cowork plugins: Claude-specific workflow packaging (instructions + tools/data integrations) (docs). Useful in Claude, but not portable as a generic MCP server config for other agent clients.
Verified against vendor docs on 2026-03-05.
If Quick Start worked in your client, you can skip this section. These are additional per-client setup options and CLI one-liners.
Use this as the baseline in any host:
- Command:
npx - Args:
["-y", "postnl-mcp"] - Required env vars:
POSTNL_API_KEY,POSTNL_CUSTOMER_CODE,POSTNL_CUSTOMER_NUMBER - Optional env vars:
POSTNL_CACHE_TTL,POSTNL_MAX_RETRIES,POSTNL_TOOLSETS(see Configuration)
Minimal JSON (adapt the top-level key to your host):
{
"<servers-key>": {
"postnl-mcp": {
"command": "npx",
"args": ["-y", "postnl-mcp"],
"env": {
"POSTNL_API_KEY": "your-api-key",
"POSTNL_CUSTOMER_CODE": "your-customer-code",
"POSTNL_CUSTOMER_NUMBER": "your-customer-number"
}
}
}
}Host key mapping:
| Host | Top-level key | Notes |
|---|---|---|
| VS Code | servers |
Add "type": "stdio" on the server object |
| Claude Desktop / Cursor / Windsurf / Cline | mcpServers |
Same command/args/env block |
| Zed | context_servers |
Same command/args/env block |
| Codex CLI (TOML) | mcp_servers |
Uses TOML, shown below |
claude mcp add --scope user postnl-mcp \
--env POSTNL_API_KEY=your-api-key \
--env POSTNL_CUSTOMER_CODE=your-customer-code \
--env POSTNL_CUSTOMER_NUMBER=your-customer-number \
-- npx -y postnl-mcpcodex mcp add postnl-mcp \
--env POSTNL_API_KEY=your-api-key \
--env POSTNL_CUSTOMER_CODE=your-customer-code \
--env POSTNL_CUSTOMER_NUMBER=your-customer-number \
-- npx -y postnl-mcp~/.codex/config.toml alternative:
[mcp_servers.postnl-mcp]
command = "npx"
args = ["-y", "postnl-mcp"]
env = { "POSTNL_API_KEY" = "your-api-key", "POSTNL_CUSTOMER_CODE" = "your-customer-code", "POSTNL_CUSTOMER_NUMBER" = "your-customer-number" }gemini mcp add postnl-mcp -- npx -y postnl-mcpSet POSTNL_API_KEY, POSTNL_CUSTOMER_CODE, and POSTNL_CUSTOMER_NUMBER in ~/.gemini/settings.json.
Open Command Palette (Cmd+Shift+P / Ctrl+Shift+P) > MCP: Add Server > Command (stdio), or use .vscode/mcp.json with top-level key servers and the canonical command/args/env block from Generic MCP Server Config.
Cowork runs inside Claude Desktop and uses the same connected MCP servers and permissions. Configure once in Claude Desktop, then the server is available in Cowork.
Use the canonical config block and place it in the host file below with the matching top-level key.
| Client | Config location | Top-level key |
|---|---|---|
| Claude Desktop (macOS) | ~/Library/Application Support/Claude/claude_desktop_config.json |
mcpServers |
| Claude Desktop (Windows) | %APPDATA%\\Claude\\claude_desktop_config.json |
mcpServers |
| Cursor (project) | .cursor/mcp.json |
mcpServers |
| Cursor (global) | ~/.cursor/mcp.json |
mcpServers |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
mcpServers |
| Cline | MCP settings UI | mcpServers |
| Zed (macOS/Linux) | ~/.zed/settings.json or ~/.config/zed/settings.json |
context_servers |
docker run -i --rm \
-e POSTNL_API_KEY=your-api-key \
-e POSTNL_CUSTOMER_CODE=your-customer-code \
-e POSTNL_CUSTOMER_NUMBER=your-customer-number \
ghcr.io/bartwaardenburg/postnl-mcpUse the values from Generic MCP Server Config.
What is portable across hosts:
- MCP server runtime settings (
command,args,env) - Transport model (
stdiocommand server) - Tool names and tool schemas exposed by this server
What is host/vendor-specific (not portable as-is):
- Host config key names (
servers,mcpServers,context_servers,mcp_servers) - Host UX/workflows for adding servers (CLI commands, UI menus, settings paths)
- Anthropic-specific concepts such as Claude Desktop local MCP servers, Claude Connectors via remote MCP, and Claude Code plugins used in Cowork workflows
- Trust model: Any prompt or agent allowed to call this MCP server can execute PostNL API actions with the configured credentials.
- Least-privilege credentials: Use separate PostNL credentials per environment/team/use case and only required API subscriptions.
- Write-action approvals: Enable host-side approvals for mutating tools (shipment creation and other write operations).
- Team config governance: Keep shared MCP config in version control, require review for changes to command/args/env/toolset filtering, and keep secrets in a vault or host secret manager (not in plain-text repo files).
| Variable | Description |
|---|---|
POSTNL_API_KEY |
Your PostNL API key |
POSTNL_CUSTOMER_CODE |
Your PostNL customer code (used in barcode generation and shipments) |
POSTNL_CUSTOMER_NUMBER |
Your PostNL customer number (used in shipment requests) |
Get your API credentials from the PostNL Developer Portal. Your customer code and customer number can be found in your PostNL business account.
| Variable | Description | Default |
|---|---|---|
POSTNL_CACHE_TTL |
Response cache lifetime in seconds. Set to 0 to disable caching. |
120 |
POSTNL_MAX_RETRIES |
Maximum retry attempts for rate-limited (429) requests with exponential backoff. | 3 |
POSTNL_TOOLSETS |
Comma-separated list of tool categories to enable (see Toolset Filtering). | All toolsets |
- Register for a PostNL Developer Portal account
- Subscribe to the APIs you need (Shipment, Barcode, Delivery Date, etc.)
- Generate an API key for your application
- Find your Customer Code and Customer Number in your PostNL business contract or portal
Depending on which tools you use, subscribe to:
| API Subscription | Tools |
|---|---|
| Barcode API | generate_barcode |
| Labelling API (Shipment v2) | create_shipment |
| Status API (Shipment v2) | get_shipment_status |
| Delivery Date API | get_delivery_date |
| Timeframe API | get_delivery_options |
| Locations API | find_locations, get_location |
| Tool | Description |
|---|---|
generate_barcode |
Generate a PostNL barcode for shipping (types: 2S mailbox, 3S domestic, CC/CP/CD/CF EU, LA/RI/UE international) |
create_shipment |
Create a shipment with label generation — provide sender/receiver address, get a PDF or ZPL shipping label back |
| Tool | Description |
|---|---|
get_shipment_status |
Track a parcel by barcode — returns current status, timestamps, and full event history |
| Tool | Description |
|---|---|
get_delivery_date |
Calculate the expected delivery date for a shipment based on postal code, shipping date, and product code |
get_delivery_options |
Get available delivery timeframes for an address (morning, afternoon, evening windows) |
| Tool | Description |
|---|---|
find_locations |
Find nearby PostNL pickup/drop-off points by postal code, city, or GPS coordinates |
get_location |
Get details of a specific PostNL location by location code |
Reduce context window usage by enabling only the tool categories you need. Set the POSTNL_TOOLSETS environment variable to a comma-separated list:
POSTNL_TOOLSETS=shipping,tracking| Toolset | Tools included |
|---|---|
shipping |
Barcode generation and shipment creation |
tracking |
Parcel tracking by barcode |
delivery |
Delivery date calculation and timeframe options |
locations |
PostNL location finder and details |
When not set, all toolsets are enabled. Invalid names are ignored; if all names are invalid, all toolsets are enabled as a fallback.
PostNL uses different barcode types depending on the shipment:
| Type | Description | Serie format |
|---|---|---|
2S |
Mailbox parcel | 000000000-999999999 |
3S |
Standard domestic parcel | 000000000-999999999 |
CC |
EU consumer parcel | 000000000-999999999 |
CP |
EU compact parcel | 000000000-999999999 |
CD |
EU standard parcel | 000000000-999999999 |
CF |
EU bulk parcel | 000000000-999999999 |
LA |
International Letter Registered | 000000000-999999999 |
RI |
International Registered Shipment | 000000000-999999999 |
UE |
International EMS | 000000000-999999999 |
| Code | Description |
|---|---|
3085 |
Standard shipment |
3385 |
Deliver to stated address only |
3090 |
Delivery to neighbour + return when not home |
3087 |
Extra cover |
3089 |
Signature on delivery + deliver to stated address only |
3189 |
Signature on delivery |
3533 |
Pickup + signature on delivery |
3534 |
Pickup + extra cover |
3543 |
Pickup + signature on delivery + notification |
3438 |
Age check (18+) |
2928 |
Mailbox parcel (brievenbuspakje) |
Evening delivery is not a separate product code — use any compatible product code (e.g. 3085) with product option {Characteristic: "118", Option: "006"} and a DeliveryDate.
Eenmaal verbonden kun je in gewoon Nederlands vragen stellen:
- "Genereer een barcode voor een binnenlands pakket"
- "Maak een zending aan van mijn magazijn op Hoofdstraat 1, Amsterdam naar Kerkstraat 42, Rotterdam"
- "Volg pakket 3STBJG123456789"
- "Wat is de verwachte bezorgdatum voor postcode 1234AB als ik vandaag verstuur?"
- "Toon bezorgtijdvakken voor 2511 BT Den Haag"
- "Zoek PostNL afhaalpunten bij postcode 3011 AA"
- "Geef details van PostNL locatie 176227"
Once connected, you can interact with the PostNL API using natural language:
- "Generate a barcode for a domestic parcel"
- "Create a shipment from my warehouse at Hoofdstraat 1, Amsterdam to Kerkstraat 42, Rotterdam"
- "Track parcel 3STBJG123456789"
- "What's the expected delivery date for postal code 1234AB if I ship today?"
- "Show me delivery timeframes for 2511 BT Den Haag"
- "Find PostNL pickup points near postal code 3011 AA"
- "Get details of PostNL location 176227"
- Support: SUPPORT.md
- Security reporting: SECURITY.md
- Contributing guidelines: CONTRIBUTING.md
- Bug reports and feature requests: Issues
# Install dependencies
pnpm install
# Run in development mode
pnpm dev
# Build for production
pnpm build
# Run tests
pnpm test
# Type check
pnpm typechecksrc/
index.ts # Entry point (stdio transport)
server.ts # MCP server setup and toolset filtering
postnl-client.ts # PostNL API HTTP client with caching and retry
cache.ts # TTL-based in-memory response cache
types.ts # TypeScript interfaces for PostNL API
tool-result.ts # Error formatting with recovery suggestions
update-checker.ts # NPM update notifications
tools/
shipping.ts # Barcode generation and shipment creation
tracking.ts # Parcel tracking by barcode
delivery.ts # Delivery date and timeframe calculation
locations.ts # PostNL location finder
- Node.js >= 20
- A PostNL business account with API credentials
MIT - see LICENSE for details.