An open-source framework for deploying autonomous AI CEOs that run onchain businesses.
FreeTurtle gives you an AI agent that operates as your project's CEO. It posts to Farcaster, responds to mentions, writes strategy briefs, manages GitHub repos, queries databases, reads smart contracts, and chats with you via Telegram. Everything it knows and does is stored as readable files (Markdown and JSON) that both you and the agent can edit. You define its identity, voice, and goals in a single soul.md file, set up cron schedules and tool access in config.md, and let it run. It modifies itself when you ask, requires your approval for anything destructive, and logs every action to an audit trail.
Coming soon: public-facing DMs with XMTP, wallet balance tracking, onchain actions (autonomous onchain transactions, creating bounty tasks via a TaskBoard contract, funding them with ETH, reviewing submissions, and paying contributors).
Beta software. FreeTurtle is under active development. Expect bugs, breaking changes, and rough edges. If you run into issues, please open a GitHub issue or reach out directly.
- X: @mattleefc
- Farcaster: @mattlee
FreeTurtle is a long-running daemon — it needs a machine that stays on 24/7.
Give your turtle its own dedicated machine using hardware you already own.
- Raspberry Pi — a $35-80 single-board computer that runs headless, draws ~5W of power, and is perfect for always-on daemons. A Pi 4 (4GB+) or Pi 5 handles FreeTurtle easily. Install the 64-bit Raspberry Pi OS Lite, plug in ethernet, and SSH in.
- Any old laptop or desktop — repurpose it as a dedicated FreeTurtle box.
If you want something accessible from anywhere without keeping a local machine running:
- Oracle Cloud — 2 CPUs, 12 GB RAM, always free ARM instance. Our setup guide walks through everything from account creation to SSH.
- Railway — deploy from a repo or Dockerfile, easy scaling, free trial available.
- Fly.io — runs containers close to users globally, generous free tier.
- DigitalOcean — straightforward VPS starting at $4/mo.
- Hostinger — budget-friendly VPS plans.
Before running init, create a separate identity for your CEO:
- Google account — use it to sign up for everything below
- Farcaster — the account your CEO will post from
- Neynar — API access for Farcaster (sign up at dev.neynar.com)
- GitHub — if your CEO will manage repos, give it its own account
The CEO is effectively a team member who needs its own accounts.
# Install Node.js and pnpm (if not already installed)
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt-get install -y nodejs
sudo npm install -g pnpm
# Install FreeTurtle
sudo pnpm install -g freeturtle
# Set up your CEO (interactive wizard)
freeturtle init
# Start the daemon
freeturtle start
# Keep it running after reboot (macOS or Linux)
freeturtle install-serviceThe setup wizard walks you through naming your AI CEO, picking an LLM provider, connecting Farcaster, Telegram, GitHub, and more.
If you want your CEO to auto-respond to Farcaster mentions and replies, you need webhooks. This requires HTTPS, which means a domain and a reverse proxy.
The quickest path:
- Get a free subdomain at duckdns.org
- Install Caddy (
sudo apt install -y caddy) — it handles HTTPS automatically - Run
freeturtle webhooksto register with Neynar
See the Oracle Cloud setup guide for full instructions.
FreeTurtle is a Node.js daemon that mostly sleeps and wakes up when:
- A cron timer fires (e.g. "post to Farcaster every 8 hours")
- A heartbeat fires (e.g. "check if anything needs attention every 30 minutes")
- The founder sends a message via Terminal or Telegram
- A webhook event arrives (e.g. someone mentions the CEO on Farcaster)
All four route to the same task runner, which:
- Loads
soul.md(the CEO's identity and voice) - Loads recent memory (posting log, post queue, long-term memory, daily memory)
- Collects tools from active modules
- Calls the LLM (Claude or OpenAI)
- Checks policy allowlists and approval requirements before executing tools
- Handles tool calls in a loop (with automatic retry on transient failures)
- Logs every tool call to the audit trail
- Persists results to workspace files
┌──────────────────────────────────────────────────────┐
│ FreeTurtle Daemon │
│ │
│ ┌──────────┐ ┌──────────┐ ┌───────┐ ┌──────────┐ │
│ │ Scheduler │ │ Channels │ │ IPC │ │ Webhooks │ │
│ │ (cron) │ │ Terminal │ │ send/ │ │ Farcaster│ │
│ │ │ │ Telegram │ │approve│ │ mentions │ │
│ └─────┬─────┘ └────┬─────┘ └───┬───┘ └────┬─────┘ │
│ │ │ │ │ │
│ └──────┬──────┘────────────┘───────────┘ │
│ ▼ │
│ ┌──────────────┐ │
│ │ Task Runner │ │
│ │ soul + memory│ │
│ │ + LLM + tools│ │
│ └──────┬───────┘ │
│ ▼ │
│ ┌─────────────────────────────────────┐ │
│ │ Policy ─► Approval ─► Retry │ │
│ │ allowlists founder gate backoff │ │
│ └──────────────────┬──────────────────┘ │
│ ▼ │
│ ┌───────────────────────────────────────────────┐ │
│ │ Modules │ │
│ │ Workspace│Farcaster│Database│ GitHub │ Onchain │ │
│ └───────────────────────────────────────────────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ Audit Log │ │
│ └───────────┘ │
└──────────────────────────────────────────────────────┘
freeturtle init # Set up a new AI CEO
freeturtle start # Start the daemon
freeturtle start --chat # Start with interactive terminal chat
freeturtle status # Show daemon status
freeturtle send "message" # Send a message to the running CEO
freeturtle setup # Reconfigure LLM provider
freeturtle connect farcaster # Set up Farcaster signer
freeturtle webhooks # Set up Neynar webhooks (mentions, replies, watched users/channels)
freeturtle approvals # List pending approval requests
freeturtle approve <id> # Approve a pending action
freeturtle reject <id> # Reject a pending action
freeturtle health # Verify daemon is healthy
freeturtle update # Update to the latest version
freeturtle install-service # Install as a system service (launchd on macOS, systemd on Linux)Read and write files in the CEO's own workspace. This is how the CEO modifies itself — updating its identity, voice, goals, config, memory, and notes.
| Tool | Description |
|---|---|
read_file |
Read any file in the workspace |
write_file |
Write or overwrite a file (soul.md/config.md/.env require approval) |
edit_file |
Find-and-replace within a file (soul.md/config.md/.env require approval) |
list_files |
List files and directories |
append_memory |
Append a note to today's daily memory log |
memory_search |
Search across all memory files, session notes, reflections, and strategy docs |
All paths are sandboxed to ~/.freeturtle/ — the CEO cannot escape its workspace.
Post and read casts via the Neynar API.
| Tool | Description |
|---|---|
post_cast |
Post a cast, optionally to a channel with embeds |
read_channel |
Read recent casts from a channel |
read_mentions |
Read notifications and mentions |
reply_to_cast |
Reply to a cast by hash |
delete_cast |
Delete a cast (requires founder approval) |
Env: NEYNAR_API_KEY, FARCASTER_SIGNER_UUID, FARCASTER_FID
FreeTurtle can listen for Farcaster events in real-time via Neynar webhooks. Set up during freeturtle init or later with freeturtle webhooks.
Supported event types:
- Mentions — someone @'s your CEO
- Replies — someone replies to your CEO's casts
- Specific users — watch casts from certain accounts
- Channels — watch new casts in Farcaster channels
The daemon runs a built-in HTTP server that receives webhook events, filters spam (Neynar user score), rate-limits per user, deduplicates, and routes events through the CEO.
Env: WEBHOOK_ENABLED, WEBHOOK_PORT, NEYNAR_WEBHOOK_SECRET (optional), WEBHOOK_WATCH_FIDS (optional)
Query a PostgreSQL database (read-only).
| Tool | Description |
|---|---|
query_database |
Execute a read-only SQL query (SELECT only) |
list_tables |
List all tables with column names and types |
Env: DATABASE_URL
Create issues, list issues, and commit files.
| Tool | Description |
|---|---|
create_issue |
Create an issue on a repo |
list_issues |
List issues for a repo |
commit_file |
Create or update a file via commit (main branch requires approval) |
Env: GITHUB_TOKEN
Read smart contracts, balances, and transactions on Base.
| Tool | Description |
|---|---|
read_contract |
Read data from a smart contract |
get_balance |
Get ETH balance of an address |
get_transactions |
Get recent transactions (requires BaseScan key) |
Env: RPC_URL, BLOCK_EXPLORER_API_KEY (optional)
FreeTurtle stores everything in ~/.freeturtle/:
~/.freeturtle/
├── soul.md # CEO identity and voice
├── config.md # Modules, cron schedules, LLM settings
├── .env # API keys and secrets
└── workspace/
├── HEARTBEAT.md # Heartbeat checklist
├── MEMORY.md # Curated long-term memory
├── memory/
│ ├── YYYY-MM-DD.md # Daily memory logs
│ ├── posting-log.json
│ ├── post-queue.json
│ └── session-notes/
├── reflections/ # Soul evolution proposals
├── audit/ # Daily audit logs
├── approvals/ # Pending/resolved approval requests
└── strategy/
Defines who your CEO is — name, voice, knowledge, goals, and boundaries. Written in plain Markdown. Edit it anytime.
Controls the daemon. Markdown format:
## LLM
- provider: claude_api
- model: claude-sonnet-4-5
- max_tokens: 4096
## Cron
### post
- schedule: 0 */8 * * *
- prompt: Check for queued posts. If there's something worth sharing, share it.
### strategy
- schedule: 0 4 * * 0
- prompt: Analyze posting history and engagement. Write a strategy brief.
- output: strategy/{{date}}.md
## Modules
### farcaster
- enabled: true
### database
- enabled: true
## Policy
### github
- approval_required_branches: main
### approvals
- timeout_seconds: 300
- fail_mode: denyThe setup wizard (freeturtle setup) supports five LLM providers: Claude Pro/Max (subscription), ChatGPT Plus/Pro (subscription), Anthropic API, OpenAI API, and OpenRouter.
API keys. Generated by freeturtle init. Never committed to git.
ANTHROPIC_API_KEY=sk-...
NEYNAR_API_KEY=...
FARCASTER_SIGNER_UUID=...
FARCASTER_FID=...
TELEGRAM_BOT_TOKEN=...
TELEGRAM_OWNER_ID=...
GITHUB_TOKEN=...
DATABASE_URL=postgres://...
RPC_URL=https://mainnet.base.org
FreeTurtle CEOs can modify their own behavior at runtime. Everything that defines the CEO — identity, voice, goals, config, memory — is a file in the workspace, and the CEO has tools to read and write those files.
Examples of what you can tell your CEO:
- "Be more direct and honest" — CEO edits the Voice section of
soul.md(requires your approval) - "Remember that @rish posts interesting stuff" — CEO appends to today's daily memory or updates
MEMORY.md - "Change posting to every 4 hours" — CEO edits the cron schedule in
config.md(requires approval, takes effect on restart) - "Add a goal about growing the Discord" — CEO edits the Goals section of
soul.md(requires approval) - "Write a brief on this week's engagement" — CEO writes to
workspace/strategy/
Changes to core files (soul.md, config.md, .env) always require founder approval. Memory and notes writes go through freely.
FreeTurtle enforces per-module allowlists and requires founder approval for destructive actions.
Add a ## Policy section to config.md:
## Policy
### github
- allowed_repos: myorg/myrepo, myorg/other-repo
- allowed_paths: strategy/, docs/
- approval_required_branches: main
### farcaster
- allowed_channels: tortoise, music
### onchain
- allowed_contracts: 0x1234...
- allowed_read_functions: balanceOf, totalSupply
### approvals
- timeout_seconds: 300
- fail_mode: denyAllowlist rules:
- Not set — allow all (no restriction)
- Empty list — deny everything
- Populated list — only allow listed values
Some actions require founder approval before execution:
delete_cast— always requires approvalcommit_fileto a protected branch (default:main) — requires approvalwrite_file/edit_filetosoul.md,config.md, or.env— requires approval
When approval is needed, FreeTurtle notifies you via Telegram/terminal with the approval ID. You can then:
freeturtle approvals # See pending requests
freeturtle approve <id> # Allow the action
freeturtle reject <id> # Block the actionIf no decision is made within the timeout (default 5 minutes), the action is denied (configurable via fail_mode).
Every task run is logged to workspace/audit/YYYY-MM-DD/{runId}.json with:
- Tool calls made (with redacted inputs)
- Duration, retries, approval decisions
- Success/error status
All external API calls (Neynar, GitHub, Postgres, BaseScan, RPC) are wrapped with:
- Automatic retry with exponential backoff + jitter
- Timeout protection (30s default)
- Smart error classification (retry on 429/5xx/network errors, fail fast on 4xx)
FreeTurtle is designed to be safe to run locally:
- Shell execution with env security — commands run directly, but dangerous environment variables (PATH, HOME, LD_, DYLD_, NODE_OPTIONS) are blocked
- Sandboxed workspace — file access is restricted to
~/.freeturtle/, path traversal is blocked - Protected self-modification — changes to soul.md, config.md, and .env require founder approval
- Closed tool set — only the tools defined by enabled modules are available
- Policy allowlists — per-module restrictions on repos, paths, channels, contracts
- Founder approval — destructive actions require explicit approval before execution
- Read-only database — all SQL runs in read-only transactions
- Read-only onchain — no wallet, no signing, no transactions
- Founder-only chat — Telegram only responds to the configured founder ID
- Webhook spam filtering — Neynar user score, per-user rate limiting, duplicate detection
- Audit trail — every tool call is logged with redacted inputs
Your .env file contains API keys and tokens. FreeTurtle automatically sets it to chmod 600 (read-only by the file owner) when writing it.
- Never commit
.envto git. It's in.gitignoreby default — don't override this. - Never paste secrets into AI coding tools. Tools like Claude Code, Codex, Cursor, and Copilot may log or transmit your input. If an AI tool asks you to paste an API key, token, or recovery phrase into chat — don't. Enter secrets only through FreeTurtle's setup wizard, which writes directly to
.envon your local machine. - Rotate keys if exposed. If a secret is accidentally committed, posted, or shared, revoke it immediately and generate a new one. Treat every key as compromised the moment it leaves your machine.
- Your Farcaster recovery phrase is the most sensitive secret. It controls the entire account. FreeTurtle only uses it once during
connect farcasterto sign a key request locally — it is never stored or transmitted.
- Download your SSH private key when creating the instance — you can't retrieve it later
- Store it securely (e.g.
~/.ssh/) withchmod 400 - Don't share it or commit it to any repository
- If lost, you lose access to the server
.envis in.gitignore— don't remove it- If you version-control your
~/.freeturtle/config, exclude.env - If you accidentally commit secrets, rotate them immediately — git history is permanent
- Oracle Cloud has two firewalls: the cloud security list AND the OS-level iptables
- Only open ports you actually need
- SSH (port 22) is open by default — everything else is closed
- See the Oracle setup guide for details
Your cloud provider (Oracle, Railway, Fly.io, DigitalOcean, etc.) has full access to the underlying infrastructure — they can technically read any file on your VM. This is true of all cloud computing and is covered by their terms of service. For most use cases this is fine. If this is unacceptable for your threat model, run FreeTurtle on hardware you physically control (e.g. a Raspberry Pi or a spare laptop).
- v0.2 — XMTP integration (public-facing DMs), onchain actions
- Future — Hosted dashboard, multi-CEO management
Apache 2.0 — see LICENSE.