charts

parcelapp-mcp

Version: 0.1.0 Type: application AppVersion: 0.2.1 Artifact Hub

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.

TL;DR

helm repo add obeone https://charts.obeone.cloud
helm repo update
helm install parcelapp-mcp obeone/parcelapp-mcp

About

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.

Prerequisites

Configuration

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

Providing the API key

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

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, 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.

Exposure and authentication

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.

Upgrading

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.

Uninstalling

helm uninstall parcelapp-mcp

PersistentVolumeClaims created by the chart are kept around: delete them manually if you also want the data gone.

Requirements

Kubernetes: >=1.31.0-0

Repository Name Version
https://bjw-s-labs.github.io/helm-charts common 5.1.0

Values

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.

Verifying the chart signature

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

Support

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