{"id":48509262,"url":"https://github.com/famclaw/famclaw","last_synced_at":"2026-05-11T05:01:09.584Z","repository":{"id":346481090,"uuid":"1185874658","full_name":"famclaw/famclaw","owner":"famclaw","description":"Self-hosted family AI gateway with parental controls. Runs on Linux, macOS, and Android (Termux) — Raspberry Pi, mini PC, old laptop, homelab server, even a phone. Telegram, Discord, web. Privacy-first, works with any LLM (local or cloud), OPA content filtering, MCP skill scanning.","archived":false,"fork":false,"pushed_at":"2026-05-06T22:55:15.000Z","size":622,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-06T23:33:44.267Z","etag":null,"topics":["ai-assistant","chatbot","chatgpt-alternative","discord-bot","family","go","homelab","llm","local-first","local-llm","mcp","ollama","openclaw","parental-control","picoclaw","privacy","raspberry-pi","self-hosted","self-hosted-ai","telegram-bot"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/famclaw.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-19T02:59:01.000Z","updated_at":"2026-05-06T21:30:03.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/famclaw/famclaw","commit_stats":null,"previous_names":["famclaw/famclaw"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/famclaw/famclaw","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/famclaw%2Ffamclaw","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/famclaw%2Ffamclaw/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/famclaw%2Ffamclaw/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/famclaw%2Ffamclaw/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/famclaw","download_url":"https://codeload.github.com/famclaw/famclaw/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/famclaw%2Ffamclaw/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32882110,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-10T13:40:02.631Z","status":"online","status_checked_at":"2026-05-11T02:00:05.975Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-assistant","chatbot","chatgpt-alternative","discord-bot","family","go","homelab","llm","local-first","local-llm","mcp","ollama","openclaw","parental-control","picoclaw","privacy","raspberry-pi","self-hosted","self-hosted-ai","telegram-bot"],"created_at":"2026-04-07T17:02:36.803Z","updated_at":"2026-05-11T05:01:09.574Z","avatar_url":"https://github.com/famclaw.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🛡️ FamClaw\n\n**A secure, local-first family AI gateway. Runs on Raspberry Pi, Mac, or any Linux box.**\n\nFamClaw is a lightweight Go gateway that connects your family to any AI model — local or cloud — through Telegram, WhatsApp, Discord, and a web interface. Every message goes through a policy engine before the AI ever sees it.\n\n---\n\n## What it is\n\n- **A gateway, not an AI.** FamClaw routes messages between your family and whatever LLM you configure — Ollama on your home server, OpenAI, Anthropic, OpenRouter, or any OpenAI-compatible endpoint.\n- **A policy enforcer.** Every message is evaluated by OPA (Open Policy Agent) before reaching the LLM. Kids get age-appropriate responses. Sensitive topics require parental approval.\n- **A family assistant.** Age-aware profiles, parental approval workflow, notification to parents via email/SMS/Slack/Discord/ntfy.\n\n---\n\n## How it works\n\n```\nFamily member sends message\n  → via Telegram / WhatsApp / Discord / Web UI\n    → FamClaw identifies user from gateway account\n      → OPA policy evaluates: allow / block / request approval\n        → if allow: forwards to your LLM endpoint\n          → streams response back\n```\n\nFamClaw itself uses ~20MB RAM. The LLM runs elsewhere — on a Mac Mini on your LAN, a cloud API, or any OpenAI-compatible server.\n\n---\n\n## Hardware\n\n| Device | Role |\n|--------|------|\n| Raspberry Pi 3/4/5 | Run FamClaw 24/7, flash SD card and plug in |\n| Mac Mini | Run as background daemon |\n| Any Linux box | One binary, no dependencies |\n\n---\n\n## LLM backends\n\nFamClaw talks to any OpenAI-compatible endpoint:\n\n| Platform | Backend | api_key needed |\n|---|---|---|\n| RPi 3/4/5 | Ollama (local, auto-installed by firstboot.sh) | No |\n| Mac Mini | Ollama (local) | No |\n| Old Android (Termux) | OpenAI / Anthropic / OpenRouter / another device's Ollama | Yes (or LAN URL) |\n| Any device | Can point at RPi's Ollama on LAN | No |\n| Any device | Claude CLI (`provider: claude_cli`) | No (uses local claude binary) |\n\n```yaml\nllm:\n  primary:\n    base_url: \"http://192.168.1.10:11434\"  # Ollama on your Mac Mini\n    model: \"llama3.2:3b\"\n\n  fallbacks:\n    - base_url: \"https://api.openai.com/v1\"\n      model: \"gpt-4o-mini\"\n      api_key: \"${OPENAI_API_KEY}\"\n```\n\n---\n\n## Quick start\n\n### Raspberry Pi (flash and plug in)\n```bash\n# Flash famclaw-rpi4-arm64.img.xz to SD card with Raspberry Pi Imager\n# Plug in, wait 2 minutes, find the device IP from your router and open:\nhttp://\u003cyour-pi-ip\u003e:8080\n```\n\n\u003e mDNS (`famclaw.local`) was removed in v0.5.x because it didn't resolve\n\u003e reliably on Windows or many home routers. Use the device's IP address\n\u003e from your router's DHCP leases page or `ip addr` on the Pi.\n\n### Mac / Linux\n```bash\ncurl -fsSL https://github.com/famclaw/famclaw/releases/latest/download/install.sh | bash\n```\n\n### Build from source\n```bash\ngit clone https://github.com/famclaw/famclaw\ncd famclaw\nmake build\n./bin/famclaw --config config.yaml\n```\n\n---\n\n## Messaging gateways\n\n| Gateway | Status |\n|---------|--------|\n| Web UI | Built — HTTP + WebSocket + embedded UI |\n| Telegram | Built — long-poll Bot API |\n| Discord | Built — via discordgo |\n| WhatsApp | Placeholder — needs whatsmeow QR pairing |\n\nEach family member's gateway account maps to their profile. Emma's Telegram account → Emma's age policy. Parent's Discord account → parent access.\n\n---\n\n## Policy system\n\nPolicies are [OPA Rego](https://www.openpolicyagent.org/) files. The default rule set lives at `internal/policy/policies/` and is **embedded in the binary** via `go:embed` — a downloaded release runs without any external policy directory. To override with custom rules, set `policies.dir` (and `policies.data_dir`) in `config.yaml` to a directory of your own `.rego` and JSON files. Run `opa test internal/policy/policies/family/ internal/policy/policies/data/ -v` to test the built-in rules locally.\n\nThree tiers per age group:\n\n```\nallow        → goes straight to LLM\nrequest_approval → parent gets notified, child waits\nblock        → never reaches LLM\n```\n\nDefault age groups: `under_8`, `age_8_12`, `age_13_17`, `parent`.\n\n---\n\n## Skills\n\nFamClaw uses the [AgentSkills](https://docs.openclaw.ai/tools/skills) spec — the same `SKILL.md` format used by OpenClaw, PicoClaw, and NanoBot. Skills from [famclaw/skills](https://github.com/famclaw/skills) work in all four runtimes. [HoneyBadger](https://github.com/famclaw/honeybadger) scans every skill before installation.\n\n```bash\nfamclaw skill install seccheck\n```\n\n---\n\n## Agent dispatch (`spawn_agent`)\n\nThe parent LLM can delegate sub-tasks to a different LLM profile via a built-in tool. Use it to send research-style or compute-heavy work to a local model (e.g., Qwen3-14B on Ollama) while the parent stays on a fast/cloud model.\n\n```jsonc\n// Tool call from the parent LLM:\n{\n  \"name\": \"builtin__spawn_agent\",\n  \"arguments\": {\n    \"prompt\": \"Summarize the key risks in the attached log\",\n    \"profile\": \"qwen3-local\",          // optional: omit to use the default profile\n    \"timeout_seconds\": 120,             // default 300, capped at 1800\n    \"tools\": [\"fs.read\", \"web.search\"], // allowlist; omit for NO MCP tools (default-deny)\n    \"deny_tools\": [\"fs.write\"]          // subtracted from the allowlist\n  }\n}\n```\n\nConcurrency is bounded by the scheduler (`subagent.NewScheduler(2)` in `cmd/famclaw/main.go`). Each `spawn_agent` invocation gets a dedicated result channel — concurrent calls do not cross-deliver. The tool is parent-only (role-gated via `turn.Tools`) and has no MCP tool access unless the parent explicitly allowlists. Lives in `internal/subagent/`.\n\n---\n\n## Web fetch (`web_fetch`)\n\nOff by default. When enabled, the LLM gets a `web_fetch` tool that retrieves a URL and returns extracted text — `text/html` is parsed via `golang.org/x/net/html` and stripped of `\u003cscript\u003e`/`\u003cstyle\u003e`/`\u003chead\u003e`; `text/plain` and `application/json` pass through. Useful for \"what's the weather\", \"look up the docs page for X\", and similar fetches.\n\nEnable in `config.yaml`:\n\n```yaml\ntools:\n  web_fetch:\n    enabled: true\n    allowed_roles: [parent]   # role gate — checked when registering the tool\n    url_allowlist:            # REQUIRED — empty list denies all (SSRF guard).\n      - wikipedia.org         #   Subdomains of an allowed host match automatically.\n      - en.wikipedia.org\n    max_bytes: 262144         # 256 KB response cap\n    timeout_seconds: 15\n```\n\nDefense in depth:\n\n- **Role gate** at registration — the tool is only added to the LLM's tool list for users in `allowed_roles`.\n- **OPA `tool_policy` rule** at the tool loop — `parent` and `age_13_17` are allowed; `under_8` and `age_8_12` are denied. Blocked calls never dispatch.\n- **URL allowlist** in `handleWebFetch` — only `http`/`https` schemes; the request host must equal an allowlist entry or be a subdomain of one. **An empty allowlist denies all fetches** (SSRF guard) — operators must list the hosts they trust. The same predicate is re-applied to every redirect target inside `webfetch.Fetch`.\n- **Private-network block** in `internal/webfetch` — the dialer resolves DNS itself and rejects loopback / RFC1918 / RFC4193 ULA / link-local / multicast / unspecified IPs, so a misconfigured allowlist or DNS-rebinding trick can't reach the home LAN.\n- **Size + timeout caps** in `internal/webfetch` — `MaxBytes` enforced via `io.LimitReader`, redirect chain capped at 5 hops, request `Timeout` from config.\n\nThe fetcher itself is in `internal/webfetch/`; the agent handler lives in `internal/agent/agent.go` (`handleWebFetch`).\n\n---\n\n## Security scanning\n\nFamClaw uses [HoneyBadger](https://github.com/famclaw/honeybadger) to scan skills at two points:\n\n**Install time.** `famclaw skill install \u003cpath\u003e` scans with HoneyBadger before writing anything to disk. FAIL verdicts block the install by default.\n\n**Runtime, asynchronously.** Tools used during a conversation are scanned in the background after the turn completes. If a scan fails, the tool is quarantined and filtered out of the next turn. This never adds latency — scanning runs in parallel with or after the response.\n\nAll behavior is configurable in `config.yaml` under the `seccheck:` section.\n\n---\n\n## Status\n\n**v0.5.0 — first deployed family release.** v0.5.1 in flight (closes the bugs surfaced by the first real-world install).\n\n### What works\n\n| Feature | Status |\n|---------|--------|\n| **Policy gate** | OPA rules for input, tool calls, and output (33 Rego tests) |\n| **Pipeline engine** | Composable stages: classify → policy → LLM → tools → output filter |\n| **Multi-backend LLM** | OpenAI-compatible: Ollama, llama.cpp, Groq, OpenAI, OpenRouter |\n| **Smart tool selection** | Token-budget-aware filtering, role+skill scoping |\n| **Context compression** | Tiered truncation keeping system prompt + pinned messages |\n| **Agent dispatch** | `spawn_agent` builtin tool — parent LLM delegates to a different profile (default-deny MCP tools, per-call timeout, scheduled with concurrency cap) |\n| **Web fetch** | `web_fetch` builtin tool (off by default) — fetch a URL and return extracted text, role-gated + OPA `tool_policy` + per-host allowlist + size/timeout caps |\n| **Skill adapters** | FamClaw (SKILL.md), OpenClaw (SOUL.md), Claude Code (.md) |\n| **Skill install** | From parent dashboard Skills tab or CLI; HoneyBadger-scanned at install time |\n| **llama.cpp sidecar** | Spawns llama-server, GGUF model catalog, TurboQuant support |\n| **Security scanning** | Honeybadger runtime stage, install-time + stale scan gates |\n| **Web UI** | Chat, parent dashboard, 5-step wizard with AI profiles, PIN-gated skill install/remove |\n| **Web auth** | Cookie-based web sessions + machine-bound credential vault (`internal/credstore`, `internal/web/middleware`); see [docs/SECURITY.md](docs/SECURITY.md) |\n| **Telegram + Discord** | Fully wired gateway bots, message chunking past per-platform limits (4096/2000 chars) |\n| **Unknown-account backend** | Strangers messaging the bot are recorded against a parent-controlled queue, never auto-promoted to a user (issue #111 backend) |\n| **MCP tools** | Multi-transport (stdio/HTTP/SSE), unified tool registry |\n| **LLM profiles** | Multiple named endpoints, per-user assignment via wizard |\n| **CI/CD** | CodeQL, govulncheck, SBOM, cosign signing, TruffleHog, race detector on gateway+agent, schema-drift gate, Telegram/Discord integration tests |\n\n### Recommended models\n\n| Hardware | Model | Why |\n|----------|-------|-----|\n| Mac Mini M1+ 16GB | `gemma4:e4b` | Native tool calling, multimodal |\n| RPi 5 8GB | `gemma4:e2b` | Fits in 3GB Q4, tool calling |\n| RPi 4 4GB | `qwen3:4b` | Best efficiency |\n| RPi 3 | Use remote | Gateway only |\n\nSee [docs/BACKENDS.md](docs/BACKENDS.md) for inference engine comparison.\n\nSee [AGENTS.md](./AGENTS.md) for the full build plan.\n\n---\n\n## Testing\n\n### Quick\n\n```bash\nCGO_ENABLED=0 go test ./... -count=1\nopa test internal/policy/policies/family/ internal/policy/policies/data/ -v\n```\n\n### Integration\n\n```bash\nCGO_ENABLED=0 go test -tags integration ./e2e/... -count=1\n```\n\nREST stubs only — no real bots, no network.\n\n### Behavioral (optional — needs local Ollama)\n\n```bash\nmake behavioral\n```\n\n13 probe×persona pairs against the assembled system prompt.\n\n### Schema golden\n\nRegenerate the SQLite schema fixture:\n\n```bash\nUPDATE_SCHEMA_GOLDEN=1 go test ./internal/store/\n```\n\n### Prompt snapshots\n\nRegenerate the four persona snapshots:\n\n```bash\nUPDATE_PROMPT_SNAPSHOTS=1 go test ./internal/prompt/\n```\n\n---\n\n## License\n\n[AGPL-3.0](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffamclaw%2Ffamclaw","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffamclaw%2Ffamclaw","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffamclaw%2Ffamclaw/lists"}