6 Commits

Author SHA1 Message Date
matthias fafda14fe9 refactor: improve Docker image pull string construction in Gitea CI workflow using jq arguments
CI/CD Pipeline / Lint & Check (push) Successful in 10s
CI/CD Pipeline / Build & Push Docker Image (push) Successful in 1m21s
2026-05-09 15:04:20 +02:00
matthias 4489e1e0e2 refactor: remove unnecessary package write permissions from CI workflow
CI/CD Pipeline / Lint & Check (push) Successful in 9s
CI/CD Pipeline / Build & Push Docker Image (push) Successful in 1m17s
2026-05-09 14:53:08 +02:00
matthias 3ce6540a8f chore: update CI/CD runner to ubuntu-latest
CI/CD Pipeline / Lint & Check (push) Successful in 1m23s
CI/CD Pipeline / Build & Push Docker Image (push) Successful in 4m35s
2026-05-09 14:03:13 +02:00
matthias cd5faa8332 chore: update Docker registry password to use MY_BUILDTOKEN secret
CI/CD Pipeline / Lint & Check (push) Successful in 55s
CI/CD Pipeline / Build & Push Docker Image (push) Successful in 12m47s
2026-05-09 05:27:19 +02:00
matthias 1da1656f16 chore: update CI/CD workflow to use GITHUB_TOKEN instead of GITEA_TOKEN
CI/CD Pipeline / Lint & Check (push) Successful in 56s
CI/CD Pipeline / Build & Push Docker Image (push) Failing after 15s
2026-05-09 05:22:20 +02:00
matthias 6dd70c29aa feat: enable unauthenticated server startup with runtime OAuth and update CI/CD to append Docker pull instructions to release notes
CI/CD Pipeline / Lint & Check (push) Successful in 54s
CI/CD Pipeline / Build & Push Docker Image (push) Failing after 11s
2026-05-09 05:19:16 +02:00
4 changed files with 47 additions and 5 deletions
+34 -4
View File
@@ -38,10 +38,7 @@ jobs:
name: Build & Push Docker Image
needs: lint
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')
runs-on: gitea-runner-on-dsm
permissions:
packages: write
contents: read
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
@@ -88,3 +85,36 @@ jobs:
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max
- name: Update Gitea Release Notes
if: startsWith(github.ref, 'refs/tags/v')
run: |
TAG_NAME=${GITHUB_REF#refs/tags/}
# Fetch the current release
RELEASE_JSON=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
${{ github.api_url }}/repos/${{ github.repository }}/releases/tags/${TAG_NAME})
# Extract Release ID (if it exists)
RELEASE_ID=$(echo "$RELEASE_JSON" | jq -r '.id // empty')
if [ -n "$RELEASE_ID" ] && [ "$RELEASE_ID" != "null" ]; then
OLD_BODY=$(echo "$RELEASE_JSON" | jq -r '.body // ""')
# Check if Docker Image section already exists
if [[ "$OLD_BODY" != *"## 🐳 Docker Image"* ]]; then
jq -n --arg old "$OLD_BODY" --arg img "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${TAG_NAME}" \
'{body: ($old + "\n\n## 🐳 Docker Image\n```bash\ndocker pull " + $img + "\n```")}' | \
curl -s -X PATCH \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Content-Type: application/json" \
-d @- \
${{ github.api_url }}/repos/${{ github.repository }}/releases/${RELEASE_ID}
echo "Successfully updated Release Notes for $TAG_NAME"
else
echo "Release Notes already contain the Docker pull command."
fi
else
echo "No associated release found for tag $TAG_NAME. Skipping."
fi
+5
View File
@@ -23,3 +23,8 @@
- [x] Callback-Endpoint `/auth/callback` im FastMCP-Server ergänzen
- [x] `STRAVA_REFRESH_TOKEN` automatisch in `.env` zurückschreiben nach Token-Rotation
- [x] Optionaler Hinweis beim Start falls kein Token vorhanden ist
## Bugs
- [x] Server startet nicht ohne Refresh Token. Brauche Möglichkeit das ich Auth über Agentgateway machen kann, damit ich nicht jedes Mal manuell den Auth Prozess anstoßen muss. Siehe Gitea MCP Server.
- [x] Hinweise für Model wie das Datum ausgegeben wird vom MCP Server. Aktuell ist das LLM oft unsicher bzgl. datums formates.
+5 -1
View File
@@ -16,7 +16,6 @@ def validate_credentials() -> None:
required = {
"STRAVA_CLIENT_ID": os.getenv("STRAVA_CLIENT_ID"),
"STRAVA_CLIENT_SECRET": os.getenv("STRAVA_CLIENT_SECRET"),
"STRAVA_REFRESH_TOKEN": os.getenv("STRAVA_REFRESH_TOKEN"),
}
missing = [k for k, v in required.items() if not v]
if missing:
@@ -26,6 +25,10 @@ def validate_credentials() -> None:
print("\nCopy .env.example to .env and fill in your Strava API credentials.")
sys.exit(1)
if not os.getenv("STRAVA_REFRESH_TOKEN"):
print("️ No STRAVA_REFRESH_TOKEN found. Server starting in unauthenticated mode.")
print(" Use the 'get_new_oauth_token' tool via MCP to authenticate.")
def main() -> None:
"""Entry point for the strava-mcp console script."""
@@ -39,6 +42,7 @@ def main() -> None:
mcp = FastMCP(
"Strava MCP Server",
instructions="Dates returned by this server are generally in ISO-8601 (UTC) or formatted as DD.MM.YYYY HH:MM. Always present dates, times, and durations to the user in a natural, human-readable format appropriate for their language.",
host=host,
port=port,
streamable_http_path="/mcp",
+3
View File
@@ -36,6 +36,9 @@ class StravaClient:
async def get_valid_token(self) -> str:
"""Returns a valid access token, refreshing it if necessary."""
if not self.refresh_token:
raise ValueError("No Strava refresh token found. Please run the 'get_new_oauth_token' MCP tool to authenticate first.")
if not self.access_token or time.time() > self.expires_at - 60:
await self._refresh_access_token()
return self.access_token