Skip to content

Commit 004aac4

Browse files
authored
Merge pull request #986 from karrioapi/patch-2026.1.16
Patch 2026.1.16
2 parents 258e650 + aff6d6e commit 004aac4

File tree

307 files changed

+32624
-2023
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

307 files changed

+32624
-2023
lines changed

CHANGELOG.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,35 @@
1+
# Karrio 2026.1.16
2+
3+
## Changes
4+
5+
### Feat
6+
7+
- feat: add order_id field to Shipment model with REST/GraphQL exposure and auto-population
8+
- feat: add failed shipments tab with failure reasons and request_id propagation
9+
- feat: add @karrio/mcp server package for AI-powered shipping workflows
10+
- feat: add optional credential encryption with KEK-based secret storage
11+
- feat: add rate sheet editor improvements, pricing config, and markup management
12+
- feat: add DPD Meta connector updates with pickup support and error handling
13+
14+
### Fix
15+
16+
- fix: SmartKargo field names to match actual API (grossVolumeUnityMeasure, hasInsurance, insuranceAmmount)
17+
- fix: SmartKargo add customs/commercialInvoice support to rate requests and label base64 extraction
18+
- fix: SmartKargo move account_id to connection config, add SiteId header and barCode extraction
19+
- fix: DHL Parcel DE add economy and GoGreen Plus options, return billing config, and fix service matrix
20+
- fix: UPS add transId and transactionSrc headers to tracking requests
21+
- fix: UPS handle null ShippingLabel in return shipment response
22+
- fix: Landmark tracking multi-leg event ordering and delivered status
23+
- fix: propagate x-request-id through tracer context to carrier calls
24+
- fix: resolve all failing tests and build issues
25+
26+
### Docs
27+
28+
- docs: add Open Shipping Protocol (OSP) specification suite
29+
- docs: add carrier testing reports for DHL Parcel DE, UPS, and DPD Meta
30+
31+
---
32+
133
# Karrio 2026.1.15
234

335
## Changes

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Please read `AGENTS.md` thoroughly before making any changes. It contains:
1818

1919
## Claude-Specific Reminders
2020

21-
- When writing Django tests, always add `print(response)` before assertions for debugging
21+
- When debugging failing Django tests, add `print(response)` before assertions to see the actual response—remove print statements once tests pass
2222
- Favor functional, declarative style over imperative loops
2323
- Write code as if the same person authored the entire codebase
2424
- Read referenced files first, create a plan, then implement step by step

PRDs/FAILED_SHIPMENTS_TAB_AND_REQUEST_ID_PROPAGATION.md

Lines changed: 776 additions & 0 deletions
Large diffs are not rendered by default.

PRDs/SHIPMENT_ORDER_ID_FIELD.md

Lines changed: 805 additions & 0 deletions
Large diffs are not rendered by default.

SPRINT_MCP.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Karrio MCP Server — Sprint Plan
2+
3+
| Field | Value |
4+
|-------|-------|
5+
| Sprint | MCP Server v1.0 |
6+
| Branch | `feat/karrio-mcp-server` |
7+
| Start Date | 2026-02-27 |
8+
| Owner | PM Agent |
9+
| PRD | [PRDs/KARRIO_MCP_SERVER.md](./PRDs/KARRIO_MCP_SERVER.md) |
10+
11+
---
12+
13+
## Task Breakdown
14+
15+
### Wave 1: Package Scaffold (Sequential — must complete first)
16+
17+
| ID | Title | Description | Effort | Status | Dependencies |
18+
|----|-------|-------------|--------|--------|--------------|
19+
| MCP-001 | Package scaffold | Create `packages/mcp/` with `package.json`, `tsconfig.json`, `tsup.config.ts`, `src/index.ts` entry point, bin entry for CLI. Register in workspace. | M | DONE | None |
20+
21+
### Wave 2: Core Infrastructure (Sequential — after Wave 1)
22+
23+
| ID | Title | Description | Effort | Status | Dependencies |
24+
|----|-------|-------------|--------|--------|--------------|
25+
| MCP-002 | Karrio API client | Create `src/client.ts` — HTTP client wrapper that calls Karrio REST API. Handles auth headers, base URL, error formatting. Methods: `fetchRates`, `createShipment`, `getShipment`, `listShipments`, `cancelShipment`, `track`, `validateAddress`, `listCarriers`, `getCarrierServices`, `listOrders`, `schedulePickup`, `createManifest`. | M | DONE | MCP-001 |
26+
| MCP-003 | MCP server setup + stdio transport | Create `src/server.ts` — MCP server using `@modelcontextprotocol/sdk`. Register tools, resources. Entry point with stdio transport. `src/index.ts` as CLI entry with env var parsing (`KARRIO_API_URL`, `KARRIO_API_KEY`). | M | DONE | MCP-001 |
27+
| MCP-004 | Auth middleware | Create `src/auth.ts` — API key auth for stdio (from env/args), Bearer token validation for HTTP transport. | S | DONE | MCP-001 |
28+
29+
### Wave 3: Core Tools — P0 (Parallel — after Wave 2)
30+
31+
| ID | Title | Description | Effort | Status | Dependencies |
32+
|----|-------|-------------|--------|--------|--------------|
33+
| MCP-005 | `get_shipping_rates` tool | `src/tools/rates.ts` — Flat params (origin/dest postal+country, weight, optional dimensions, carrier filter, sort). Calls `POST /v1/proxy/rates`. Returns sorted rates with carrier, service, price, transit days. | M | DONE | MCP-002, MCP-003 |
34+
| MCP-006 | `create_shipment` tool | `src/tools/shipments.ts` — Flat params (shipper/recipient addresses, weight, carrier, service, label_type). `destructiveHint: true`. Calls `POST /v1/shipments` + `POST /v1/shipments/{id}/purchase`. Returns tracking number, label URL. | L | DONE | MCP-002, MCP-003 |
35+
| MCP-007 | `get_shipment` + `list_shipments` tools | `src/tools/shipments.ts` — get by ID, list with filters (status, date range, carrier). Pagination with limit/offset. | M | DONE | MCP-002, MCP-003 |
36+
| MCP-008 | `cancel_shipment` tool | `src/tools/shipments.ts` — Cancel/void by shipment ID. `destructiveHint: true`. | S | DONE | MCP-002, MCP-003 |
37+
| MCP-009 | `track_package` tool | `src/tools/tracking.ts` — Track by number + optional carrier. Returns status, events, estimated delivery. | M | DONE | MCP-002, MCP-003 |
38+
| MCP-010 | `validate_address` tool | `src/tools/addresses.ts` — Validate address fields, return corrected address + validation status. | S | DONE | MCP-002, MCP-003 |
39+
| MCP-011 | `list_carriers` tool | `src/tools/carriers.ts` — List connected carriers with capabilities. Read-only. | S | DONE | MCP-002, MCP-003 |
40+
41+
### Wave 4: Extended Tools + Resources — P1 (Parallel — after Wave 3)
42+
43+
| ID | Title | Description | Effort | Status | Dependencies |
44+
|----|-------|-------------|--------|--------|--------------|
45+
| MCP-012 | `schedule_pickup` tool | `src/tools/pickups.ts` — Schedule carrier pickup. | M | DONE | MCP-002, MCP-003 |
46+
| MCP-013 | `create_manifest` tool | `src/tools/manifests.ts` — Create end-of-day manifest. | M | DONE | MCP-002, MCP-003 |
47+
| MCP-014 | `list_orders` tool | `src/tools/orders.ts` — List orders with fulfillment status. | S | DONE | MCP-002, MCP-003 |
48+
| MCP-015 | MCP Resources — carrier catalog | `src/resources/carriers.ts``karrio://carriers`, `karrio://carriers/{id}`, `karrio://carriers/{id}/services`. Hybrid: also register read-only tool fallbacks. | M | DONE | MCP-002, MCP-003 |
49+
| MCP-016 | Streamable HTTP transport | `src/transports/http.ts` — Streamable HTTP (SSE) transport for remote deployment. Express/Hono server with `/mcp` endpoint. | M | DONE | MCP-003 |
50+
51+
### Wave 5: Tests (After Waves 3-4)
52+
53+
| ID | Title | Description | Effort | Status | Dependencies |
54+
|----|-------|-------------|--------|--------|--------------|
55+
| MCP-017 | Unit tests | `tests/unit/` — Test each tool's parameter validation, response formatting, error handling. Mock KarrioClient. Vitest. | M | DONE | MCP-005 through MCP-015 |
56+
| MCP-018 | Integration tests | `tests/integration/` — Test full MCP protocol round-trips (tools/list, tools/call, resources/list, resources/read). | M | DONE | MCP-017 |
57+
58+
### Wave 6: Documentation + Publishing
59+
60+
| ID | Title | Description | Effort | Status | Dependencies |
61+
|----|-------|-------------|--------|--------|--------------|
62+
| MCP-019 | README + setup docs | `packages/mcp/README.md` — Installation, Claude Desktop config, Cursor config, VS Code config, tool reference, env vars. | M | DONE | MCP-005 through MCP-016 |
63+
| MCP-020 | npm publish setup | Ensure `package.json` has correct `bin`, `files`, `main`, `types` fields. `prepublishOnly` script. `.npmignore`. | S | DONE | MCP-019 |
64+
65+
---
66+
67+
## Execution Order
68+
69+
```
70+
Wave 1 (sequential): MCP-001
71+
72+
73+
Wave 2 (sequential): MCP-002 ──► MCP-003 ──► MCP-004
74+
75+
76+
Wave 3 (parallel): MCP-005 | MCP-006 | MCP-007 | MCP-008 | MCP-009 | MCP-010 | MCP-011
77+
78+
79+
Wave 4 (parallel): MCP-012 | MCP-013 | MCP-014 | MCP-015 | MCP-016
80+
81+
82+
Wave 5 (sequential): MCP-017 ──► MCP-018
83+
84+
85+
Wave 6 (sequential): MCP-019 ──► MCP-020
86+
```
87+
88+
---
89+
90+
## Agent Assignments
91+
92+
| Agent | Tasks | Description |
93+
|-------|-------|-------------|
94+
| scaffold-agent | MCP-001 | Package setup, tsconfig, tsup, bin entry |
95+
| infra-agent | MCP-002, MCP-003, MCP-004 | API client, server setup, auth |
96+
| rates-agent | MCP-005 | get_shipping_rates tool |
97+
| shipment-agent | MCP-006, MCP-007, MCP-008 | create/get/list/cancel shipment tools |
98+
| tracking-agent | MCP-009 | track_package tool |
99+
| address-carrier-agent | MCP-010, MCP-011 | validate_address + list_carriers tools |
100+
| extended-tools-agent | MCP-012, MCP-013, MCP-014 | pickup, manifest, orders tools |
101+
| resources-agent | MCP-015 | MCP Resources for carrier catalog |
102+
| http-transport-agent | MCP-016 | Streamable HTTP transport |
103+
| test-agent | MCP-017, MCP-018 | Unit + integration tests |
104+
| docs-agent | MCP-019, MCP-020 | README, publish setup |
105+
106+
---
107+
108+
## Sprint Results
109+
110+
**Status**: COMPLETE
111+
112+
**Build**: `npm run build` passes (tsup, ESM, node18 target)
113+
**Tests**: 48/48 passing across 6 test files (vitest)
114+
**Files**: 29 files created in `packages/mcp/`
115+
116+
### Deliverables
117+
118+
| Deliverable | Status |
119+
|-------------|--------|
120+
| 11 MCP Tools (rates, shipments x4, tracking, address, carriers, pickups, manifests, orders) | Done |
121+
| 2 MCP Resources (karrio://carriers, karrio://carriers/{id}) | Done |
122+
| stdio transport (default) | Done |
123+
| Streamable HTTP transport (--http flag) | Done |
124+
| API key authentication | Done |
125+
| Unit tests (client, auth, tool registration) | Done |
126+
| Integration tests (server creation) | Done |
127+
| README with Claude Desktop / Cursor / VS Code / Claude Code config | Done |
128+
| npm publish setup (bin, exports, engines, .npmignore) | Done |

apps/api/karrio/server/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2026.1.15
1+
2026.1.16

apps/api/karrio/server/settings/base.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import decouple
1515
import importlib
1616
import dj_database_url
17+
import base64
18+
1719
from pathlib import Path
1820
from datetime import timedelta
1921
from django.urls import reverse_lazy
@@ -687,6 +689,55 @@
687689
},
688690
}
689691

692+
# ─────────────────────────────────────────────────────────────────────────────
693+
# SECRET ENCRYPTION (KEK Configuration)
694+
# ─────────────────────────────────────────────────────────────────────────────
695+
696+
697+
active_versions_str = config("ACTIVE_KEK_VERSIONS", default=None)
698+
699+
SECRET_ENCRYPTION_ENABLED = bool(active_versions_str)
700+
SECRET_KEK_REGISTRY = {}
701+
702+
if SECRET_ENCRYPTION_ENABLED:
703+
try:
704+
active_versions = [
705+
int(v.strip()) for v in active_versions_str.split(',') if v.strip()
706+
]
707+
except ValueError as e:
708+
raise ValueError(
709+
f"Invalid ACTIVE_KEK_VERSIONS format: {active_versions_str}. "
710+
"Expected comma-separated integers (e.g., '1,2,3')"
711+
) from e
712+
713+
if not active_versions:
714+
raise ValueError(
715+
"ACTIVE_KEK_VERSIONS must contain at least one version number"
716+
)
717+
718+
for version in active_versions:
719+
env_key = f'SECRET_KEK_V{version}'
720+
kek_b64 = config(env_key, default=None)
721+
722+
if not kek_b64:
723+
raise ValueError(
724+
f"KEK version {version} is listed in ACTIVE_KEK_VERSIONS "
725+
f"but {env_key} environment variable is not set"
726+
)
727+
728+
try:
729+
kek_bytes = base64.b64decode(kek_b64)
730+
731+
if len(kek_bytes) != 32:
732+
raise ValueError(
733+
f"{env_key} must decode to exactly 32 bytes (256 bits), "
734+
f"got {len(kek_bytes)}"
735+
)
736+
737+
SECRET_KEK_REGISTRY[version] = kek_bytes
738+
except Exception as e:
739+
raise ValueError(f"Invalid {env_key}: {e}") from e
740+
690741
# Initialize Loguru if enabled
691742
if USE_LOGURU:
692743
try:

apps/api/karrio/server/settings/debug.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# type: ignore
22
import sys
3-
import importlib.util
43
from karrio.server.settings.base import *
54

65
TESTING = sys.argv[1:2] == ["test"]

apps/api/karrio/server/static/karrio/elements/chunks/brace-fold.es-DzCN8vuL.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/api/karrio/server/static/karrio/elements/chunks/closebrackets.es-8vP0jBsb.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)