From fdba242f488cfa51765071dd5912a5198cc22bce Mon Sep 17 00:00:00 2001 From: Moritz Graf Date: Tue, 21 Oct 2025 20:53:16 +0200 Subject: [PATCH] Adding latest changes before switching to an approach that might actually work... with mcp-remote --- k8s/README.md | 17 ++++- k8s/n8n/_tmp_generate-token.yaml | 65 ------------------- k8s/n8n/garmin-mcp.yaml | 104 +++++++++++++++---------------- k8s/n8n/garmin.secret.yaml | Bin 737 -> 0 bytes 4 files changed, 65 insertions(+), 121 deletions(-) delete mode 100644 k8s/n8n/_tmp_generate-token.yaml delete mode 100644 k8s/n8n/garmin.secret.yaml diff --git a/k8s/README.md b/k8s/README.md index a8ac36e..b92dcb6 100644 --- a/k8s/README.md +++ b/k8s/README.md @@ -710,6 +710,21 @@ oci://8gears.container-registry.com/library/n8n \ To verify installation was correcet, use the following command: -``` +```sh helm get manifest mop-n8n -n n8n | less ``` + +Apply the garth mcp server: + +```sh +kubectl apply -f n8n/garmin-mcp.yaml +``` + +Generate token: + +```sh +uvx garth login +#login with user+pw+token +#take output, put in in garth_tkomen.txt +kubectl create secret generic garth-token-secret --from-file=GARTH_TOKEN=./garth_token.txt -n n8n +``` diff --git a/k8s/n8n/_tmp_generate-token.yaml b/k8s/n8n/_tmp_generate-token.yaml deleted file mode 100644 index 47cc409..0000000 --- a/k8s/n8n/_tmp_generate-token.yaml +++ /dev/null @@ -1,65 +0,0 @@ -# --- Garmin Token Generator Pod --- -# This pod is a temporary, interactive tool to generate Garmin Connect session tokens. -# -# --- WORKFLOW --- -# 1. Ensure the `garmin-credentials` secret is applied in the `n8n` namespace. -# 2. Apply this manifest: `kubectl apply -f token-generator-pod.yaml` -# 3. View the logs to see instructions: `kubectl logs -n n8n -f garmin-token-generator` -# 4. Exec into the pod and run the login command provided in the logs. -# 5. Retrieve the generated token data from within the pod. -# 6. Create the `garmin-tokens` Kubernetes secret. -# 7. Delete this pod: `kubectl delete pod -n n8n garmin-token-generator` -# -apiVersion: v1 -kind: Pod -metadata: - name: garmin-token-generator - namespace: n8n -spec: - volumes: - # This is temporary storage that will be deleted when the pod is deleted. - # We use it to hold the generated token files. - - name: garmin-connect-storage - emptyDir: {} - containers: - - name: helper - image: python:3.12-slim - # Mount the garmin-credentials secret as environment variables - envFrom: - - secretRef: - name: garmin-credentials - # The main command installs dependencies, prints instructions, and then sleeps. - # This keeps the pod running so you can exec into it. - command: ["/bin/sh", "-c"] - args: - - | - set -e - echo "--- Garmin Token Generator Pod ---" - echo "[Step 1/3] Installing dependencies (git and uv)..." - # Set debconf to non-interactive mode to prevent installation prompts and fix warnings. - export DEBIAN_FRONTEND=noninteractive - # Redirect noisy output to /dev/null - apt-get update > /dev/null && apt-get install -y git --no-install-recommends > /dev/null && rm -rf /var/lib/apt/lists/* - pip install uv > /dev/null - - echo "[Step 2/3] Setup complete. Pod is ready for interactive login." - echo "------------------------------------------------------------------" - echo "ACTION REQUIRED:" - echo "1. Ensure the 'garmin-credentials' secret has been applied to this namespace." - echo "2. Open a new terminal." - echo "3. Connect to this pod by running:" - echo " kubectl exec -it -n n8n garmin-token-generator -- /bin/sh" - echo "" - echo "4. Inside the pod's shell, run the following simplified command:" - echo " uvx --from garminconnect gcexport --username \"$GARMIN_EMAIL\" --password \"$GARMIN_PASSWORD\"" - echo "" - echo "5. Follow the prompts to enter your MFA code." - echo "6. Once successful, the tokens will be saved to /root/.garminconnect" - echo "------------------------------------------------------------------" - - echo "[Step 3/3] Sleeping indefinitely. This pod will remain running until you delete it." - sleep infinity - volumeMounts: - # Mount the temporary storage at the path where the library saves tokens. - - name: garmin-connect-storage - mountPath: "/root/.garminconnect" \ No newline at end of file diff --git a/k8s/n8n/garmin-mcp.yaml b/k8s/n8n/garmin-mcp.yaml index c3d1d8d..6675800 100644 --- a/k8s/n8n/garmin-mcp.yaml +++ b/k8s/n8n/garmin-mcp.yaml @@ -1,84 +1,78 @@ -# --- Garmin MCP Server Deployment --- -# This manifest defines the desired state for the Garmin MCP server. -# It uses a standard Python image and installs the necessary tools and -# the application itself upon startup. +# --- 1. Secret to hold your Garmin Connect token --- +# You must create this secret before applying the rest of the manifest. +# Replace 'your_base64_encoded_token_here' with your actual token encoded in Base64. +# To encode your token, run: echo -n 'your_token_from_login' | base64 +# apiVersion: v1 +# kind: Secret +# metadata: +# name: garth-mcp-secret +# namespace: default +# type: Opaque +# data: +# # This key MUST be GARTH_TOKEN to match the application's environment variable +# GARTH_TOKEN: your_base64_encoded_token_here +--- +# --- 2. Deployment for the Garth MCP Server --- +# This will create a Pod running the server application. apiVersion: apps/v1 kind: Deployment metadata: - name: garmin-mcp-server + name: garth-mcp-server-deployment namespace: n8n labels: - app: garmin-mcp-server + app: garth-mcp-server spec: replicas: 1 selector: matchLabels: - app: garmin-mcp-server + app: garth-mcp-server template: metadata: labels: - app: garmin-mcp-server + app: garth-mcp-server spec: containers: - - name: server - # Use a standard, slim Python image as the base. - image: python:3.12-slim - # Override the default command to perform setup and then run the server. + - name: garth-mcp-server + # Use a standard Python slim image as a base + image: python:3.11-slim + # The command first installs the 'uv' tool, then uses 'uvx' to run the server. + # It's configured to listen on all interfaces (0.0.0.0) inside the container. command: ["/bin/sh", "-c"] args: - - | - set -e - echo "Step 1/4: Installing git client..." - # Update package lists and install git. --no-install-recommends keeps it minimal. - # rm -rf cleans up the apt cache to keep the running container lean. - apt-get update && apt-get install -y git --no-install-recommends && rm -rf /var/lib/apt/lists/* - - echo "Step 2/4: Installing uv package manager..." - pip install uv - - echo "Step 3/4: Launching server via uvx (will install from git)..." - # 'uvx' runs a command from a temporary environment. - # We specify the git repository to install the package from. - # The '--host 0.0.0.0' flag is crucial to ensure the server - # is accessible from outside its container within the cluster network. - uvx --from git+https://github.com/Taxuspt/garmin_mcp garmin-mcp --host 0.0.0.0 --port 8000 - - echo "Step 4/4: Server has been started." - + - "pip install -U garth-mcp-server && garth-mcp-server --host 0.0.0.0 --port 8080" ports: - name: http - containerPort: 8000 + containerPort: 8080 protocol: TCP - # Mount the Garmin credentials from the Kubernetes secret as environment variables. envFrom: + # Load environment variables from the Secret created above - secretRef: - name: garmin-credentials - # Basic readiness probe to ensure the service is not marked ready until the app is listening. - readinessProbe: - tcpSocket: - port: 8000 - initialDelaySeconds: 25 # Increased delay to account for git installation - periodSeconds: 10 + name: garth-token-secret + resources: + requests: + memory: "64Mi" + cpu: "100m" + limits: + memory: "128Mi" + cpu: "250m" --- -# --- Garmin MCP Server Service --- -# This manifest creates a stable internal endpoint (ClusterIP service) -# for the Garmin MCP server deployment. Your n8n instance will use this -# service's DNS name to communicate with the server. +# --- 3. Service to expose the Deployment --- +# This creates a stable internal endpoint for the server. apiVersion: v1 kind: Service metadata: - name: garmin-mcp-service + name: garth-mcp-service namespace: n8n spec: - # This service will be of type ClusterIP, only reachable from within the cluster. - type: ClusterIP selector: - # This selector must match the labels of the pods created by the Deployment. - app: garmin-mcp-server + app: garth-mcp-server ports: - - name: http - protocol: TCP - # The port the service will be available on within the cluster. - port: 80 - # The port on the container that the service will forward traffic to. - targetPort: 8000 \ No newline at end of file + - name: http + protocol: TCP + # The port the service will be available on within the cluster + port: 80 + # The port on the container that the service will forward traffic to + targetPort: 8080 + # ClusterIP is the default, but we're explicit here. + # This service is only reachable from within the Kubernetes cluster. + type: ClusterIP \ No newline at end of file diff --git a/k8s/n8n/garmin.secret.yaml b/k8s/n8n/garmin.secret.yaml deleted file mode 100644 index 0e453a1949b2d4d3f5c6812892e440fe5a826eda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 737 zcmV<70v`PUM@dveQdv+`0PDHE&ccg}05fv!?c|4)IVI3iWin$|NQZ)NuX^oMm6=>Q zir+l3k`}zn%Cz5365TH%Vl{o)m5^yktWRoP!&-kBXWHRC4iXnWX+$ zajfgYjH&BFu31{OSm(rO1^#)GOV|L8$6pw~EviQ{y-Ru6_^8o2b@ji!0uT5v2W8@R z4BF;10bz;o8l*8Hu-VAuRgfhWpV}<#7z@lwiG?l# z2jQ5d1Vpu@YZ#V0F{y_eDDN;94?zqhYy=A+l7H*>M4Bq zR&{ot6d()lE+6Yd+9=bOpaBS~NAE`?3L6$KGbQBjUdj#2_d6%QN z3BfLO_QDGVFO$6fAa#B_7su3xdtXMeyF?&lrqI(0xf5VEFfe^ty5hL3j99G;O7RZ+ z;(Zjc*+bl?<#|o*tEJyNJFqA4pk5lR!PP?e<&r~s{z)3k@^mU`#1$`a-sAa%u-`;j z_E!x1QG}|P;bjx<1^s^)%IWlV`N4Io(=hif@9wntC+|D75VT&+>E@$~tbB|vb**$L zAi>MRgW_|z7{+eH0|8n~Vqm|%LtkXjQ?teP1V$oAuv}v2hj*g)W1`SBjz z`;;RqG^Jo>onFQ3r7T-cAtrZKTJ@mFD8iI;0Wv-ig|2l` zvmka$czOUvD}1SDIsviBo^_=6MRc<_)bX8L0!CJ95`L4rvRTsX=OL2>o^Y_d`ctF5 T5--GBIs|uR8Kk4E17sE*@qK9p