关于 FitnessSyncer
FitnessSyncer 为需要访问用户健康和健身数据的应用提供基于 OAuth 的 REST API,数据来自 50 多个来源。项目提供 OpenAPI 规范以支持代码生成,也提供 MCP 服务。
主要功能
- 01访问多个来源的健康和健身数据
- 02使用基于 OAuth 的 REST API
- 03根据 OpenAPI 规范生成应用代码
- 04使用 OAuth 授权和令牌刷新流程
适用场景
- 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 提供 API,帮助用户访问来自 50 多个来源的健康与健身数据。我们的 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
通知时序图
通知有两种模式。第一种是此处所示的推送通知:
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
第二种是此处所示的拉取通知:
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 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。