← nocci に戻るMCP Server Spec v0.4.1

nocci MCP Server Specification (Draft v0.4.1)

最終更新: 2026-05-04 ステータス: Draft(実装着手) 準拠: Model Context Protocol 対応コードベース: nocci main branch (Next.js 15 + AWS CDK + DynamoDB 単一テーブル)


1. 概要

nocci MCP サーバーは、ユーザー自身の美容/ウェルネスログ(コスメ・サプリ・体調記録)を、Claude Desktop / その他 MCP 対応 AI アシスタントから安全に参照できるようにするインターフェースです。

「ユーザーが nocci に記録したデータを、ユーザーの AI アシスタントが読み取り、文脈に合った美容アドバイスや振り返りを返す」というユースケースを想定しています。

2. なぜ nocci が MCP を提供するのか

既存の美容/ウェルネスアプリは、ユーザーのデータをアプリ内に閉じ込めてきました。一方、ユーザーは Claude や ChatGPT と日常的に会話しており、そこで美容相談もしています。しかし AI アシスタントには「そのユーザーが実際に何を使い、肌の調子がどう変動したか」のコンテキストがありません。

nocci MCP は、このコンテキストの分断を解消する規格です。ユーザーがログを記録する場所(nocci)と、相談する場所(AI アシスタント)を、ユーザー自身のコントロール下で接続します。

3. 設計原則

  1. Read-only first:v1.0 では参照のみ。書き込みは将来検討。
  2. User-scoped:認証トークンに紐づく actorIdGUEST#{uuid} または USER#{cognitoSub})のデータのみ返す。
  3. Privacy-first:他人のデータには絶対にアクセスできない。
  4. Stateless:サーバー側で AI クライアントの会話状態を保持しない。
  5. Narrative over score:レポートは数値スコアではなく文章として返す(nocci の差別化②)。
  6. 薬機法準拠:医療的アドバイスや断定表現を含めない(後述)。
  7. JST 統一:日付境界はすべて JST(UTC+9)。既存実装と整合。

4. アーキテクチャ上の位置づけ

nocci の既存コードベースに対する変更点:

infra/functions/
  mcp/                        新規追加
    index.ts                   MCP HTTP エンドポイント (Streamable HTTP)
    protocol.ts                JSON-RPC 2.0 ルーティング
    tools/
      get_recent_logs.ts
      get_latest_weekly_report.ts
      get_correlations.ts
      list_items.ts
  _shared/
    db.ts                    既存 listLogs / listItems / getLatestAiReport を再利用
    report.ts                既存 generateWeeklyReport を correlations 抽出に再利用
    auth.ts                  既存 verifyToken を再利用(JWT)
    rate-limit.ts            既存 isUserRateLimited を MCP にも適用

DynamoDB 側の追加は v0.1 ではなし(既存のキー設計をそのまま参照)。将来的に MCP 専用の長寿命 API キーを実装する場合は MCP_KEY#{keyHash} の SK パターンを追加。

5. 認証

v0.1: 既存 JWT を流用

ユーザーは nocci アプリ内「設定 → MCP連携」画面で自分の JWT を表示・コピーできる。AI アシスタント側の MCP クライアント設定に Authorization: Bearer <jwt> ヘッダとして貼り付け。

  • ゲストトークン(HS256):発行から 1 年間有効(issueGuestToken の挙動)
  • Cognito トークン(RS256):短命(要 refresh)。v0.1 ではゲスト想定が中心。

v1.0 以降: 専用 MCP API キー

DynamoDB に MCP_KEY#{sha256(key)} を追加し、ユーザー単位で複数発行・個別失効可能に。Authorization: Bearer mcp_<base64key> 形式。

6. エンドポイント

POST https://nocciapp.com/mcp
Transport: Streamable HTTP (MCP 標準)
Content-Type: application/json
Accept: application/json, text/event-stream

レート制限:既存 isUserRateLimited を流用(5分ウィンドウあたり 60 回)。

6.1 Claude Desktop からの接続 (mcp-remote ブリッジ)

Claude Desktop は現時点で MCP の HTTP transport を直接サポートしていないため、 mcp-remote ブリッジを介して接続する。 npx が初回実行時に自動でダウンロードするので、ユーザー側の事前準備は不要。

claude_desktop_config.json への記述例:

{
  "mcpServers": {
    "nocci": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://nocciapp.com/mcp",
        "--header",
        "Authorization: Bearer mcp_<上で発行したキー>"
      ]
    }
  }
}

設定ファイルの場所:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

将来 Claude Desktop が MCP の HTTP transport を直接サポートした時点で、 ブリッジ無しの { url, headers } 形式へ切り替え可能。サーバー側の API は変えない。

7. ツール

7.1 get_recent_logs

ユーザーが記録した最近の日次ログを返す。AI 側の文脈把握の起点。itemId は denormalize してアイテム名・種別・ブランド情報をインライン展開する(追加クエリを不要にするため)。

パラメータ

名前 必須 デフォルト 説明
days integer (1–30) No 7 過去何日分
include_items boolean No true アイテム情報を denormalize するか

返り値

{
  "generated_at": "2026-05-04T05:00:00.000Z",
  "period": { "from": "2026-04-27", "to": "2026-05-04" },
  "user_timezone": "Asia/Tokyo",
  "tier": "free",
  "logs": [
    {
      "date": "2026-05-04",
      "condition": "good",
      "skin": "good",
      "sleep": "6-7",
      "memo": "肌の調子が安定している",
      "usedItems": [
        {
          "itemId": "item_abc123",
          "name": "ビタミンC 1000mg",
          "type": "supplement",
          "brand": "Now Foods",
          "category": null,
          "timeSlots": ["morning"],
          "dose": 1,
          "doseUnit": "粒"
        }
      ]
    }
  ]
}

include_items: false の場合、usedItems{itemId, timeSlots, dose?, doseUnit?} のみ。

enum 制約(既存スキーマと完全一致):

  • condition, skin: "good" | "ok" | "bad"
  • sleep: "<5" | "5-6" | "6-7" | "7+"
  • timeSlots[i]: "morning" | "noon" | "evening" | "night"
  • type: "cosmetic" | "supplement"
  • doseUnit: "錠" | "粒" | "包" | "ml" | "g" | "滴" | "本" | "回"

旧データの sleep: "<6" 等は DB レイヤーで <5 に自動マイグレーション済み。MCP は新形式のみを返す。

7.2 get_latest_weekly_report

直近の週次 AI レポートを返す。nocci 差別化②「narrative型レポート」をそのまま AI クライアント側にコンテキストとして渡す。

無料ユーザーは月曜生成の7日分析、有料ユーザーは日次生成の30日分析。

パラメータ:なし

返り値

{
  "generated_at": "2026-05-04T05:00:00.000Z",
  "result_hash": "a1b2c3d4e5f60708",
  "available": true,
  "report": {
    "date": "2026-05-04",
    "periodFrom": "2026-04-28",
    "periodTo": "2026-05-04",
    "summary": "今週は肌コンディションが安定していました。睡眠時間も6時間以上を維持できた日が多めです。",
    "insights": [
      "今週7日中5日、睡眠が6時間以上でした",
      "ビタミンB群を毎日摂取できていた一週間でした"
    ],
    "advice": "来週も現在の睡眠リズムを継続できると良さそうです。",
    "suggestions": [
      {
        "careCategory": "保湿ケア",
        "logBasis": "今週7日中5日肌がgoodだったので、来週は保湿の継続にも注目できそうです",
        "label": "参考情報"
      }
    ],
    "generatedAt": "2026-05-04T03:00:00.000Z",
    "model": "claude-haiku-4-5-20251001"
  },
  "tier": "free"
}

未生成の場合 (available: false のときは result_hash を含めない):

{
  "generated_at": "2026-05-04T05:00:00.000Z",
  "available": false,
  "reason": "not_generated",
  "tier": "free"
}

AI クライアントへの注意

  • suggestions[].careCategoryスキンケアカテゴリのみ。サプリ・成分名・商品名は含まれない。
  • suggestions[].label は常に "参考情報" 固定。
  • このデータを引用する際、AI クライアント側は断定表現に変換しない。

7.3 get_correlations

ログから観察される傾向(相関の候補)を返す。nocci 差別化①「横断記録による相関の可視化」を外部公開するコアツール。

検出される傾向は以下の3種:

  • 睡眠(<5h)× 全体コンディション
  • アイテム使用 vs 非使用 × 肌コンディション
  • 習慣サプリ(pinned)の摂取漏れ × 全体コンディション

検出には最低 3 日以上の記録と、絶対差 25〜30 % 以上が必要。

パラメータ

名前 必須 デフォルト 説明
days integer (1–14) No 7 観察期間
min_confidence enum No "low" "low" / "medium" / "high" 以上を返す

返り値

{
  "generated_at": "2026-05-04T05:00:00.000Z",
  "result_hash": "a1b2c3d4e5f60708",
  "observation_period": { "from": "2026-04-28", "to": "2026-05-04" },
  "days_recorded": 6,
  "correlations": [
    {
      "title": "睡眠が短い日にコンディションが低め",
      "body": "5時間未満の日は67%が不調(3日中2日)、それ以外は20%(5日中1日)でした。",
      "confidence": "medium"
    }
  ],
  "disclaimer": "観察的傾向であり因果関係を示すものではありません。記録日数が少ない場合は精度が下がります。"
}

7.4 list_items

ユーザーの登録アイテム(コスメ・サプリ)の一覧を返す。AI クライアントが「あなたのスタックは何?」のような質問に即答できるようにする。get_recent_logs の補助的役割。

パラメータ

名前 必須 デフォルト 説明
type enum No 全種別 "cosmetic" または "supplement"
include_archived boolean No false isActive: false のアイテムも含める

返り値

{
  "generated_at": "2026-05-04T05:00:00.000Z",
  "items": [
    {
      "itemId": "item_abc123",
      "name": "ビタミンC 1000mg",
      "type": "supplement",
      "category": null,
      "brand": "Now Foods",
      "isActive": true,
      "pinned": true,
      "defaultDose": 1,
      "doseUnit": "粒",
      "notes": "朝食後に摂取",
      "startDate": "2026-02-01"
    }
  ]
}

意図的に除外するフィールドreminderTimesjanCodePK/SK/createdAt/updatedAt

7.5 AI クライアント向け補足: generated_atresult_hash の使い方

すべてのツールのレスポンス最上位に generated_at (ISO8601) が含まれます。これはサーバーが レスポンスを組み立てた時刻で、レイテンシ計測やログ用途を想定しています。

加えて get_correlationsget_latest_weekly_reportavailable: true のとき)は result_hash を返します。これは結果本体の SHA-256 ハッシュ先頭 16 文字(64bit)で、 generated_at の時刻揺れの影響を受けません。サーバー側に格納されているデータが 変わらない限り、何度呼んでも同じ値が返ります。

推奨される使い方

同じ会話内で同じツールが繰り返し呼ばれた場合、AI クライアントは前回のレスポンスと result_hash を比較することで、結果が変わっていないかを O(1) で判定できます。 同一の場合、再呼び出しせず前回の結果を再利用することで、ユーザー体験の冗長性と レイテンシを改善できます。

result_hashgenerated_at の時刻揺れの影響を受けないため、サーバー側で同じデータが 格納されている限り同じ値を返します。

list_itemsget_recent_logs には result_hash を付けていません。前者は 個人情報的な内容を含み AI クライアント側のキャッシュ滞留を抑えたいため、後者は 日付計算の都合上「同じ呼び出しでも翌日には別結果」になりやすいためです。

8. エラーハンドリング

MCP 標準のエラーコードに加え、以下を定義:

コード 意味
INSUFFICIENT_DATA 分析に必要なログ件数(最低 3 日)に達していない
RATE_LIMITED 5分ウィンドウあたりの上限を超過
INVALID_TOKEN JWT または API キーが無効・失効
REPORT_NOT_GENERATED AI レポートがまだ生成されていない

9. 薬機法・コンテンツ安全性に関する制約

nocci は美容/ウェルネスアプリとして、薬機法および景品表示法を遵守した表現ルールを内部で定めています。MCP 経由でデータを取得する AI クライアントも、以下の制約を理解した上で扱う必要があります:

  • レポート・相関の本文にサプリメント・成分名の推奨は含まれない
  • スキンケアの suggestionsカテゴリ名のみ(例:「保湿ケア」「日焼け止め」)
  • 断定表現(「〜の原因です」「使わないでください」等)は使わない

10. ライセンス

  • 本仕様ドキュメント:CC0 / Public Domain
  • サーバー実装コード:クローズド
  • 本番 MCP エンドポイント利用:nocci 利用規約に準拠

11. 変更履歴

日付 バージョン 変更内容
2026-05-04 0.4.1 Claude Desktop 接続には mcp-remote ブリッジが必要であることを明記。§6 に接続例を追記。
2026-05-04 0.4 全ツールに generated_atget_correlationsget_latest_weekly_reportresult_hash を追加。AI クライアントによる結果キャッシュ判定を可能に。
2026-05-04 0.3 4ツール構成で確定

付録: 実装メモ

  • get_recent_logstiergetProfile(actorId).entitlements.premium から導出
  • get_latest_weekly_report は既存 getLatestAiReport(actorId) をそのまま使う
  • get_correlationslistLogs + listItemsgenerateWeeklyReportreport.insights をマップ
  • list_items は既存 listItems(actorId) をそのまま使い、isActive でフィルタ + 不要フィールド除去
  • 認証は既存 verifyTokentoActorId の流れに乗せる
  • JST 日付計算は const jstNow = new Date(Date.now() + 9 * 60 * 60 * 1000)

本仕様ドキュメントはCC0 / Public Domainで公開されています。自由に参照・引用・実装可能です。

Last updated: 2026-05-04