feat: migrate credential storage to platform-specific configuration directories
CI/CD Pipeline / Lint & Check (push) Successful in 10s
CI/CD Pipeline / Publish to PyPI (push) Has been skipped
CI/CD Pipeline / Build & Push Docker Image (push) Successful in 1m18s

This commit is contained in:
2026-05-14 21:29:18 +02:00
parent 6db9e87f96
commit b8bce4ee7f
4 changed files with 66 additions and 9 deletions
+19 -8
View File
@@ -19,7 +19,13 @@ from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import urlparse, parse_qs
from dotenv import load_dotenv
load_dotenv()
from strava_mcp_server.config import get_config_file, ensure_config_dir
# Load config: platform config dir first, then local .env (local overrides)
load_dotenv(
get_config_file()
) # e.g. ~/Library/Application Support/strava-mcp-server/config.env
load_dotenv(override=False) # local .env overrides if present
CLIENT_ID = os.getenv("STRAVA_CLIENT_ID")
CLIENT_SECRET = os.getenv("STRAVA_CLIENT_SECRET")
@@ -127,6 +133,7 @@ class CallbackHandler(BaseHTTPRequestHandler):
client_secret: str = ""
tokens: dict = {}
error: str | None = None
config_path: str = ""
def do_GET(self):
parsed = urlparse(self.path)
@@ -176,7 +183,8 @@ class CallbackHandler(BaseHTTPRequestHandler):
<pre>STRAVA_CLIENT_ID={self.client_id}
STRAVA_CLIENT_SECRET={self.client_secret}
STRAVA_REFRESH_TOKEN={refresh_token}</pre>
<p style="font-size: 13px; color: #666; margin-bottom: 0;">This information has been automatically saved to your .env file.</p>
<p style="font-size: 13px; color: #666; margin-bottom: 0;">Automatically saved to:</p>
<code style="font-size: 12px; color: #fc4c02; word-break: break-all;">{CallbackHandler.config_path}</code>
</div>
<p style="margin-top: 40px; color: #444;">You can now close this window and restart the server.</p>
</body>
@@ -199,10 +207,13 @@ STRAVA_REFRESH_TOKEN={refresh_token}</pre>
def save_to_env(client_id, client_secret, refresh_token=None):
env_path = ".env"
# Always save to the platform config directory so uvx finds it
ensure_config_dir()
config_path = get_config_file()
lines = []
if os.path.exists(env_path):
with open(env_path, "r") as f:
if config_path.exists():
with open(config_path, "r") as f:
lines = f.readlines()
keys_to_set = {
@@ -230,12 +241,11 @@ def save_to_env(client_id, client_secret, refresh_token=None):
if key not in seen_keys:
new_lines.append(f"{key}={value}\n")
with open(env_path, "w") as f:
with open(config_path, "w") as f:
f.writelines(new_lines)
# Debug output
saved_keys = ", ".join(keys_to_set.keys())
print(f"📝 Updated .env with: {saved_keys}")
print(f"📝 Saved to {config_path}: {saved_keys}")
def main():
@@ -275,6 +285,7 @@ def main():
CallbackHandler.client_secret = CLIENT_SECRET
CallbackHandler.tokens = {}
CallbackHandler.error = None
CallbackHandler.config_path = str(get_config_file())
print("\n" + "=" * 60)
print(" Strava OAuth2 Authorization")