Skip to main content
Glama
README.md
# Now MCP

Now MCP synchronizes data known to an iOS app at its most recent sync to a
self-hosted server and exposes that data through Remote MCP. It does not claim
continuous background or real-time observation.

## Requirements

- Node.js 24 LTS and npm 11
- Xcode 26 or newer with an iOS 26 or newer Simulator runtime
- XcodeGen 2.44 or newer only when regenerating the committed Xcode project

## Server

```sh
npm install
npm run generate:tokens > .env
npm run dev
curl http://127.0.0.1:3000/healthz
```

`npm run generate:tokens` creates independent random `DEVICE_TOKEN` and
`MCP_TOKEN` values. Use `npm run generate:tokens -- --json` when a script needs
machine-readable output. Keep the generated `.env` private; production
supervisors should inject these values through their secret configuration.

The health endpoint returns HTTP 200 with `status: "ok"`. Run the full server
check with `npm run verify:server`.

Configuration keys are documented in `.env.example`. `npm run dev` and
`npm start` load `.env` automatically from the current package directory (and
fall back to the repository root when run from `server/`). Injected environment
variables take precedence. Never reuse the example token values.

Phase 2 adds the authenticated sync API. See the complete request and response
contract in [Sync API](docs/sync-api.md). A minimal status request is:

```sh
curl -H "Authorization: Bearer $DEVICE_TOKEN" \
  http://127.0.0.1:3000/api/sync/status
```

Phase 3 adds the MCP endpoint at `POST /mcp`. Configure a Streamable HTTP client
with `Authorization: Bearer <MCP_TOKEN>`; this credential must differ from the
device credential. See [MCP Server](docs/mcp.md) for tools and error semantics.

## iOS app

Open `ios/Now.xcodeproj`, select an iOS 26 or newer simulator, and run the `Now`
scheme. To regenerate the checked-in project after editing `ios/project.yml`:

```sh
cd ios
xcodegen generate
```

For a non-signing command-line build:

```sh
xcodebuild -project ios/Now.xcodeproj -scheme Now \
  -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' \
  -derivedDataPath /tmp/now-mcp-derived-data CODE_SIGNING_ALLOWED=NO build
```

## Documentation

- [Architecture](docs/architecture.md)
- [MCP Server](docs/mcp.md)
- [Platform, deployment, and secrets decision](docs/decisions/0001-platform-deployment-and-secrets.md)
- [Implementation phases](IMPLEMENTATION_PHASES.md)

## macOS client

The macOS command-line client is in `macos/`. Build it with `swift build` and
run it with `NOW_SERVER_URL`, `NOW_DEVICE_TOKEN`, and a stable `NOW_DEVICE_ID`.
It invokes `dayflow export --json` for historical app usage and uploads a
minute-sized sample for the current frontmost app. macOS privacy permissions
and the installed Dayflow CLI determine which rows are available.

Phases 0-5 are implemented: the server has a repeatable SQLite migration,
typed repositories, 30-day retention, an authenticated versioned batch sync API,
and seven authenticated read-only MCP tools. The iOS app now requests read-only
HealthKit access, persists an idempotent offline queue, uploads with the device
token, and presents Liquid Glass overview, detail, access, and sync controls.
The iOS project now contains an isolated screen-time feasibility collector. It
can request individual Family Controls authorization when the framework is
available and reports the remaining `DeviceActivityReport` extension boundary.
Apple does not provide a supported API for the containing app to retrieve and
serialize arbitrary historical per-app report rows, so screen-time upload is
not enabled. The collector's failure cannot block HealthKit synchronization.

The app also registers HealthKit background delivery and iOS BackgroundTasks
for opportunistic refresh and processing. See [iOS background sync](docs/ios-background-sync.md)
for the scheduling limits and the conditions under which an upload can be
deferred.