FitnessSyncer について
FitnessSyncer は、50 以上のソースにあるユーザーの健康・フィットネスデータを利用するアプリ向けに、OAuth ベースの REST API を提供します。コード生成に使える OpenAPI 仕様と、MCP サーバーも用意されています。
主な機能
- 01複数ソースの健康・フィットネスデータへのアクセス
- 02OAuth ベースの REST API
- 03OpenAPI 仕様からのアプリコード生成
- 04OAuth 認証とトークン更新フロー
活用シーン
- 01集約されたフィットネスデータにアクセスするアプリの構築
- 02仕様からの API クライアントコード生成
- 03アクセス認証と期限切れトークンの更新
MCP 対応
FitnessSyncer は連携を簡単にする MCP サーバーも提供しますが、README にはツールや公開データの詳細が記載されていません。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://www.fitnesssyncer.com/services/mcpclaude mcp add --transport http FitnessSyncerAPI https://www.fitnesssyncer.com/services/mcp{"mcpServers":{"FitnessSyncerAPI":{"type":"http","url":"https://www.fitnesssyncer.com/services/mcp"}}}Cursor で開く{"servers":{"FitnessSyncerAPI":{"type":"http","url":"https://www.fitnesssyncer.com/services/mcp"}}}VS Code で開く{"mcpServers":{"FitnessSyncerAPI":{"type":"http","url":"https://www.fitnesssyncer.com/services/mcp"}}}{"mcpServers":{"FitnessSyncerAPI":{"serverUrl":"https://www.fitnesssyncer.com/services/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
https://www.fitnesssyncer.com/services/mcp認証が必要ツール
詳細
FitnessSyncer OpenAPI 仕様
FitnessSyncer は、ユーザーが50 を超えるソースから健康とフィットネスのデータにアクセスできるようにする API を提供しています。OAuth ベースの REST API を使用すれば、ソースを問わずデータをシームレスに取得でき、サービスとの連携ではなく、アプリケーションの構築に集中できます。
このリポジトリには、アプリケーション用のコードをすばやく生成できるOpenAPI 仕様が含まれています。
詳細については、ドキュメントをご確認のうえ、こちらで個人用の認証情報を作成してください。
個人利用以外の用途やサポートについては、お問い合わせください。
一部の連携をより簡単にする MCP サーバーも提供しています。詳しくは、ドキュメントをご確認ください。
図
認証シーケンス図
すべてのパラメーターと詳細については、認証シーケンス図をご覧ください。
スクリプトの例については、認証フローのfitnesssyncer_oauth_authorization_flow.pyをご覧ください。
--client-id、--client-secret、--redirect-uri を指定すると、ブラウザーウィンドウが開き、ログイン後にリダイレクトされた URL を使用して
access_token と refresh_token を取得します。access_token の有効期限が切れると、
fitnesssyncer_oauth_refresh_flow.py スクリプトが、--refresh-token、
--client-id、--client-secret の各パラメーターを使用して、新しい access_token と refresh_token を取得します。これらは PKCE に対応していません。
sequenceDiagram
participant User
participant Your Application
participant FitnessSyncer
%% https://www.fitnesssyncer.com/api/documentation.html#authorize
Your Application->>User: Send Redirect to FitnessSyncer https://api.fitnesssyncer.com/api/oauth/authorize
User->>FitnessSyncer: Follow Redirect, maybe login, and authorize Your Application to use the User's data.
FitnessSyncer->>User: Send redirect URL with code and state query parameters
User->>Your Application: Follow Redirect with code and state query parameters.
%% https://www.fitnesssyncer.com/api/documentation.html#accessing_token
Your Application->>FitnessSyncer: POST parameters to https://api.fitnesssyncer.com/api/oauth/access_token
FitnessSyncer->>Your Application: Return access_token, refresh_token, expires_in, scope, and user_id values.
Your Application->>Your Application: Use token until it expires
%% https://www.fitnesssyncer.com/api/documentation.html#refreshing_token
Your Application->>FitnessSyncer: POST parameters to https://api.fitnesssyncer.com/api/oauth/access_token
FitnessSyncer->>Your Application: Return access_token, refresh_token, expires_in, scope, and user_id values.
ソースとデスティネーションの認証シーケンス図
データソースの作成、デスティネーションの作成、プロバイダー認証をご覧ください。
これはソース認証フローを示しています。デスティネーション認証フローも同様です。
sequenceDiagram
actor EndUser as End User
participant YourServer as Your Server
participant FitnessSyncer as FitnessSyncer Auth Service
participant FitBit as Fitbit
note right of EndUser: Assumes the user is already authenticated with FitnessSyncer
EndUser ->> YourServer: Add a Data Source such as Fitbit
%% https://www.fitnesssyncer.com/api/documentation.html#data_source_create
YourServer ->> FitnessSyncer: Create new Data Source via PUT to /api/providers/sources/
FitnessSyncer ->> YourServer: Return create id
%% https://www.fitnesssyncer.com/api/documentation.html#provider_list
note right of YourServer: If you do not know the authentication scheme for the selected service, use https://api.fitnesssyncer.com/api/providers/types/ . This example assumes OAuth.
YourServer ->> FitnessSyncer: Set authentication via PUT to /api/providers/sources/{id}/authentication
note right of YourServer: Ensure you set the Redirect URL on this request.
FitnessSyncer ->> YourServer: Return redirect URL
YourServer ->> EndUser: Send Redirect
EndUser ->> Fitbit: Process Redirect
note right of Fitbit: Allow FitnessSyncer access to your Fitbit Account?
Fitbit -> FitnessSyncer: User Authenticated -- follow requested redirect URL.
FitnessSyncer ->> EndUser: Follow requested redirect URL
EndUser ->> YourServer: Authentication complete
通知シーケンス図
通知には 2 つのモデルがあります。1 つ目は、以下に示すプッシュ通知です。
sequenceDiagram
participant FitnessSyncer as FitnessSyncer Data Processor
participant YourServers as Your Notification Service
note right of YourServers: You must register for push notifications via e-mail
%% https://www.fitnesssyncer.com/api/documentation.html#notifications_subscribe
YourServers ->> FitnessSyncer: Subscribe User for Notifications
FitnessSyncer ->> YourServers: OK
FitnessSyncer ->> FitnessSyncer: Acquire/Process Data
%% https://www.fitnesssyncer.com/api/documentation.html#notifications
FitnessSyncer ->> YourServers: POST of the changed items
YourServers ->> FitnessSyncer: OK
%% https://www.fitnesssyncer.com/api/documentation.html#data_source_items_get
YourServers ->> FitnessSyncer: Get Updated Data
FitnessSyncer ->> YourServers: Results
2 つ目は、以下に示すプル通知です。
sequenceDiagram
participant FitnessSyncer as FitnessSyncer Data Processor
participant YourServers as Your Notification Service
note right of YourServers: You must register for pull notifications via e-mail
%% https://www.fitnesssyncer.com/api/documentation.html#notifications_subscribe
YourServers ->> FitnessSyncer: Subscribe User for Notifications
FitnessSyncer ->> YourServers: OK
FitnessSyncer ->> FitnessSyncer: Acquire/Process Data
%% https://www.fitnesssyncer.com/api/documentation.html#notifications_claims
YourServers ->> FitnessSyncer: Get Notifications via POST to https://api.fitnesssyncer.com/api/notifications/
FitnessSyncer ->> YourServers: Notification Claim
%% https://www.fitnesssyncer.com/api/documentation.html#data_source_items_get
YourServers ->> FitnessSyncer: Get Updated Data
FitnessSyncer ->> YourServers: Results
YourServers ->> YourServers: Handle errors, which are typically reauthentication errors.
%% https://www.fitnesssyncer.com/api/documentation.html#notifications_delete
YourServers ->> FitnessSyncer: Delete Claim via DELETE to https://api.fitnesssyncer.com/api/notifications/claimId
FitnessSyncer ->> YourServers: OK
データ構造の概要
classDiagram
SyncItemItem ..> SyncItem
SyncItem ..> TaskType
Activity ..> GPSData
GPSData ..> Lap
Lap ..> Point
Point ..> LatLng
Glucose ..> GlucosePoint
Oxygen ..> OxygenPoint
Sleep ..> SleepEvent
Sleep ..> SleepPoint
Temperature ..> TemperaturePoint
ListSourceData ..> SyncItemListItem
ListSyncItems ..> SyncItem
SyncItemListItem ..> SyncItemLinks
SyncItem ..> SyncItemLinks
ListOfSourceData ..> SourceData
SourceDataItem ..> SourceData
ListDestinationTask ..> DestinationTask
DestinationTaskItem ..> DestinationTask
SyncDestination ..> TaskType
SyncDestination ..> ProviderConfig
SourceData ..> ProviderConfig
ProviderConfig ..> MapsProviderConfig
ProviderConfig ..> CsvProviderConfig
CsvProviderConfig ..> CsvColumnMapping
AlertDestination ..> TaskType
ListTaskType ..> TaskType
ProviderList ..> Provider
ProviderAuthentication ..> ProviderAuthenticationItem
ProviderAuthenticationItem ..> ProviderAuthenticationKey
SyncStatusResults ..> SyncStatus
Notification ..> Notifications
Notifications ..> NotificationItem
Notifications ..> NotificationErrorItem
DescriptionResults ..> Description
Description ..> TaskType
LeaderboardList ..> Leaderboard
LeaderboardItem ..> Leaderboard
AnnotationList ..> Annotation
Annotation ..> TaskType
class PowerZones{
+number: base
+number: maxZone1
+number: maxZone2
+number: maxZone3
+number: maxZone4
+number: maxZone5
+number: maxZone6
}
class Error{
+string: error
+string: error_description
+string: argument
+string: item
+string: id
+string: request_id
}
class UserPreferences{
+bool: autosync
+number: bmr
+number: birthdate
+number: age
+bool: canemail
+bool: distanceOverSteps
+bool: privateActivities
+number: heightInMeters
+bool: distanceMetric
+bool: nutritionMetric
+bool: weightMetric
+bool: glucoseMetric
+bool: temperatureCelsius
+bool: waterML
+bool: internationaltime
+bool: weekStartsOnMonday
+string: locale
+string: emailLocale
+string: numericLocale
+string: bodyshape
+string: sex
+string: timezone
+string: timezoneDisplayName
+string: displayname
+number: heartRateLevel1
+number: heartRateLevel2
+number: heartRateLevel3
+number: heartRateLevel4
+number: heartRateLevel5
+number: heartRateAge
+number: heartRateMax
+bool: pro
+bool: beta
+object: powerZones
+number: sleepRatio
+bool: graphSleepByWakeTime
+number: glucoseLow
+number: glucoseHigh
+number: glucosePercent
+bool: bandsBasedOnGlucoseRange
+string[]: hiddenReports
+string[]: hiddenNotebookTypes
}
class SyncItemItem{
+SyncItem: item;
}
class SyncItem{
+string: providerType
+string: device
+string: attribution
+boolean: requiredAttribution
+number: date
+string: itemId
+string: taskId
+string: apiVersion
+string: comment
+string[]: tags
+TaskType: type;
+SyncItemLinks: links;
}
class Activity{
+string: activity
+string: fitnessSyncerActivity
+string: title
+number: distanceKM
+number: duration
+number: calories
+number: bmr
+number: endDate
+number: steps
+number: avgHeartrate
+number: minHeartrate
+number: maxHeartrate
+number: restingHeartrate
+number: avgStressLevel
+number: minStressLevel
+number: maxStressLevel
+number: lowStressDurationSeconds
+number: mediumStressDurationSeconds
+number: highStressDurationSeconds
+number: vo2Max
+number: respiratoryRate
+number: mindfulMinutes
+bool: summary
+number: temperatureCelsius
+number: avgCoreTemperatureCelsius
+number: minCoreTemperatureCelsius
+number: maxCoreTemperatureCelsius
+number: repetitions
+number: weight
+number: rpe
+bool: manual
+number: floorsClimbed
+GPSData: gps;
}
class Allergy{
+string: allergy
+bool: isNegated
+string: treatment
+number: endDate
}
class GPSData{
+string: id
+string: title
+string: sport
+number: date
+Lap[]: lap;
}
class Lap{
+number: start
+number: millis
+number: totalMovingTimeMillis
+number: totalMovingTimeMillisCalc
+number: dist
+number: calories
+number: speed
+number: maxHeart
+number: avgHeart
+number: cadence
+string: sport
+number: notes
+number: hrr
+number: avgCoreTemperature
+number: minCoreTemperature
+number: maxCoreTemperature
+number: avgSmo2
+number: avgLeftRightBalance
+number: avgLeftTorqueEffectiveness
+number: avgRightTorqueEffectiveness
+number: avgLeftPedalSmoothness
+number: avgRightPedalSmoothness
+number: avgCombinedPedalSmoothness
+number: avgLeftPco
+number: avgRightPco
+Point[]: points;
}
class Point{
+number: time
+number: distance
+number: altitude
+number: heartRate
+number: speed
+number: cadence
+number: calories
+number[]: hrv
+number: hrv_sdnn
+number: power
+number: estimatedPower
+number: temperature
+number: coreTemperature
+number: skinTemperature
+number: coreDataQuality
+number: smo2
+number: thb
+number: leftRightBalance
+number: leftTorqueEffectiveness
+number: rightTorqueEffectiveness
+number: leftPedalSmoothness
+number: rightPedalSmoothness
+number: combinedPedalSmoothness
+number: leftPco
+number: rightPco
+number: steps
+number: torque
+number: locationAccuracy
+number: bearing
+number: tilt
+number: pedometerCadence
+number: crankCadence
+number: crankRevolutionDelta
+number: wheelCadence
+number: wheelRevolutionDelta
+bool: moving
+number: stanceTime
+number: legSpringStiffness
+number: stress
+number: formPower
+number: verticalOscilation
+number: vo2Max
+number: respiratoryRate
+LatLng: point;
}
class LatLng{
+number: lat
+number: lng
}
class BodyComposition{
+number: weight
+number: height
+number: fatFreeMass
+number: fatRatio
+number: boneMass
+number: bodyWaterKg
+number: extracellularWater
+number: intracellularWater
+number: visceralFat
+number: bmi
+number: muscleMass
+number: fatMassWeight
+number: bicep
+number: calf
+number: chest
+number: forearm
+number: hips
+number: neck
+number: thigh
+number: waist
+number: caliperChest
+number: caliperMidaxillary
+number: caliperBicep
+number: caliperAbdominal
+number: caliperSuprailiac
+number: caliperThigh
+number: caliperCalf
+number: caliperSubscapular
+number: caliperTricep
+number: caliperLowerBack
}
class BloodPressure{
+number: diastolic
+number: systolic
+number: pulse
+bool: arrhythmia
}
class Cholesterol{
+number: ldl
+number: hdl
+number: totalCholesterol
+number: triglyceride
}
class Condition{
+string: condition
+number: endDate
}
class CycleTracking{
+string: flowLevel
+number: basalBodyTempCelsius
+string: cervicalMucus
+string: ovulationTest
}
class ECG{
+number: durationMs
+number: sampleRateHz
+number[]: samples
+string: leadConfig
+string: classification
+string: classificationRaw
+string: inconclusiveReason
+number: avgHeartRateBpm
+string[]: symptoms
}
class Glucose{
+number: value
+bool: a1c
+string: measurementType
+string: measurementContext
+GlucosePoint[]: entries;
}
class GlucosePoint{
+number: time
+number: value
+string: comment
}
class Medication{
+string: medication
+number: dose
+string: doseUnit
+number: strength
+string: strengthUnit
+number: endDate
}
class Nutrition{
+string: food
+string: meal
+string: mealApproximation
+boolean: hasNutrition
+boolean: hasWater
+number: calories
+number: carbohydrates
+number: fat
+number: fiber
+number: protein
+number: sugar
+number: cholesterol
+number: saturatedFat
+number: sodium
+number: iron
+number: potassium
+number: vitaminA
+number: vitaminC
+number: vitaminD
+number: calcium
+number: glycemicLoad
+number: water
}
class Oxygen{
+number: spo2
+number: pulse
+OxygenPoint[]: entries;
}
class OxygenPoint{
+number: time
+number: spo2
+number: pulse
+string: comment
}
class Sleep{
+number: bedTime
+number: awakeTime
+number: sleepingMinutes
+number: awakenings
+number: efficiency
+number: settlingMinutes
+number: lightSleepMinutes
+number: l2SleepMinutes
+number: l3SleepMinutes
+number: deepSleepMinutes
+number: remSleepMinutes
+number: awakeMinutes
+number: avgHR
+number: avgRR
+number: hrvRmssdEvening
+number: hrvRmssdMorning
+SleepEvent[]: sleepEvents;
+SleepEvent[]: inferredSleepEvents;
+SleepPoint[]: sleepPoints;
}
class SleepEvent{
+string: type
+number: offsetMinutes
+number: durationMinutes
}
class SleepPoint{
+number: time
+number: heartRate
+number: respiratoryRate
+number: hrv_sdnn
}
class Temperature{
+number: temperature
+TemperaturePoint[]: entries;
}
class TemperaturePoint{
+number: time
+number: value
+string: comment
}
class Id{
+string: id
}
class HistoricSync{
+number: start
+number: end
+bool: email
}
class HistoricSyncStatus{
+string: status
+string: summary
+double: percentComplete
+number: queueTime
+number: startPeriod
+number: endPeriod
+number: currentStartPeriod
+number: currentEndPeriod
}
class ListSourceData{
+SyncItemListItem[]: items;
}
class ListSyncItems{
+SyncItem[]: items;
}
class SyncItemListItem{
+string: itemId
+number: date
+SyncItemLinks: links;
}
class SyncItemLinks{
+string: fit
+string: pwx
+string: tcx
+string: kml
+string: kmz
+string: csv
+string: gpx
}
class ListOfSourceData{
+SourceData[]: items;
}
class SourceDataItem{
+SourceData: item;
}
class SourceData{
+String: type
+string: id
+string: name
+string: context
+string: providerType
+string: connectionId
+bool: enabled
+bool: deprecated
+bool: ignoreDailyCalories
+string: lastError
+string: errorCode
+number: date
+string: identifier
+ProviderConfig: providerConfig
}
class ListDestinationTask{
+DestinationTask[]: items;
}
class DestinationTaskItem{
+DestinationTask: item;
}
class DestinationTask{
+string: type
+string: id
+string: name
+string: connectionId
+number: hour
+number: localHour
+string: lastError
+string: errorCode
+number: date
+bool: enabled
}
class SyncDestination{
+string: providerType
+string[]: skipDataFields
+bool: onlyIfNotOnDest
+string: identifier
+TaskType: taskType;
+ProviderConfig: providerConfig
}
class ProviderConfig{
+MapsProviderConfig: maps
+CsvProviderConfig: csv
}
class MapsProviderConfig{
+string: fileFormat
+string: filenameFormat
+string: path
}
class CsvProviderConfig{
+string: separator
+string: quote
+string: comment
+number: startingRow
+string: locale
+string: overrideTimezone
+bool: sumStepsPerDay
+bool: groupByDate
+bool: groupByMeal
+bool: sendSummaryData
+bool: appendToFile
+CsvColumnMapping[]: columns
}
class CsvColumnMapping{
+string: column
+number: index
+string: defaultValue
}
class EmailDestination{
+string: granularity
+string: granularityFriendly
+bool: removeDuplicates
+string: dataView
+string: fileFormat
+string: message
+string: otherEmail
}
class AlertDestination{
+string: alarmType
+number: alarmArgument
+string: reducer
+string: field
+string: comparison
+number: compareTo
+string: message
+string: otherEmail
+TaskType: taskType;
}
class ShoeDestination{
+number: shoes
+number: miles
+number: renotify
+number: sofar
+bool: useHoursInstead
+number: lastNotification
+number: LastNotificationMiles
}
class RefreshDestination{
}
class ReportPDFDestination{
+string: granularity
+string[]: reportIds
+string: message
+string: otherEmail
}
class ListPrintableReports{
+PrintableReport[]: items;
}
class PrintableReport{
+string: id
+string: name
}
class ListTaskType{
+TaskType[]: items;
}
class TaskType{
}
class ProviderList{
+Provider[]: providers;
}
class Provider{
+string: providerType
+string: name
+string: authentication
+bool: beta
+bool: notifications
+bool: cloudStorageMapsProvider
+bool: cloudStorageCsvProvider
+bool: reauthenticateAll
+bool: historicSync
+string[]: compatibleAuthentication
+string: faq
+string: notice
+string: noticeurl
+string: logo
+string: appurl
+bool: ActivityRead
+bool: ActivityWrite
+bool: AllergyRead
+bool: AllergyWrite
+bool: WeightRead
+bool: WeightWrite
+bool: BloodPressureRead
+bool: BloodPressureWrite
+bool: CholesterolRead
+bool: CholesterolWrite
+bool: ConditionRead
+bool: ConditionWrite
+bool: CycleTrackingRead
+bool: CycleTrackingWrite
+bool: ECGRead
+bool: ECGWrite
+bool: GlucoseRead
+bool: GlucoseWrite
+bool: MedicationRead
+bool: MedicationWrite
+bool: NutritionRead
+bool: NutritionWrite
+bool: OxygenRead
+bool: OxygenWrite
+bool: SleepRead
+bool: SleepWrite
+bool: TemperatureRead
+bool: TemperatureWrite
}
class Authentication{
+string: type
}
class AuthenticationUsernamePassword{
+string: username
+string: password
}
class AuthenticationUsernamePasswordKey{
+string: username
+string: password
+string: clientId
+string: clientSecret
}
class AuthenticationIdentifier{
+string: identifier
}
class AuthenticationOAuth{
+string: redirect
}
class AuthenticationOAuthReuse{
+string: id
}
class ProviderAuthentication{
+ProviderAuthenticationItem[]: providers;
}
class ProviderAuthenticationItem{
+string: name
+string: providerType
+ProviderAuthenticationKey[]: keys;
}
class ProviderAuthenticationKey{
+string: name
+string: id
}
class SyncStatusResults{
+SyncStatus[]: results;
}
class SyncStatus{
+boolean: success
+string: id
+string: type
+string: queueStatus
+string: status (deprecated, use queueStatus)
+string: state
+string: info
+number: upTo
+string: update
+string: errorCode
}
class Subscription{
+string: notificationKey
}
class Annotation{
+string: id
+string: dataField
+string: taskType
+number: date
+string: annotation
+number: created
+number: modified
}
class AnnotationList{
+Annotation[]: items;
}
class Notification{
+string: claim
+Notifications: notifications;
}
class Notifications{
+NotificationItem[]: items;
+NotificationErrorItem[]: errors;
}
class NotificationItem{
+string: notificationKey
+string: sourceId
+string: itemId
}
class NotificationErrorItem{
+string: notificationKey
+string: error
+string: providerType
+string: sourceId
+string: destinationId
}
class DescriptionResults{
+Description[]: results;
}
class Description{
+string: key
+string: description
+string: defaultReducer
+bool: isMeasuredType
+bool: metric
+bool: onlyReportSettings
+bool: postProcessed
+bool: isCumulative
+string: measurementType
+string: group
+string: groupDescription
+bool: requiresColumnMapping
+TaskType: taskType;
}
class LeaderboardList{
+Leaderboard[]: own;
+Leaderboard[]: pending;
+Leaderboard[]: accepted;
}
class LeaderboardUser{
+string: user
+string[]: users
+object: teams
}
class LeaderboardItem{
+Leaderboard: item;
}
class Leaderboard{
+string: id
+string: name
+string: description
+string: granularity
+number: userLimit
+bool: email
+bool: anyoneCanSignUp
+bool: chartLineGranularity
+bool: chartTableGranularity
+bool: chartClassicLeaderboard
+bool: relative
+number: groupGoal
+string[]: dataField
+number: startDate
+number: endDate
+string: scoringField
+object: scoringWeights
+string[]: scoringFields
+number: scoringDailyLimit
+string: rankBy
+bool: lowerWins
+bool: hideValues
+bool: teams
+string[]: teamNames
+bool: participantsChooseTeam
+bool: teamSum
+string[]: display
+bool: publicLeaderboard
}
class LeaderboardUserPreferences{
+bool: emailUpdate
}
class LeaderboardData{
+object: data
}
class DashboardRequest{
+bool: includeNotebook
+string[]: sourceIds
+integer[]: activityTypes
+number: customStart
+number: customEnd
+bool: removeDuplicates
+string: reducer
+string: finalReducer
+bool: treatNoDataAsZero
+bool: treatZeroAsNoData
+string: dataView
+string: granularity
+string: labeler
+string[]: dataFields
}
class SessionCreatedResponse{
+string: session
}
class DashboardResponse{
+bool: noData
+string[]: categories
+object[]: series
}
class ResearchUsersList{
+ResearchApiUser[]: users;
}
class ResearchApiUser{
+string: displayName
+string: accessToken
+string: refreshToken
+number: expires
}
%% non-generated
<<abstract>> SyncItem
SyncItem <|-- Activity
SyncItem <|-- Allergy
SyncItem <|-- BodyComposition
SyncItem <|-- BloodPressure
SyncItem <|-- Cholesterol
SyncItem <|-- Condition
SyncItem <|-- CycleTracking
SyncItem <|-- ECG
SyncItem <|-- Glucose
SyncItem <|-- Medication
SyncItem <|-- Oxygen
SyncItem <|-- Sleep
SyncItem <|-- Temperature
<<abstract>> DestinationTask
DestinationTask <|-- SyncDestination
DestinationTask <|-- EmailDestination
DestinationTask <|-- AlertDestination
DestinationTask <|-- ShoeDestination
DestinationTask <|-- RefreshDestination
DestinationTask <|-- ReportPDFDestination
<<abstract>> Authentication
Authentication <|-- AuthenticationUsernamePassword
Authentication <|-- AuthenticationUsernamePasswordKey
Authentication <|-- AuthenticationIdentifier
Authentication <|-- AuthenticationOAuth
Authentication <|-- AuthenticationOAuthReuse
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。