EN · RU
Iva is a self-hosted Telegram AI assistant with layered memory that turns your messages into an Obsidian-compatible vault. You talk, it files: voice notes, photos, forwarded posts and decisions become plain-markdown cards it actually remembers. Everything runs on your own server, with your keys and your data.
One command installs it:
curl -fsSL https://raw.githubusercontent.com/smixs/iva-agent/main/install.sh | bash
Why people run Iva
- "What did we agree with client X about the last shipment?" — found in seconds, months later.
- A five-minute voice note from the car → a task list, a draft email, a meeting card.
- "Make a quote from this price list, cut the discount by 2.5%, send it to the client" — a finished Google Doc, link in the chat.
The rest — for business owners, specialists, executives and everyday life: Use cases.
How it works
The bridge long-polls Telegram, so no public HTTPS, domain or webhook is needed. Iva runs as two systemd user services, two systemd watchdog timers and five in-process eve schedules — operations live in docs/deploy.md.
Wondering what you'd actually use an agent for? → 25+ real scenarios — business, work, everyday life.
Features
Voice, vision, memory, personal CRM, Google Workspace, skills — expand the full list
- Voice — voice, audio and video notes transcribed with Deepgram nova-3; auto-detects ru/uz/en.
- Vision — photos described by your provider's own vision model; no extra key, no extra bill.
- Rich replies — tables, checklists, collapsible blocks and formulas render natively in Telegram via Bot API 10.1 rich messages; plain formatting keeps its proven path, with a graceful fallback.
- Quiet update checks — once a day Iva checks for a newer stable release without spending model tokens. If one exists, Telegram offers Update or Later once; otherwise it says nothing.
- Layered memory — remembers across months, long after the chat window has scrolled away.
- Personal CRM — who your people are, what you agreed, when to follow up.
- Search by meaning — BM25 plus link-graph rerank, any language; optional vector mode with one key.
- Decision cards — what you chose, when and why; old versions stay in a dated History.
- Tasks & reminders — priorities, due dates and a morning digest.
- Web search — four pluggable providers: Tavily, Exa, Parallel or Brave.
- Google Workspace — Gmail, Calendar, Drive, Sheets, Docs and Tasks from chat via the
gwsCLI; installed for you, with a guided key setup right in the conversation. - Skills & MCP — drop one file to add a procedure or connect an MCP server; keys stay in
.env. - Personal Telegram — userbot (beta) — read and send from your own account, not just the bot; connect by chat (QR, no terminal). Rough and buggy — opt-in, at your own risk. A server-side anti-ban guardrail (FloodWait compliance + randomized pacing + circuit-breaker) is enforced, not just advised. Details.
- Safe to forward — forwarded text, captions and voice transcripts pass an injection screen before the model reads them. A flagged message or transcript reaches the model tagged as data rather than as an instruction; for media captions the screen runs but the tag does not travel with it yet.
- Token accounting — every model step is logged;
/usagereports it for free.
The Memory Tree
| Layer | What lives there | Path |
|---|---|---|
| 🍃 Leaves | the word-for-word transcript of each day, Iva's replies included | daily/YYYY-MM-DD.md |
| 🌿 Branches | summaries folded upward: day → week → month → year | summaries/daily/, weekly/, monthly/, yearly/ |
| 🪵 Trunk | CORE.md (≤1200 chars, in every prompt) + typed cards: contacts, projects, decisions, ideas, notes | CORE.md, cards/ |
- Every message lands verbatim in a daily markdown log — nothing is paraphrased on arrival.
- A nightly rollup at 04:00 distills day → week → month → year into schema-validated cards; facts that change get rewritten, not piled up.
- One core file,
CORE.md(≤1,200 chars), rides in every prompt — Iva knows you before it searches anything.
Full architecture and search internals: docs/memory.md.
A secretary inside Telegram
The bot is half of Telegram. The other half is your personal account: connect the userbot (beta, opt-in) and Iva works from it like a secretary — reads the group chats you never keep up with, folds them into summaries, catches the messages that actually need you, and replies as you.
- All of Telegram — groups, channels, unreads, search and the full history of your personal account.
- Onboarding in chat — tell the bot to connect your Telegram, scan a QR. No terminal.
- Anti-ban guardrail on the server — FloodWait compliance, a randomized delay after every send, and a circuit-breaker that pauses sending after three FloodWaits in 24 hours. It is enforced in the proxy rather than asked for in a prompt, and it wraps the three outbound calls that actually get accounts flagged: messages, files, forwards. Joins, invites, contact imports and reactions are not wrapped — those limits live in the skill file, which is a prompt.
- Read-only mode — one
.envswitch and Iva can read and search but physically cannot send.
[!WARNING] Automating a personal account is against Telegram's ToS and can get the account limited or banned. The userbot is opt-in, beta, and used at your own risk — reading is far safer than sending. Details: docs/userbot.md.
Security & privacy
Web pages, search results, voice transcripts, captions and the vision model's description of a picture reach the model only through a prompt-injection sanitizer. On a forwarded text message the same gate annotates the turn with a warning instead of filtering the text, and document bodies, userbot-read chats and agent-browser output are not screened at all. Everything that leaves through the Outbox passes a secret-redaction gate, and the user allowlist fails closed — an empty list answers nobody. Your memory is a private git repo you own; the honest boundary is that the model and transcription are cloud APIs you choose and pay for. Gate internals and the full boundary: docs/security.md.
Install
One command on any Ubuntu/Debian box — a fresh VPS or your own machine:
curl -fsSL https://raw.githubusercontent.com/smixs/iva-agent/main/install.sh | bash
- Get a bot token from @BotFather.
- Run the installer and answer its questions.
- Message your bot. The wizard picks your Telegram ID out of that message, finishes setup, and Iva confirms right in the chat that it's live.
Brand-new VPS, still logged in as root? Run bash <(curl -fsSL https://raw.githubusercontent.com/smixs/iva-agent/main/bootstrap.sh) first: it creates your sudo user (with lingering enabled), updates the box, and turns on a firewall, fail2ban and SSH hardening. It asks three things — a login, its password, and the timezone — and no SSH key. Then log in as that user with that password and run the installer above. Details: docs/install.md.
Install as a normal user, not as root — Iva's shell tool runs as whoever installed it. Headless installs take --skip-setup or --non-interactive. Prefer to read before you run? Fetch it with curl -fsSL https://raw.githubusercontent.com/smixs/iva-agent/main/install.sh -o install.sh, read it, then bash install.sh. Wizard walkthrough and an SSH primer for first-time VPS owners: docs/install.md.
The first minute
Three messages, and you can watch the memory work:
- Send a voice note about your day — anything, out loud. Then look in
daily/inside your vault on the server: your words are sitting there in plain markdown, dated, yours. No other assistant hands you the file. - Tell it something a colleague would remember:
Marina at Acme wants the revised quote by Friday — she never picks up the phone. - Ask for it back the way a person would:
how should I follow up with Marina?— the answer comes from the card Iva just wrote, not from the last few messages.
Then send a photo of a business card, or forward a long post and ask for the gist. /menu has the rest; the full list is in 25+ scenarios.
Install from a clone — build it yourself
git clone https://github.com/smixs/iva-agent.git ~/iva
cd ~/iva && bash install.sh
The installer reuses the existing checkout instead of re-cloning, keeps .env and the vault untouched, and installs the same dependencies. A fork or a branch works through variables read at startup: REPO_URL=…, BRANCH=…, INSTALL_DIR=… (defaults: this repo, main, ~/iva). Details: docs/install.md.
Providers & cost
Four model providers. Pick one and fill its block in .env:
| Provider | How you pay |
|---|---|
| OpenCode Go | API key, ~$10/mo ($5 first month) |
| Ollama Cloud | API key, ~$20/mo |
| OpenRouter | API key, pay-as-you-go, 300+ models |
| OpenAI (ChatGPT) | your Plus/Pro subscription, no API key |
Default model is deepseek-v4-pro, 131k context. On Go it runs about $14–15/mo all-in ($10 model + $4–5 VPS; the model's first month is $5), no markup; voice rides Deepgram's free starter credit. Model lists, limits and the search matrix: docs/providers.md.
Documentation
Use cases · Install · Configuration · Memory · Providers · Security · Deploy · Commands & CLI · Menu · Extending · Plugins · FAQ · Troubleshooting
Документация на русском → docs/ru/
What's New
v0.3.29 · 24.08.2026 — expand the latest releases
24.08.2026
v0.3.29
- Install no longer loses
agent-browserandgwson a fresh VPS: the verified download landed in amktempfile with no extension, npm 11 read that path as a package directory and died withENOTDIR … /package.json. The tarball now downloads into its own private directory under its published name (agent-browser-0.34.0.tgz,cli-0.22.5.tgz); the SHA-256 check still runs before anything reaches npm, and the directory is removed after (#197). - The agent reads its memory again:
10-map.mdtold the model to callread_filewithvault/summaries/daily/…, while the tool resolves a relative path against the vault root — the result wasvault/vault/…and ENOENT on every day summary. Every model-facing memory path is now vault-relative (CORE.md,summaries/daily/…,cards/…, the same shapememory_searchreturns), the nightly rollup hands the model absolute paths, and a guard test fails on any instruction that brings the prefix back (#199). - CORE.md is edited, not rewritten: the nightly rollup used to rewrite the whole file from the template, and a section the owner added by hand could vanish overnight. Now the rollup edits single lines only when the day produced a durable fact, preference, goal or lesson; a day with nothing new leaves the file byte-identical; sections outside the template stay verbatim. The «last day» pointer is written by code after the turn. If a
##heading present before the turn is gone after it, the previous file is restored and one Alert names the lost heading (#201). - Forwarded messages carry their origin: a repost used to reach the model as the owner's own words. The first line of the text now says
[forwarded from @user],[forwarded from channel Title (@name)]or[forwarded (hidden sender: Name)]— the same line in the context and in the daily log; source names are stripped of brackets and line breaks so a channel title cannot forge a label. The allowlist is untouched: access is still decided by the actual sender (#195). - Three contributor fixes to the update rails: recovery keeps the permissions it captured, so a group-writable tree (
664/775underumask 002) no longer fails everyiva updatewithgit recovery snapshot permissions do not matchandRollback: FAILED(#196); a failed update drops its recovery stash the way a successful one does, so stale stashes stop piling up ingit stash list(#200); the isolated build promotes.eve/agent-summary.jsonalongside.output, so/menu → Skillsno longer says «Skill list is unavailable» after every update (#198).
19.08.2026
v0.3.28
- The update cleans up after itself: the disk keeps the running version and one rollback, everything else goes. Before a build only the running version stays — the build takes the rollback slot, so the peak is two versions (~400 MB each), not three. In the finish, removing old versions is the first step, ahead of
npm i -g @googleworkspace/cli@latest, which downloads onto the same disk; a failed cleanup chore no longer cancels it.iva doctorremoves leftovers of interrupted builds and surplus versions by itself, under the update lock, and printsversions on disk: N (current …, rollback …) — X GB free; with an update running it saysversion cleanup skipped, with a corruptactive.jsonit reports and deletes nothing. The cleanup before a build starts working from the update after this one —iva updateruns on the installed CLI. Prompted by a test droplet with 8.7 GB that stalled on three copies ofnode_modules(#194). New troubleshooting section «Disk full during update», an honest disk line in install. - The promoted runtime carries every source tree: the stable runtime snapshot copied
agent/andscripts/by hand,packages/never reached it, and on an install with a non-empty custom layer the agent died with[UNRESOLVED_IMPORT]onagent/lib/data-dir.tsin a restart loop. One list now —RUNTIME_SOURCE_TREES— feeds both the snapshot and the replica smoke, the layout digest moves to v3 so a runtime staged withoutpackages/rebuilds itself, and a guard test resolves every import of those trees and fails on a tree the snapshot would leave behind (#192, #191). - Timezones come back in canonical spelling: Intl accepted
europe/moscowin.env, systemd rejectedOnCalendar=*-*-* 05:00:00 europe/moscow, and the nightly timer never came up. The validator now returns what Intl resolves —Europe/Moscow; aliases canonicalize (US/Pacific→America/Los_Angeles); property tests pin idempotence and insensitivity to case and padding (#190). - A vision model per provider: instead of a constant in code, a variable in
.enveach, blank meaning the provider default —OLLAMA_VISION_MODEL(gemma4:31b),OPENCODE_VISION_MODEL(qwen3.7-plus),OPENROUTER_VISION_MODEL(google/gemini-2.5-flash); Codex has none, the subscription is multimodal.iva configasks for the vision model right after the text model and writes it next to*_MODEL. The OpenCode Go default comes from live runs on 18.08:gpt-5.6-lunaanswers 400 to any image,minimax-m3wraps its answer in<think>insidecontent,qwen3.7-plusreturns a clean description with OCR in 4–6 seconds. - Three Telegram fixes: the Stop button only in private chats — its callback has been rejected in groups since the last release, and the button hung there dead. Messages buffered during a rolling update pass the inbound gate with the same warning to the model and the same
[security] inbound flaggedline as fresh ones — the verdict used to be ignored. Prose that looks like a code placeholder (the price is 50 dollars, tables with padded numbers) is no longer cut out of an HTML reply: the placeholder moved to the Private Use Area, such code points from outside are stripped first, and a seeded property test walks digits, space runs and code spans mixed in prose.
18.08.2026
v0.3.27
- MCP servers of a plugin, both transports:
streamable-httpandsseinmcp.jsonbecome a generated eve connectionmcp-<name>--<server>, and${VAR}in a header is filled at run time fromdata/custom/plugins/<name>.env, so no token is baked into a build.stdioruns as the systemd unitiva-mcp-<name>-<server>.servicebehind Iva's own MCP proxy (services/mcp-proxy/,@modelcontextprotocol/sdk): the agent reaches it over127.0.0.1:<port>/mcpwith a bearer, and the token lives indata/plugin-data/<name>/mcp-<server>.tokenat mode 0600. The server sees onlyPATH,HOME,PLUGIN_ROOT,PLUGIN_DATA, its own env frommcp.jsonand<name>.env— nothing of the agent's environment reaches it. A second switch joins the first:trusted, throughiva plugin trust | untrust, andaddprints the processes and asksStart these processes on this machine? [y/N](--trustanswers yes; a shell without a terminal answers no). Ports are handed out from 8730, once, and stay until the plugin is removed. Proven end to end against a real stdio server and a real client from the SDK, not fakes. - Plugin services:
sh.iva/services/<svc>/service.jsonwith{command,args,port}becomes the unitiva-plugin-<name>-<svc>.service— envIVA_SERVICE_PORT,IVA_DATA_DIR,PLUGIN_ROOTandPLUGIN_DATA, the service's own folder as the working directory, started only while the plugin is enabled and trusted.iva plugin updaterestarts the units of a plugin whose content changed,iva updatebrings them back right after the flip, andiva doctorlists the units, printsis-activeand callsGET /healthon every MCP proxy.sh.iva/is now two kinds: an eve Extension (sh.iva/package.json, built into a version) and services, which never rebuild one. - The default Marketplace is live —
smixs/iva-plugins: the list sits at github.com/smixs/iva-plugins and carries two plugins.traceis the Trace viewer: the schema of Iva with the path of a turn lit across it, the feed of turns, replay at ×1, ×2 and ×4, tiles for today, 7 and 14 days; it listens on loopback only, andiva trace openprints the ready ssh tunnel command.hellois the demo code plugin authors copy: one skill, one tool. Three commands to get there:iva plugin add trace,iva plugin trust trace,iva trace open. Checked live from the public list:list --available,add tracepinned to a sha,update,remove. - Plugin docs:
docs/plugins.md(Russian:docs/ru/plugins.md) — what a plugin is, how to install one (a folder,owner/repo[/subdir][@ref], a git URL or a name from a Marketplace), how enabled differs from trusted, whativa updatedoes to plugins, how to write your own (skills, an Extension undersh.iva/,mcp.json, services) and what you risk;SECURITY.mdgains a Plugins section. Also: theiva pluginCLI is split into modules with no command changed, and on a development checkoutaddandremoveof a code plugin stop promising a build that never happened and say plainly that no version was built there.
Full history — CHANGELOG.md.
Built on
eve 0.30.8, Vercel's agent framework, runs the agent; Node 24's built-in SQLite runs the search index — no separate database. Iva grew out of agent-second-brain and autograph — that story is in docs/memory.md.
Thanks
Iva gets better because people run it for real — contributors are welcome. Open an issue with what breaks, or send a PR. Everyone who already helped: docs/thanks.md.
License
MIT — take it, change it, run it on a hundred servers; just don't blame anyone if something breaks.