github Python analyzed da31349 unconfirmed MCP

natejswenson/local-fitness

github

A personal running coach that turns your Garmin data into daily briefings, graded workout report cards, and an adaptive training plan — driven entirely through MCP.

maintainer
natejswenson
license
MIT
first seen
2026-08-03
last seen
2026-08-11
releases · 30d
10
short id

Drift inferred · capture-to-capture

No drift recorded — single capability capture; advisories appear once its surface changes.

capabilities 0 tools
transport stdio · streamable-http · http counts 0 tools · 0 res · 0 prompts permission surface via code analysis

No tools enumerated yet for this server.

skills & danger signals github-tarball
prompt-surface shipped agent-instruction files + hidden-content / dangerous-code findings — quoted from the analyzed source

analyzed commit da31349 · analyzer v33 · 7h ago

skills & prompt files 1

danger signals1

code evidence vv0.60.2 · github-tarball
evidence-backed findings quoted directly from the published source artifact — not inferred

code files: 124

filesystem 44

  • fs (weak) natejswenson-local-fitness-da31349/scripts/ab_brief.py :171 with open(args.mock) as fh:
  • fs (weak) natejswenson-local-fitness-da31349/scripts/calibrate_report_card.py :67 from pathlib import Path
  • fs (weak) natejswenson-local-fitness-da31349/scripts/capture_baseline.py :46 from pathlib import Path
  • fs (weak) natejswenson-local-fitness-da31349/scripts/eval_fixtures.py :28 from pathlib import Path
  • fs (weak) natejswenson-local-fitness-da31349/scripts/perf_fixture.py :31 from pathlib import Path
  • fs (weak) natejswenson-local-fitness-da31349/scripts/score_profiles.py :26 from pathlib import Path
  • fs (weak) natejswenson-local-fitness-da31349/scripts/score_prompt.py :27 from pathlib import Path
  • fs (weak) natejswenson-local-fitness-da31349/scripts/shadow_run.py :42 from pathlib import Path
  • fs (weak) natejswenson-local-fitness-da31349/scripts/warm_report_cards.py :52 from pathlib import Path
  • fs natejswenson-local-fitness-da31349/src/local_fitness/agent/branding.py :27 from pathlib import Path
  • fs natejswenson-local-fitness-da31349/src/local_fitness/agent/brief_planner.py :22 from pathlib import Path
  • fs natejswenson-local-fitness-da31349/src/local_fitness/agent/briefing.py :19 from pathlib import Path
  • fs natejswenson-local-fitness-da31349/src/local_fitness/agent/briefs.py :22 from pathlib import Path
  • fs natejswenson-local-fitness-da31349/src/local_fitness/agent/calendar_sync.py :24 from pathlib import Path
  • fs natejswenson-local-fitness-da31349/src/local_fitness/agent/card_store.py :49 from pathlib import Path
  • fs natejswenson-local-fitness-da31349/src/local_fitness/agent/coach.py :24 from pathlib import Path
  • fs natejswenson-local-fitness-da31349/src/local_fitness/agent/journal.py :26 from pathlib import Path
  • fs natejswenson-local-fitness-da31349/src/local_fitness/agent/ledger.py :30 from pathlib import Path
  • fs natejswenson-local-fitness-da31349/src/local_fitness/agent/memory.py :19 from pathlib import Path
  • fs natejswenson-local-fitness-da31349/src/local_fitness/agent/plan_coach.py :31 from pathlib import Path
  • fs natejswenson-local-fitness-da31349/src/local_fitness/agent/tools.py :18 import shutil
  • fs natejswenson-local-fitness-da31349/src/local_fitness/agent/visuals.py :30 from pathlib import Path
  • fs natejswenson-local-fitness-da31349/src/local_fitness/agent/workout_coach.py :33 from pathlib import Path
  • fs natejswenson-local-fitness-da31349/src/local_fitness/cli.py :22 from pathlib import Path
  • fs natejswenson-local-fitness-da31349/src/local_fitness/db.py :17 from pathlib import Path
  • fs natejswenson-local-fitness-da31349/src/local_fitness/ingest/backfill.py :40 from pathlib import Path
  • fs natejswenson-local-fitness-da31349/src/local_fitness/ingest/daily.py :15 from pathlib import Path
  • fs natejswenson-local-fitness-da31349/src/local_fitness/notes.py :27 from pathlib import Path
  • fs natejswenson-local-fitness-da31349/src/local_fitness/plans.py :16 from pathlib import Path
  • fs (weak) natejswenson-local-fitness-da31349/tests/conftest.py :16 from pathlib import Path
  • fs (weak) natejswenson-local-fitness-da31349/tests/evals/report_cards.py :46 from pathlib import Path
  • fs (weak) natejswenson-local-fitness-da31349/tests/test_brief_planner.py :15 from pathlib import Path
  • fs (weak) natejswenson-local-fitness-da31349/tests/test_calibrate_report_card.py :23 from pathlib import Path
  • fs (weak) natejswenson-local-fitness-da31349/tests/test_cli.py :16 from pathlib import Path
  • fs (weak) natejswenson-local-fitness-da31349/tests/test_cli_brief_email.py :20 from pathlib import Path
  • fs (weak) natejswenson-local-fitness-da31349/tests/test_coach.py :6 from pathlib import Path
  • fs (weak) natejswenson-local-fitness-da31349/tests/test_docs_drift.py :22 from pathlib import Path
  • fs (weak) natejswenson-local-fitness-da31349/tests/test_interpret.py :292 import pathlib
  • fs (weak) natejswenson-local-fitness-da31349/tests/test_mcp_server.py :14 from pathlib import Path
  • fs (weak) natejswenson-local-fitness-da31349/tests/test_prompts.py :5 import pathlib
  • fs (weak) natejswenson-local-fitness-da31349/tests/test_report_card.py :2988 import pathlib
  • fs (weak) natejswenson-local-fitness-da31349/tests/test_smoke.py :5 from pathlib import Path
  • fs (weak) natejswenson-local-fitness-da31349/tests/test_tools.py :14 import shutil
  • fs (weak) natejswenson-local-fitness-da31349/tests/test_visuals.py :43 with pdfplumber.open(io.BytesIO(pdf_bytes)) as doc:

shell / exec 6

  • shell natejswenson-local-fitness-da31349/src/local_fitness/agent/opencode_model.py :17 import subprocess
  • shell natejswenson-local-fitness-da31349/src/local_fitness/agent/tools.py :20 import subprocess
  • shell natejswenson-local-fitness-da31349/src/local_fitness/cli.py :19 import subprocess
  • shell (weak) natejswenson-local-fitness-da31349/tests/test_opencode_model.py :16 import subprocess
  • shell (weak) natejswenson-local-fitness-da31349/tests/test_report_card.py :2557 import subprocess
  • shell (weak) natejswenson-local-fitness-da31349/tests/test_tools.py :16 import subprocess

network 6

  • net natejswenson-local-fitness-da31349/src/local_fitness/agent/gcal.py :33 from urllib.parse import quote
  • net natejswenson-local-fitness-da31349/src/local_fitness/agent/local_model.py :10 (``urllib.request``) since neither ``httpx`` nor ``ollama`` is currently a
  • net natejswenson-local-fitness-da31349/src/local_fitness/cli.py :452 import urllib.parse
  • net (weak) natejswenson-local-fitness-da31349/tests/test_gcal.py :317 assert source.count("import requests") == 1
  • net (weak) natejswenson-local-fitness-da31349/tests/test_local_model.py :3 No real network calls: urllib.request.urlopen is mocked. Focus is the
  • net (weak) natejswenson-local-fitness-da31349/tests/test_security.py :12 import httpx

secrets 4

  • secrets natejswenson-local-fitness-da31349/src/local_fitness/cli.py :502 client_secret = os.environ.get("LOCAL_FITNESS_GCAL_CLIENT_SECRET", "").strip()
  • secrets natejswenson-local-fitness-da31349/src/local_fitness/ingest/auth.py :13 import getpass
  • secrets natejswenson-local-fitness-da31349/src/local_fitness/web/server.py :39 API_TOKEN = os.environ.get("LOCAL_FITNESS_API_TOKEN") or None
  • secrets (weak) natejswenson-local-fitness-da31349/tests/test_auth.py :13 import keyring

database 24

  • db (weak) natejswenson-local-fitness-da31349/scripts/calibrate_report_card.py :63 import sqlite3
  • db natejswenson-local-fitness-da31349/src/local_fitness/agent/card_store.py :47 import sqlite3
  • db natejswenson-local-fitness-da31349/src/local_fitness/agent/coach.py :21 import sqlite3
  • db natejswenson-local-fitness-da31349/src/local_fitness/agent/journal.py :24 import sqlite3
  • db natejswenson-local-fitness-da31349/src/local_fitness/agent/ledger.py :28 import sqlite3
  • db natejswenson-local-fitness-da31349/src/local_fitness/agent/memory.py :18 import sqlite3
  • db natejswenson-local-fitness-da31349/src/local_fitness/agent/report_card.py :103 import sqlite3
  • db natejswenson-local-fitness-da31349/src/local_fitness/agent/tools.py :19 import sqlite3
  • db natejswenson-local-fitness-da31349/src/local_fitness/config.py :17 import sqlite3
  • db natejswenson-local-fitness-da31349/src/local_fitness/db.py :12 import sqlite3
  • db natejswenson-local-fitness-da31349/src/local_fitness/ingest/details.py :23 import sqlite3
  • db natejswenson-local-fitness-da31349/src/local_fitness/plans.py :13 import sqlite3
  • db natejswenson-local-fitness-da31349/src/local_fitness/web/mcp_server.py :19 import sqlite3
  • db (weak) natejswenson-local-fitness-da31349/tests/test_calibrate_report_card.py :21 import sqlite3
  • db (weak) natejswenson-local-fitness-da31349/tests/test_db.py :194 import sqlite3
  • db (weak) natejswenson-local-fitness-da31349/tests/test_hr_trace.py :10 import sqlite3
  • db (weak) natejswenson-local-fitness-da31349/tests/test_interpret.py :295 for banned in ("import sqlite3", "from .. import", "from . import",
  • db (weak) natejswenson-local-fitness-da31349/tests/test_journal.py :4 import sqlite3
  • db (weak) natejswenson-local-fitness-da31349/tests/test_plan_tools.py :875 import sqlite3
  • db (weak) natejswenson-local-fitness-da31349/tests/test_plans.py :517 import sqlite3
  • db (weak) natejswenson-local-fitness-da31349/tests/test_plans_db.py :150 import sqlite3
  • db (weak) natejswenson-local-fitness-da31349/tests/test_security.py :10 import sqlite3
  • db (weak) natejswenson-local-fitness-da31349/tests/test_smoke.py :4 import sqlite3
  • db (weak) natejswenson-local-fitness-da31349/tests/test_tools.py :15 import sqlite3

declared dependencies 13

  • claude-agent-sdk@>=0.1.68
  • click@>=8.3.3
  • fastapi@>=0.136.1
  • fitparse@>=1.2.0
  • garminconnect@>=0.3.5
  • keyring@>=25.7.0
  • markdown@>=3.10.2
  • matplotlib@>=3.11.0
  • python-dotenv@>=1.0.1
  • requests@>=2.32.0
  • rich@>=15.0.0
  • uvicorn@>=0.46.0
  • weasyprint@>=69.0

transport_posture 1

  • binds all interfaces (0.0.0.0) natejswenson-local-fitness-da31349/tests/test_security.py :268 srv.serve(host="0.0.0.0", port=18999)