Embed Wave Passport Bluetooth door unlock into your product. Native SDKs for engineers, a drop-in button for vibe coders, and an MCP server so your AI agent does the integration for you.
Add the Wave MCP server to your coding agent and say "add Wave door unlock." It scaffolds, validates, diagnoses, and tests the full flow — with no hardware.
{
"mcpServers": {
"wave": {
"command": "npx",
"args": ["-y", "@wave/mcp"],
"env": {
"WAVE_GATEWAY_URL": "https://app.wavepassport.com/api"
}
}
}
}
The whole SDK as agent-ingestible text.
Writes a working starter into your project.
Catches missing BLE permissions before you build.
Proves grant/deny end-to-end — no reader needed.
Checks your key + sites are correct.
Provisions your partner keys.
Prove the whole unlock flow in your terminal, no door required.
wave_register_app, or use the keys from your Wave dashboard. You get a wave_pub_* (in-app) and a wave_test_* (testing).POST /partner-auth/token with your test key returns a short-lived session token.POST /unlock-mock with a scenario, then read /unlock-stream — the exact result a real door would return.wave_scaffold web (runs today via Web Bluetooth) or a native SDK; embed your wave_pub_* key.A public demo test key. It only drives the mock (synthetic events on an isolated demo site) — it cannot open a real door. You'll get a real granted back from the live gateway.
BASE="https://app.wavepassport.com/api"
TEST_KEY="wave_test_9097529120bb93a92d058d65007fb555"
TOKEN=$(curl -s "$BASE/partner-auth/token" \
-H "Content-Type: application/json" -d "{\"key\":\"$TEST_KEY\"}" | jq -r .token)
curl -s "$BASE/unlock-mock" -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" -d '{"card_id":"10001","scenario":"granted"}'
curl -s "$BASE/unlock-stream" -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" -d '{"card_id":"10001"}'
# -> {"status":"granted","reason":"[mock] Access Granted"}
# try a denial: swap scenario for member_not_found | outside_hours |
# membership_expired | outstanding_balance
Five steps, hidden behind one SDK call.
SKBluTag / service 496B2C43-….0x01 + member number, write-without-response.Native background BLE. Swift Package + WaveUnlockButton.
Foreground-service BLE. AAR + Compose button.
One JS API bridging the native cores.
Dart plugin over the native cores.
Web Bluetooth, foreground-only. Runs today.
Base https://app.wavepassport.com/api — no API key header required; the gateway handles it.
| Endpoint | Auth | Returns |
|---|---|---|
POST /partner-auth/token | — | session token from a pub/test key |
POST /unlock-stream | Bearer token | {status, reason}, tenant-scoped |
POST /unlock-mock | Bearer test token | emits a synthetic event |
POST /partner-auth/register | admin key | partner keys (once) |
Full machine-readable spec: openapi.yaml · agent context: llms.txt / llms-full.txt