Integrations & enabling tools

Every capability is wired and tested; you switch each one on by adding its key/credential. Anything you skip degrades gracefully — Watari just says “that isn't configured yet”. Set values in .env (or answer the setup wizard).

How enabling works. Tools register at startup regardless; a tool becomes usable when its credential is present. So you can enable integrations one at a time, restart the brain, and they light up. Reads are frictionless; outward/destructive actions (send, delete, spend, lock) are always confirm-gated.

Telegram — read DMs, send, voice notes

Telegram has up to three roles; add only what you want:

a) Read your DMs (Telethon user client)

The Bot API can't read your DMs, so reading needs a one-time user login.

  1. Get an api_id + api_hash at my.telegram.org → API development tools.
  2. In .env:
    JARVIS_TELEGRAM_API_ID=...
    JARVIS_TELEGRAM_API_HASH=...
    JARVIS_TELEGRAM_PHONE=+15551234567   # your number, for the one-time sign-in
  3. One-time interactive login (creates the gitignored jarvis.session):
    uv run python bench/telegram_login.py   # enter the code Telegram texts you

Verify: “read me my last messages with Anna” (reads without marking them seen), “any unread Telegram?”. Tools: check_telegram, read_chat, mark_telegram.

b) DM Watari 24/7 (a dedicated bridge bot)

So you can text Watari from any device, give it its own bot — separate from any other bot you run (two pollers on one token steal each other's messages).

  1. In Telegram, message @BotFather/newbot → copy the token.
  2. JARVIS_TELEGRAM_BRIDGE_BOT_TOKEN=123456:ABC...

Now DM that bot — the same shared brain answers, so Telegram and voice share one memory. It can reply with a voice note for proactive nudges.

c) Send messages / GIFs (bot)

JARVIS_TELEGRAM_BOT_TOKEN=...        # can be the same as the bridge bot
JARVIS_TELEGRAM_DEFAULT_CHAT=...     # your chat id, the default recipient

Verify: “tell Anna I'll be five minutes late” (it confirms first). GIFs: “@gif panda”.

Music Room — stream music live into a group call

The Music Room plays a track live inside a Telegram group voice chat (via pytgcalls) — so you hear it on your phone when you join that call, not as a file. It needs the Telethon user login (a) above and the channels extra.

  1. Install the streaming deps:
    uv sync --extra channels
  2. Create a Telegram group (or use one you own) and start a voice chat in it.
  3. Get the group's id (a -100… number). Easiest: add @myidbot to the group, or read it from read_chat.
  4. In .env:
    JARVIS_TELEGRAM_MUSIC_ROOM_CHAT=-1001234567890

Then: “play lo-fi in the music room.” Watari joins that group's voice chat and streams the track into the call. Open the group's voice chat on your phone and join to hear it live. “stop the music” leaves the call. (Only the user account can stream into a call — a bot can't join voice chats.)

Prefer files on your phone instead? Set a personal playlist chat and use telegram_music: JARVIS_TELEGRAM_PLAYLIST_CHAT (a chat/group of audio tracks). local=true plays out loud on the desktop; default delivers to your phone Telegram to tap-and-play. Or just “play X” — default source is free YouTube Music (no account).

Web search & page reading

JARVIS_TAVILY_API_KEY=...     # web_search (answer + sources); free tier at tavily.com
# scrape_url uses Jina Reader — FREE + KEYLESS; JARVIS_JINA_API_KEY only raises rate limits

Verify: “what's the latest on X” (search), “open this URL and read the headline” (scrape). The visible local browser tool needs no key.

Notion — pages & the tasks dashboard

  1. Create an internal integration at notion.so/my-integrations → copy the secret (ntn_…). JARVIS_NOTION_TOKEN=ntn_…
  2. Share each page/database with the integration: open it → ••• → Connections → add your integration. (Notion is deny-by-default.)
  3. For the tasks dashboard, share your Tasks database and set its id (the 32-hex chunk in its URL):
    JARVIS_NOTION_TASKS_DB_ID=9c5a572c...bd68

Verify: “what's on my plate today?”, “add a task to call the bank Friday”, “mark groceries done”. A morning voice briefing reads overdue + today + this-week deadlines + recurring tasks. Tools: notion_tasks, notion_create_task / update / complete / delete, plus notion_search / read_page / append / comment / create_page.

Gmail + Google Calendar (one OAuth app)

  1. In Google Cloud Console: new project → enable Gmail API + Calendar API → OAuth consent screen (External, add yourself as a test user) → create an OAuth client (Web) with redirect http://127.0.0.1:8585/oauth2callback.
  2. JARVIS_GOOGLE_CLIENT_ID=...apps.googleusercontent.com
    JARVIS_GOOGLE_CLIENT_SECRET=...
  3. One-time login → paste the refresh token it prints:
    uv run python bench/google_login.py
    # -> JARVIS_GOOGLE_REFRESH_TOKEN=1//0g...

Verify: “read my unread email”, “what's on my calendar today?”. Sending mail + creating events are confirm-gated.

Home Assistant (smart home)

JARVIS_HA_URL=http://homeassistant.local:8123   # or the IP
JARVIS_HA_TOKEN=...   # Profile -> Security -> Long-lived access token

Verify: “is the front door locked?” (ha_state), “turn on the living-room lights” (ha_call). Locks, alarms, covers confirm first. Local-first — the brain talks straight to your HA box, nothing via the cloud.

Phone push (ntfy) & recurring reminders

JARVIS_NTFY_TOPIC=watari-<your-unguessable-string>
JARVIS_NTFY_SERVER=https://ntfy.sh

Install the ntfy app and subscribe to that topic. Reminders fire as a phone push when you're away from the mic. One-shot/at reminders even fire with the PC off (ntfy holds them). For recurring reminders with the PC off, deploy the always-on VPS ticker — see Production readiness.

Respond only to your voice (speaker biometrics)

uv sync --extra identity
uv run python bench/enroll_voice.py --script "to-read-script.md"   # ~3 min
# then in .env:
JARVIS_SPEAKER_ID_ENABLED=true

After enrolling, Watari obeys only your enrolled voice and ignores the TV or a guest. Until you enroll it answers anyone (so it never locks you out). Tune strictness with JARVIS_SPEAKER_THRESHOLD.

Cloud browser (optional)

JARVIS_BROWSERBASE_API_KEY=...
JARVIS_BROWSERBASE_PROJECT_ID=...
uv sync --extra browse

For headless browse_web. The local visible browser tool (Playwright) already works without this — uv sync --extra browse && playwright install chromium.

Optional: an external specialist fleet

For deep multi-step work Watari can delegate to an external OpenClaw gateway via a single team-lead agent. It ships fully disabled with no host baked in. Enable only if you run your own gateway:

JARVIS_OPENCLAW_GATEWAY_URL=http://<your-gateway>:3200
JARVIS_OPENCLAW_TOKEN=...
JARVIS_FLEET_AUTHORIZED=true   # opt-in; it reaches shared infra

Most users never need it — see Security.

No keys needed. The utilities belt (weather, crypto, stocks, FX, news, Wikipedia, dictionary, unit/currency convert), local music (YouTube Music), page scraping (Jina), reminders, the task queue, system control, and coding tools all work out of the box.