How to Turn Your Mac into an Autonomous Agent with Claude Code and Codex

5 min read

The Concept

The idea is simple: an M1 MacBook Air running Claude Code permanently, acting as a personal agent you can control from your phone. You send tasks from Telegram or the Claude app, and while you’re out and about, the agent reads your backlog, executes code, creates PRs on GitHub, syncs with Notion, and notifies you when it’s done.

This is not science fiction. With the tools Anthropic released over the past few months — Remote Control, Channels, Skills, Subagents, and Hooks — you can set this up in an afternoon.

This tutorial documents the complete setup we built step by step, including integration with Obsidian for task management, Notion as a backup, GitHub for repos, and OpenAI’s Codex CLI as a second agent for code review.

What You’ll Need

Hardware:

  • A Mac with Apple Silicon (M1 or later). We used an M1 MacBook Air, but it works with any modern Mac.
  • The Mac must be powered on and plugged in 24/7.

Subscriptions:

  • Claude Pro ($20/month minimum) or Max ($100–200/month for more headroom). Remote Control requires Pro at minimum.
  • A GitHub account with a Fine-grained Personal Access Token.
  • A Notion account (the free tier works).
  • A ChatGPT account (Plus or above) if you want to use Codex CLI.

Software we’ll install:

  • Claude Code CLI (npm)
  • tmux (brew)
  • Bun (for plugins/channels)
  • Codex CLI (npm, optional)
  • Obsidian (to view the backlog)

System Architecture

The system has three layers:

Control layer — how you give instructions to the agent:

  • Claude app on your phone (Remote Control)
  • Telegram (Channels)
  • Direct terminal (tmux)
  • OS cron jobs (automatic)

Agent layer — who does the work:

  • Claude Code as the primary agent (tasks, PRDs, code, communication)
  • Codex CLI as the secondary agent (code review, tests, second opinion)

Tool layer — where it connects:

  • Obsidian vault (local markdown backlog)
  • Notion (backup and visibility)
  • GitHub (repos, PRs, issues)
  • Gmail and Google Calendar (native claude.ai connectors)

Step 1: Install Prerequisites

Terminal window
# Homebrew (if you don't have it)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Node.js, tmux, and Bun
brew install node tmux
curl -fsSL https://bun.sh/install | bash
exec /bin/zsh
# Verify
echo "Node: $(node --version) | tmux: $(tmux -V) | Bun: $(bun --version)"

If zsh tries to autocorrect tmux to _tmux, fix it with:

Terminal window
echo 'alias tmux="nocorrect tmux"' >> ~/.zshrc
source ~/.zshrc

Step 2: Install Claude Code and Authenticate

Terminal window
npm install -g @anthropic-ai/claude-code
claude --version # You need v2.1.80+

Open a session to log in:

Terminal window
cd ~
claude

Inside Claude Code:

/login # Opens the browser for OAuth with your Pro/Max account
/config # Enable "Enable Remote Control for all sessions" → true
/exit

Step 3: Create the Folder Structure

The entire workspace lives inside a single folder. Claude Code only works here.

Terminal window
# Container workspace
mkdir -p ~/claude-setup/{vault/backlog/{pending,in-progress,done},vault/prd,vault/daily-logs,projects}
# Claude Code configuration (skills, agents, scripts)
mkdir -p ~/.claude/skills/{backlog-manager,notion-sync,daily-standup,pr-creator,run-codex}
mkdir -p ~/.claude/{agents,scripts}

Step 4: The Global CLAUDE.md

This is the most important file in the setup. Claude reads it at the start of every session and it contains all the rules, conventions, and context it needs to work the way you want.

Terminal window
cat > ~/.claude/CLAUDE.md << 'EOF'
# Global Configuration
## Workspace
Everything lives inside ~/claude-setup/
- Vault (Obsidian backlog): ~/claude-setup/vault/
- Projects: ~/claude-setup/projects/
- Do NOT access files outside ~/claude-setup/ unless explicitly asked
## Task system
- Backlog lives in ~/claude-setup/vault/backlog/
- Tasks are markdown with YAML frontmatter (status, priority, project, type, assigned_to)
- Statuses: pending → in-progress → done
- Priorities: critical > high > medium > low
- When completing a task, move file to done/ and update frontmatter
- Write daily log in ~/claude-setup/vault/daily-logs/YYYY-MM-DD.md
## Code conventions
- TypeScript strict mode
- Functional components
- Conventional commits (feat:, fix:, chore:)
- Run tests before committing
EOF

Adapt this file with your own conventions, tech stack, and name.

Step 5: Create the Skills

Skills are SKILL.md files that teach Claude how to perform specific tasks. They are loaded on-demand and consume only 30–50 tokens each until activated.

The most important skill is the backlog manager:

Terminal window
cat > ~/.claude/skills/backlog-manager/SKILL.md << 'EOF'
---
name: backlog-manager
description: Use when managing tasks, reading the backlog, creating or updating tasks in the Obsidian vault
allowed-tools: Read, Write, Edit, Bash, Grep, Glob
---
# Backlog Manager
## Vault location
~/claude-setup/vault/backlog/
## Task file format
Files named YYYY-MM-DD-short-description.md with YAML frontmatter:
status, priority, project, type, assigned_to, created, completed
## Rules
1. Pick highest priority pending task with assigned_to: claude-code
2. Change status to in-progress before starting
3. After completing, move to done/ and add completed date
4. Write log entry in daily-logs/
EOF

Create additional skills for Notion sync, standup generation, PR creation, and Codex delegation. The format is always the same: YAML frontmatter with name and description, followed by instructions in markdown.

Step 6: Create the Subagents

Subagents are specialized Claude instances running in their own context. Unlike skills (instructions), subagents are independent workers.

Terminal window
cat > ~/.claude/agents/task-runner.md << 'EOF'
---
name: task-runner
description: Autonomous task executor for processing the backlog
tools: Read, Write, Edit, Bash, Grep, Glob
model: sonnet
memory: project
permissionMode: acceptEdits
---
You are an autonomous task execution agent.
Read ~/claude-setup/vault/backlog/pending/, pick the highest
priority task, execute it, update status, and write a log.
EOF

Step 7: Configure Hooks

Hooks execute code automatically at specific points in the Claude Code lifecycle. They are configured in ~/.claude/settings.json:

{
"hooks": {
"SessionStart": [{
"hooks": [{
"type": "command",
"command": "~/.claude/scripts/inject-date.sh"
}]
}],
"Notification": [{
"hooks": [{
"type": "command",
"command": "~/.claude/scripts/notify.sh \"$CLAUDE_NOTIFICATION\""
}]
}]
}
}

Support scripts:

Terminal window
# inject-date.sh — tells Claude what day it is
echo "Today is $(date '+%A, %B %d, %Y'). Current time: $(date '+%H:%M %Z')."
# notify.sh — native macOS notification
osascript -e "display notification \"$1\" with title \"Claude Code\" sound name \"Glass\""

Step 8: Connect MCP Servers

MCPs connect Claude to external services. You only need MCPs for things that aren’t on your local filesystem.

Terminal window
# Notion (official, hosted by Notion)
claude mcp add --transport http notion https://mcp.notion.com/mcp --scope user
# GitHub (requires a Fine-grained Personal Access Token)
claude mcp add --transport stdio github --env GITHUB_TOKEN=your_token -- npx -y @modelcontextprotocol/server-github --scope user
# Slack (official, if you use it)
claude mcp add --transport http slack https://mcp.slack.com/mcp --scope user

For Obsidian you don’t need MCP. The vault is just markdown files on your disk — Claude reads them directly with its native tools (Read, Write, Edit, Bash).

For GitHub, use a Fine-grained Personal Access Token (not classic) that limits access to specific repos. Create it at GitHub → Settings → Developer Settings → Fine-grained tokens, selecting “Only select repositories” and granting only Contents, Pull Requests, and Issues permissions.

MCPs that require OAuth (Notion, Slack) authenticate the first time you use them inside Claude Code.

Step 9: The Always-On Session with tmux

tmux is a terminal multiplexer that keeps processes running even after you close the window. It’s the piece that makes “always-on” possible.

Startup script:

cat > ~/.claude/scripts/start-agent.sh << 'EOF'
#!/bin/bash
SESSION_NAME="claude-agent"
if tmux has-session -t $SESSION_NAME 2>/dev/null; then
echo "Session '$SESSION_NAME' already running."
exit 0
fi
tmux new-session -d -s $SESSION_NAME
tmux send-keys -t $SESSION_NAME 'cd ~/claude-setup/projects && claude --remote-control --dangerously-skip-permissions' Enter
echo "Claude agent started in tmux session '$SESSION_NAME'"
echo "Attach: tmux attach -t $SESSION_NAME"
echo "Detach: Ctrl+B, then D"
echo "Kill: tmux kill-session -t $SESSION_NAME"
EOF
chmod +x ~/.claude/scripts/start-agent.sh

To use it:

Terminal window
~/.claude/scripts/start-agent.sh # Launch
tmux attach -t claude-agent # View the session
# Ctrl+B, D # Detach
tmux kill-session -t claude-agent # Kill

Once running, copy the Remote Control URL and open it on your phone. From that point on, everything is controlled from your phone.

Note on --dangerously-skip-permissions: this flag gives Claude full access without confirmation prompts. It’s necessary for fully autonomous operation (so it doesn’t wait for your approval on every action), but it means Claude can execute any command. That’s why we constrain its scope in CLAUDE.md to ~/claude-setup/.

Step 10: Crons for Automation

OS cron jobs run tasks periodically using Claude Code in headless mode (-p). Each run starts a clean session.

Terminal window
# crontab -e
# Run backlog tasks every 2 hours
0 */2 * * * ~/.claude/scripts/cron-wrapper.sh backlog
# Sync to Notion every 4 hours
0 */4 * * * ~/.claude/scripts/cron-wrapper.sh sync
# Daily standup at 9pm
0 21 * * * ~/.claude/scripts/cron-wrapper.sh standup

On macOS, you need to grant Full Disk Access to /usr/sbin/cron in System Settings → Privacy & Security for crons to work.

Codex as a Second Agent

Optionally, you can install OpenAI’s Codex CLI as a secondary agent for code review and testing:

Terminal window
npm install -g @openai/codex

The run-codex skill and codex-reviewer subagent we configured use it like this:

Terminal window
codex exec "Review these files for bugs and security issues" --sandbox read-only

Claude Code orchestrates: it decides when to delegate to Codex, passes the context, receives the result, and integrates it with its own analysis. It’s an automatic second pair of eyes.

The Daily Workflow

  1. When you turn on the Mac: ~/.claude/scripts/start-agent.sh
  2. Create tasks: from your phone via Remote Control, or by creating files in ~/claude-setup/vault/backlog/pending/
  3. Claude executes: automatically (crons) or on demand (when you ask from your phone)
  4. Review results: in Obsidian, in Notion, or by asking “what did you do today”
  5. Code review: Codex reviews automatically when Claude delegates to it

Context Management

The Remote Control session accumulates context. To keep it clean:

  • Crons always run in isolated sessions (clean context every time)
  • Subagents run in their own context (they don’t pollute the main session)
  • Restart the session: tmux kill-session -t claude-agent && ~/.claude/scripts/start-agent.sh
  • With Opus 4.6 you have 1M tokens of context, so it takes a long time to fill up
  • Claude performs automatic compaction when approaching the limit

Limitations to Keep in Mind

  • The Mac must be powered on and awake for everything to work
  • --dangerously-skip-permissions grants full access. Only use it on your personal machine
  • GitHub Fine-grained tokens expire (I recommend 90-day expiry) and need to be renewed
  • Obsidian → Notion sync is one-directional. Notion is just a mirror
  • Remote Control generates a new URL every time you restart the session
  • Each cron execution consumes tokens from your Claude plan

Next Steps

  • Telegram Channel: control the agent from Telegram instead of (or in addition to) Remote Control
  • Agent Teams: for large tasks, launch teams of agents that work in parallel
  • More MCPs: Slack, Linear, Figma, Playwright for visual testing
  • Codex Cloud: when OpenAI launches it, Codex tasks could run in the cloud without depending on your Mac
  • Claude Code on the web: Anthropic is developing cloud sessions that don’t depend on your local machine

Setup built in March 2026 using Claude Code v2.1.80+, Codex CLI, and macOS Sequoia on an M1 MacBook Air.