Akari Health MCP
Provides tools for retrieving health data stored in a SQLite database, such as the latest heart rate, SpO2, stress, and sleep records from a vivo watch.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Akari Health MCPwhat's my latest heart rate and SpO2?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Akari Pulse
English | 中文
Research notes and a working reference implementation for getting health data off a vivo WATCH GT (first-generation Bluetooth model, WA2456C, BlueOS 3.0) into a self-hosted backend and MCP server. The full chain — watch RPK → Cloudflare relay → drain into a local Node.js service → SQLite → MCP over stdio and Streamable HTTP — was verified end-to-end on a real device on 2026-08-12; the exact evidence is in docs/REAL_DEVICE_RESULTS.md.
Status: reference / research. Published as-is with no maintenance or support promise. Not affiliated with, endorsed by, or sponsored by vivo. Every endpoint, database ID, and token in the runnable code and configs has been replaced with a placeholder (REPLACE_WITH_* or pulse.example.com) — bring your own Cloudflare Worker, D1 database, VPS, and tunnel; nothing points at anyone else's infrastructure by default. Narrative documentation still names the domains the author's own deployment used (pulse.yoru-and-akari.dev, pulse-mcp.yoru-and-akari.dev) because they are part of the verified-deployment story on 2026-08-12.
Privacy note: this project handles real personal health data. Run your own relay, database, and MCP; do not point this at a third party's infrastructure or someone else's watch. RPK binaries are deliberately not shipped because they bake the private ingest token in — see artifacts/README.md.
The RPK sideloading path relies on the OrbitV community's work; without it the watch could not receive an unsigned developer build at all.
Akari Pulse is a private, inspectable health-data path for Yoru's first-generation Bluetooth vivo WATCH GT:
WA2456C / BlueOS 3.0
-> BlueOS health + sensor APIs
-> durable on-watch queue
-> HTTPS via the paired phone's Bluetooth internet proxy
-> Cloudflare Worker relay (D1 buffer)
-> drained into the Akari Health service (Node.js + SQLite)
-> independent Akari Health MCP (stdio / Streamable HTTP)
-> ChatGPT / Claude
(Android bridge retained in-tree as a fallback receiver only)The repository contains real watch, Android, service, and MCP implementations. It does not contain demo health values, vivo developer credentials, account tokens, or private signing keys. A host build is not reported as a real-watch success. Confirmed WA2456C / DPD2346C_A_1.54.5 observations and unresolved reboot boundaries are recorded separately from host evidence in REAL_DEVICE_RESULTS.md.
Current delivery status
Layer | Host result | Real-device result |
BlueOS watch app |
|
|
Watch health chain | one-test-per-launch harness |
|
Official BlueXlink RPC | public watch API and official Android AAR integrated | closed: |
Cloudflare relay | deployed at |
|
Akari Health service | authenticated routes tested against temporary databases |
|
Akari Health MCP | official SDK client lists and invokes all 14 tools |
|
Always-on VPS + remote MCP | deployed on the Tokyo VPS (systemd: service, 2-min drain timer, Streamable-HTTP MCP, Cloudflare Tunnel) |
|
Android bridge | debug APK built, unit-tested, linted, and signature-checked | fallback only; not on the active path |
See REAL_DEVICE_RESULTS.md and DIAGNOSTICS.md for the exact evidence and adaptive one-test-per-launch sequence.
Current artifact (0.1.5, device-verified 2026-08-12):
keeps every 0.1.4 button unchanged; tightens collect stats with the
ZERO_SENTINEL rule for heart_rate_today_max/min and raw-payload evidence in
every stat event; changes the sample_acquisition layer diag to a per-metric
breakdown message; adds one new one-per-launch button probe sleep that
records SLEEP_STATUS/SLEEP_UNIT/SLEEP_STAGES via getRecentSamples.
Device results: sentinel rule confirmed, SUM-stats conclusively empty-object
({}, no fields), sleep boundaries established (instantaneous SLEEP_STATUS only;
SLEEP_UNIT, SLEEP_STAGES, and health.getStatistic all unavailable),
NOT_APPLICABLE layer semantics live. VPS store: 94 records (67 PASS, 25 NO_DATA,
2 ERROR). See REAL_DEVICE_RESULTS.md for the
full acceptance results and DIAGNOSTICS.md for the
tightened contracts and device quirks.
Previous device-verified artifact (0.1.4, 2026-08-12): all three collect+sync
buttons passed end-to-end — real nonzero HR (62 bpm live, 61 resting), SpO2
(99 %), stress (35) landed in the VPS store and are queryable via the remote
MCP. Daily SUM statistics all returned empty (device capability boundary — the
outstanding question the 0.1.5 raw-payload dump resolved conclusively).
Final host-built deliverables (2026-08-11, watch 0.1.3 added 2026-08-12, watch 0.1.4 added 2026-08-12, watch 0.1.5 added 2026-08-12):
Binaries are not distributed in this repository (see artifacts/README.md); the table below is the historical hash record of the privately built and device-verified artifacts.
Artifact | Bytes | SHA-256 |
| 31,164,014 |
|
| 89,461 |
|
| 84,899 |
|
| 75,466 |
|
| 69,649 |
|
| 15,674 |
|
| 8,757 |
|
The Cloudflare relay is deployed from relay/ (Worker akari-pulse-relay, D1 akari-pulse-relay, custom domain pulse.yoru-and-akari.dev); its tokens live in Cloudflare secrets and the untracked relay/.secrets.local.
The machine-readable list, APK signer certificate digest, and vendored AAR digest are in SHA256SUMS.txt.
Related MCP server: Mi Fitness MCP
Repository
akari-pulse/
|-- watch/ BlueOS health collection, durable queue, HTTPS/RPC adapters, diagnostics UI
|-- relay/ Cloudflare Worker ingest buffer (pulse.yoru-and-akari.dev) and D1 schema
|-- android/ fallback bridge: Room inbox/outbox, official vivo RPC receiver, HTTP probe receiver
|-- server/ Node.js 24 HTTP service and SQLite persistence
|-- mcp/ independent MCP (stdio + Streamable HTTP) using the official TypeScript SDK
|-- deploy/ Tokyo VPS systemd units and runbook (always-on store + remote MCP)
|-- contracts/ strict shared event and batch schemas
|-- scripts/ install, start, smoke, relay-drain, and exact-tailnet-bind scripts
|-- docs/ architecture, research, diagnostics, testing, and real-device evidence
`-- artifacts/ built deliverables and SHA-256 manifestArchitecture choice
The production route is watch-direct HTTPS: @blueos.network.fetch POSTs the batch contract to the Cloudflare relay at pulse.yoru-and-akari.dev, which buffers in D1 and is drained into the local Akari Health service by scripts/drain-relay.mjs. vivo's official BlueXlink/device RPC pair was the original candidate and is now closed on this hardware: the real WA2456C fails at interconnect connection time with code=1001 interconnectfeature error, the official support table lists only vivo WATCH 3, and the required vivo appid/encryStr are not obtainable for this project. Evidence and classification live in RESEARCH.md; the Android bridge remains buildable as a fallback receiver. OrbitV is used for RPK sideloading only and is not treated as a generic bridge API.
Every transport shares one durable contract. A receiver acknowledges a watch batch only after durable storage (relay: D1 insert; Android: Room transaction), and the watch dequeues only after a matching batch_id plus exact accepted/duplicate counts. The relay is drained — rows deleted — only after the local service acknowledges the same batch, so no layer drops data it has not handed off.
The backend is a local Node.js 24 service backed by node:sqlite. The MCP calls that service rather than opening the database, exposes read-only raw-health tools plus non-destructive start/stop session metadata actions, and does not modify the existing Akari Surface Desktop MCP.
Details and evidence are in ARCHITECTURE.md and RESEARCH.md.
Prerequisites
Windows PowerShell 7 or Windows PowerShell 5.1.
Node.js 24 or newer for the service and MCP.
JDK 17 and Android SDK API 35 for rebuilding the Android app.
BlueOS Studio 2.x, including its bundled Node.js and
blueos-pack, for rebuilding the RPK.Optional: Tailscale for phone-to-Windows private-network access.
For official vivo RPC at runtime: a vivo developer
appid, intelligent-terminal SDK key (encryStr), vivo Health on the phone, and a package/signing-fingerprint pair accepted by the watch.
Install and verify the service/MCP
From the repository root:
.\scripts\install.ps1
.\scripts\verify-service.ps1Start the loopback service:
.\scripts\start-server.ps1To bind only the machine's current Tailscale IPv4, first provide a strong bearer token:
$env:AKARI_HEALTH_TOKEN = '<strong-random-token>'
.\scripts\start-server-tailnet.ps1The tailnet script reads the exact IPv4 from tailscale ip -4. It does not run tailscale up, alter grants, change Windows Firewall, or modify an existing Serve/Funnel configuration.
Start the independent MCP in another terminal:
$env:AKARI_HEALTH_URL = 'http://127.0.0.1:8787'
$env:AKARI_HEALTH_TOKEN = '<same-token-if-configured>'
.\scripts\start-mcp.ps1Ready-to-edit client examples are codex.example.toml and claude-desktop.example.json. Keep the bearer token in the local environment/config only; do not commit it.
Build and configure Android
The official public AAR is vendored at android/app/libs/device-rpc-1.0.0.17.aar with its SHA-256 sidecar. To rebuild, put only local machine values in the ignored android/local.properties:
sdk.dir=C\:\\Users\\<you>\\AppData\\Local\\Android\\Sdk
VIVO_RPC_APP_ID=<numeric-vivo-appid>If no app ID is available, omit the second line; the APK still builds and the UI truthfully reports official RPC as API_MISSING. Build and validate:
Set-Location .\android
.\gradlew.bat testDebugUnitTest assembleDebug lintDebug --no-daemon --max-workers=1
.\scripts\verify-device-rpc.ps1Install the resulting debug APK with Android Studio or:
adb install -r .\app\build\outputs\apk\debug\app-debug.apkIn the app, configure the Akari Health base URL/token. Enter encryStr in the secure runtime field only; Android Keystore encrypts it at rest. Start official vivo rpc only after the app ID and key exist. The session notification controls are explicitly best-effort: dispatch does not confirm watch execution or create the backend session.
The debug-only HTTP receiver permits cleartext for a controlled loopback/tailnet probe. A non-loopback listener requires a separate bridge token of at least 16 characters. Release builds reject cleartext service URLs.
Build and configure the watch
The watch app calls the current official modules directly:
@blueos.health.healthwithwatch.permission.READ_HEALTH_DATA;@blueos.hardware.sensor.sensorwithwatch.permission.STEP_COUNTER;@blueos.bluexlink.connectionManagerfor the production RPC candidate;@blueos.network.fetchfor the explicit HTTP probe.
Before a paired RPC build, set watch/src/config.js phonePackage to dev.akari.pulse.bridge and phoneSha256 to the SHA-256 signer fingerprint of the exact APK being installed. Rebuilding the APK with a different debug/developer certificate changes that fingerprint and requires rebuilding the RPK.
Use the build command documented in watch/README.md, then install the RPK through the current OrbitV sideload flow. The checked-in project never carries a watch signing private key. BlueOS Studio's debug builder may generate a local debug signature; a release RPK requires the operator's own developer certificate and key.
Since 0.1.3 the watch adapter defaults to http against your relay's /v1/health/batches endpoint with your ingest token compiled in via watch/src/config.js (placeholders pulse.example.com / REPLACE_WITH_YOUR_INGEST_TOKEN in this repository). Rotating that token requires wrangler secret put INGEST_TOKEN (or the REST equivalent) plus a watch rebuild. Pointing the adapter at the Android LAN listener instead is a fallback: set an address the physical watch can actually reach and the Android bridge token; 127.0.0.1:23102 is deliberately not claimed to map to the phone on a real watch.
Data and failure semantics
Every observation is one immutable event containing the producer timestamp, metric, source device, status, and optional real value/sample timestamp/callback delta/session/error. PASS requires a real value. Missing or failed measurements remain NO_DATA, DENIED, UNSUPPORTED, API_MISSING, or ERROR; no layer substitutes zero or a stale value.
Failures are attributed to watch_module_api, permission, sample_acquisition, watch_transport, phone_receive, phone_persistence, uplink, backend_ingest, database, or mcp_query. Follow DIAGNOSTICS.md from the first non-PASS layer.
Raw health records have no update/delete HTTP or MCP route. Session summaries may calculate baseline, peak, delta, latency-to-rise, and time-to-peak from real samples and timestamped events, but they state that temporal association does not establish causality.
Tests and artifacts
The complete reproducible verification record is TESTING.md. Built files and their checksums are under artifacts; use SHA256SUMS.txt rather than assuming similarly named local builds are identical.
Do not interpret an RPK/APK build, an RPC send callback, a simulator request, or /healthz as a physical-watch end-to-end pass. Only update REAL_DEVICE_RESULTS.md after capturing evidence from the named baseline without including tokens, SDK keys, serial numbers, MAC addresses, cookies, or account identifiers.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseBqualityBmaintenanceMCP server that provides local caching, sync, and tools for Zepp Life health data including steps, sleep, heart rate, workouts, and body measurements, supporting both file exports and cloud session access.109MIT
- AlicenseCqualityCmaintenanceMCP server for Mi Fitness cloud data. Provides a local SQLite-backed server to sync and query daily activity, heart rate, and body measurements.124MIT
- Alicense-qualityDmaintenanceMCP server that exposes Garmin Connect health and activity data (steps, sleep, stress, activities, etc.) via tools for querying, analysis, and visualization.Apache 2.0
- AlicenseAqualityBmaintenanceUnofficial MCP server bridging Garmin Connect to MCP clients and ChatGPT, providing tools to access health data, activities, and trends via a self-hosted API.11MIT
Related MCP Connectors
MCP server for Withings health data — sleep, activity, heart, and body metrics.
Self-hosted MCP gateway: turn any API, database or MCP server into AI connectors — no code.
Markdown-first MCP server for Notion API with 8 composite tools and 39 actions.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/yoruuuchan/akari-pulse'
If you have feedback or need assistance with the MCP directory API, please join our Discord server