Mimir

Bots and chats

Bots #

You can run several bots. Each has its own name, role (persona and instructions), AI account and model, messaging-app tokens and tool allowlist. Create them with + in the sidebar; a template by job (Morning briefer, Follow-up keeper, Researcher, Page watcher, Weekly reviewer) fills in the role and offers the routines that job needs.

Click a bot in the sidebar to chat with it: you see your conversation with that bot only. This computer under Chats shows the built-in chat with all your bots together. Its page, with all of the above, is a right-click away (Settings), or the gear next to the bot picker under the chat.

Each bot is a small creature in its own colour, with a shape, eyes and a detail of its own. You choose it: a new bot starts as a random creature, and clicking its face (on the new-bot page, on its page later, or when naming your first bot) opens the picker: 12 colours, 4 shapes, 4 kinds of eyes and a detail (rosy cheeks, a sprout, an antenna, freckles, or nothing), each shown on the creature itself, plus Surprise me. Bots you never styled get a look from their id, so no two neighbouring bots look alike. It breathes, blinks and glances around; the one you're talking to follows your pointer and listens while you type. While it works its face shows what it's doing: thinking, searching, reading, writing, saving to memory, waiting for your OK. That shows in the sidebar too, whatever it's working on and wherever: a reply in Telegram, a routine, a task another bot handed it, a memory tidy-up, with the line under its name saying what ("Running a routine", "Searching memory…"). It's pleased when a reply lands, startled when you stop it, and upset when a messaging app fails or a run went wrong. On the bots' computer it watches you while you teach it by showing. Faces in history and lists only blink, so a long chat doesn't fidget; with reduced motion on, they keep still.

What's shared and what isn't:

Shared by all your bots Per bot
Memory (facts, preferences, tasks about you) Routines, conversations, AI sessions
Meetings Approvals and the run log
Saved logins, tool servers (each bot can switch servers off) Skills (unless shared with all bots), allowed tools

Export, import and duplicate #

Right-click a bot and choose Export… to save it as one file (<name>.mimir-bot.json). The file holds its name, look, role, AI account and model, allowed tools, accepted skills, repeating routines, your tool rules for the tools it may use, and the tool servers it uses (their config only). It never holds tokens, keys, saved logins, memories, chats or the run log. A tool server's env and header values are left empty (their names stay, so you know what to fill in), an argument that looks like a key is blanked, and a server URL loses its ?… part. A skill or routine that mentions a saved login or a key is left out. A password typed into the role or a tool server's settings isn't recognised, so check those before you share the file.

From a file… on the new-bot page (+ in the sidebar) reads one. Before anything is added you see the bot and everything in the file:

Nothing is added until you press Add bot. The bot gets "(copy)" after its name if you already have one by that name. If this Mimir can't use its AI account, it uses your first bot's account instead. Duplicate… in the right-click menu does the same with the bot's own file: an export, then an import on this computer that keeps the original's AI address.

Where you talk to them #

What a reply did, from the log #

Every reply is checked against its own run log. No model and no network requests are involved, and the reply itself is never changed.

Guests #

You can let someone else talk to your bots (a partner, a housemate): give them a pairing code and they pair their own chat with it. The first person to pair on each app is you; anyone else pairing after that is a guest, and Mimir tells them so when they pair. In a guest's chat the bots keep the guest's own memory, routines, reminders and files, and can read the web, search and make calendar links. They get none of yours: no email, calendar, meetings, saved logins, browser, tool servers or the bots' computer, and they can't make new bots. Guest chats say guest in the sidebar. The Guest / Yours button at the top of a chat changes it (say, for your own second account, or a chat someone else paired before Mimir told guests apart).

The household and family groups #

The Household (in the sidebar once it's used) is a set of memories and lists you share with people you choose: a shopping list, plans, who does what. Bots in your own direct chats and the built-in chat read it and can add to it (memory_store with household). A guest reads it once you press Add to household at the top of their chat. What a guest adds doesn't change anything yet: it's a suggestion in your Needs you ("Sam wants to add this to the household"), which you accept or dismiss. Your own additions go straight in. The household has a Memory tab like any chat (edit, pin, forget, history), but no conversation of its own.

Family group. In a group chat you paired (say a Telegram group with your partner and kids), Make family group lets everyone in your household talk to the bots there, not just you. People outside the household are still ignored, and only you can press Approve / Deny. Each message reaches the bot with who wrote it ("Sam: …"). A family group is a guest's chat whoever paired it (several people read it), so bots there get none of your email, calendar, meetings or logins. Your household is you plus each guest whose direct chat you added on the same app. (On Telegram, a bot in a group only sees every message if its privacy mode is off in @BotFather; otherwise talk to it with an @-mention.)

Pairing a messaging app #

Only chats you've paired can talk to your bot. Send it pair <CODE> (the code is on the bot's page, or printed by mimir serve), or on Telegram tap the t.me/<bot>?start=CODE link. A code pairs one chat, then the bot makes a new one (the page shows it), so a code someone else saw can't be reused; after 5 wrong codes, a chat's tries are ignored for an hour. The bot answers only the person who paired it: in a group, channel or server, other members' messages are ignored and only you can press its Approve / Deny buttons. (A group paired before this rule asks to be paired once more.) Only a person writing as themselves can pair it (not an anonymous group admin or a channel), and wrong codes count per person. A message, photo or voice note you forward to it counts as outside content, like a file (except on Signal, which doesn't mark forwards): it's someone else's words. Replies never show link previews (the apps fetch those on their own) and never ping @everyone, @here or roles. In Slack channels and Discord servers the bot answers only when @-mentioned; DMs always work. In a Slack channel it answers in a thread; in a Discord server, as a reply. A Discord thread under a paired channel counts as that channel (no second pairing), and the bot answers in the thread. Once you've @-mentioned it in a thread, it follows that thread for half an hour: your next replies there reach it without another @-mention (on Slack, the app needs the message.channels and message.groups events for this). Other people's replies in the thread are still ignored. (Mentions in a thread while Mimir was off aren't picked up later.)

Replying to one of its messages (swipe to reply on Telegram, Reply on Discord) tells the bot which message you mean, so "move this one to Friday" under item 3 of a briefing works. On Telegram, select part of the message first to quote just that part. In a Slack thread the bot is told the message that started the thread (this needs the history scopes: im:history, channels:history, groups:history); if someone other than you wrote it, it's read as outside content.

Replies stream on all three: a message appears as soon as the bot starts and is edited as it grows (Telegram private chats use Telegram's own streaming, with a native stop button). A message answered 10+ minutes late (the computer was asleep) starts with "Sorry for the slow reply". Messages sent while Mimir was off are picked up when it reconnects, up to a day back: Telegram keeps them for it; on Slack your DMs and @-mentions in paired channels (with the channels:history and groups:history scopes; not replies inside threads), on Discord your paired DMs and channels. A failed reply says why in plain words and what to do.

A bot does one thing at a time per chat; its other chats don't wait. A message sent while it's writing you a reply steers that reply: the draft says Changing course… and one reply answers both. With Claude the message goes into the run in progress (the answer so far stays in its session); the other AI accounts can't take a message mid-run, so that run stops and starts over with your new message added (anything it already did, like a saved memory, stays done). A message that arrives while a routine runs there, or with a photo or file, waits instead: typing at once, and after a few seconds one note: "Finishing a routine first…" or "Finishing my last reply first…". Its reply follows.

Chat commands: /memory, /why (what the last reply used: memories, skills, pages), /routines, /new, /stop (a bare "stop" works too while it's writing), /undo <n> (take back something it learned; see Memory), and /<skill> for each of the bot's skills (see Skills). Everything else is plain language.

Telegram topics (opt-in): with topics turned on in your private chat with the bot, switch on "Each topic is its own conversation" under Telegram on the bot's page. Each topic then has its own conversation, its own "read outside content" state and its own /new, and replies land in the topic you wrote in. Memories, routines and pairing stay shared by the whole chat, and routine results and approval cards arrive in the main thread. The app's chat view shows only the main thread. One reply is written at a time per chat, so /stop stops it whichever topic it's in. This is opt-in because Telegram is still changing the feature.

Bots answer in the language you write in. What Mimir itself says in the chat apps (pairing, approval cards and their buttons, errors, the digest, the weekly "what I learned", the Telegram "/" menu) follows Settings → Language: English or Dutch so far, by default the computer's language (a server's: its LANG). The app itself is still English.

Photos, voice notes and files #

Send a photo on Telegram, Slack or Discord (up to 4 at once there), or paste or drop one into the app's chat, and the bot looks at it with your own AI (big photos are shrunk to what each model accepts). Voice notes (Slack's audio clips, Discord's voice messages) are transcribed with your OpenAI-compatible key (Settings → AI keys) if you've added one, else by whisper.cpp where the bot runs (built into the desktop app; on a server, an installed whisper-cli), and echoed back ("🎙️ I heard: …"). Telegram's and Discord's voice notes need nothing else; Slack's audio clips need ffmpeg installed for whisper.cpp.

Send a PDF, a Word or Excel file (.docx, .xlsx) or a text file (.txt, .md, .csv, .json) on any of the apps, or drop or paste one into the app's chat (up to 20 MB), and the bot reads its text; the chat shows your message with the file's name. A file's text is outside content, like a web page: the bot won't follow instructions written in it, and anything that changes data asks you first for the rest of that conversation (Tools and safety). Excel files arrive sheet by sheet, a row per line; dates show as Excel's day numbers. A scanned PDF has no text, so its pages go to the bot as photos instead (the first 10; a page stored as a JPEG or plain grey/colour pixels, which is how scanners and scanning apps save them). Slack needs the files:read scope for this (see the hint when you add Slack). In a channel or server, only the files of the person who paired it are fetched.

Bots send files back too, with send_file: a file from the chat's workspace, or a screenshot of the bots' computer (the proof that a booking or a form went through). It arrives after the reply: a photo or document on Telegram, an upload in Slack (needs the files:write scope), an attachment on Discord (invite the bot with Attach Files), and in the app's chat, shown in place. In your own direct chat it just goes; in a group, channel or guest's chat it asks you first. At most 5 files with one reply.

Pinned cards #

A bot can keep a card pinned at the top of a chat in the app, for things you come back to: a shopping list, bills due, a project's state. It's quieter than a message. Ask ("add oat milk to my shopping list") and the bot rewrites the card with card_write; a routine can update one on each run instead of messaging you (Routines → Send it → Update a card). In Telegram, Slack or Discord the bot reads the card when you ask what's on it.

Cards hold only text, checklists (- [ ] item), tables and links. Mimir refuses HTML in them, and the app never shows a card as HTML anyway. Tick an item and it's saved as your edit: the card shows you as its last change, and the bot sees your ticks the next time it reads or rewrites the card. Each card folds away from its title, and the bin removes it. A chat holds up to 20 cards.

Incognito #

The mask button in the app's chat starts an incognito chat: the bot can't see or save memories, routines or meetings, and nothing is kept: no chat history, run log or tool log, and the AI CLIs are told not to save the session. The conversation exists only in the window. Photos are off there (they'd be saved to disk).

Handing tasks to another bot #

A bot can pass a task to another of your bots with the ask_bot tool ("ask Researcher to…"). It runs with that bot's own AI account, role, tools and permissions, against your shared memory, and the answer comes back to the bot you're talking to. A "chief of staff" is just a bot whose role says to coordinate. It goes one level deep (no chains), and approval cards come from the bot you're talking to. Turn it off per bot with the Hand tasks to other bots tool.

A long task doesn't have to hold up the chat: the bot can hand it over to report back later. It tells you it's handed over and carries on; the other bot works on its own, and when it's done the bot you were talking to gets its result and tells you, in the same chat (Telegram, Slack, Discord or the app). The run log shows the hand-off, the other bot's run and the report back together. Handed-over tasks are kept in the database: one not started yet runs after a restart, but one Mimir stopped in the middle isn't run again (it may have done half of something), and the bot says it didn't finish. A paused bot's handed-over tasks wait until the pause ends. In a rehearsal the bot waits for the answer instead.

A bot that makes a bot #

Ask a bot for a new one ("make me a bot for SEO on heymimir.app") and it drafts it with bot_create: a name and a role (its standing instructions). You see the whole role on the approval card, and nothing is made until you approve. The card never offers Always, so every new bot is your call; after a web page or file it's marked as such, since the role could be that page's words. The new bot uses the same AI account as the one that made it and gets at most the same tools (minus making bots itself); messaging apps and saved logins aren't passed on, so connect those on its page if you want them. Then chat with it in the app, or let the first bot hand it tasks: "check our SEO every Monday" becomes a routine that asks the new bot. Bots on another bot's task, and incognito chats, can't make bots.

When a bot can't help #