Messwerte senden
Über diese Schnittstelle kommen Körperwerte von jeder Waage, App oder Automation zu training mcp. Woher sie stammen, spielt keine Rolle, das Format schon. Dein Sprachmodell liest die Werte anschließend über das Werkzeug body-metrics.
POST https://api.training-mcp.app/api/ingest/v1/bodyToken anlegen
Du brauchst ein eigenes Schnittstellen-Token. Es darf nur Messwerte an /api/ingest schicken. Lesen kann es nichts, und andere Routen erreicht es nicht. Ein MCP-Token oder das Token der App funktioniert hier nicht.
- Öffne im Kontobereich „Verbindungen“.
- Klicke bei „Eigene Messwerte“ auf „Schnittstellen-Token erzeugen“ und gib ihm einen Namen, etwa den der Waage oder der Automation.
- Kopier das Token. Es steht nur einmal im Klartext da. Verlierst du es, widerrufst du es und legst ein neues an.
Ein Token je Gerät oder Automation hat einen Vorteil: Fällt eines in falsche Hände, widerrufst du nur dieses.
Anfrage
Ein POST mit JSON im Körper. Das Token steht im Header Authorization, mit „Bearer “ davor. Ein Aufruf darf bis zu 100 Messungen enthalten.
Authorization: Bearer DEIN_TOKEN
Content-Type: application/json
Accept: application/json{
"measurements": [
{
"measured_at": "2026-10-05T07:12:00+02:00",
"device": "Tanita RD-545",
"context": "morning_fasted",
"weight_kg": 96.05,
"body_fat_pct": 30.1,
"muscle_mass_kg": 63.4,
"body_water_pct": 50.2,
"bone_mass_kg": 3.3,
"visceral_fat": 14,
"bmr_kcal": 2034,
"metabolic_age": 52,
"segments": {
"trunk": { "fat_pct": 34.6, "muscle_mass_kg": 33.1 },
"left_leg": { "fat_pct": 24.0, "muscle_mass_kg": 10.9 }
}
}
]
}Felder einer Messung
Pflicht ist nur measured_at, dazu mindestens ein Wert. Die Einheit steht im Feldnamen. Unbekannte Felder lehnt der Server ab, statt sie still zu übergehen. So fällt ein Tippfehler sofort auf und nicht erst nach Wochen.
| Feld | Typ | Bereich | Bedeutung |
|---|---|---|---|
| measured_at | string | ISO 8601 | Zeitpunkt der Messung, ISO 8601 mit Zeitzone, etwa 2026-10-05T07:12:00+02:00. Ohne Zeitzone wird die Messung abgelehnt. |
| device | string | ≤ 120 | Waage oder App als Freitext, höchstens 120 Zeichen. Steht später neben dem Wert. |
| context | string | morning_fasted, morning_other, midday, evening, post_exercise, unknown | Bedingung der Messung. Vergleichbar sind nur Messungen unter gleicher Bedingung; den Trend tragen die nüchternen Morgenmessungen (morning_fasted). Ohne Angabe bleibt die Bedingung offen. |
| external_id | string | ≤ 120 | Deine eigene Kennung der Messung, höchstens 120 Zeichen. Dieselbe Kennung ein zweites Mal schreibt dieselbe Messung fort. |
| weight_kg | number | 20 – 400 | Körpergewicht in Kilogramm. |
| body_fat_pct | number | 1 – 75 | Körperfett in Prozent des Gewichts. |
| muscle_mass_kg | number | 5 – 200 | Muskelmasse in Kilogramm. |
| body_water_pct | number | 20 – 85 | Körperwasser in Prozent des Gewichts. |
| bone_mass_kg | number | 0,5 – 10 | Knochenmasse in Kilogramm. |
| visceral_fat | number | 1 – 59 | Viszerales Fett als Kennzahl der Waage, ohne Einheit. |
| bmr_kcal | integer | 500 – 5000 | Grundumsatz in Kilokalorien je Tag, ganze Zahl. |
| metabolic_age | integer | 10 – 120 | Stoffwechselalter in Jahren, ganze Zahl. |
| bmi | number | 10 – 80 | Body-Mass-Index, wie ihn die Waage ausgibt. |
| segments | object | Werte je Körperteil, siehe unten. |
Segmente
Waagen mit Segmentmessung liefern Werte je Körperteil. Erlaubt sind trunk, left_arm, right_arm, left_leg und right_leg, jeweils mit fat_pct (1 bis 75) und muscle_mass_kg (0,1 bis 80). Fehlt ein Teil, bleibt er leer.
Antwort
Der Server prüft jede Messung für sich. Eine fehlerhafte kippt nicht die ganze Lieferung: Du bekommst je Messung einen Status in der Reihenfolge, in der du sie geschickt hast, dazu eine Zusammenfassung.
- received
- neu angenommen
- updated
- dieselbe Messung mit geänderten Werten, fortgeschrieben
- known
- genau so schon vorhanden, nichts geändert
- rejected
- abgelehnt, der Grund steht in reason
{
"results": [
{ "index": 0, "status": "received", "measured_at": "2026-10-05T05:12:00Z" },
{ "index": 1, "status": "rejected", "reason": "weight_kg is 960, outside 20 to 400." }
],
"summary": { "received": 1, "rejected": 1 }
}HTTP-Status
- 200
- Die Lieferung wurde verarbeitet. Ob einzelne Messungen abgelehnt wurden, steht in results.
- 401
- Kein oder ein widerrufenes Token.
- 403
- Das Token gilt für diese Route nicht, oder die Einwilligung zur Verarbeitung von Gesundheitsdaten ist widerrufen (code consent_revoked).
- 422
- measurements fehlt, ist leer oder hat mehr als 100 Einträge.
- 429
- Mehr als 120 Aufrufe in der Minute. Warte die Zeit aus Retry-After ab.
Regeln
- Wiederholbar: Dieselbe Messung zweimal ergibt einen Datensatz. Erkannt wird sie an external_id, ohne Kennung an Zeitpunkt und Gerät. Schick ruhig nach jedem Lauf deiner Automation den ganzen Tag noch einmal.
- Fortschreiben ergänzt: Eine geänderte Messung überschreibt die geschickten Werte. Werte, die du diesmal weglässt, bleiben stehen.
- Zeitpunkt mit Zone: measured_at braucht eine Zeitzone. Messungen mehr als zehn Minuten in der Zukunft lehnt der Server ab, das ist fast immer eine falsch gestellte Uhr.
- Grenzen: höchstens 100 Messungen je Aufruf und 120 Aufrufe in der Minute. Zahlen werden auf zwei Nachkommastellen gerundet.
- Nur schreiben: Über die Schnittstelle kommt nichts zurück. Gelesen werden die Werte über MCP (body-metrics) mit Quelle „ingest“ und dem Gerät aus device.
Beispiele
curl -X POST https://api.training-mcp.app/api/ingest/v1/body \
-H "Authorization: Bearer DEIN_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"measurements":[{"measured_at":"2026-10-05T07:12:00+02:00","device":"Tanita RD-545","weight_kg":96.05,"body_fat_pct":30.1}]}'Kurzbefehl auf dem iPhone
Für eine Waage, deren App nur einen Text zum Teilen anbietet, oder für Werte, die du von Hand eingibst:
- Neuer Kurzbefehl, bei Bedarf „Im Teilen-Menü anzeigen“ einschalten, Eingabe: Text.
- Mit „Text abgleichen“ die Zahlen herausziehen, etwa mit dem Muster Gewicht: ([0-9,]+) für das Gewicht. Das Komma mit „Text ersetzen“ gegen einen Punkt tauschen.
- „Wörterbuch“ mit den Feldern measured_at (Aktuelles Datum im Format ISO 8601), device und weight_kg anlegen, als Zahl, nicht als Text. Ein zweites Wörterbuch mit dem Schlüssel measurements und einer Liste aus dem ersten.
- „Inhalte von URL abrufen“: die Adresse oben, Methode POST, Header Authorization mit „Bearer “ und deinem Token, Header Accept application/json, Anfragetext JSON mit dem Wörterbuch.
- Zum Prüfen die Antwort mit „Ergebnis anzeigen“ ausgeben. Steht dort received oder known, ist die Messung da.
Home Assistant
Mit einem rest_command, ausgelöst durch eine Automation, sobald der Sensor der Waage einen neuen Wert meldet. Das Token gehört mit „Bearer “ davor in secrets.yaml.
# configuration.yaml
rest_command:
training_mcp_body:
url: https://api.training-mcp.app/api/ingest/v1/body
method: POST
headers:
Authorization: !secret training_mcp_token # "Bearer DEIN_TOKEN"
Accept: application/json
content_type: application/json
payload: >
{"measurements":[{
"measured_at": "{{ now().isoformat() }}",
"device": "Withings Body+",
"weight_kg": {{ states('sensor.waage_gewicht') | float }},
"body_fat_pct": {{ states('sensor.waage_fett') | float }}
}]}
# automations.yaml
- alias: Waage an training mcp
trigger:
- platform: state
entity_id: sensor.waage_gewicht
action:
- service: rest_command.training_mcp_bodyPython
import requests
r = requests.post(
"https://api.training-mcp.app/api/ingest/v1/body",
headers={"Authorization": "Bearer DEIN_TOKEN", "Accept": "application/json"},
json={"measurements": [{
"measured_at": "2026-10-05T07:12:00+02:00",
"device": "Tanita RD-545",
"weight_kg": 96.05,
"body_fat_pct": 30.1,
}]},
timeout=10,
)
r.raise_for_status()
print(r.json()["summary"])Maschinenlesbar
Die Schnittstelle beschreibt sich selbst als OpenAPI 3.1. Wer eine Anbindung bauen lässt, auch von einem Sprachmodell, gibt am besten diese Datei mit.
https://api.training-mcp.app/api/ingest/v1/openapi.jsonDatenschutz
Körperwerte sind Gesundheitsdaten. Sie liegen auf Servern in Deutschland und gehen nur an das Sprachmodell, das du selbst verbindest. Widerrufst du die Einwilligung zur Verarbeitung von Gesundheitsdaten, nimmt die Schnittstelle nichts mehr an. Löschst du dein Konto, sind auch diese Werte weg.
Datenschutzerklärung