ultrahuman_mcp

ultrahuman_mcp

Exposes real-time health data from the Ultrahuman Ring to AI agents via the Model Context Protocol, providing optimized summaries with trend analysis and actionable insights.

Category
访问服务器

README

💍 Ultrahuman Ring MCP Server

A Model Context Protocol (MCP) server that exposes real-time health data from the Ultrahuman Ring to AI agents, LLMs, and agentic workflows. The server connects to the Ultrahuman Partner API, processes raw biometric data, and returns agent-optimized summaries with trend analysis, quality classifications, and actionable insights.


Table of Contents


Architecture Overview

┌─────────────────────┐       stdio        ┌──────────────────────────┐       HTTPS        ┌──────────────────────┐
│   LLM / AI Agent    │◄──────────────────►│  Ultrahuman MCP Server   │◄──────────────────►│  Ultrahuman API      │
│  (Claude, GPT, etc) │   MCP Protocol     │  (Node.js / TypeScript)  │   Partner API v1   │  partner.ultrahuman  │
└─────────────────────┘                    └──────────────────────────┘                    └──────────────────────┘
                                                     │
                                                     ▼
                                           ┌──────────────────────┐
                                           │  Smart Summarization │
                                           │  • Time filtering    │
                                           │  • Trend analysis    │
                                           │  • Quality scoring   │
                                           │  • Insight generation│
                                           └──────────────────────┘

The server sits between the LLM agent and the raw Ultrahuman API. It performs:

  1. Authentication — Injects the API key on every request.
  2. Smart Summarization — Converts raw time-series arrays into aggregated stats (avg, min, max, trend, count).
  3. Time Filtering — Supports last_minutes, start_time/end_time windows, and date selection.
  4. Quality Classification — Maps numeric scores to human-readable labels (excellent, good, fair, poor).
  5. Insight Generation — Produces contextual health insights from cross-metric analysis.

Prerequisites

Requirement Details
Node.js v18 or higher
Ultrahuman Ring With active subscription and data synced
API Key Obtain from Ultrahuman Vision

Quick Start

1. Install Dependencies

npm install

2. Configure API Key

cp .env.example .env

Edit .env:

ULTRAHUMAN_API_KEY=your_api_key_here

3. Build & Start

npm run build
npm start

The server communicates over stdio (standard input/output) using the MCP protocol.


MCP Client Configuration

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "ultrahuman": {
      "command": "node",
      "args": ["/absolute/path/to/ultrahuman_mcp/dist/index.js"],
      "env": {
        "ULTRAHUMAN_API_KEY": "your_api_key_here"
      }
    }
  }
}

Cursor / Windsurf / Other MCP Clients

Configure with:

  • Command: node
  • Args: ["/absolute/path/to/ultrahuman_mcp/dist/index.js"]
  • Environment: ULTRAHUMAN_API_KEY=your_key
  • Transport: stdio

Common Parameters

Most tools accept the following optional filter parameters:

Parameter Type Format Description
date string YYYY-MM-DD Target date. Defaults to today if omitted.
last_minutes number integer Restrict data to the last N minutes from now. Example: 30 returns data from the last 30 minutes.
start_time string HH:MM (24h) Start of a time window on the given date. Example: "09:00"
end_time string HH:MM (24h) End of a time window on the given date. Example: "17:00"
format string "summary" | "detailed" "summary" (default) returns aggregated statistics. "detailed" returns raw time-series arrays.

Note: last_minutes takes precedence over start_time/end_time. If neither is specified, the full day's data is used. The format parameter is only supported by get_heart_vitals.

Time Filtering Behavior

  • last_minutes=30 — Computes an epoch range from (now - 30min) to now and filters all time-series readings.
  • start_time="09:00" + end_time="17:00" — Filters readings to the 9 AM – 5 PM window on the specified date.
  • No time filter — Returns the complete day's data.
  • Empty result in time range — If no readings fall in the requested window, the summary will include a message field explaining when the latest available reading was, along with latest_available (ISO timestamp) and minutes_since_last_reading.

Tools Reference

1. get_health_summary

Best starting tool. Use this first to get a high-level overview of the user's health before drilling into specifics.

Returns a comprehensive health overview combining sleep, recovery, activity, vitals, and AI-generated insights.

Input Schema

{
  "date": "2025-01-27",          // optional, defaults to today
  "last_minutes": 60,            // optional
  "start_time": "06:00",        // optional
  "end_time": "22:00"           // optional
}

All parameters are optional. Calling with {} returns today's full summary.

Response Schema

{
  "date": "2025-01-27",
  "time_range": {                         // null if no time filter applied
    "start": "2025-01-27T06:00:00.000Z",
    "end": "2025-01-27T22:00:00.000Z"
  },
  "scores": {
    "sleep": 82,                          // 0–100, null if unavailable
    "recovery": 75,                       // 0–100, null if unavailable
    "activity": 6.5                       // movement index, null if unavailable
  },
  "vitals": {
    "resting_hr": 58,                     // BPM, null if unavailable
    "avg_hrv": 45,                        // ms, null if unavailable
    "avg_spo2": 97.2,                     // %, null if unavailable
    "body_temp": 36.5                     // °C, null if unavailable
  },
  "activity": {
    "total_steps": 8432,
    "active_minutes": 45,                 // null if unavailable
    "vo2_max": 42.3                       // ml/kg/min, null if unavailable
  },
  "sleep": {
    "total_hours": 7.2,                   // null if unavailable
    "efficiency": 88,                     // %, null if unavailable
    "quality": "good"                     // "excellent" | "good" | "fair" | "poor"
  },
  "insights": [
    "Excellent sleep quality last night",
    "Body is well recovered and ready for activity",
    "Great job! Step goal achieved"
  ]
}

Insight Generation Rules

Condition Insight
Sleep score ≥ 80 "Excellent sleep quality last night"
Sleep score < 60 "Sleep quality could be improved"
Recovery score ≥ 80 "Body is well recovered and ready for activity"
Recovery score < 50 "Consider lighter activity today for recovery"
Steps ≥ 10,000 "Great job! Step goal achieved"
Steps < 3,000 "Consider increasing movement today"
Heart rate trend = rising "Heart rate trending upward"

2. get_heart_vitals

Returns heart rate, HRV (heart rate variability), and SpO2 (blood oxygen) metrics. Supports both summary and detailed output formats.

Input Schema

{
  "date": "2025-01-27",          // optional
  "last_minutes": 30,            // optional
  "start_time": "09:00",        // optional
  "end_time": "17:00",          // optional
  "format": "summary"           // optional: "summary" (default) | "detailed"
}

Response Schema — Summary (default)

{
  "heart_rate": {
    "count": 482,
    "avg": 72.3,
    "min": 54,
    "max": 132,
    "latest": 68,
    "trend": "stable",              // "rising" | "falling" | "stable"
    "time_range": {
      "start": "2025-01-27T00:05:00.000Z",
      "end": "2025-01-27T23:55:00.000Z"
    },
    "resting_hr": 56                // from night/sleep RHR, null if unavailable
  },
  "hrv": {
    "count": 240,
    "avg": 42.8,
    "min": 18,
    "max": 89,
    "latest": 45,
    "trend": "rising",
    "time_range": { "start": "...", "end": "..." },
    "avg_sleep_hrv": 52             // null if unavailable
  },
  "spo2": {
    "count": 120,
    "avg": 97.1,
    "min": 94,
    "max": 99,
    "latest": 97,
    "trend": "stable",
    "time_range": { "start": "...", "end": "..." }
  }
}

Response Schema — Detailed (format: "detailed")

{
  "hr": [
    { "value": 72, "timestamp": 1706313600 },
    { "value": 68, "timestamp": 1706313900 }
  ],
  "hrv": [
    { "value": 45, "timestamp": 1706313600 }
  ],
  "spo2": [
    { "value": 97, "timestamp": 1706313600 }
  ],
  "night_rhr": 56,
  "sleep_rhr": 54,
  "avg_sleep_hrv": 52
}

Trend Calculation

Trend is determined by comparing the average of the first third of readings to the average of the last third:

  • Rising: Last third avg is >5% higher than first third avg
  • Falling: Last third avg is >5% lower than first third avg
  • Stable: Within ±5%

3. get_sleep_analysis

Returns comprehensive sleep metrics for a given night. Sleep data is a nightly aggregate — time filters (last_minutes, start_time, end_time) are not applicable.

Input Schema

{
  "date": "2025-01-27"           // optional, defaults to today
}

Response Schema

{
  "sleep_score": 82,                       // 0–100, null if no data
  "total_sleep_hours": 7.2,               // decimal hours, null if no data
  "sleep_efficiency_percent": 88,          // %, null if no data
  "time_in_bed_hours": 8.1,              // decimal hours, null if no data
  "rem_sleep_hours": 1.8,                // decimal hours, null if no data
  "deep_sleep_hours": 1.5,               // decimal hours, null if no data
  "light_sleep_hours": 3.9,             // decimal hours, null if no data
  "restorative_sleep_percent": 42,        // %, null if no data
  "full_sleep_cycles": 4,                // integer count, null if no data
  "tosses_and_turns": 12,                // integer count, null if no data
  "morning_alertness_minutes": 15,        // minutes, null if no data
  "quality": "good"                       // "excellent" | "good" | "fair" | "poor"
}

Quality Classification

Sleep Score Quality
≥ 85 "excellent"
70 – 84 "good"
50 – 69 "fair"
< 50 "poor"

4. get_activity_data

Returns activity and movement metrics including step counts, active minutes, and fitness indicators.

Input Schema

{
  "date": "2025-01-27",          // optional
  "last_minutes": 60,            // optional
  "start_time": "06:00",        // optional
  "end_time": "22:00"           // optional
}

Response Schema

{
  "total_steps": 8432,
  "steps_trend": {                           // TimeSeriesSummary of step readings
    "count": 96,
    "avg": 87.8,
    "min": 0,
    "max": 520,
    "latest": 42,
    "trend": "falling",
    "time_range": { "start": "...", "end": "..." }
  },
  "active_minutes": 45,                     // null if unavailable
  "movement_index": 6.5,                    // null if unavailable
  "vo2_max": 42.3,                          // ml/kg/min, null if unavailable
  "activity_level": "active"                // classification (see table below)
}

Activity Level Classification

Total Steps Level
≥ 12,000 "very_active"
8,000 – 11,999 "active"
5,000 – 7,999 "moderate"
< 5,000 "sedentary"

Note: When a time filter is applied, total_steps represents the sum of steps within that window only. Activity level classification still applies to the filtered total.


5. get_recovery_score

Returns recovery status indicating the body's readiness for physical activity. Recovery data is a daily aggregate — time filters are not applicable.

Input Schema

{
  "date": "2025-01-27"           // optional, defaults to today
}

Response Schema

{
  "recovery_score": 75,                    // 0–100, null if no data
  "recovery_index": 75,                   // same as recovery_score
  "status": "good"                         // "excellent" | "good" | "fair" | "poor"
}

Recovery Status Classification

Recovery Score Status
≥ 80 "excellent"
60 – 79 "good"
40 – 59 "fair"
< 40 "poor"

6. get_temperature_data

Returns body temperature metrics including skin temperature readings, baseline deviation, and average body temperature. Useful for detecting illness, stress, or menstrual cycle patterns.

Input Schema

{
  "date": "2025-01-27",          // optional
  "last_minutes": 60,            // optional
  "start_time": "22:00",        // optional
  "end_time": "06:00"           // optional
}

Response Schema

{
  "readings": {                             // TimeSeriesSummary of temperature readings
    "count": 240,
    "avg": 33.2,                            // °C (skin temperature)
    "min": 31.8,
    "max": 34.5,
    "latest": 33.0,
    "trend": "stable",
    "time_range": { "start": "...", "end": "..." }
  },
  "temperature_deviation": 0.3,            // °C deviation from baseline, null if unavailable
  "average_body_temperature": 36.5          // °C, null if unavailable
}

7. get_daily_metrics

Raw data tool. Returns the complete, unprocessed API response from the Ultrahuman Partner API. Use this only when you need access to metric types not covered by the other tools, or when you need the original API structure.

Input Schema

{
  "date": "2025-01-27",          // optional, defaults to today
  "start_date": "2025-01-20",   // optional, for date range queries
  "end_date": "2025-01-27"      // optional, for date range queries
}

Note: Use either date (single day) OR start_date + end_date (range). If none are provided, defaults to today.

Response Schema

Returns the raw Ultrahuman API response:

{
  "status": "success",
  "error": null,
  "data": {
    "metrics": {
      "2025-01-27": [
        {
          "type": "hr",
          "object": {
            "values": [
              { "value": 72, "timestamp": 1706313600 }
            ]
          }
        },
        {
          "type": "hrv",
          "object": { "..." }
        },
        {
          "type": "sleep",
          "object": { "..." }
        }
      ]
    }
  }
}

Known metric types in the raw response: hr, hrv, spo2, night_rhr, sleep_rhr, avg_sleep_hrv, sleep, steps, movement_index, active_minutes, vo2_max, recovery_index, temp.


Tool Selection Guide

Use this decision tree to pick the right tool:

User Intent Recommended Tool
"How am I doing today?" / general health check get_health_summary
"What's my heart rate?" / "How's my HRV?" / "Check my SpO2" get_heart_vitals
"How did I sleep?" / "Sleep quality?" get_sleep_analysis
"How many steps?" / "Am I active enough?" get_activity_data
"Am I recovered?" / "Ready for a workout?" get_recovery_score
"What's my body temperature?" / "Am I running a fever?" get_temperature_data
Need raw/unprocessed data or unsupported metric types get_daily_metrics

Recommended Agent Workflow

  1. Start with get_health_summary to get the big picture.
  2. Drill into specific tools based on what the user asks about or what the insights suggest.
  3. Use time filters (last_minutes, start_time/end_time) to narrow down to relevant windows.
  4. Use format: "detailed" on get_heart_vitals only when the user wants to see individual readings or plot data.
  5. Fall back to get_daily_metrics only when none of the specialized tools cover the requested data.

Response Conventions

TimeSeriesSummary Object

Many tools return a TimeSeriesSummary object for time-series metrics. Its shape is:

{
  "count": 482,                // number of data points
  "avg": 72.3,                 // arithmetic mean
  "min": 54,                   // minimum value
  "max": 132,                  // maximum value
  "latest": 68,                // most recent reading, null if no data
  "trend": "stable",           // "rising" | "falling" | "stable"
  "time_range": {
    "start": "ISO-8601",       // timestamp of earliest reading
    "end": "ISO-8601"          // timestamp of latest reading
  },
  // Only present when no data in requested time range:
  "message": "No data in requested time range. Latest reading was 45 minutes ago.",
  "latest_available": "ISO-8601",
  "minutes_since_last_reading": 45
}

Null Values

All metric fields may return null when:

  • The ring wasn't worn during the relevant period
  • Data hasn't synced yet
  • The metric isn't available for this day

Error Responses

On failure, tools return:

{
  "error": "Description of what went wrong"
}

Common errors:

  • "API request failed: 401 Unauthorized" — Invalid or expired API key
  • "API request failed: 429 Too Many Requests" — Rate limit hit
  • "Unknown tool: <name>" — Requested a tool that doesn't exist

Scoring & Classification Thresholds

Sleep Quality

Score Range Classification
85–100 excellent
70–84 good
50–69 fair
0–49 poor

Recovery Status

Score Range Classification
80–100 excellent
60–79 good
40–59 fair
0–39 poor

Activity Level

Step Count Classification
≥ 12,000 very_active
8,000–11,999 active
5,000–7,999 moderate
< 5,000 sedentary

Heart Rate Trend

Metric Threshold
Rising Last third avg > first third avg by >5%
Falling Last third avg < first third avg by >5%
Stable Within ±5%

Example Agent Conversations

Quick Health Check

User: "How am I doing today?"

Agent calls: get_health_summary({})
→ Reviews scores, vitals, and insights
→ "Your sleep was good at 82/100 with 7.2 hours. Recovery is at 75 — you're in good shape for moderate activity. You've taken 8,432 steps so far. Your resting heart rate is 58 bpm, which is normal."

Morning Routine Check

User: "How was my sleep and am I ready for a run?"

Agent calls: get_sleep_analysis({})   +   get_recovery_score({})
→ "You slept 7.2 hours with 88% efficiency — quality is 'good'. Your recovery score is 75/100 (good), so you're ready for a run, but maybe not an intense sprint session."

Real-Time Heart Monitoring

User: "What's my heart rate been like in the last hour?"

Agent calls: get_heart_vitals({ "last_minutes": 60 })
→ "Over the last 60 minutes, your heart rate averaged 78 bpm (range 65–95). Trend is stable. HRV avg is 38ms."

Post-Workout Analysis

User: "How was my heart rate during my workout from 6 to 7 PM?"

Agent calls: get_heart_vitals({ "start_time": "18:00", "end_time": "19:00", "format": "detailed" })
→ Returns individual HR, HRV, and SpO2 readings with timestamps for the workout window.

Historical Check

User: "Compare my recovery yesterday vs today"

Agent calls: get_recovery_score({ "date": "2025-01-26" })   +   get_recovery_score({})
→ "Yesterday your recovery was 62 (good), today it's 75 (good) — trending upward. You're more recovered today."

Temperature Concern

User: "I feel unwell, is my temperature elevated?"

Agent calls: get_temperature_data({})
→ "Your skin temperature deviation from baseline is +0.8°C, which is higher than normal. Average body temperature is 37.1°C. You may want to monitor this."

Project Structure

ultrahuman_mcp/
├── src/
│   ├── index.ts                 # MCP server — tool definitions & request routing
│   ├── ultrahuman-client.ts     # API client — data fetching, filtering, summarization
│   └── types.ts                 # TypeScript interfaces for API responses
├── dist/                        # Compiled JavaScript (generated by `npm run build`)
├── package.json                 # Dependencies & scripts
├── tsconfig.json                # TypeScript configuration
├── .env                         # Your API key (gitignored)
├── .env.example                 # API key template
├── .gitignore
└── README.md

License

MIT License


Links

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选