Semantic Search MCP Servers Now Index Your Health Data: What Retrieval Adds, and What It Costs

A new class of MCP server does not just read your Apple Health export, it embeds it into a vector store and answers by similarity. Here is what that actually buys you, where it quietly breaks, and why the numbers still have to be computed rather than searched.

By MetricBridge · Updated 22 October 2026 · ~7 min read

AI-assisted, human reviewed. How we use AI

Quick answer. Semantic retrieval earns its keep when you ask about text you wrote (notes, symptoms, journal entries) or about a metric you cannot name exactly. It adds almost nothing to "what was my average HRV last week", because that answer is arithmetic on exact samples, not the nearest vector. The cost is a second pipeline, embeddings plus a vector store, that must be rebuilt every time your export refreshes, and it usually calls a cloud embedding model, which puts health data on someone else's server.

For a year the Apple Health MCP conversation was about plumbing: get the export out of the phone, put a server in front of it, let Claude or Cursor run SQL. The 2026 crop adds a semantic layer on top. Instead of only exposing query_health_data, these servers chunk your records, embed them, and retrieve by meaning. It sounds strictly better. It is better, for one specific kind of question, and worse for the one you probably care about most.

What "semantic search over health data" means in practice

Three pieces move in. First, a chunker that turns rows or notes into text units. Second, an embedding model that turns each unit into a vector. Third, a vector store that holds those vectors and returns the nearest ones to your question. The MCP server wraps retrieval as a tool, so the agent calls it like any other and reads back the top matches.

That is the same RAG pattern people use for documentation. Health data just makes it harder, because most of the payload is numeric time series rather than prose.

Three real projects doing it right now

This is not hypothetical. The pattern is already in public repos:

  • Barbaroso/apple-health-semantic-mcp reads your export.zip directly into DuckDB and adds what its author calls a "clinical semantic layer". Its stated reason is the interesting part: Apple Health is full of traps that produce confidently wrong answers, like percentages stored as fractions, sleep that changes date at midnight, and three apps recording the same metric. The semantic layer exists to stop silent misreadings, not to add fuzzy search.
  • Svetafo/health-agent is a self-hosted agent with long-term memory that stores health history in pgvector and runs in Telegram. It is built around remembering what matters across months of data.
  • Community RAG tutorials, like Beck Moulton's DuckDB plus Pinecone walkthrough on DEV, wire LangChain to an Apple Health export and vectorize it. Useful as a pattern, but the tutorial is explicit that this is a build-it-yourself pipeline.

Notice what each one had to add: a database (DuckDB or Postgres), an embedding step, and a vector index. The zero-dependency server that just reads a JSON file is a different shape entirely.

Why numbers are the wrong input for a vector search

Similarity is not arithmetic. An embedding turns "resting heart rate 61" and "resting heart rate 58" into vectors that sit close together, which is fine. It also turns "resting heart rate 61" and "resting heart rate 610" into vectors that are not far apart, because the model learned meaning, not magnitude. Ask a vector store for the average of your last 30 nights and it will hand you the nights that look most relevant. It will not add them up.

Concretely, suppose you ask: "What was my HRV average over the last 7 days?" A retrieval-only server returns the seven most similar HRV chunks. A compute layer returns one number: 49.6 ms, plus the date range and the exact samples behind it. Those are different answers, and only one of them is right.

Our own provenance card. On a seeded 30-day series, the on-device answer was a 7-day average of 49.6 ms and a 16.3% change against the prior 14 days, byte-identical across runs (sha256 f2e87621). Same input, same number, every time. That reproducibility is the point: a deterministic computation can be checked, a nearest-neighbour ranking cannot.

What retrieval genuinely adds

Do not write it off. Three jobs it does better than SQL:

  • Metric-name resolution. "That wrist thing at night" should land on resting heart rate or respiratory rate without you knowing the HealthKit identifier.
  • Free-text recall. Anything you wrote down (a symptom note, a training log, a workout name) is text, and text is exactly what embeddings are for.
  • Cross-metric discovery. "Find weeks where my sleep and my training load moved in opposite directions" is a search problem before it is a query problem.

The pattern that holds up is hybrid: retrieve to find the right metric and window, then compute the answer deterministically over the exact samples. Retrieval narrows. Computation decides.

What the semantic layer costs you

CostWhat it means in a health setup
Ingest timeEvery record has to be embedded once before the first query. A 190-metric export is a lot of rows.
Re-embeddingThe index is a snapshot. New samples mean re-embedding and re-upserting, or the agent answers from stale vectors.
DependenciesA vector store plus an embedding runtime. That is Docker, Python, or a hosted service where there used to be one Node file.
Where the embedding runsMost embedding models are hosted APIs. If you embed on the cloud, the text and values leave your machine for that call.
VerifiabilityA similarity score is not a citation. You cannot show the user which samples produced a ranking.

The last row is the one that matters for health data. If an answer cannot show its numbers, the user has no way to tell a real trend from a retrieval artifact.

The read-only alternative, and when to skip retrieval

The MetricBridge MCP server takes the other path. It is a zero-dependency Node server that reads your exported .health-cache.json on demand and exposes 16 read-only tools and 22 prompts, with zero runtime network calls. There is no index to go stale, no embedding call, and nothing to re-ingest: the file the app wrote is the file the agent reads. Every delivery is token-authenticated and logged.

On the app side, the same philosophy runs the other way. You ask a question and the answer is computed on the iPhone, rendered as a provenance card with the headline number, an inline chart, and a tappable strip showing the samples, date range, and computation. No health data leaves the phone, and there is no account.

So when is a semantic layer worth it? When your questions are mostly about text you wrote, or when you have months of narrative notes and no idea what to query. When your questions are numeric ("how did my sleep trend this month", "compare my HRV this week vs last"), retrieval is a detour. You want the numbers computed, and you want to see them.

Frequently asked questions

What does a semantic search MCP server add to an Apple Health setup?

It adds fuzzy matching and free-text recall. You can ask about a metric you cannot name exactly, or search health notes and journal text by meaning rather than keyword. It does not add arithmetic, so questions like "average HRV this week" still need a compute layer that aggregates exact samples.

Does embedding Apple Health data send it to the cloud?

Often, yes. Most embedding models that produce the vectors are hosted APIs, so the text and values you embed leave your machine for that call. You can embed locally with a small on-device model, but that adds a model download, more memory, and a slower ingest.

Why does my vector index go stale?

Because embeddings are computed once and frozen. Every time your export refreshes with new samples, the affected rows have to be re-embedded and re-upserted, or the index answers from an old snapshot. A read-only server that reads the file on demand has no such lag.

Can semantic search replace SQL over Apple Health data?

No. Semantic search ranks by similarity, and similarity is the wrong operator for numbers. Two HRV readings 40 ms apart can sit closer in vector space than a reading and its own weekly average. Use retrieval to find the right metric or note, then compute the number deterministically.

Doing this yourself? MetricBridge handles the export step: all 190 metrics as local JSON, with the open-source MCP server (GitHub).

Answers with their numbers, on your phone

One $24.99 unlock covers everything: 190 metrics as local JSON, the zero-dependency MCP server, on-device Ask with provenance cards, and the Weekly Brief. No subscription, no account, no server of ours in the path.

MetricBridge · Apple Health → your AI agent, privately. · Home · Privacy · Terms · Support