{"slug": "show-hn-open-source-grok-bot-alternative", "title": "Show HN: Open-source Grok Bot alternative", "summary": "A developer has released an open-source desktop app that lets users chat with multiple LLM agents that communicate with each other asynchronously, featuring a Slack-like interface and support for OpenAI-compatible endpoints. The app runs locally, with only user and agent messages sent to the configured endpoint, and includes tools for agent memory, scheduling, and optional computer control via E2B. The project is available via pnpm and supports custom models and endpoints, including local servers like llama.cpp.", "body_md": "A local desktop app where you talk to LLM agents and those agents talk to each other. Slack-shaped: a rail of agents on the left, a conversation on the right, and an activity view showing every message they send between themselves.\n\nAsk the Manager for something. It works out who on its team can help, sends them each a message, and they think at once rather than in turn. You watch it happen: who is typing, who wrote to whom, what the group has spent so far. When they are done you get one answer, not a transcript to wade through.\n\nEverything runs on your machine. The only thing that leaves is what you and your agents type, sent to whichever OpenAI-compatible endpoint you point it at.\n\nSixteen of them, one per agent. They are not decoration: an agent's character is how you find it in a rail of eight, and it is doing something at any moment. It blinks and glances around while idle, looks toward whoever it is writing to, winds up and throws when a message goes out, and gets visibly hit when one arrives. Watching the rail tells you what your crew is doing before you have read a single word of it.\n\n```\npnpm install\npnpm app          # dev, with hot reload\npnpm app:build    # an installable bundle\n```\n\nOpen Settings, put in your name and an OpenRouter key, and press **Test\nconnection**, which checks the endpoint, the key and the model separately. You\nfind out which one is wrong rather than watching an agent sit silent.\n\nThe endpoint is configurable, so a local llama.cpp or LM Studio server works\nwithout a code change. Point **Inference endpoint** at it and leave the key\nblank if it does not need one.\n\n- On first run, choose\n**Add a starter crew**: Manager, Researcher, Critic and Scribe. - Open\n**Manager** and send`Introduce yourself to your team.`\n\n- Watch the rail. Each message between agents draws a pulse travelling between them in the sender's colour.\n- Open any other agent to see what it received, or the activity view to see the whole thing as a sequence diagram, one board per run.\n\nMessaging is asynchronous throughout. Manager does not wait for Researcher; all four peers think at once.\n\nEight tools, described to the model and visible in the transcript when used:\n\n| Tool | What it does |\n|---|---|\n`directory` |\nLists the other agents in its group, with their skills |\n`send_message` |\nQueues a message to one or more of them, and returns |\n`update_notes` |\nRewrites its own memory, which it is shown every turn |\n`schedule` |\nSets or cancels its own routines |\n`run_command` |\nA shell on its own machine |\n`open_on_desktop` |\nLaunches something on that machine's screen |\n`use_screen` |\nLooks at the screen, clicks, types |\n`browse` |\nDrives Chrome through the DevTools protocol |\n\nThe last four need a computer, which is optional; see below.\n\nA group is an isolation boundary. Agents in different groups cannot see or message each other, and a name in another group does not resolve. It reads exactly like a name belonging to nobody, so the roster cannot be probed across the line.\n\nEach group can pin its own model, endpoint and key. Settings resolve agent over group over app, so an expensive crew and a cheap one can run side by side.\n\nEvery group header carries a running token count, a cost, and a sparkline of the last ninety seconds, so a crew working on its own errands looks different from a crew that is stuck.\n\nEach agent has a notes file it maintains itself with `update_notes`\n\n, shown to it\nat the start of every turn. It is the only thing that survives between\nconversations. You can read and edit it in the agent editor.\n\nAn agent can also keep its own schedule: \"check the listings every five hours\" is a routine, stored as a next-due time rather than a timer, so it survives a restart. Routines are listed in the agent editor and can be written, retimed and deleted by hand.\n\nWith an [E2B](https://e2b.dev) key configured, an agent can be given a Linux\nmachine with a desktop, a browser and a shell. The screen appears in the corner\nof its channel: a live picture while you read, and interactive when expanded.\n\n- The machine sleeps after fifteen idle minutes and keeps its disk, so it wakes up still signed in to whatever it was signed in to.\n- Sandboxes are private, and the viewer is a loopback proxy that holds the access tokens, so no URL that reaches a machine is ever guessable or exposed to the webview.\n- A machine that no live agent refers to is released on the next launch. A forgotten sandbox bills exactly like a used one.\n\nWithout an E2B key none of this appears, and the other four tools are not offered.\n\nAn agent with a computer can already reach almost anything. What it cannot do is know what it is already allowed into: sign its browser in to LinkedIn and it will still tell you it has no way to post. The access was never missing. The knowledge was.\n\nTwo halves, and which one you get is decided by the service rather than by a preference.\n\n**Sign in on the agent's computer.** Open its screen, log in to whatever you\nlike, and that is the whole procedure. Nothing is declared anywhere: Chrome is\nholding the cookies, so Guaca asks the browser what it is signed in to and puts\nthe answer in that agent's prompt and on every other agent's roster. Log out and\nit disappears the same way. There is nowhere to type a password because Guaca\nnever handles one.\n\n**Credentials, on the group.** For an API with a plain token, paste it into the\ngroup's settings and name a variable. Every machine in that group gets it in the\nenvironment of every command it runs.\n\nTwo things follow from where each half physically lives, and both are load bearing:\n\n- A browser session is cookies on\n**one** machine, so it belongs to one agent. The rest of the crew is told who holds it, in the same roster that lists skills, so an agent asked to post to LinkedIn says \"Researcher can do that\" rather than \"I am not signed in\". A skill is a claim an agent wrote about itself; a session is a fact read off a disk. - A credential is a string, so the whole group gets it, and\n**it never reaches the model.** It goes from SQLite into the environment of a sandbox command and nowhere else: not into a prompt, not into the transcript, not into the webview, not onto the sandbox's disk. The agent is told the variable's name and told not to print it.\n\nDetection is deliberately cautious, because a wrong claim is worse than a\nmissing one: an agent that believes it can read Gmail wastes a turn finding out\nit cannot, and you see a broken account rather than an absent one. Sites are\nrecognised by the cookie that actually means somebody logged in, so a browser\nholding `google.com`\n\ncookies it collected while signed out is correctly reported\nas signed out. Anything not on that list is only mentioned if the browser has\ngenuinely visited it *and* holds a cookie implying an identity, and it is passed\nto the agent as a maybe. On a real profile holding a thousand cookies across\nthree hundred domains, that combination reported exactly the one account the\nmachine actually had.\n\nThe recognised-service list lives in `domain/signin.rs`\n\nand adding one is a\nline. There is no OAuth: a local, open-source app cannot honestly ship \"Log in\nwith Google\", because Gmail scopes are restricted and verification is per-app.\nSigning in on the agent's own browser gets you Gmail today, through the same\ndoor a person uses.\n\nBeing signed in is also what makes a hostile web page worth writing, so every\npage an agent reads arrives labelled as content rather than instruction, and the\nsystem prompt says what a signed-in agent must stop short of. See **Credit**.\n\nEverything lives in one directory:\n\n```\n~/Library/Application Support/com.madebywelch.guac/\n  guac.db        agents, groups, messages, routines, usage\n  config.json    settings, written 0600\n  workspace/     one markdown file per agent: its notes\n```\n\nThe API key is stored in `config.json`\n\nin plaintext. Guaca is a local app with\nno auth, and a key encrypted with a key sitting beside it would be theatre. The\nhonest answer is the OS keychain, and that is a deliberate follow-up rather than\nsomething faked here.\n\nDeleting an agent is a soft delete: it leaves the rail and can never be messaged\nagain, its computer is destroyed and its notes go, but what it already said\nstays readable and its name becomes free to reuse. **Start fresh** on a group\nresets its whole crew (transcripts, routines, notes and spend) while keeping the\nagents themselves.\n\n```\n./scripts/ci.sh          # lint, typecheck, build, every suite\nGUAC_LOG=guac=debug pnpm app\n```\n\n`AGENTS.md`\n\nis the short version for anyone, human or otherwise, about to change\nsomething: what is surprising, what will bite, and how to check.\n`docs/ARCHITECTURE.md`\n\nis the long version, including why agent conversations\nend rather than going round forever, which is the hardest thing here.\n`docs/PROTOCOL.md`\n\nrecords what the interoperability literature contributed.\n\nA working app that its author uses, not a product. It is macOS-first: the paths above are macOS paths, and nothing else has been tried. Expect rough edges, particularly around sandboxes, which are the newest part.\n\nThe shape of this app, agents you talk to that also talk to each other in a room you can watch, is heavily inspired by Grok bot.\n\nIts message layer is derived from the four agent interoperability protocols\n(MCP, ACP, A2A, ANP) and from the survey comparing them, *A survey of agent\ninteroperability protocols* by Abul Ehtesham, Aditi Singh, Gaurav Kumar Gupta\nand Saket Kumar ([arXiv 2505.02279](https://arxiv.org/abs/2505.02279)). A2A in\nparticular gave the Agent Card, discovery as a first-class operation, and card\nversioning. `docs/PROTOCOL.md`\n\nrecords what was taken from each, what was cut,\nand what had to be invented, chiefly termination, which none of them specify.\n\nConnectors have two kinds rather than one because of *Beyond Browsing: API-Based\nWeb Agents* by Yueqi Song, Frank Xu, Shuyan Zhou and Graham Neubig\n([arXiv 2410.16464](https://arxiv.org/abs/2410.16464)). Putting API-calling and\nbrowsing agents on the same WebArena tasks, they found APIs beat browsing, and a\nhybrid that could choose beat both, by 24.0 points absolute over browsing alone.\nThe design that follows is not \"an API when there is one, a browser otherwise\":\nit is telling one agent about both and letting it pick, which is what the\nprompt's **What you can reach** section is for.\n\nThe security half comes from *BrowseSafe: Understanding and Preventing Prompt\nInjection Within AI Browser Agents* by Kaiyuan Zhang, Mark Tenenholtz, Kyle\nPolley, Jerry Ma, Denis Yarats and Ninghui Li\n([arXiv 2511.20597](https://arxiv.org/abs/2511.20597)). Its useful move is to\nbenchmark injections that drive real-world *actions* rather than text output,\nwhich is exactly what a signed-in session turns a web page into: the payload no\nlonger has to talk an agent into obtaining access, because it already has the\noperator's. Guaca takes the architectural half of their defence-in-depth\nargument, which is what a local app can actually hold: page content is labelled\nat the point it enters the turn, credentials never enter the model's context at\nall, and the signed-in agent is told where to stop. Neither paper's authors\nendorse any of this.\n\n[GNU AGPL v3](/madebywelch/guaca/blob/main/LICENSE). You can use, modify and run it, including commercially;\nif you distribute it or run a modified version as a network service, that\nversion has to be published under the same licence.", "url": "https://wpnews.pro/news/show-hn-open-source-grok-bot-alternative", "canonical_source": "https://github.com/madebywelch/guaca", "published_at": "2026-08-15 21:03:51+00:00", "updated_at": "2026-08-15 21:10:40.377979+00:00", "lang": "en", "topics": ["artificial-intelligence", "large-language-models", "ai-agents", "developer-tools", "ai-products"], "entities": ["OpenRouter", "E2B", "llama.cpp", "LM Studio", "Chrome"], "alternates": {"html": "https://wpnews.pro/news/show-hn-open-source-grok-bot-alternative", "markdown": "https://wpnews.pro/news/show-hn-open-source-grok-bot-alternative.md", "text": "https://wpnews.pro/news/show-hn-open-source-grok-bot-alternative.txt", "jsonld": "https://wpnews.pro/news/show-hn-open-source-grok-bot-alternative.jsonld"}}