Metadata-Version: 2.4
Name: soma-mcp
Version: 0.2.1
Summary: MCP server exposing Soma's local SQLite sensor replica to AI agents
Project-URL: Homepage, https://github.com/dylan-buck/Soma
Project-URL: Repository, https://github.com/dylan-buck/Soma
Project-URL: Issues, https://github.com/dylan-buck/Soma/issues
License: MIT
License-File: LICENSE
Keywords: apple-health,health,healthkit,location,mcp,sensor
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: fastmcp<4,>=3.0
Description-Content-Type: text/markdown

# soma-mcp

MCP server that exposes Soma's local Mac SQLite sensor replica to AI agents.

Reads from a local SQLite replica maintained by the [Soma Mac app](https://github.com/dylan-buck/Soma). Designed for use with any MCP-compatible agent (Claude, ChatGPT, Cursor, etc.).

In the App Store-safe build, HealthKit-derived rows are not synced through
CloudKit, so health tools may return empty or stale data unless the local
replica was populated by a future compliant transport. Location and activity
tools continue to read replicated Mac data.

If Soma Mac has **Agent Access** turned off, every MCP tool returns a
permission error with instructions to re-enable access in the Mac app.
The local SQLite replica may still exist and continue syncing; the
toggle only controls whether `soma-mcp` is allowed to serve it.

## Consumer Setup

For end users, the Soma Mac app generates the correct MCP configuration automatically from the menu bar.

Until `soma-mcp` 0.2.1 is published on PyPI, use a local checkout with `uvx --from <path-to-soma-mcp> soma-mcp`. Do not use unpinned `uvx soma-mcp`; PyPI may resolve an older package.

## Development Quick Start

```bash
cd soma-mcp
uv run soma-mcp --db ~/.soma/sensors.db
```

## Agent Configuration

The Soma Mac app generates the correct config for your machine — open the menu bar and click **Copy Agent Config**. Manual setup is below.

### Claude Desktop

Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):

```json
{
  "mcpServers": {
    "soma": {
      "type": "stdio",
      "command": "uvx",
      "args": ["--from", "/path/to/Soma/soma-mcp", "soma-mcp", "--db", "~/.soma/sensors.db"]
    }
  }
}
```

### Claude Code

Use the CLI (recommended):

```bash
claude mcp add --transport stdio --scope user soma -- uvx --from /path/to/Soma/soma-mcp soma-mcp --db ~/.soma/sensors.db
```

Or edit `~/.claude.json` (user scope) / `.mcp.json` (project scope) with the same JSON shape as Claude Desktop above.

### Cursor

Add to `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (per-project):

```json
{
  "mcpServers": {
    "soma": {
      "type": "stdio",
      "command": "uvx",
      "args": ["--from", "/path/to/Soma/soma-mcp", "soma-mcp", "--db", "~/.soma/sensors.db"]
    }
  }
}
```

### VS Code / GitHub Copilot

Add to `.vscode/mcp.json`. Note the root key is `servers`, not `mcpServers`:

```json
{
  "servers": {
    "soma": {
      "type": "stdio",
      "command": "uvx",
      "args": ["--from", "/path/to/Soma/soma-mcp", "soma-mcp", "--db", "~/.soma/sensors.db"]
    }
  }
}
```

Tools are available in Copilot Agent mode (VS Code 1.99+).

### Codex CLI / Codex IDE

Codex shares config between the CLI and the IDE extension via `~/.codex/config.toml`. Add:

```toml
[mcp_servers.soma]
command = "uvx"
args = ["--from", "/path/to/Soma/soma-mcp", "soma-mcp", "--db", "~/.soma/sensors.db"]
```

Or use the CLI:

```bash
codex mcp add soma --command uvx --arg --from --arg /path/to/Soma/soma-mcp --arg soma-mcp --arg --db --arg ~/.soma/sensors.db
```

### OpenAI Agents SDK (Python)

The Agents SDK supports stdio MCP servers natively. Wire `uvx --from /path/to/Soma/soma-mcp soma-mcp --db ~/.soma/sensors.db` in via the SDK's `MCPServerStdio` class.

### ChatGPT (consumer)

ChatGPT's Developer Mode supports MCP but requires **remote HTTPS-hosted** servers (Streamable HTTP / SSE) — stdio is not supported. Soma is a local-only product by design, so direct ChatGPT integration would require a stdio→HTTP bridge (e.g. `mcp-proxy`) plus a tunnel (Cloudflare Tunnel, ngrok). This isn't a natively supported flow.

### Any other MCP client

The server uses stdio transport. Spawn `uvx --from <path-to-soma-mcp> soma-mcp --db <path>` as a subprocess.

## Tools

| Tool | Description |
|------|-------------|
| `get_user_location()` | Current GPS coordinates, address, and freshness metadata |
| `get_location_history(since?, limit?)` | Location time-series, newest first |
| `get_health_summary()` | Latest sample metrics + current activity + daily snapshots |
| `get_health_metric(metric, since?, limit?)` | Metric history with metric-aware routing |
| `get_health_metrics_list()` | Available metrics inventory with latest values |
| `get_user_activity()` | Current physical activity (stationary, walking, running, etc.) |
| `get_daily_summary(date?)` | Daily health rollup with cumulative and aggregate stats |
| `get_workouts(since?, limit?)` | Workout session history with type, duration, distance, calories |
| `query_sensor_data(sql, limit?)` | Read-only SQL against the local replica |

## Health Metrics (50 HealthKit metrics + activity + workouts)

**Hourly stats (17):** `steps`, `active_calories`, `basal_calories`, `distance_walking/cycling/swimming`, `workout_minutes`, `flights_climbed`, dietary metrics (energy, water, caffeine, protein, carbs, fat, fiber, sugar, sodium)

**Daily snapshots (2):** `stand_hours`, `sleep_duration`

**Sample events (20):** `heart_rate`, `resting_heart_rate`, `walking_heart_rate_avg`, `blood_oxygen`, `respiratory_rate`, body composition (mass, fat %, BMI, lean mass, height, waist), `hrv`, `vo2_max`, body/wrist temperature, blood pressure, `blood_glucose`, `environmental_audio`, `walking_steadiness`

**Category events (11):** `mindful_session`, cardiac events (low/high HR, irregular rhythm), symptoms (headache, fatigue, nausea), reproductive health (`menstrual_flow`, `cervical_mucus`, `ovulation_test`, `sexual_activity`)

**Activity:** `user_activity` (stationary, walking, running, automotive, cycling, unknown)

**Workouts:** Full `HKWorkout` records with type, duration, distance, energy

## Freshness Metadata

Every response includes freshness fields so agents can assess data recency:

- `recorded_at` — when the sensor reading was taken
- `updated_at` — when it was last applied to local SQLite
- `age_seconds` — how old the reading is
- `stale` — boolean based on metric-specific thresholds

## Requirements

- The [Soma iOS app](https://github.com/dylan-buck/Soma) collecting sensor data on your iPhone
- The [Soma Mac app](https://github.com/dylan-buck/Soma) replicating data to `~/.soma/sensors.db`
- Python 3.10+ (managed automatically by `uvx`)

## Changelog

### 0.2.1

Maintenance release with stricter MCP query parsing and compatibility fixes.

### 0.2.0

Response field names normalized to snake_case for consistency with SQLite column names and Python conventions:
- `ageSeconds` → `age_seconds`
- `activityLabel` → `activity_label`
- `latestMetrics` → `latest_metrics`

Response fields are snake_case to match SQLite column names and Python conventions.

Added MCP tool annotations (`readOnlyHint`, `idempotentHint`) and server instructions for agent discovery. SQL validation rejects mutating statements and disallowed SQLite escape hatches before execution.

### 0.1.0

Initial release with all 8 MCP tools.

## Development

```bash
cd soma-mcp
pip install -e .
soma-mcp --db ~/.soma/sensors.db
```
