Ship parcels via any configured carrier — MyParcel, Sendcloud, DHL Parcel NL, PostNL, DPD, UPS, FedEx. Auto-selects the first carrier whose credentials are configured, or pass --carrier <name> to override. Verbs: ship, label, track, list, carriers.
npx skills add https://github.com/davepoon/buildwithclaude --skill ops-package
One skill, seven carriers. The router picks the carrier automatically based on which credentials are configured.
| Condition | Selected carrier |
| -------------------------------------------------------------------- | ------------------------- |
| --carrier <name> flag passed | That carrier (validated) |
| Exactly one carrier has credentials | That carrier |
| Multiple carriers have credentials | First match in this order |
| No carrier has credentials | Exit 2 with setup help |
Preference order: myparcel → sendcloud → dhl → postnl → dpd → ups → fedex.
Each carrier resolves its credential(s) from, in order:
preferences.json key (lowercase of the env var name) at ${CLAUDE_PLUGIN_DATA_DIR:-$HOME/.claude/plugins/data/ops-ops-marketplace}/preferences.json.doppler secrets get <NAME> --plain.| Carrier | Env vars required | Docs |
| ---------- | ---------------------------------------------------------------------- | --------------------------------------------------- |
| MyParcel | MYPARCEL_API_KEY | https://developer.myparcel.nl/api-reference/ |
| Sendcloud | SENDCLOUD_PUBLIC_KEY + SENDCLOUD_PRIVATE_KEY | https://api.sendcloud.dev/docs/ |
| DHL NL | DHL_PARCEL_USER_ID + DHL_PARCEL_KEY | https://api-gw.dhlparcel.nl/docs |
| PostNL | POSTNL_API_KEY + POSTNL_CUSTOMER_CODE + POSTNL_CUSTOMER_NUMBER | https://developer.postnl.nl/ |
| DPD | DPD_DELIS_ID + DPD_PASSWORD | https://esolutions.dpd.com/ |
| UPS | UPS_CLIENT_ID + UPS_CLIENT_SECRET + UPS_SHIPPER_NUMBER | https://developer.ups.com/api/reference/shipping |
| FedEx | FEDEX_CLIENT_ID + FEDEX_CLIENT_SECRET + FEDEX_ACCOUNT_NUMBER | https://developer.fedex.com/api/en-us/catalog/ |
All API calls are delegated to ${CLAUDE_PLUGIN_ROOT}/skills/ops-package/ops-package.sh. Do not re-implement curl logic inline — pass args through.
| First token | Action |
| ----------- | ------------------------------------------------------------------ |
| carriers | Show configured vs unconfigured carriers |
| ship | Create a shipment |
| label | Download + open label PDF |
| track | Show status + tracking barcode |
| list | List last 10 shipments (MyParcel / Sendcloud; others unsupported) |
| (empty) | Show usage |
Required: --to "<address>". Address format:
"Person / Company, Street 12A, 1011AB Amsterdam, NL"
/ Company segment is optional.Flags (not every carrier honours every flag — unsupported flags are safely ignored per adapter):
--from "<address>" override sender; default is the account's configured sender.--weight <grams> integer grams.--package-type 1|2|3 1=parcel (default), 2=mailbox, 3=letter (MyParcel only).--signature require signature on delivery.--insurance <EUR> integer EUR; 0 disables (MyParcel only).--description "<text>" label reference (carriers differ; ~45 char max).--pickup request home pickup at sender (MyParcel only).${CLAUDE_PLUGIN_ROOT}/skills/ops-package/ops-package.sh \
[--carrier myparcel|sendcloud|dhl|postnl|dpd|ups|fedex] \
ship --to "$TO" [--from "$FROM"] [--weight "$W"] \
[--signature] [--insurance "$INS"] [--description "$DESC"] \
[--package-type "$TYPE"] [--pickup]
Returns:
{"carrier": "<name>", "shipment_id": "<id>", "response": { /* raw carrier JSON */ }}
Summarise to the user as:
Shipment created — <carrier> #<id>
Next: /ops:ops-package label <id> to download the PDF.
Offer via AskUserQuestion (≤4 options):
[Download label now] — call label <id> immediately[Track it] — call track <id>[Ship another][Done]<shipment-id>${CLAUDE_PLUGIN_ROOT}/skills/ops-package/ops-package.sh label "$ID"
Behaviour per carrier:
/tmp/myparcel_label_<id>.pdf and opened on macOS. If unpaid, returns {"status":"payment_required","payment_url":"..."} and opens the MultiSafepay URL./labels/<id>) and saves locally./labels/<id>?format=PDF&printerType=A4./v1/parcellabelnumber/<id>?paperFormat=A4.ship call and cached to /tmp/<carrier>_label_<id>.pdf. Calling label re-opens that cached file. If the cache is gone, re-run ship (none of these carriers expose a stable label-recovery endpoint here).<shipment-id>Returns a normalised object across all carriers:
{"carrier":"<n>","id":"<id>","status":"<s>","barcode":"<b>","tracking_url":"<u>","recipient":<o>,"updated":"<ts>"}
MyParcel returns the last 10 shipments. Sendcloud returns the last 10 parcels. All other carriers return {"shipments":[],"note":"..."} because their APIs don't expose a customer-facing list endpoint — track by id instead.
Prints which carriers are configured (✓) vs which are missing credentials (·). Use this when deciding which --carrier to pass.
AskUserQuestion:[Paste key now] [Open carriers doc] [Skip — configure later]
On "Paste key now", collect via AskUserQuestion free-text and write to preferences.json.
| Carrier | Status |
| ---------- | ------------------------------------------------------------------ |
| MyParcel | Verified against api.myparcel.nl v1.1 (same working reference) |
| Sendcloud | Verified request/response shapes against Sendcloud Panel API v3 |
| DHL NL | UNVERIFIED — modelled on My DHL Parcel Swagger, needs live account |
| PostNL | UNVERIFIED — modelled on Send API v2.2 docs, needs live account |
| DPD | UNVERIFIED — modelled on DPD eSolutions REST, needs live account |
| UPS | UNVERIFIED — modelled on UPS v2403 Ship/Track REST, needs account |
| FedEx | UNVERIFIED — modelled on FedEx Ship v1 + Track v1 REST |
Unverified adapters are tagged with # UNVERIFIED - pending live test with account in the source. Payloads match the documented contract; adjustments may be needed when tested against live accounts.
Integration with protocols.io API for managing scientific protocols. This skill should be used when working with protocols.io to search, create, update, or publish protocols; manage protocol steps and materials; handle discussions and comments; organize workspaces; upload and manage files; or integrate protocols.io functionality into workflows. Applicable for protocol discovery, collaborative protocol development, experiment tracking, lab protocol management, and scientific documentation.
Analyzes job descriptions and generates tailored resumes that highlight relevant experience, skills, and achievements to maximize interview chances
Generate Excalidraw diagrams from natural language descriptions. Use when asked to "create a diagram", "make a flowchart", "visualize a process", "draw a system architecture", "create a mind map", or "generate an Excalidraw file". Supports flowcharts, relationship diagrams, mind maps, and system architecture diagrams. Outputs .excalidraw JSON files that can be opened directly in Excalidraw.
Build and distribute Expo development clients locally or via TestFlight
Use when you have a written implementation plan to execute in a separate session with review checkpoints
Data structure for annotated matrices in single-cell analysis. Use when working with .h5ad files or integrating with the scverse ecosystem. This is the data format skill—for analysis workflows use scanpy; for probabilistic models use scvi-tools; for population-scale queries use cellxgene-census.
Benchling R&D platform integration. Access registry (DNA, proteins), inventory, ELN entries, workflows via API, build Benchling Apps, query Data Warehouse, for lab data management automation.
Comprehensive molecular biology toolkit. Use for sequence manipulation, file parsing (FASTA/GenBank/PDB), phylogenetics, and programmatic NCBI/PubMed access (Bio.Entrez). Best for batch processing, custom bioinformatics pipelines, BLAST automation. For quick lookups use gget; for multi-service integration use bioservices.
Take davepoon/ops-package from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.