Fitatu について
Fitatu は、Fitatu アカウントの食事日記や健康データを読み書きする非公式の Python クライアントおよび MCP サーバーです。スクリプトや AI エージェント向けに、構造化ツールと CLI を提供します。
主な機能
- 01食事日記の読み取りと編集
- 02活動、身体測定、水分の記録
- 03食品、レシピ、活動の検索
- 04概要、目標、習慣の読み取り
- 05セッションやツール、エクスポートの CLI 操作
活用シーン
- 01AI エージェント経由で食事を記録
- 02体重、水分、運動の記録を確認
- 03日付範囲を指定して日記を集計
MCP 対応
`fitatu-mcp` はエージェントツールを標準入出力または HTTP 経由で MCP ホストに公開します。読み取り専用モードとデモモードにも対応します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
47掲載時のツール一覧 · 2 週間前に更新
このツールにパラメーターはありません。
詳細
fitatu-api
カロリー計算アプリFitatuの API を利用する、非公式の Python クライアントです。AI エージェントやスクリプトから操作できるように作られています。食事日記、アクティビティ、身体測定値、水分の読み取りと記録、目標の読み取りと設定、サマリーや食品カタログの参照ができます。
FitatuToolsを使うと、日記を言語モデルが呼び出せるツールに変換できます。セッション管理はpython-garminconnectに倣っています。一度ログインし、セッションファイルを1つ保持すれば、クライアントがセッションを更新します。
非公式です。 このプロジェクトは Fitatu Sp. z o.o. と提携しておらず、同社から承認も受けていません。API は Fitatu アプリをリバースエンジニアリングして調査したもので、予告なく変更される場合があります。自動アクセスは Fitatu の利用規約に違反する可能性があります。規約を確認のうえ、ご自身のアカウントで、ご自身の責任においてのみこのライブラリを使用してください。MIT ライセンスの対象はこのコードであり、Fitatu のサービス、API、データは対象外です。
インストール
Python 3.11 以降が必要です。依存関係は requests のみです(Windows では tzdata も必要です)。
pip install fitatu-api # the library and the fitatu-api command
pip install "fitatu-api[mcp]" # plus fitatu-mcp, the MCP server
pip install "git+https://github.com/Jezue/fitatu_library" # unreleased changes from main
ライブラリの開発やオフラインでのテスト実行には、代わりにリポジトリをクローンしてください:git clone https://github.com/Jezue/fitatu_library && cd fitatu_library && pip install -e ".[dev]"。
クイックスタート
fitatu-api login # asks for e-mail and password, writes ~/.fitatu/session.json
Apple または Facebook で登録しましたか?その場合、アカウントにパスワードはありません。認証とセッションファイルの説明に従って、代わりに fitatu-api import-session でウェブアプリからセッションをコピーしてください。
from datetime import date
from fitatu_api import FitatuApiClient
with FitatuApiClient.from_session() as client: # closes the HTTP connections at the end
user_id = client.auth.fitatu_user_id
today = date.today()
day = client.planner.get_day(user_id, today)
for meal_key, meal in day["dietPlan"].items():
for row in meal["items"]:
print(meal_key, row["name"], row["energy"], row["planDayDietItemId"])
egg = client.search_food("jajko kurze", limit=1)[0] # search rows carry the id as foodId
added = client.planner.add_product_to_day_meal(
user_id, today, meal_type="breakfast", product_id=egg["foodId"],
measure_id=egg["measure"]["measureId"], measure_quantity=2, # 2 of the hit's measure
)
print("added row", added["row_id"])
記録、行 ID、削除の仕組みについては、docs/PLANNER.mdをご覧ください。
ケータリング食のメニューを日記にコピーするには(繰り返し実行しても安全です)、リポジトリの catering_sync.py を使用してください:ケータリングメニューのインポート。
AI エージェント向け
FitatuTools は、47 個のツール(今日の記録の読み取り、食品の検索、食品の記録、体重、水分、ワークアウト、非公開レシピや商品など)を、JSON Schema 入力と読み取り専用/破壊的/冪等の注釈付きで提供します。
call() は例外を送出せず、{"ok": true, "data": ...} または {"ok": false, "error": {"error_type", "message", "retryable", "hint", ...}} を返すため、モデルは何が問題だったかを確認できます。
SYSTEM_PROMPT は推奨されるシステムプロンプトです。ツールの説明に加えてモデルが必要とするルール(書き込む前に読み取る、ユーザー独自の食事名を使う、data.ok、確認)を記載しています。モデルは get_today を使って、アカウントのタイムゾーンでの日付を取得します。
import json
import anthropic
from fitatu_api import FitatuTools
from fitatu_api.agent import READ_ONLY_TOOLS, SYSTEM_PROMPT, anthropic_tools # openai_tools() for OpenAI
client = anthropic.Anthropic()
messages = [{"role": "user", "content": "How many kcal did I eat today?"}]
# Only the read tools, as this loop runs tool calls without asking the user: call() refuses
# any other tool, which the model can still name.
with FitatuTools.from_session(tools=READ_ONLY_TOOLS) as tools:
while True:
response = client.messages.create(
model="claude-opus-5-5",
max_tokens=16000,
system=SYSTEM_PROMPT,
tools=anthropic_tools(READ_ONLY_TOOLS),
messages=messages,
)
messages.append({"role": "assistant", "content": response.content})
if response.stop_reason != "tool_use":
break
results = [
{
"type": "tool_result",
"tool_use_id": block.id,
"content": json.dumps(tools.call(block.name, block.input)),
}
for block in response.content
if block.type == "tool_use"
]
messages.append({"role": "user", "content": results})
if response.stop_reason != "end_turn": # max_tokens or refusal: the answer is cut or missing
raise RuntimeError(f"the model stopped early: {response.stop_reason}")
print("".join(block.text for block in response.content if block.type == "text"))
書き込みツール(食品の記録、行の更新・移動・コピー・削除、体重、水分、ワークアウト、非公開レシピや商品)には、破壊的な呼び出しの前にユーザーへ確認するループが必要です。その実装はdocs/AGENTS.mdにあります。ツール一覧、公開してはならない呼び出し(セッショントークン、カタログへの書き込み)、書き込みを安全に繰り返す方法、error_type ごとの対処、OpenAI 向けのバリエーション、長時間実行ホスト、オフラインのテストバックエンドを使ってアカウントなしでツールを試す方法も記載されています。
MCP
fitatu-mcp は、SYSTEM_PROMPT を指示として、3 つのポーランド語のスラッシュコマンド
(podsumowanie_dnia、przeglad_tygodnia、zaloguj_posilek)とともに、stdio 経由で Claude Code、Claude Desktop およびほかの MCP ホストに同じツールを提供します。
pipx install "fitatu-api[mcp]"
fitatu-api login
claude mcp add fitatu --scope user -- fitatu-mcp # fitatu-mcp --read-only: the read tools only
fitatu-mcp --http は、トークンを使って HTTP 経由で同じツールを提供します。n8n、別のコンピューター、または Docker で利用できます(リポジトリには Dockerfile があります)。
docs/AGENTS.md。
アカウントがなくても、fitatu-mcp --demo(または FitatuTools.demo())を使えば、メモリー上に保持される小規模な架空の日記を利用できます。Claude Desktop 向けには、各 GitHub リリース
に fitatu-<version>.mcpb があり、ダブルクリックでインストールできます(先に fitatu-api login でログインしてください)。何もインストールせずに、uvx --from "fitatu-api[mcp]" fitatu-mcp を実行してサーバーを起動できます。MCP レジストリ(MCP Registry)には
io.github.Jezue/fitatu-api(server.json)として登録されています。Agent Skills を読み込む Hermes Agent などのホストでは、skills/fitatu-diary/SKILL.md
を参照すると、エージェントによるサーバーの設定方法とツールの効果的な使い方がわかります。
ホストの権限確認プロンプトが確認手順となるため、破壊的なツールについては有効にしておいてください。 Claude Desktop、uvx、およびサーバーの動作については、こちらを参照してください。 docs/AGENTS.md。
対応範囲
| 領域 | クライアント(FitatuApiClient) | エージェントのツール |
|---|---|---|
| 食事記録 | client.planner:1日分の読み取り、食品、レシピ、カスタム行、検索結果の追加、更新、移動、コピー、削除、その日のメモ | get_day、add_food、add_foods、add_custom_item、update_item、move_item、copy_meal、preview_removal、remove_items、set_note |
| アクティビティ | planner.add_activity / remove_activity、client.activities(カタログ、検索、最近使った項目) | search_activity、add_activity、remove_activity |
| 食品 | search_food、get_product_details、get_recipe、レシピカタログとその検索、client.foods(お気に入り、最近使った項目) | search_food、search_recipes、get_recipe、find_by_barcode、get_food_measures、get_recent_foods、get_favorite_foods、set_favorite |
| ユーザー独自の食品 | search_user_food、create_product、update_product、delete_product、create_recipe、update_recipe、delete_recipe | get_my_foods、create_food、update_food、delete_food、およびユーザー自身の非公開食品のみを対象とするレシピツール |
| 計測値 | client.measurements:日ごとの体重と身体サイズ、履歴、グラフ | get_weight_history、get_body_measurements、get_measurement_history、log_weight、log_measurements |
| 水分 | client.water | get_water、set_water |
| サマリーとエクスポート | client.summary:期間の合計、日ごとの栄養素、上位の食品、食事記録のエクスポート | get_range_summary、get_progress、get_top_foods、get_report、get_shopping_list(予定されている行から算出) |
| 断食と習慣 | client.fasting(プラン、日ごとの食事時間帯)、client.habits(カタログ、ユーザーの習慣、調子のよい日);読み取り専用 | get_fasting、get_habits、get_good_days |
| 目標と設定 | client.user_settings:目標、BMR/TMR、プロフィール | get_targets、set_targets(手動または自動の目標、マクロ栄養素の配分、グラスのサイズ)、get_profile(身長、体重、目標、BMI、Premium;ユーザーを特定する情報は含まれません) |
| カタログへの書き込み | create_recipe(shared=True)、set_product_proposal、重複項目の整理 | なし。意図的に設けていません |
これらの大半を *_via_api メソッドでラップし、例外を送出する代わりに {"status": ...} を返す FitatuLibrary は非推奨であり、1.0 で削除されます。例外を送出しない結果が必要な場合は FitatuTools({"ok": true, "data": ...})を、それ以外の場合はクライアントを使用してください。安定性を含むすべての公開呼び出しについては、docs/API_REFERENCE.md に記載しています。
無料アカウントとPremiumアカウント
| 無料アカウント | Premium | |
|---|---|---|
| 日記:食品、メモ、アクティビティ、水分、体重、身体測定値の読み取り、記録、更新、移動、コピー、削除 | ✅ | ✅ |
検索、バーコード、食品の計量単位、単語と max_energy_kcal によるレシピ検索、レシピの全情報、プライベートレシピと商品、お気に入り、最近使った食品 | ✅ | ✅ |
レシピ検索フィルター(min_protein_g、max_carbohydrate_g、max_cooking_time、diets、meal)とPremiumカタログのレシピ(get_recipe、get_food_measures、add_food、add_foods。買い物リストには材料が含まれません) | ❌「Fitatu Premiumが必要です」:ツールはアプリに準じます | ✅ |
目標:読み取りと設定(get_targets、set_targets)、進捗(get_progress)、レポート(get_report)、期間合計(get_range_summary) | ✅(進捗:1日につき1リクエスト、最大31日) | ✅ |
| 体重と身体測定値の履歴、プロフィール、断食と習慣(読み取り)、買い物リスト | ✅ | ✅ |
よく食べる食品(get_top_foods、summary.get_top_products()) | ❌ 403:Fitatu Premiumが必要です | ✅ |
日記のエクスポート(fitatu-api export、summary.export_diary()) | ❌ 403:「Fitatu Premiumが必要です」 | ✅ |
タンパク質/脂質/炭水化物の日別データ(summary.get_nutrient_by_day()。エネルギーはどちらのアカウントでも取得可能) | ❌ 403(get_progress はこの制限を回避して読み取ります) | ✅ |
Fitatu Premiumに加入していないアカウントでも、ほとんどの機能が使えます。Fitatuでは、Premiumに加入していない場合、次の操作に対して403を返します (2026-10-15に実環境で確認):
- タンパク質、脂質、炭水化物の
summary.get_nutrient_by_day()(エネルギーはどのアカウントでも取得可能); summary.get_top_products()と、それに対応するget_top_foodsツール;summary.export_diary()と、それに対応するfitatu-api export。その場合、必要なプランがないことを1行で知らせます。
Fitatuはレシピ検索フィルターとPremiumカタログのレシピをすべてのアカウントに提供していますが、アプリではPremium限定になっており、ツールも同様です。ツールはアカウントの accessControl フラグを確認し、フラグがない場合は forbidden エラーを返します。クライアント自体は確認しません。
get_progress と get_report はどのアカウントでも使えます。マクロ栄養素の日別データを取得するルートが拒否された場合は、各日の個別のサマリーを読み取ります(1日につき1リクエスト、最大31日)。また、get_report では top_foods がnullになり、top_foods_note が含まれます。無料アカウントのマクロ目標は範囲(target_min が target_max より小さい値)ですが、Premiumアカウントでは1日分のサマリーで両方が同じ値になりました(日別データを取得するルートを使った get_progress の結果も一致。実環境で確認済み)。手動での目標と、独自のマクロ栄養素の配分にも対応しています(set_targets、2026-10-15に実環境で確認)。配分を設定すると、マクロ目標は単一の数値になります。fitatu-api doctor で、アカウントにPremiumプランがあるか確認できます。ツールについては、docs/AGENTS.md の無料アカウントとPremiumアカウントを参照してください。
コマンドライン
fitatu-api(または python -m fitatu_api)は、セッションファイル、$FITATU_SESSION、または
~/.fitatu/session.json を使用します。
fitatu-api login # or import-session, see Authentication & session file below
fitatu-api status # the session: file, user id, host, token expiry; sends nothing
fitatu-api doctor # checks the session, the clock and the client version with Fitatu
fitatu-api logout # deletes the session file after asking (--yes: without asking)
fitatu-api tools # the agent tools: name, read / write / destructive, what it does
fitatu-api tools --json # the same tools in the Anthropic API format, anthropic_tools()
fitatu-api call get_day '{"date": "2026-10-14"}'
fitatu-api export --from 2026-10-01 --to 2026-10-14 --format csv -o diary.csv # needs Fitatu Premium
status は、セッションの取得元(ファイルとその権限、または
$FITATU_SESSION_JSON)、ユーザー ID、API ホスト、ロケール、Bearer トークンの有効期限、更新トークンの有無を、何も送信せずに表示します。--check を指定すると、さらにプロフィールを一度読み込みます。doctor は Fitatu を使って設定を確認し、各項目について ok/WARN/FAIL のいずれかの行を表示します。確認項目は、セッションファイルの権限、更新トークン(通常の更新処理と同様に、Bearer トークンを一度更新して保存します)、このコンピューターの時計と新しいトークンの発行時刻とのずれ、プロフィールの読み込み、プレミアムプランが有効かどうか(有効期限や価格は確認しません)、Fitatu のウェブアプリがライブラリから送信されるバージョンのままかどうか(GET /upgrade-application/WEB/<version>)です。確認に失敗した項目がある場合は終了コード 1 で終了します。また、出力にトークン、ユーザー ID、ホームディレクトリは含まれないため、バグ報告にそのまま使用できます。logout はセッションファイルを削除します。fitatu-mcp やそのファイルを使用するほかのプロセスは、更新したトークンをファイルに書き戻すため、先に停止してください。ライブラリが把握している範囲では、Fitatu にトークンを失効させる呼び出しはありません。これらのコマンドはいずれもトークンを表示しません。fitatu-api --version はバージョンを表示します。
call は FitatuTools.call() を通じて 1 つのツールを実行し、その結果のエンベロープを JSON で表示します。ok が true の場合は終了コード 0、false の場合は 1 で終了します。--allow-writes を指定しない限り、読み取りツール(READ_ONLY_TOOLS)のみが実行されます。export は Fitatu の日記エクスポート(csv、xls、pdf、txt)を、新規ファイルとしてあなたのみが読み取り可能な権限(0600)で保存します。--overwrite を指定しない限り既存ファイルは置き換えません。また、記録が何もない期間を指定した場合はファイルを作成せず、終了コード 1 で終了します。fitatu-api COMMAND --help で各コマンドの説明を確認できます。ログは stderr に出力され、設定が変更されない限り WARNING 以上が対象です。変更するには fitatu-api --log-level DEBUG COMMAND または FITATU_LOG_LEVEL を指定してください(プライバシーとログ記録を参照)。
認証とセッションファイル
fitatu-api login [--email ADDRESS] [-o PATH] [--base-url URL](または python -m fitatu_api login)はログインし、アカウントのロケールとタイムゾーンを取得するためにプロフィールを読み込んで、セッションファイルを書き込みます。FITATU_EMAIL と
FITATU_PASSWORD が設定されている場合はその値を使用し、設定されていない場合は入力を求めます。パスワードを設定していないアカウントでは、fitatu-api import-session(以下を参照)を使用します。
-
保存先。
fitatu-api login、fitatu-api import-session、FitatuApiClient.from_session()、FitatuTools.from_session()、および非推奨のFitatuLibrary.from_session()は、同じファイルを使用します。渡したパス(CLI では-o)、それ以外の場合は$FITATU_SESSION、次に$FITATU_SESSION_PATH、それもなければ~/.fitatu/session.jsonです。ファイルが見つからない場合は、fitatu-api loginの実行を案内するFitatuAuthErrorが発生します。 -
内容。
bearer_token、refresh_token、fitatu_user_id、base_url(地域の API ホスト)、app_locale、app_searchlocale、app_storagelocale、app_timezone、およびスキーマバージョンを含む JSON です。クライアントの識別情報(API キー、アプリのバージョンなど)は保存されず、ライブラリから取得されます。 -
権限。 ファイルは所有者のみが読み書きできる権限(0600)で、0700 の権限で作成されたディレクトリ内に、一時ファイルを使って置き換える形で書き込まれるため、読み取り側が不完全なセッションを目にすることはありません。このファイルには有効なトークンが含まれています。パスワードと同様に扱ってください。
-
トークン。 2026-10-13 に実環境で確認したところ、ベアラートークンは有効期間が 1 時間の JWT です。リフレッシュトークンは不透明な文字列で、Fitatu はこれをローテーションしません。
POST /token/refreshは新しいベアラートークンと同じリフレッシュトークンを返し、そのリフレッシュトークンは引き続き有効です。また、以前のベアラートークンも期限切れになるまで有効です。POST /loginは、メールアドレスまたはパスワードが誤っている場合、401 ではなく 422 を返します。 -
リフレッシュと書き戻し。 クライアントは、ベアラートークンの有効期限が切れる 60 秒前(JWT の
expに基づく)と、401 の後に 1 回、トークンをリフレッシュします。リフレッシュは一度に 1 件だけ実行されます。トークンはセッションファイルに統合して保存されるため、次のプロセスは保存済みのトークンを使って起動します。また、ファイルを共有するプロセスは、別のプロセスが保存したトークンのペアを取得します(例:fitatu-api loginを再実行した後)。ファイルを変更しないようにするには、persist_tokens=Falseを渡してください。同じファイルで別のアカウントにログインした場合、そのアカウントのトークンのペアは取得されません。実行中のクライアントは自身のトークンを使い続け、ファイルへの書き込みを停止するため、ログインしたアカウントの情報はそのまま残ります。Fitatu から受け取ったばかりのトークンがすでに期限切れに見える場合は、コンピューターの時計が進みすぎています。その場合、クライアントは警告を 1 回ログに記録し、401 の後にのみリフレッシュします。 -
再ログイン。 Fitatu がリフレッシュトークンを拒否すると、呼び出しで
FitatuAuthError(error_typeはauth)が発生します。再度fitatu-api login(またはimport-session)を実行してください。実行中のクライアントは、次回リフレッシュが必要になったときにファイルから新しいトークンのペアを取得します。 -
パスワードのないアカウント。 Apple または Facebook で作成したアカウント(Apple の「メールを非公開」アドレスを含む)には、
fitatu-api loginで使用できるパスワードがありません。代わりに、ウェブアプリからセッションをコピーしてください。-
Apple または Facebook で https://www.fitatu.com/app/ にログインします。
-
そのページでブラウザーの開発者コンソールを開き、以下の行を実行します。トークンとユーザー ID のみがコピーされます。ウェブアプリの
localStorage.userには、メールアドレス、ニックネームなども含まれています。copy(JSON.stringify((u => ({token: u.token, refresh_token: u.refresh_token, id: u.id}))(JSON.parse(localStorage.user)))) -
macOS では
pbpaste | fitatu-api import-sessionを実行します。Linux または Windows では、ファイルに貼り付けてfitatu-api import-session < fileを実行し(PowerShell の場合:Get-Content file | fitatu-api import-session)、ファイルを削除します。
import-session [-o PATH] [--base-url URL]は標準入力から JSON を読み込み(このライブラリのセッションファイルも使用できます)、ベアラートークンを 1 回リフレッシュして Fitatu で両方のトークンを確認します(これにより、保存されたトークンは 1 時間有効になります)。また、loginと同様にアカウントのロケールとタイムゾーンを読み取り、同じ方法でセッションファイルを書き込みます。 入力からほかの情報が保存されることはありません。トークンはアカウント全体へのアクセスに使える認証情報です。ほかの場所には貼り付けないでください。 -
-
コンテナと cron。 書き込み可能なセッションファイルを使えない場合は、セッション JSON 自体を
FITATU_SESSION_JSONに設定します。fitatu-api login --print(またはimport-session --print)を実行すると、 ファイルに書き込む代わりに標準出力に出力されるため、シークレットストアに保存できます。パスを指定せずにfrom_session()を呼び出すと、ファイルより先にこの値が使われ、更新されたトークンはメモリ内に保持されます。 Fitatu はリフレッシュトークンをローテーションしないため、リフレッシュトークン自体が期限切れになる(有効期間は まだ不明です)か、再ログインするまでは、同じ値を毎回使用できます。 -
ファサード(非推奨)。
FitatuLibrary.from_session()は同じファイルを読み込み、更新されたトークンを ファイルに書き戻します。FitatuLibrary(session_data, session_path=...)はセッション辞書に対して同じ処理を行い、 呼び出しのたびに最新のトークンペアをsession_dataにコピーします。 -
Python から。
FitatuApiClient.login(email, password, token_store_path=path)はログインし、 セッション全体をpathにマージします。
地域と言語ヘッダー
API ホストには、セッションの base_url が使われます。指定されていない場合は、アカウントのストレージロケールに対応するホストが使われます。
pl_PL は https://pl-pl.fitatu.com/api に、de_DE は https://de-de.fitatu.com/api に変換されます。
fitatu-api login は https://pl-pl.fitatu.com/api でログインし、ストレージロケールに対応するホストを保存します。
--base-url を指定すると、その URL でログインし、その URL を保存します。
| グループ | ヘッダー | 備考 |
|---|---|---|
| 必須 | API-Key、API-Secret、Authorization: Bearer <jwt> | キーとシークレットは固定のアプリ値です(これらがない場合は 403)。ユーザー向けルートでは Authorization が必要です(401)。 |
| セマンティック | APP-SearchLocale、APP-Locale、APP-StorageLocale、APP-Timezone | APP-SearchLocale と locale クエリパラメーターは検索結果を変更します。その他はユーザーに関する情報です。4 つすべてセッションに由来し、login() はプロフィールの値で設定します。これらがないセッションでは、pl_PL と Europe/Warsaw がデフォルトで送信されます。 |
| 識別 | APP-OS、APP-Version、APP-UUID、API-Cluster、User-Agent | クライアントの識別にのみ使われます。ライブラリは常に 1 つの固定された Web アプリ用プロファイル(constants.py の WEB_CLIENT_PROFILE)を送信し、セッションには保存しません。 |
ライブラリのリリース前に Fitatu が Web アプリから送信される情報(バージョン、または API キーとシークレット)を変更した場合は、
FITATU_CLIENT_PROFILE に、変更する WEB_CLIENT_PROFILE のキーを含む JSON オブジェクトを設定します。例:FITATU_CLIENT_PROFILE='{"app_version": "4.14.0"}'。
その他のキーや、プレーンテキストではない値は FitatuValidationError で拒否されます(その場合、fitatu-mcp は起動しません)。
fitatu-api doctor を実行すると、バージョンが引き続き最新かどうかを確認できます。
ログイン(_username と _password を指定した POST /login)とリフレッシュ({"refresh_token": ...} を指定した POST /token/refresh)は、
同じリクエスト経路を通り、Authorization を除く同じヘッダーを送信します。ログイン時のロケールヘッダーは
pl_PL のデフォルト値です。リクエストの署名はなく、Firebase App Check も強制されません。ライブラリはこれを送信しません。
認証情報の送信先は、fitatu.com 配下の https ホストに限られます。その他の base_url や絶対 URL を指定すると、
リクエストを行う前に FitatuValidationError が発生します。また、Authorization は base_url 配下の URL、
または https://fitatu.com/api にのみ送信されます。リダイレクトは追跡されません。3xx の応答は FitatuApiError となるため、
リクエスト本文が別のホストに送られることはありません。
エラー、再試行、レート制限
ライブラリのエラーは FitatuApiError のサブクラスです。describe_error(exc) は、あらゆる例外を
FitatuTools.call()(および非推奨の FitatuLibrary)が返す JSON 対応の辞書に変換します。
| 例外 | 発生する条件 | error_type |
|---|---|---|
FitatuValidationError(ValueErrorでもあります) | 引数が無効です。何も送信されません。 | validation |
FitatuNotFoundError | 指定した ID、食事、または行が見つかりません。ライブラリが読み取ったデータ内に存在しないことを確認した場合(メッセージには存在するデータが記載されます)、またはサーバーが 404(status_code 404)を返した場合に発生します。 | not_found |
FitatuAuthError | 更新後の 401、拒否された更新トークン、セッションファイルがない場合、またはログイン時のメールアドレスやパスワードが間違っている場合(Fitatu は 422 を返します)。この場合、hint は import-session を示します。 | auth |
FitatuRateLimitError | 再試行後も 429 が返された場合です。retry_after にはサーバーが指定した待機時間(秒)が格納されます。 | rate_limit |
FitatuConnectionError | HTTP レスポンスがありません(DNS、タイムアウト、接続リセット)。 | network |
FitatuMaintenanceError | Fitatu の technical-break ヘッダーが返された場合です。display_from / display_to が格納されます。 | maintenance |
FitatuPlannerSyncError | 日次同期が 202 を返したものの、特定の日付の同期が拒否された場合です。results には日付ごとのエラーが格納されます。 | sync_rejected |
FitatuPremiumRequiredError | Fitatu アプリで Premium 向けに提供される機能のツールを、Premium ではないアカウントで使用した場合です。その処理は送信されません。 | forbidden |
FitatuApiError | その他の HTTP エラーです。status_code、body、codename(例:NUMBER_OF_USES_EXCEEDED)が格納されます。 | forbidden(403)、validation(400/409/422)、server |
メッセージは METHOD /path -> status CODENAME: server message の形式です。describe_error() のメッセージでは、ユーザー ID は <user>(GET /diet-plan/<user>/days -> 403)に置き換えられます。また、user_id= が指定されている場合(FitatuTools.call() が渡す場合)、ほかの箇所にユーザー ID が含まれていても同様に置き換えられるため、結果にユーザー ID が含まれてモデルプロバイダーに渡ることはありません。本文が HTML ページの 403 は、Fitatu の Premium やキーのチェックではなく、API の前段にあるファイアウォール(例:Cloudflare)から返されたものです。その場合、hint にその旨が示されます。ライブラリ内部で発生した TypeError など、その他の例外は unexpected です。FitatuTools.call() が最初に引数をチェックするため、報告すべきバグです。
再試行:ネットワークエラー、429、500/502/503/504、および Cloudflare の 520~524 は、GET、HEAD、OPTIONS と、冪等としてマークされた書き込み(日次同期(すべてのプランナー書き込み。行 ID による upsert を行います)、water.set_day、measurements.set_day、measurements.delete_day、foods.set_favorite)で再試行されます。その他の書き込み(カタログへの書き込み、設定、ログイン、更新)は 1 回だけ送信されます。最大 retry_max_attempts=3 回試行し、retry_base_delay_seconds=0.5 から指数バックオフします。最大 30 秒までの Retry-After に従います。それを超える場合は待機せず、ただちにエラーを送出します(429 の場合は retry_after を含む FitatuRateLimitError)。技術的な停止中は、再試行も更新も行われません。with client.time_limit(seconds): の実行中は、リクエスト全体が指定時間内に終了します。待機すると残り時間が 2 秒未満になる再試行は行わず、各リクエストのタイムアウトは残り時間に合わせて短縮され、残り時間がない場合はリクエストを送信しません(FitatuConnectionError)。FitatuTools は各呼び出しを 45 秒(call_timeout)の制限時間内で実行します。
多くの書き込みでは複数のリクエストが発生するため、429 対策として件数を見積もる際にはこれも考慮してください。ツールは日誌への書き込みの前に毎回その日のデータを読み取ります。また、更新、移動、削除、アクティビティの書き込みでは、ok を設定するために処理後にも再度読み取ります。トークン更新と再試行を除いた、エージェントツールの呼び出しごとのリクエスト数は次のとおりです。
| リクエスト数 | ツール |
|---|---|
| 0 | get_today |
| 1 | その他の読み取りツール;set_water;set_favorite;dry_run を指定した preview_removal と remove_items;すでに削除済みのレシピに対する delete_recipe、すでに削除済みの商品に対する delete_food |
| 2 | get_range_summary、get_profile、get_fasting(設定でスキーム名を ID で指定している場合は 3)、get_habits、find_by_barcode(商品がヒットしない場合は 1)、ポーション単位のレシピに対する add_food(Premium フラグ分としてさらに 1、10 分以内の最初の呼び出し;Fitatu Premium なしの場合は、最初にレシピを読み取るため、さらに 1);add_custom_item、log_weight、delete_recipe、set_targets、create_food、delete_food;add_foods。unit または measure_id を指定した各項目につき 1 を追加し、Fitatu Premium なしの場合は、ポーション単位の各レシピにつき 1 を追加(さらに add_food と同様に Premium フラグ分として 1);create_recipe。各材料につき 1 を追加;フィルターを指定し、max_energy_kcal は指定しない search_recipes、および Premium レシピに対する get_recipe と get_food_measures。10 分以内の FitatuTools での最初の呼び出しではアカウントの Premium フラグを読み取り、その後は 1 |
| 3 | unit または measure_id を指定した add_food(最初に食品を読み取る)、log_measurements(プロフィールからサイズ単位を読み取る)、同じ日の copy_meal、remove_items、add_activity、remove_activity、set_note、update_food;update_recipe。新しい材料ごとに 1 を追加 |
| 4 | update_item、同じ日の move_item、別の日への copy_meal |
| 5 | get_progress(最大 62 日の任意の範囲。Fitatu Premium なしの場合は下記を参照) |
| 6 | 別の日への move_item |
| 8 | get_report(範囲内の体重記録が 41 件増えるごとに 1 を追加) |
| 1 日あたり 1 | get_shopping_list。範囲内で予定されているレシピごとに 1 を追加し、Premium レシピがある場合は Premium フラグ分として 1 を追加;Fitatu Premium なしの場合の get_progress と get_report。範囲分として 1 を追加(1 日のみの場合はなし)、および get_report の体重記録分を追加。10 分以内の FitatuTools での最初の呼び出しではさらに 1 が追加され、Fitatu に拒否されます |
プライバシーとログ
このライブラリは標準の logging モジュールを使ってログを記録し、ハンドラーは設定しません。
fitatu-api コマンドと fitatu-mcp は stderr にログを出力し、stdout には出力しません(stdout はコマンドの結果または MCP プロトコルに使用されます)。ライブラリのログレベルは WARNING、または --log-level DEBUG|INFO|WARNING|ERROR(fitatu-api ではコマンドの前に指定します。例:fitatu-api --log-level DEBUG call get_today)もしくは FITATU_LOG_LEVEL で設定されたレベルです。その他のライブラリのログレベルは WARNING です。
INFO(fitatu_api.client):認証イベントを JSON 行として記録します。ログイン(ユーザー ID)、トークン更新の開始・成功・失敗、clear_authと、秘密情報を含まない状態のスナップショット(ユーザー ID、ロケール、タイムゾーン、ホスト、トークンの有効期限、トークンの有無)。WARNING(fitatu_api.client):ネットワークエラー、429、または 5xx によりリクエストが最終的に失敗した場合のfitatu.request.error、Fitatu から取得したばかりのトークンが期限切れに見える場合(ローカルの時計がずれており、期限前の更新が停止する状態)のfitatu.auth.clock_skew、およびセッションファイルに別アカウントのトークンが保存された場合(クライアントは自身のトークンを保持します)のfitatu.auth.store_other_account。fitatu_api.agent、fitatu_api.facade、fitatu_api.mcp_serverでは、結果がunexpectedエラー(トレースバックを含む)、authエラー、またはmaintenanceエラーを報告した呼び出しを記録します(例:get_day failed (auth): ...)。fitatu_api.authでは、読み取れなかったトークンストア(通常はセッションファイル)を記録します。--http使用時のfitatu_api.mcp_serverでは、トークンを理由に拒否された各リクエストをクライアントのアドレスとともに記録します(トークン自体は記録しません)。uvicorn は起動と停止の行を追加します。DEBUG(fitatu_api.client):各リクエストを JSON 行として記録します。fitatu.request.start(メソッド、パス、検索語句などのクエリパラメーター)、各リトライの待機前のfitatu.request.retry(失敗したattempt、delay_seconds、およびステータスやネットワークエラーの種類などのreason)、続いてfitatu.request.okまたはfitatu.request.error(ステータス、attempt、開始からのelapsed_ms、エラーボディの先頭 300 文字。4xx は、呼び出し元に例外として返され、404 のように想定されるものもあるため、DEBUG のままです)。fitatu_api.plannerではプランナーへの書き込みごとに 1 行(ユーザー ID、日付、食事、食品 ID、カスタム行の名前と kcal)、ツールレイヤーでは結果が報告するその他すべてのエラーを記録します。パスにはユーザー ID と日付が含まれます。
リクエストボディ、パスワード、トークンはログに記録されません。キーに token、secret、password、authorization のいずれかが含まれる値は [redacted] に置き換えられ、認証コンテキストの repr にはトークンと API シークレットが含まれません。エラーメッセージにはサーバーのメッセージが最大 200 文字含まれます。レスポンスボディ全体は exc.body に格納されますが、describe_error() と FitatuTools のエラー結果(および非推奨の FitatuLibrary)では省略されます。ヘッダー値として無効なトークン(例:改行を含めて貼り付けたもの)は、引用符で囲まずに報告されます。
テスト
pip install -e ".[dev]"
pytest -q
テストスイートはオフラインで実行できます。tests/fixtures/api_recording.json には、日次同期、測定値、サマリー、検索、設定に関する実際の API レスポンス(個人データを削除済み)が保存されています。tests/fake_server.py はこれらを基に構築された偽のバックエンドであり、記録との間にずれがあると tests/test_recorded_contract.py が失敗します。記録の作成と更新方法については、こちらをご覧ください:
tests/fixtures/README.md。
ライブテストスイート(tests/test_live_all.py)は実際のアカウントに対して実行され、アカウントに書き込みを行います:
FITATU_RUN_LIVE_TESTS=1 pytest tests/test_live_all.py
fitatu-api login が書き込んだセッションファイル(または $FITATU_SESSION)を使用し、更新されたトークンをそのファイルに保存します。$FITATU_SESSION_JSON を設定すると、代わりにそのセッションが使われ、更新されたトークンは保存されません。オプション:FITATU_LIVE_DAY(今日以降の日付。デフォルトは今日から1年後)、FITATU_LIVE_MEAL_KEY(snack)、FITATU_LIVE_PRODUCT_ID、FITATU_LIVE_RECIPE_ID、FITATU_LIVE_MEASUREMENT_DAY(2020-01-01。測定値がある場合はスキップ)、FITATU_LIVE_RUN_WRITE_ACCOUNT=1。
各テストは FITATU_LIVE_DAY に追加した行だけを正確に削除し、1行でも残っていれば失敗します。今日以前の日付を指定すると拒否されます。その日の水分量とメモは元に戻され、FITATU_LIVE_MEASUREMENT_DAY に記録した体重と測定値は削除されます。-k ReadOnly を指定すると、読み取りのみを行うテストだけが実行されます。
食品カタログを記録するとアカウントの最近使用した食品に追加されますが、これは元に戻りません。FITATU_LIVE_RUN_WRITE_ACCOUNT=1 を指定すると、テストスイートは水分のグラスサイズと1日の目標も変更して復元します(Fitatu は復元された目標を今日からの新しいバージョンとして保持します)。また、プライベートな商品1件とレシピ2件(うち1件はツール経由で作成して FITATU_LIVE_DAY に記録した後に削除)を作成して削除し、さらにツール経由でプライベートな商品1件を作成し(FITATU_LIVE_DAY に記録)、変更して削除します。商品とレシピの削除は論理削除のため、最近使用した食品と同様、完全には元に戻りません。アカウントに残りますが、削除済みとしてマークされ、食品一覧と検索結果には表示されなくなります。全項目の一覧は tests/test_live_all.py のモジュール docstring にあります。大切な記録がある日を FITATU_LIVE_DAY に指定しないでください。
scripts/check_contract.py は読み取りのみで、ライブ API が記録にある構造で引き続き応答するかどうかを確認します。ルート名とキー名を出力し、値は出力しません。キーがなくなった場合、型が変わった場合、またはルートが失敗した場合は、終了コード 1 で終了します。Live contract ワークフローは、毎週月曜日にこれを実行し、読み取り専用のライブテストも行います。セッションは使い捨てアカウントのもので、FITATU_SESSION_JSON シークレットに設定します。設定されていない場合はスキップされます:
CONTRIBUTING.md。
scripts/eval_agent.py は、デモ用日記で Claude モデルがツールをどの程度適切に使うかを評価します(ポーランド語と英語の29タスク。ANTHROPIC_API_KEY が必要で、API 使用料が発生するため、CI では実行されません):
docs/AGENTS.md。
ドキュメント
- docs/AGENTS.md:エージェント向けのツール、安全な書き込み、エラー処理、MCP サーバーについて説明しています。
- docs/PLANNER.md:1日の同期契約、ID、日誌への各書き込みの結果について説明しています。
- docs/API_REFERENCE.md:すべての公開クラスとメソッド、およびその安定性について説明しています。
- docs/APP_4_17_1_API_CATALOG.md:逆コンパイルから得られた、Fitatu Android アプリ 4.17.1 のすべてのルートについて説明しています。
- docs/RELEASING.md:メンテナー向けのリリース手順です。
- CHANGELOG.md
バグや質問については、GitHub issuesをご利用ください。セキュリティ上の問題は、非公開で報告してください:SECURITY.md。 セットアップ、チェック、プルリクエストのルールについては、CONTRIBUTING.mdをご覧ください。
ライセンス
MIT ライセンスです。LICENSEをご覧ください。このライセンスの対象はこのコードのみであり、Fitatu サービス、その API、またはそのサービスが返すデータは対象外です。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。