Independent AI intelligence Two editions daily · ET
FervorAI

Analysis · July 25, 2026 · repo

OpenWorkerAndrew NgaisuiteOllamaagent-harnessagent-infrastructurelocal-aiagent-securitymcp

OpenWorker Is Local-First. Three Things About It Are Not.

Andrew Ng's open-source desktop agent keeps your keys and your data on your machine. A Slack mention, a scheduler, and a cloud OAuth broker can all start it while you are somewhere else.

OpenWorker's README makes two claims about four bullet points apart. The first: "Everything lives on your machine: the agent loop, your conversations, connector tokens, and model keys." The second: "mention @OpenWorker in a channel; a session opens on your desktop, the work happens with your tools, and the answer comes back as a thread reply."

Both are true. They describe different things, and the gap between them is the most interesting design question in the repo.

Andrew Ng released OpenWorker on July 23 under MIT, in open beta, v0.1.6 tagged the same day. It landed near the top of the momentum boards within forty-eight hours. The pitch is that it hands you finished work instead of chat: a document you can open, a Slack reply with the numbers in it, a calendar that has been untangled. Twenty-five-plus connectors including GitHub, Slack, Jira, Notion, Linear, HubSpot, Outlook, monday.com, Gmail, and Google Calendar, plus your terminal and your local files, plus anything else reachable over MCP.

Local-first answers "where does my data sit," not "who pulls the trigger"

Most write-ups this week praised OpenWorker's approval design, and they are right to. MarkTechPost's breakdown says the approval layer is typed rather than cosmetic: every tool call gets sorted into one of four risk classes before it runs, read (no side effects, always allowed), write_local (mutates the workspace, path-scoped), exec (runs commands), and external (side effects outside the machine). The README's own version is blunter: "writes, sends, and shell commands are approval-gated. Unattended runs park their asks in an inbox instead of acting on their own."

That is a better approval model than most desktop agents ship. My argument is that it answers a question that comes second.

An approval layer governs what the agent does once it is running. It says nothing about who got it running. For a program holding OAuth tokens for twenty-five services, a model key, and a shell, the trigger surface is the boundary that decides how much the approval layer has to catch. And OpenWorker has three trigger paths that are not "you, at your desk, typing."

The three doors

The Slack mention. Type @OpenWorker in a channel and a session opens on your desktop. This is a genuinely useful feature and I understand why it shipped. It also means the start button for an agent holding your credentials lives in a chat workspace, alongside everyone else who can post in that channel and whatever automation posts there on your behalf. A typed approval class fires on external actions. It does not fire on "a session began."

The scheduler. OpenWorker runs automations: a morning brief, a weekly report, "a standing watch over a channel." Runs land in the app with full transcripts, and unattended runs park their approval requests in an inbox rather than proceeding. The inbox is the right call. It also converts approval from a synchronous stop into a queue you review later, which is a different psychological act. Reviewing eleven queued approvals on Monday morning is not the same as being interrupted once, mid-task, with context in your head.

The OAuth broker. From the README's privacy section: "The only cloud piece is a small service that brokers OAuth handshakes for connectors." They tell you this directly, which I respect, and they give you the escape hatch: "You can always use the App without signing-in, use the connectors via manually-created credentials/API-keys." So the default path for connecting twenty-five services routes a handshake through a service the OpenWorker team runs, and the fully local path exists but costs you the convenience that made you install a desktop agent in the first place.

None of these is a flaw in the sense of a bug. Each is a deliberate trade, and each sits upstream of the four risk classes. Approval typing is a good answer to "what is this thing allowed to do." The doors are the answer to "when does it get to try," and that answer is: more often than you are watching.

What is actually under the hood

The architecture is three processes and it is easy to read.

+------------------------------------------------+
|              OpenWorker desktop app            |   Tauri 2 shell + React UI
+------------------------------------------------+
|           local agent server (Python)          |   engine, tools, connectors
+---------------+----------------+---------------+
|  your files   |   your tools   |  your model   |
|  & terminal   | 25+ connectors |  any provider |
+---------------+----------------+---------------+

A Tauri 2 native shell wraps a React UI. Under it, a Python agent server (3.10+) binds locally and holds the engine, the tools, the connectors, the MCP client, memory, and automations. A small Rust sidecar does speech-to-text. The engine is built on aisuite, Ng's provider-agnostic LLM library, and the README is explicit that if you want to build your own harness instead, aisuite is the place to start and this repo is a working reference for what it can carry.

Model access is bring-your-own-key across OpenAI, Anthropic, Google Gemini, Inkling, GLM, DeepSeek, Kimi, Qwen, MiniMax, Mistral, and Grok, plus open-weight models through Together and Fireworks, plus fully local models through Ollama. A curated list marks which models the team has verified for tool-calling work, with a warning I like: "Adding any model string works at your own risk."

Put this into practice

The fastest honest evaluation takes about half an hour and deliberately skips the features that make it impressive.

  1. Install and point it at Ollama first. macOS builds are signed and notarized; Windows builds are not code-signed yet, so SmartScreen will complain. Starting local means your first task runs with no model key and no external network dependency for inference, which makes the next steps easier to read.

  2. Connect exactly one connector, and pick a read-heavy one. GitHub or Google Calendar. Do not connect Gmail and Slack and your terminal on day one just because the onboarding makes it easy. You are trying to learn where the approval prompts fire, and one connector makes that legible.

  3. Give it a real task with a file at the end. "Summarize the open issues on this repo into a document." Watch which steps stop and ask you and which ones do not. Write down the ones that surprised you in either direction.

  4. Now go find the Slack and scheduler settings, and leave them off. Read what enabling them would do before enabling them. If a Slack mention starting a desktop session is fine for your setup, turn it on deliberately, in one channel, and know who can post there.

  5. If you want to read the connector code, run from source. git clone, then bash packaging/setup_dev_env.sh, then .venv/bin/openworker-server --cwd ~/some/project --port 8765, then npm run tauri dev from surfaces/gui/. Prerequisites are Python 3.10+, Node 20+, and the Rust toolchain. The connectors live in coworker/. This is the step that takes an hour, not ten minutes, and it is the one worth doing if OpenWorker is going near a machine with anything sensitive on it.

Honest limitations

The version number is the headline. v0.1.6, three releases, forty-five commits, open beta by the maintainers' own label. The app auto-updates, which is how fixes reach you quickly and also how code you did not review reaches you quickly.

The star count is unresolvable this week and I will not pretend otherwise. GitHub's own repository page served me 46 stars, 3 forks, and one watcher when I loaded it on July 25. Search-indexed copies of that same page from the preceding days report figures between roughly 3.3k and 4.5k, and the project sat near the top of Trendshift's daily board. I cannot reconcile those, and I am not going to average them into a number that sounds confident. Treat any star figure for this repo this week as unreliable, including mine.

"Open source" here comes with a closed roadmap. The contributing section says it directly: "we are actively developing based off a internal list and goal, so we may not approve PRs that add features that are already under-development or deviates from our vision." That is an honest and reasonable thing for a young project to say. It also means the license is MIT and the direction is not community-governed.

I have not audited the connector permission scopes. Twenty-five integrations means twenty-five OAuth scope requests, and I read the README rather than each connector's implementation. If you are putting this on a work machine, that audit is yours to do and I would do it before the Gmail connector, not after.

A desktop agent with a terminal is a large surface no matter whose it is. This is not specific to OpenWorker and it is the reason the typed approval classes exist. Worth saying plainly anyway: the failure mode here is not "the model says something wrong," it is "the model does something on a machine you use for everything else."

The question I keep coming back to

Every local-first agent this year has converged on the same shape: your data on your machine, your keys in a local store, your choice of model. That is settled. What nobody has settled is the trigger surface, and OpenWorker is the clearest example yet because it is honest enough to document all three of its doors in a public README instead of burying them.

So here is the thing I would argue about: I think "local-first" has stopped being a useful safety claim and started being a data-residency claim, and we need a second word for the property people think they are buying. Something about who is allowed to start the loop.

If you have been running OpenWorker with the Slack trigger on, I want to hear how that has gone. That is the configuration I have the least evidence about and the most curiosity toward.

Sources: andrewyng/openworker README and repository, aisuite, Andrew Ng's announcement, MarkTechPost coverage of the typed approval layer.