The Mac mini in the house. Your account is already set up and waiting. By the end of this page it will be reading the news for you every morning before you are awake, and emailing you what matters.
If a box is dark, you paste it. If it is light, you read it. Every dark box is a command. You do not need to understand any of them — they have all been run and tested on this exact machine.
Work top to bottom. Steps 1 to 5 take about fifteen minutes, most of which is waiting.
Install Tailscale on your Mac and sign it in. Until that is done, none of the addresses below will work. Everything else on the Mini is ready.
Three small programs in a row. That is genuinely the whole thing.
All three are written and tested already. You do not have to write a line of code — you copy them across, then change two plain-English files: which news sources you want, and what kind of briefing you want.
The summarising happens on this Mac, using a model that already lives on its hard drive. No subscription, no account, no per-question cost, and nothing you feed it ever leaves the house. A full run takes about half a minute.
Two ways in. You will use the desktop for setting up and the terminal for everything after.
In Finder press ⌘K, enter this, and log in as jess:
vnc://ph4-compute
Open Terminal on your Mac and run:
$ ssh jess@ph4-compute
First time only, it asks whether you trust the machine — type yes. Everything from here on is typed on the Mini, not on your own Mac.
Matt has left the three programs ready for you in a shared folder. One command copies them into your account and sets up the rest:
$ cp -r /Users/Shared/agentkit ~/agents $ mkdir -p ~/agents/output ~/agents/logs $ echo 'export PATH="/opt/homebrew/bin:$PATH"' >> ~/.zprofile $ source ~/.zprofile
You now have a folder called agents in your home directory with everything in it.
The Mini needs permission to send mail as you. That is an app password — a long code that only works for sending email, that you can cancel at any time, and that is not your real password.
Go to myaccount.google.com → Security → App passwords. Create one called “PH4”. Google gives you sixteen letters — copy them.
$ nano ~/.agent-mail # paste it, then Control-O, Return, Control-X $ chmod 600 ~/.agent-mail # now only you can read the file
$ nano ~/agents/bin/send-digest.py
Near the top there is a line reading ADDRESS = "you@gmail.com". Change it to your own address, keeping the quote marks. Save and exit as before.
Two plain-English files. These are the only ones you will ever really fiddle with, and neither is technical.
$ nano ~/agents/news-digest/feeds.txt
One web address per line. It starts with BBC, the Guardian and Ars Technica. Most news sites publish one of these — search for “[site name] RSS” to find it. Delete what you do not want, add what you do.
$ nano ~/agents/news-digest/prompt.md
This is just instructions, written the way you would explain it to a person. Ask for shorter or longer, more or less serious, particular subjects emphasised. This is where you will get the most out of tinkering.
Never schedule something you have not watched work. Run it now:
$ ~/agents/news-digest/run.sh
It goes quiet for roughly half a minute while the model reads everything. Then check your inbox. Read what arrives critically — too long? wrong emphasis? Adjust prompt.md and run it again. Getting this right is the actual work, and it is worth three or four goes.
Once you are happy with what it sends:
$ nano ~/Library/LaunchAgents/com.jess.news-digest.plist
Paste this in exactly as it is, then save:
~/Library/LaunchAgents/com.jess.news-digest.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.jess.news-digest</string>
<key>ProgramArguments</key>
<array>
<string>/Users/jess/agents/news-digest/run.sh</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key><integer>6</integer>
<key>Minute</key><integer>45</integer>
</dict>
<key>RunAtLoad</key>
<false/>
</dict>
</plist>
Then switch it on:
$ launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.jess.news-digest.plist
Done. It now runs at 6:45 every morning. To change the time, edit the Hour and Minute numbers, then run the same command with bootout in place of bootstrap, and bootstrap again.
Never log out of the Mini. Use Fast User Switching in the menu bar to hand the screen back to Matt. Scheduled jobs run inside your login session — log out and they stop firing, silently, with no error. Switching users is fine; logging out is not.
Copy the folder, change the two plain-English files, give it a new name and time.
$ cp -r ~/agents/news-digest ~/agents/my-new-agent $ nano ~/agents/my-new-agent/feeds.txt # different sources $ nano ~/agents/my-new-agent/prompt.md # different instructions $ nano ~/agents/my-new-agent/run.sh # change NAME and DIR at the top
Then copy the schedule file too, giving it a new Label, the new path, and whatever time suits.
| Agent | Sources | When |
|---|---|---|
| Subject you follow | Feeds for one topic, asked to flag only genuinely new developments | Daily |
| Weekly roundup | Same feeds, but asked for themes across the week rather than headlines | Sunday evening |
| Local news | Your council and local paper feeds | Weekday mornings |
| Slow reading | Long-form and essay feeds, asked to pick the two best things and say why | Saturday |
Put “if nothing much happened, say so in one line and stop” in every prompt. An agent that dutifully sends 400 words of nothing each morning gets ignored inside a fortnight, and then it may as well not exist.
Every run writes a log. Always look there first — the messages are written in plain English on purpose:
$ cat ~/agents/logs/news-$(date +%Y-%m-%d).log
| What the log says | What to do |
|---|---|
| No email password found… | Step 3 was skipped. Create ~/.agent-mail and chmod 600 it. |
| …still has the placeholder address… | Step 3, part three. Change ADDRESS in send-digest.py. |
| Google rejected the login | Wrong app password, or you used your normal Google password. Make a fresh app password. |
| Nothing to send — empty | The feeds gave nothing back. Check the addresses in feeds.txt open in a browser. |
| Could not reach the local model | Rare. Tell Matt — the model service needs a nudge. |
| Nothing in the logs folder at all | The schedule never fired. Almost always because you were logged out. Check with launchctl list | grep jess. |
Your briefings are saved in ~/agents/output whatever happens, so even when the email fails the work is never lost.
Worth understanding, because it is unusual and it is the reason all of this is free.
The thing writing your briefings is called Gemma, and it lives on this Mac's hard drive — about 17 GB of it. When your agent runs, nothing is sent to any company. No account, no subscription, no record anywhere of what you asked.
You can also just talk to it directly, which is handy for anything you would rather not put into a website:
$ ollama run gemma4:26b
Ask it anything, press Return. Type /bye when you are done. It cannot search the web or read your files — it only knows what you tell it in the conversation — but for drafting, thinking aloud, or working through something private, it is genuinely useful and costs nothing.
It takes about 17 GB of the machine's memory while running, and Matt may have a different one loaded. It is the one thing on this Mac where you two genuinely compete. Your 6:45am runs are safely out of his way; interactive use in the evening is worth a quick word.
Everything above you set up by following instructions. This is the step where you stop needing them — you describe what you want, and something on this machine goes and builds it.
The tool is called goose. It is not a chat window: it can read your files, write new ones, run them, look at what happened, and fix its own mistakes. It runs on the same private model already on this Mac, so it is free and nothing leaves the house.
$ curl -fsSL https://github.com/block/goose/releases/download/stable/download_cli.sh | CONFIGURE=false bash
Then create its settings file with nano ~/.config/goose/config.yaml and paste this in exactly:
~/.config/goose/config.yaml
GOOSE_PROVIDER: ollama
GOOSE_MODEL: qwen3-coder:30b
OLLAMA_HOST: localhost:11434
GOOSE_MODE: approve
extensions:
developer:
enabled: true
name: developer
type: builtin
If it complains that the folder does not exist, run mkdir -p ~/.config/goose first.
approve matters
That line makes goose ask you before it does anything — every file it writes, every command it runs. It is slower, and it is the right setting while you are learning what it does. You will see exactly what it is about to do and can say no. Change it to auto later if you get tired of approving things, but not before you trust it.
$ goose session
That is it — you are in. Type what you want in plain English and press Return. It will tell you what it is doing as it goes. Type exit when you are finished.
Move to the folder you want it working in before you start, so it does not scatter files around. For a new idea: mkdir -p ~/projects/my-idea && cd ~/projects/my-idea && goose session
It can also run things for you and read what happened, which is what makes it worth having over a plain chat — ask it to write a script and try it, and it will come back and tell you whether it worked.
You may not. But it is worth knowing where the ceiling is.
The setup above is very good at one particular shape of job: here is some text, write me something about it. Summarising, condensing, drafting, pulling themes out of a pile of articles — all of that it does well and free.
What it cannot do is go and find things out. It cannot decide what to search for, follow a lead, chase a half-answer, or judge whether a source is trustworthy. If you find yourself wanting an assistant that genuinely investigates — “work out what happened with X and tell me who is right” — that is where a paid service like Claude earns its keep, and Matt can set it up alongside this.
Everything you have built stays useful either way. The fetch-and-email machinery is the same; only the middle step changes.
/Users/matt. His side of the house. Yours is /Users/jess, and it is private to you.You cannot install system-wide software — brew install will refuse. Deliberate, and not a problem: ask Matt, it takes seconds.
| Command | What it does |
|---|---|
| ssh jess@ph4-compute | Terminal on the Mini, from your Mac |
| vnc://ph4-compute | The Mini's desktop (Finder, ⌘K) |
| ~/agents/news-digest/run.sh | Run that agent right now |
| nano ~/agents/news-digest/prompt.md | Change what kind of briefing you get |
| nano ~/agents/news-digest/feeds.txt | Change where the news comes from |
| ls -lt ~/agents/output | head | Your recent briefings |
| cat ~/agents/logs/news-$(date +%F).log | What happened on today's run |
| launchctl list | grep jess | Which of your agents are scheduled |
| ollama run gemma4:26b | Talk to the private model directly |
| goose session | Start a session that can build and run things for you |
| nano <file> | Edit a file. Control-O saves, Control-X exits |
| exit | Close the connection |