{"slug": "i-built-a-personal-ai-agent-in-swift-on-top-of-what-macos-ships", "title": "I built a personal AI agent in Swift on top of what macOS ships", "summary": "Developer Ivan Magda released clawd v0.2.0, an open-source personal AI agent written in Swift 6 that runs as a daemon on macOS 15+ and Linux, pairing a private Telegram bot with any OpenAI-compatible LLM. The agent features durable SQLite memory, Markdown-based skills, scheduled proactive tasks, a policy engine with SSRF protection and approval gates for writes and code execution, sandboxed VM code execution, and MCP server tool integration, with all data stored locally in ~/.swift-claw.", "body_md": "**Your always-on personal AI assistant. One pure-Swift daemon on hardware you own.**\n\n`clawd`\n\npairs a private Telegram bot with the LLM of your choice. It remembers what you\ntell it and runs scheduled and proactive tasks. Consequential tool calls wait for your\napproval. Everything it keeps stays in one directory on your own machine: a SQLite\ndatabase, encrypted secret envelopes, and Markdown files you edit by hand.\n\n**A real Telegram chat.** Answers stream in as live message drafts.`/stop`\n\ncancels a turn,`/new`\n\nstarts a fresh session, clawd transcribes voice notes on-device (macOS 26), and it looks at photos you send if your model can see them.**Durable memory.** Facts you confirm persist in SQLite, and clawd recalls them by importance and recency. Workspace Markdown files hold your profile, notes, and daily logs, and conversation history is full-text searchable.**Skills you write once.** A`skills/<name>/SKILL.md`\n\nfile shows up in context as its name and one line about when to use it; when a task matches, clawd loads the body and follows your procedure instead of asking you to paste it again. Send`/skills`\n\nto see every accepted skill and each file the scanner rejected.**Proactive, on your clock.**\"Every weekday at 07:00\" schedules fire once per occurrence across restarts and DST changes, and an opt-in heartbeat respects quiet hours.**Tools behind a policy engine.**`web_fetch`\n\nsits behind an SSRF gate; writes and code execution wait for an explicit tap-to-approve in Telegram. clawd enforces policy in code and treats inbound content as data, never as instructions.**Sandboxed code execution.** Untrusted code runs in a fresh disposable VM per request (macOS 26 arm64, off by default).**Tools from MCP servers.** List a server, store its token encrypted, and its tools join the built-ins as the least-trusted tools clawd has. Calls ask by default; you may mark a named tool safe, but the exfiltration gate can still require approval. Only you can add a server or change what it exposes.**Bring your own model.** Any OpenAI-compatible endpoint works, and`clawd auth login`\n\ncan run an eligible model on a ChatGPT subscription.**One binary.** Swift 6 with strict concurrency, from the Telegram long-poll down to SQLite.\n\nA file write suspends the run until you answer. Every field on the card comes from the daemon's own\nrecord of the action: the target path after symlink and `..`\n\nresolution, the size, and a preview of\nthe content. Tap Deny and clawd writes nothing.\n\n```\ncurl -fsSL https://raw.githubusercontent.com/ivan-magda/swift-claw/main/install.sh | sh\n```\n\nEverything lands in `~/.swift-claw`\n\n, with no sudo. The script verifies every download\nagainst the release checksums, stages the service files, and prints the next steps.\nPin a release with `curl … | CLAWD_VERSION=v0.2.0 sh`\n\n, read the\n[script source](/ivan-magda/swift-claw/blob/main/install.sh) first, or follow the manual route in\n[docs/INSTALL.md](/ivan-magda/swift-claw/blob/main/docs/INSTALL.md) (macOS 15+ arm64; Linux x86_64 with glibc 2.38+).\n\nOr build from source with a Swift 6.3 toolchain (Linux needs `libsqlite3-dev`\n\n):\n\n```\ngit clone https://github.com/ivan-magda/swift-claw.git && cd swift-claw\nswift build -c release\nsudo install -m755 .build/release/clawd /usr/local/bin/clawd\n```\n\n- Get a bot token from\n[@BotFather](https://t.me/BotFather)(send`/newbot`\n\n). - Edit\n`~/.swift-claw/clawd.env`\n\n: set the token and your LLM provider (`CLAW_LLM_BASE_URL`\n\n,`CLAW_LLM_MODEL`\n\n,`CLAW_LLM_API_KEY`\n\n). - Load the config and encrypt your secrets at rest:\n`set -a && . ~/.swift-claw/clawd.env && set +a && clawd secrets seal`\n\n- Say hello once in the foreground:\n`clawd run`\n\n, then send`/start`\n\nto your bot. The refusal shows your numeric ID; set it as`CLAW_ALLOWLIST=<id>`\n\nin`clawd.env`\n\n, then Ctrl-C. - Check health and start the service:\n`set -a && . ~/.swift-claw/clawd.env && set +a && clawd doctor`\n\n, then run the start command doctor prints.\n\nThe full walkthrough, including the ChatGPT-subscription route and troubleshooting, is\nin [docs/GETTING_STARTED.md](/ivan-magda/swift-claw/blob/main/docs/GETTING_STARTED.md).\n\nswift-claw assumes you are the only person it serves.\n\n**Default-deny.** Only allowlisted Telegram IDs get a conversation. clawd refuses everyone else, and answers`/start`\n\nwith the sender's own numeric ID so you can allowlist them.`CLAW_ALLOWLIST`\n\nonly ever adds, so revoking an ID means deleting its row from the database ([details](/ivan-magda/swift-claw/blob/main/docs/CUSTOMIZATION.md#everything-else)).**Secrets encrypted at rest.**`clawd secrets seal`\n\nwraps the bot token and API keys in an AES-GCM envelope. Plaintext env secrets remain available as a dev fallback that warns on every boot.**Approvals are durable and unforgeable.** File writes, memory writes, and code execution suspend into a durable state machine until you tap Approve in Telegram. A forged or third-party callback cannot approve, and pending approvals expire to deny.**Prompt injection contained.** Messages, web content, tool output, and stored memory enter the context as untrusted data. Once a session has both ingested untrusted content and pulled your private files into context, fetching an arbitrary URL also needs your approval. clawd pins your LLM and search providers in config, and the model cannot redirect them.\n\nThe full model is in [docs/ARCHITECTURE.md](/ivan-magda/swift-claw/blob/main/docs/ARCHITECTURE.md) (§12). To report a\nvulnerability, see [SECURITY.md](/ivan-magda/swift-claw/blob/main/SECURITY.md).\n\nPersona and behavior live in Markdown files under `~/.swift-claw/workspace/`\n\n:\n\n| File | Shapes | Trust |\n|---|---|---|\n`SOUL.md` |\nPersonality and tone | System prompt |\n`AGENTS.md` |\nBehavior rules | System prompt |\n`TOOLS.md` |\nWhen and how to use tools | System prompt |\n`USER.md` |\nWho you are | Untrusted, labeled |\n`HEARTBEAT.md` |\nThe proactive heartbeat checklist | Heartbeat runs only |\n`skills/<name>/SKILL.md` |\nA procedure the agent loads when a task calls for it | Untrusted, labeled |\n\nMCP servers go in `~/.swift-claw/mcp.yaml`\n\n, with their tokens stored encrypted by\n`clawd mcp set-token`\n\n. Other runtime knobs are environment variables: the model route\n(`CLAW_LLM_MODEL`\n\n), an optional fallback route (`CLAW_LLM_FALLBACK_MODEL`\n\n, off unless you\nset it), USD budgets, schedules and quiet hours, voice locales, sandbox limits.\n[ .env.example](/ivan-magda/swift-claw/blob/main/.env.example) documents every variable;\n\n[docs/CUSTOMIZATION.md](/ivan-magda/swift-claw/blob/main/docs/CUSTOMIZATION.md)is the guide.\n\n| You want to | Read |\n|---|---|\n| Set it up end to end |\n|\n\n[docs/INSTALL.md](/ivan-magda/swift-claw/blob/main/docs/INSTALL.md)[docs/CUSTOMIZATION.md](/ivan-magda/swift-claw/blob/main/docs/CUSTOMIZATION.md)[docs/INSTALL.md](/ivan-magda/swift-claw/blob/main/docs/INSTALL.md#4-running-as-a-service)[docs/LOCAL_DEV.md](/ivan-magda/swift-claw/blob/main/docs/LOCAL_DEV.md)[docs/ARCHITECTURE.md](/ivan-magda/swift-claw/blob/main/docs/ARCHITECTURE.md)[SECURITY.md](/ivan-magda/swift-claw/blob/main/SECURITY.md)Contributions are welcome. Open an issue to discuss what you have in mind before\nsending a pull request; [CONTRIBUTING.md](/ivan-magda/swift-claw/blob/main/CONTRIBUTING.md) has the details and the\nlint/test gate.\n\n[MIT](/ivan-magda/swift-claw/blob/main/LICENSE) © Ivan Magda", "url": "https://wpnews.pro/news/i-built-a-personal-ai-agent-in-swift-on-top-of-what-macos-ships", "canonical_source": "https://github.com/ivan-magda/swift-claw", "published_at": "2026-08-12 12:23:50+00:00", "updated_at": "2026-08-12 12:42:26.079959+00:00", "lang": "en", "topics": ["artificial-intelligence", "ai-agents", "ai-tools", "developer-tools", "ai-infrastructure"], "entities": ["Ivan Magda", "clawd", "Swift", "Telegram", "OpenAI", "SQLite", "MCP", "macOS"], "alternates": {"html": "https://wpnews.pro/news/i-built-a-personal-ai-agent-in-swift-on-top-of-what-macos-ships", "markdown": "https://wpnews.pro/news/i-built-a-personal-ai-agent-in-swift-on-top-of-what-macos-ships.md", "text": "https://wpnews.pro/news/i-built-a-personal-ai-agent-in-swift-on-top-of-what-macos-ships.txt", "jsonld": "https://wpnews.pro/news/i-built-a-personal-ai-agent-in-swift-on-top-of-what-macos-ships.jsonld"}}