8 min read

OpenClaw: A Personal AI Agent You Text From Your Phone (GitHub, Scanned)

A self-hosted AI assistant you text from WhatsApp, Telegram or Slack that acts on your own machine.

OpenClaw logo
✅
Scan: safe. Nothing malicious. Three things to know: the recommended installer can use sudo and edits your shell profile, agent tools run directly on your machine unless you turn on sandboxing, and ClawHub skills are unreviewed third-party code. Scanned Oct 3, 2026; the full report is below.

OpenClaw is a personal AI assistant that lives on your own computer and answers in the chat apps you already use. A local Gateway process connects it to WhatsApp, Telegram, Slack, Discord, Signal, iMessage, Teams and more than 20 other channels, plus native apps for macOS, iOS, Android, Windows and Linux. You bring the model (Claude, Codex, a local model through a plugin), and the assistant can read and write files, run commands, browse and act on your behalf. Memory, state and credentials stay on your hardware, and by default the only call home is a daily version check.

It is on this list because it is the agent that went mainstream. Peter Steinberger first published it in November 2025; it went through the names Warelay, Clawdbot and Moltbot (the last after a trademark complaint from Anthropic) before settling on OpenClaw in January 2026, and it now has about 391,000 GitHub stars, a Wikipedia article and a steady stream of TikTok setup tutorials. Steinberger joined OpenAI in February 2026 and the project moved to the OpenClaw Foundation, an independent 501(c)(3) whose donors include OpenAI, Amazon and Red Hat. There is no paid tier, hosted service or token.

The power is also the risk. Tools run directly on the host for your main session unless you turn on sandboxing, inbound messages are untrusted input, and skills from the ClawHub registry are third-party code: Cisco researchers found published skills that exfiltrated data and injected prompts. The project's own security guide and exposure runbook are worth reading before you connect a chat account.

  • Repository: github.com/openclaw/openclaw
  • Licence: MIT (MIT License)
  • Language: TypeScript. Stars: 391.2K. Forks: 82.2K. Last push: Oct 3, 2026.
  • Scan: safe, Oct 3, 2026, commit efcd9ff

Who it is for

Technical users who want an always-on assistant reachable from their phone, are comfortable reviewing what an agent is allowed to do on their machine, and already pay for a model API or run a local model.

Getting started

1. Install on macOS, Linux or WSL2 (Windows: iwr -useb https://openclaw.ai/install.ps1 | iex)

curl -fsSL https://openclaw.ai/install.sh | bash

2. Or, if you manage Node 24.16+ yourself, install the npm package

npm install -g openclaw@latest --allow-scripts=openclaw

3. Run onboarding and install the background service (the script installer starts this for you)

openclaw onboard --install-daemon

4. Check the gateway and open the Control UI

openclaw gateway status && openclaw dashboard

The recommended installer is a shell script piped from openclaw.ai, and it can install a Node.js runtime for you. Onboarding asks for a model provider, so you need an API key or subscription (or a local model). Tools run on the host unless you configure sandboxing; read the security guide before pairing a chat account or exposing the Gateway beyond localhost.

Safety scan

We cloned openclaw/openclaw at commit efcd9ff on Oct 3, 2026 and ran the checks described on the GitHub Tools page: credential patterns, decode-and-execute code, install-time scripts, committed binaries, risky CI workflows, every host the code talks to, known vulnerabilities in pinned dependencies, and project hygiene. A person read every hit. This is what we found.

  • A large codebase: 51,928 files and about 13 million lines, mostly TypeScript, with Swift and Kotlin for the companion apps. All 147 secret candidates sit in tests and QA fixtures (fake Slack xoxb tokens, ghp_ tokens, AWS keys and PEM blocks used to prove the log redaction and secret scanners work). None is a live credential.
  • The 181 pattern hits are the product doing what it says. 55 persistence hits are the macOS LaunchAgent and systemd units that keep the Gateway running; 78 api.telegram.org hits are the Telegram channel and its tests; the curl | bash lines are the installer's own usage text; the crypto-miner hit is a detection rule in OpenClaw's skill security scanner; the encoded PowerShell is a Windows process-identity probe; the very long line is a base64 Ogg test clip. The 125 bare-IP URLs are tests plus Tailscale's local API at 100.100.100.100.
  • scripts/install.sh, the curl | bash installer, is 3,855 lines. It can call sudo to install Node.js through your package manager or NodeSource, and it adds OpenClaw to PATH in your shell profile. Five npm lifecycle scripts run on a source install, including a postinstall that sets up bundled plugins.
  • 14 known advisories across 2,735 packages, low for a project this size. The two criticals (the sandbox package) are in .github/release/vercel-cli, release tooling that never ships; the main pnpm lockfile of 1,724 packages has two highs (braces, http-cache-semantics); the rest are unmaintained-crate notices in the Linux app's Tauri build.
  • 111 workflows. Five use pull_request_target and none checks out the pull request, and all 76 third-party actions are pinned to commits, which is rare. Security policy, Dependabot, CodeQL, licence and contributing guide all present.

What the scanner counted

CheckResult
Secrets147 candidates found and read; see the notes above.
Suspicious code181 pattern hits found and read; every one is listed under the raw findings.
Install-time code5 npm lifecycle scripts. 1 Cargo build script. 24 installer scripts (one fetches and runs a remote script; one edits your shell profile; one can call sudo)
Committed binaries1 executable or compiled object committed; listed under the raw findings.
CI workflows111 workflows. 5 use pull_request_target, none check out the pull request head. 0 of 76 third-party actions pinned to a tag rather than a commit.
Network hosts40 distinct hosts referenced from source; most often github.com, example.test, api.openai.com, docs.openclaw.ai. 125 URLs to a bare IP address, listed under the raw findings.
Known vulnerabilities14 advisories across 2,735 pinned packages: 2 critical, 2 high, 4 moderate, 0 low, 6 unrated. .github/actions/setup-security-review/package-lock.json: 4 packages, 0 advisories; .github/release/clawhub-cli/package-lock.json: 47 packages, 0 advisories; .github/release/vercel-cli/package-lock.json: 396 packages, 6 advisories; apps/linux/src-tauri/Cargo.lock: 612 packages, 7 advisories; apps/shared/OpenClawWatchRTC/Cargo.lock: 143 packages, 0 advisories; crates/Cargo.lock: 126 packages, 0 advisories; pnpm-lock.yaml: 1,724 packages, 2 advisories; scripts/docs-i18n/go.mod: 3 packages, 0 advisories.
Project hygieneHas security policy, automated dependency updates, CodeQL, licence file, contributing guide.
OpenSSF ScorecardNot scored: the project is not in Scorecard's weekly index.

The raw findings

Every hit the scanner wrote out, with a link to the exact line at the scanned commit. Secrets candidates are redacted.

Secret candidates (147, redacted)
WhereRuleMatch
.agents/skills/autoreview/tests/fixtures/typescript-sensitive-literals.ts:5aws-access-keyAKIAFA…000 (20 chars)
.agents/skills/autoreview/tests/fixtures/typescript-sensitive-literals.ts:6slack-tokenxoxb-F…000 (61 chars)
extensions/acpx/src/codex-auth-bridge.test.ts:583private-key-----B…--- (27 chars)
extensions/acpx/src/codex-auth-bridge.test.ts:586private-key-----B…--- (27 chars)
extensions/acpx/src/codex-auth-bridge.test.ts:617github-tokengithub…xyz (47 chars)
extensions/msteams/src/sdk.test.ts:27private-key-----B…--- (31 chars)
extensions/msteams/src/sdk.test.ts:65private-key-----B…--- (31 chars)
extensions/qa-lab/src/crabline-slack-transport.test.ts:34slack-tokenxoxb-c…ken (25 chars)
extensions/qa-lab/src/crabline-slack-transport.test.ts:43slack-tokenxoxb-c…ken (25 chars)
extensions/qa-lab/src/live-transports/slack/slack-live.approvals.test.ts:46slack-tokenxoxb-q…ure (24 chars)
extensions/qa-lab/src/live-transports/slack/slack-live.approvals.test.ts:139slack-tokenxoxb-q…ure (24 chars)
extensions/qa-lab/src/scenario-catalog.test.ts:217slack-tokenxoxb-i…cle (36 chars)
extensions/slack/src/account-inspect.test.ts:159slack-tokenxoxb-l…nce (21 chars)
extensions/slack/src/action-request-authority.test.ts:9slack-tokenxoxb-i…ity (26 chars)
extensions/slack/src/actions.reactions-limit.test.ts:21slack-tokenxoxb-l…oof (16 chars)
extensions/slack/src/actions.reactions-limit.test.ts:29slack-tokenxoxb-l…oof (16 chars)
extensions/slack/src/actions.reactions-limit.test.ts:128slack-tokenxoxb-l…oof (16 chars)
extensions/slack/src/approval-auth.test.ts:133slack-tokenxoxb-e…ise (15 chars)
extensions/slack/src/client.test.ts:292slack-tokenxoxb-s…ken (20 chars)
extensions/slack/src/client.test.ts:299slack-tokenxoxb-o…ken (16 chars)
extensions/slack/src/client.web-api.test.ts:228slack-tokenxoxb-e…oof (21 chars)
extensions/slack/src/client.web-api.test.ts:481slack-tokenxoxb-r…oof (16 chars)
extensions/slack/src/client.web-api.test.ts:490slack-tokenxoxb-r…oof (16 chars)
extensions/slack/src/client.web-api.test.ts:511slack-tokenxoxb-r…oof (16 chars)
and 123 more
Pattern hits (181)
WhereRuleMatch
.agents/skills/openclaw-live-updater/scripts/update-main.mjs:1441persistenceconst plistPath = path.join(home, "Library/LaunchAgents/ai.openclaw.gateway.plist");
.agents/skills/openclaw-live-updater/scripts/update-main.mjs:1533persistenceif (!home || !existsSync(path.join(home, "Library/LaunchAgents/ai.openclaw.gateway.plist"))) {
.agents/skills/telegram-e2e-userbot/scripts/telegram-test-doctor.test.mjs:37exfil-hostassert.equal(url, "https://api.telegram.org/botsynthetic-token/test/getMe");
.agents/skills/telegram-e2e-userbot/scripts/telegram-test-scenario.test.mjs:757exfil-hostassert.equal(url, "https://api.telegram.org/botsynthetic-token/test/getMe");
.agents/skills/telegram-e2e-userbot/scripts/user-driver.py:262exfil-hostf"https://api.telegram.org/bot{token}/{'test/' if test_dc else ''}{method}",
.agents/skills/telegram-e2e-userbot/scripts/user-driver.test.py:383exfil-host"https://api.telegram.org/botfixture-token/test/sendMessage",
.agents/skills/telegram-e2e-userbot/scripts/user-driver.test.py:384exfil-host"https://api.telegram.org/botfixture-token/test/sendPhoto",
.agents/skills/telegram-e2e-userbot/scripts/user-driver.test.py:423exfil-hostside_effect=OSError("https://api.telegram.org/bot" + token)
apps/macos/Sources/OpenClaw/ApplicationRelocator.swift:367persistencehomeDirectory.appendingPathComponent("Library/LaunchAgents/\(serviceName).plist"),
apps/macos/Sources/OpenClaw/ApplicationRelocator.swift:368persistenceURL(fileURLWithPath: "/Library/LaunchAgents/\(serviceName).plist"),
apps/macos/Sources/OpenClaw/ApplicationRelocator.swift:369persistenceURL(fileURLWithPath: "/System/Library/LaunchAgents/\(serviceName).plist"),
apps/macos/Sources/OpenClaw/GatewayLaunchAgentManager.swift:48persistence"Library/LaunchAgents/\(profile.gatewayLaunchAgentLabel).plist")
apps/macos/Sources/OpenClaw/LaunchAgentManager.swift:11persistence.appendingPathComponent("Library/LaunchAgents/ai.openclaw.mac.plist")
apps/macos/Sources/OpenClaw/NodeServiceManager.swift:9persistence.appendingPathComponent("Library/LaunchAgents/\(nodeLaunchdLabel).plist")
apps/macos/Tests/OpenClawIPCTests/ApplicationRelocatorTests.swift:405persistence (test/example)let launchAgentURL = home.appendingPathComponent("Library/LaunchAgents/\(serviceName).plist")
apps/macos/Tests/OpenClawIPCTests/BundledGatewayPreparationTests.swift:32persistence (test/example)? home.appendingPathComponent("Library/LaunchAgents/\(nodeLaunchdLabel).plist")
apps/macos/Tests/OpenClawIPCTests/BundledGatewayPreparationTests.swift:562persistence (test/example)? home.appendingPathComponent("Library/LaunchAgents/\(label).plist") : fixture.plist
apps/macos/Tests/OpenClawIPCTests/GatewayLaunchAgentManagerTests.swift:21persistence (test/example)"/Users/test/Library/LaunchAgents/ai.openclaw.gateway.plist")
apps/macos/Tests/OpenClawIPCTests/GatewayLaunchAgentManagerTests.swift:23persistence (test/example)"/Users/test/Library/LaunchAgents/ai.openclaw.work.plist")
apps/macos/Tests/OpenClawIPCTests/LaunchAgentManagerTests.swift:32persistence (test/example)let plistURL = directory.appendingPathComponent("Library/LaunchAgents/login.plist")
apps/macos/Tests/OpenClawIPCTests/LaunchAgentManagerTests.swift:55persistence (test/example)let plistURL = directory.appendingPathComponent("Library/LaunchAgents/login.plist")
apps/macos/Tests/OpenClawIPCTests/NodeServiceManagerTests.swift:52persistence (test/example)let plist = root.appendingPathComponent("Library/LaunchAgents/\(nodeLaunchdLabel).plist")
apps/macos/Tests/OpenClawIPCTests/NodeServiceManagerTests.swift:249persistence (test/example)let plist = root.appendingPathComponent("Library/LaunchAgents/\(nodeLaunchdLabel).plist")
apps/macos/Tests/OpenClawIPCTests/NodeServiceManagerTests.swift:288persistence (test/example)let plist = home.appendingPathComponent("Library/LaunchAgents/\(nodeLaunchdLabel).plist")
and 157 more
URLs to bare IP addresses (125)
WhereRuleMatch
apps/android/app/src/test/java/ai/openclaw/app/gateway/CloudflareAccessClientTest.kt:76ip-literal-urlfor (url in listOf("https://gateway.example.test", "https://127.0.0.1", "https://gateway.example.test:8443", "https://192.0.2.1:8443")) {
apps/android/app/src/test/java/ai/openclaw/app/gateway/GatewaySessionInvokeTest.kt:252ip-literal-urlRouteCase("192.0.2.10", "https://192.0.2.10:7443", true),
apps/android/app/src/test/java/ai/openclaw/app/gateway/GatewaySessionInvokeTest.kt:259ip-literal-urlRouteCase("192.0.2.10", "https://192.0.2.11:7443", false),
apps/android/app/src/test/java/ai/openclaw/app/gateway/GatewaySessionInvokeTest.kt:261ip-literal-urlRouteCase("::ffff:192.0.2.10", "https://192.0.2.11:7443", false),
apps/android/app/src/test/java/ai/openclaw/app/gateway/GatewaySessionInvokeTest.kt:264ip-literal-urlRouteCase("::ffff:192.0.2.10", "https://192.0.2.10:7443", true),
apps/android/app/src/test/java/ai/openclaw/app/ui/chat/ChatLinkPreviewTest.kt:82ip-literal-url"http://100.64.0.1/",
apps/android/app/src/test/java/ai/openclaw/app/ui/chat/ChatLinkPreviewTest.kt:83ip-literal-url"http://198.18.0.1/",
apps/android/app/src/test/java/ai/openclaw/app/ui/chat/ChatLinkPreviewTest.kt:84ip-literal-url"http://192.0.2.1/",
apps/android/app/src/test/java/ai/openclaw/app/ui/chat/ChatLinkPreviewTest.kt:86ip-literal-url"http://224.0.0.1/",
apps/android/app/src/test/java/ai/openclaw/app/ui/chat/ChatLinkPreviewTest.kt:87ip-literal-url"http://255.255.255.255/",
apps/android/app/src/test/java/ai/openclaw/app/ui/chat/ChatLinkPreviewTest.kt:102ip-literal-urlassertTrue(isPubliclyRoutableHost("http://93.184.216.34/".toHttpUrl()))
apps/macos/Sources/OpenClaw/TailscaleService.swift:18ip-literal-urlprivate static let tailscaleAPIEndpoint = "http://100.100.100.100/api/data"
apps/shared/OpenClawKit/Tests/OpenClawKitTests/ChatLinkPreviewTests.swift:89ip-literal-url"http://100.64.0.1",
apps/shared/OpenClawKit/Tests/OpenClawKitTests/ChatLinkPreviewTests.swift:90ip-literal-url"http://100.127.255.254",
apps/shared/OpenClawKit/Tests/OpenClawKitTests/ChatLinkPreviewTests.swift:97ip-literal-url"http://224.0.0.1",
apps/shared/OpenClawKit/Tests/OpenClawKitTests/ChatLinkPreviewTests.swift:98ip-literal-url"http://255.255.255.255",
apps/shared/OpenClawKit/Tests/OpenClawKitTests/ChatLinkPreviewTests.swift:116ip-literal-url"http://1.1.1.1",
apps/shared/OpenClawKit/Tests/OpenClawKitTests/ChatLinkPreviewTests.swift:117ip-literal-url"https://8.8.8.8",
extensions/browser/src/browser/cdp.helpers.test.ts:30ip-literal-urlcdpUrl: "https://1.1.1.1",
extensions/browser/src/browser/cdp.test.ts:332ip-literal-urlurl: "https://93.184.216.34",
extensions/browser/src/browser/cdp.test.ts:343ip-literal-urlurl: "https://93.184.216.34",
extensions/browser/src/browser/pw-session.connections.test.ts:281ip-literal-urlcdpUrl: "http://93.184.216.34:9222",
extensions/browser/src/browser/pw-session.create-page.navigation-guard.test.ts:33ip-literal-urlconst publicUrl = "https://93.184.216.34/start";
extensions/browser/src/browser/pw-tools-core.browser-ssrf-guard.test.ts:165ip-literal-urlcurrentUrl = "https://93.184.216.34/target";
and 101 more
npm lifecycle scripts (5)
  • package.json preinstall: node scripts/preinstall-package-manager-warning.mjs
  • package.json postinstall: node scripts/postinstall-bundled-plugins.mjs
  • package.json prepare: node scripts/prepare-git-hooks.mjs
  • package.json prepack: node --import ./scripts/tsx.mjs scripts/openclaw-prepack.ts
  • packages/gateway-protocol/package.json prepack: pnpm run build && node --import tsx ../../scripts/protocol-gen.ts --out ./protocol.schema.json
Installer scripts (24)
Committed binaries (1)
  • apps/android/gradle/wrapper/gradle-wrapper.jar: JAR, 48 KB
Worst known vulnerabilities (14 of 14)
AdvisorySeverityPackageSummary
GHSA-gc25-3vc5-2jf9criticalsandbox@4.4.0Sandbox Breakout / Arbitrary Code Execution in sandbox
GHSA-gc25-3vc5-2jf9criticalsandbox@4.1.0Sandbox Breakout / Arbitrary Code Execution in sandbox
GHSA-vfj7-8cjw-p6xmhighbraces@3.0.3braces vulnerable to stack-exhaustion denial of service through deeply nested patterns
GHSA-ch52-4w7c-c8xphighhttp-cache-semantics@4.2.0http-cache-semantics max-stale handling can disclose cross-user cached responses
GHSA-hrr3-gc8f-f4qjmoderatefast-uri@3.1.7fast-uri vulnerable to inconsistent host case normalization via percent-encoded octets
GHSA-fm4j-4xhm-xpwxmoderatesandbox@4.4.0Sandbox Breakout / Arbitrary Code Execution in sandbox
GHSA-fm4j-4xhm-xpwxmoderatesandbox@4.1.0Sandbox Breakout / Arbitrary Code Execution in sandbox
GHSA-wrw7-89jp-8q8gmoderateglib@0.18.5Unsoundness in `Iterator` and `DoubleEndedIterator` impls for `glib::VariantStrIter`
RUSTSEC-2024-0370unknownproc-macro-error@1.0.4proc-macro-error is unmaintained
RUSTSEC-2025-0081unknownunic-char-property@0.9.0`unic-char-property` is unmaintained
RUSTSEC-2025-0075unknownunic-char-range@0.9.0`unic-char-range` is unmaintained
RUSTSEC-2025-0080unknownunic-common@0.9.0`unic-common` is unmaintained
RUSTSEC-2025-0100unknownunic-ucd-ident@0.9.0`unic-ucd-ident` is unmaintained
RUSTSEC-2025-0098unknownunic-ucd-version@0.9.0`unic-ucd-version` is unmaintained
Workflows worth a look

By the numbers

Stars391.2K
Forks82.2K
Contributors3,479
Commits104.5K
Open issues5,935
Open pull requests3,233
Releases252
Latest releasev2026.9.8
LicenceMIT
Main languageTypeScript
Project age10 months
Last pushOct 3, 2026
Tracked files51,928
Lines of code13.2M
Checkout size644 MB

Lines by language: TypeScript 11.2M, Markdown 504.4K, Swift 449.9K, Kotlin 257.5K, JavaScript 186.8K, JSON 185.5K.

Questions

Is OpenClaw free?

Yes. OpenClaw is MIT-licensed and the Foundation has no paid tier, hosted service or token. What costs money is the model: you connect your own Anthropic, OpenAI or other provider account and pay its usage, or run a local model at no API cost.

Is OpenClaw safe to run?

It is as safe as the permissions you give it. By default tools run on the host for your own session, so an agent that is tricked by a message or a bad skill can act with your user account. Unknown senders must be approved with a pairing code, and sandboxing is available. Treat ClawHub skills like any third-party code and read them before installing.

What is the difference between OpenClaw and Hermes Agent?

Both are self-hosted agents you reach through chat apps. OpenClaw centres on a Gateway with many channels, companion device apps and a plugin and skill registry. Hermes Agent, from Nous Research, focuses on a learning loop that writes and refines its own skills, and ships a hermes claw migrate command to import OpenClaw settings, memories and skills.


This post is part of GitHub Tools, where every repository is cloned and scanned before it is written up. The scan is a snapshot of one commit on one day; the repository has moved on since, so check it before you install.