Parcel App MCP — a Model Context Protocol server wrapping the Parcel delivery-tracking API, so an LLM client can list deliveries, add tracking numbers and look up carrier codes. This Helm chart runs it in its streamable-http transport, reachable over the cluster network and driven entirely from values.yaml via the bjw-s common library.
helm repo add obeone https://charts.obeone.cloud
helm repo update
helm install parcelapp-mcp obeone/parcelapp-mcp
parcelapp-mcp is a Model Context Protocol server around the API of Parcel, the iOS/macOS delivery-tracking app. It lets an LLM client list your deliveries, register new tracking numbers and look up carrier codes. This chart runs it with its streamable-http transport, so the MCP endpoint is reachable over the cluster network instead of only over stdio.
The Parcel API is a premium feature of the app: you need an active subscription and an API key before any of the tools return something useful.
ghcr.io/obeone/parcelapp-mcpcharts/parcelapp-mcpkubeVersion constraint (see Chart.yaml)This chart is built on the bjw-s-labs common library.
Most configuration keys (controllers, service, ingress, persistence,
…) follow its schema; see the common library documentation
for everything it supports beyond what is spelled out in values.yaml.
Defaults are meant to work out of the box on any cluster. The full list of
options lives in values.yaml, is validated by
values.schema.json at install time, and is documented
in the Values section below. Override it with your own values file:
helm install parcelapp-mcp obeone/parcelapp-mcp -f my-values.yaml
The server reads the key from PARCEL_TOKEN, or from PARCEL_API_KEY as an alias.
Neither is set by default: the pod starts and answers MCP requests, but every call
to the Parcel API fails.
Point it at a Secret you manage yourself:
controllers:
main:
containers:
main:
env:
PARCEL_TOKEN:
valueFrom:
secretKeyRef:
name: parcelapp-credentials
key: PARCEL_TOKEN
Or let the chart create the Secret, at the cost of keeping the key in your values file:
secrets:
credentials:
enabled: true
stringData:
PARCEL_TOKEN: "your-api-key"
controllers:
main:
containers:
main:
envFrom:
- secret: credentials
The server exposes no HTTP health endpoint. Its only route is the MCP path, which
answers a JSON-RPC POST and rejects a plain GET, so the chart probes the listener
with a TCP connect. For an end-to-end check, replace them with an exec probe that
performs an initialize call, the way the image’s own HEALTHCHECK does.
The chart ships no authentication in front of the MCP endpoint, and both ingress
and route are disabled by default. Anyone who can reach the Service can read your
deliveries and add tracking numbers to your account. Put an authenticating proxy in
front of it before exposing it outside the cluster.
helm repo update
helm upgrade parcelapp-mcp obeone/parcelapp-mcp
Each release lists its changes in the Artifact Hub changelog; give it a look before jumping across several chart versions.
helm uninstall parcelapp-mcp
PersistentVolumeClaims created by the chart are kept around: delete them manually if you also want the data gone.
Kubernetes: >=1.31.0-0
| Repository | Name | Version |
|---|---|---|
| https://bjw-s-labs.github.io/helm-charts | common | 5.1.0 |
| Key | Type | Default | Description |
|---|---|---|---|
| controllers.main.containers.main.env | object | {"PARCEL_HOST":"0.0.0.0","PARCEL_LOG_LEVEL":"INFO","PARCEL_PATH":"/mcp","PARCEL_PORT":"8000","PARCEL_TRANSPORT":"streamable-http"} |
Environment driving the server. The image has no entrypoint arguments, so the whole configuration is expressed through these PARCEL_* variables. |
| controllers.main.containers.main.image.pullPolicy | string | "IfNotPresent" |
|
| controllers.main.containers.main.image.repository | string | "ghcr.io/obeone/parcelapp-mcp" |
Container image, published on GitHub Container Registry by the upstream project. Override it to pull your own build or a mirror. |
| controllers.main.containers.main.image.tag | string | "0.2.1" |
Image tag. Tracks the chart’s appVersion, so bumping one bumps the other. Floating tags 0.2 and 0 also exist upstream. |
| controllers.main.containers.main.probes | object | {"liveness":{"custom":true,"enabled":true,"spec":{"failureThreshold":5,"initialDelaySeconds":10,"periodSeconds":30,"tcpSocket":{"port":8000},"timeoutSeconds":5}},"readiness":{"custom":true,"enabled":true,"spec":{"failureThreshold":3,"initialDelaySeconds":5,"periodSeconds":10,"tcpSocket":{"port":8000},"timeoutSeconds":5}},"startup":{"custom":true,"enabled":false,"spec":{"failureThreshold":30,"periodSeconds":5,"tcpSocket":{"port":8000}}}} |
Health probes. The server exposes no HTTP health endpoint: its only route is the MCP path, which answers a JSON-RPC POST and rejects a plain GET. A TCP connect on the listener is therefore the honest check here. If you want a real end-to-end probe, switch to an exec probe running a JSON-RPC initialize POST, the way the image’s own HEALTHCHECK does. |
| controllers.main.containers.main.resources.limits.memory | string | "256Mi" |
|
| controllers.main.containers.main.resources.requests.cpu | string | "10m" |
|
| controllers.main.containers.main.resources.requests.memory | string | "64Mi" |
|
| controllers.main.containers.main.securityContext.allowPrivilegeEscalation | bool | false |
|
| controllers.main.containers.main.securityContext.capabilities.drop[0] | string | "ALL" |
|
| controllers.main.containers.main.securityContext.readOnlyRootFilesystem | bool | true |
|
| controllers.main.strategy | string | "RollingUpdate" |
|
| defaultPodOptions | object | {"automountServiceAccountToken":false,"securityContext":{"fsGroup":10001,"runAsGroup":10001,"runAsNonRoot":true,"runAsUser":10001,"seccompProfile":{"type":"RuntimeDefault"}}} |
Pod-wide options applied to every controller in this chart. |
| ingress | object | {"main":{"className":"","enabled":false,"hosts":[{"host":"chart-example.local","paths":[{"path":"/","pathType":"Prefix","service":{"identifier":"main","port":"http"}}]}],"tls":[{"hosts":["chart-example.local"],"secretName":"tls-chart-example-local"}]}} |
Ingress. Disabled by default; flip enabled and set a real host to expose the MCP endpoint. The server speaks plain HTTP, so terminate TLS at the ingress. |
| persistence | object | {"tmp":{"globalMounts":[{"path":"/tmp"}],"sizeLimit":"64Mi","type":"emptyDir"}} |
Storage. The read-only root filesystem above leaves Python nowhere to write its temporary files, so /tmp comes from a small emptyDir. |
| route | object | {"main":{"enabled":false,"hostnames":["chart-example.local"],"kind":"HTTPRoute","parentRefs":[{"name":"gateway","namespace":"gateway-system"}],"rules":[{"backendRefs":[{"identifier":"main"}],"matches":[{"path":{"type":"PathPrefix","value":"/"}}]}]}} |
Gateway API HTTPRoute, mirroring the Ingress above. Disabled by default: pick either Ingress or HTTPRoute, not both. Requires the Gateway API CRDs and an existing Gateway in the cluster. |
| route.main.enabled | bool | false |
Enable the HTTPRoute. Mutually exclusive with ingress.main.enabled. |
| route.main.hostnames | list | ["chart-example.local"] |
Hostnames served by this route. |
| route.main.kind | string | "HTTPRoute" |
Route kind. HTTPRoute, GRPCRoute, TCPRoute, TLSRoute or UDPRoute. |
| route.main.parentRefs | list | [{"name":"gateway","namespace":"gateway-system"}] |
Gateways this route attaches to. |
| route.main.rules | list | [{"backendRefs":[{"identifier":"main"}],"matches":[{"path":{"type":"PathPrefix","value":"/"}}]}] |
Routing rules. identifier refers to a Service defined above. |
| secrets | object | {"credentials":{"enabled":false,"stringData":{"PARCEL_TOKEN":""}}} |
Secrets created by this chart. Disabled by default: the recommended path is to point PARCEL_TOKEN at a Secret you manage yourself (see the env block above). Enable this only if you are comfortable with the API key living in your values file, and pair it with envFrom: [{ secret: credentials }] on the container. |
| secrets.credentials.stringData.PARCEL_TOKEN | string | "" |
Parcel API key, taken from the app’s settings. Replace before enabling. |
| service | object | {"main":{"controller":"main","ports":{"http":{"port":8000,"protocol":"TCP","targetPort":8000}},"type":"ClusterIP"}} |
Service exposing the streamable-http MCP endpoint inside the cluster. |
Charts in this repository are signed with GPG and every release ships a
provenance file. The public key is available at
charts.obeone.cloud/public_key.gpg,
fingerprint B9FE852F28888D27F8C9A11CD33E04CD22E335CE.
# Import the signing key into a legacy keyring (helm verifies with GnuPG v1 keyrings)
curl -fsSL https://charts.obeone.cloud/public_key.gpg | gpg --import
gpg --export > ~/.gnupg/pubring.gpg
# Pull the chart and check it against its provenance file
helm pull --verify obeone/parcelapp-mcp
This is a personal chart repository, maintained on a best-effort basis. Bug reports and contributions are welcome on GitHub.
Autogenerated from chart metadata using helm-docs v1.14.2