gen3ric-labs
← AI Lab Work

Mac & automation · Oct 2026 · with AFM + Claude Delivered B+

Apple Foundation Models on the command line

There is a language model built into my Mac mini, and with macOS 27 I can talk to it straight from Terminal. No account, no API key, no per-token cost.

Apple Foundation Models icon: a network of linked nodes on a green-to-blue rounded square
AFM, short for Apple Foundation Models, is the model family behind Apple Intelligence. This page covers the on-device side of it.

What AFM is

Apple's own write-up, Introducing the Third Generation of Apple's Foundation Models, describes a family of five models. Two run on the device:

The other three (AFM 3 Cloud, AFM 3 Cloud Pro and an image model) run on Apple's Private Cloud Compute servers instead of on the Mac.

AFM is not purely an Apple model. Apple says the third generation was custom-built in collaboration with Google, and coverage of the announcement describes it as built on the technology behind Gemini, adapted for Apple silicon. The largest cloud tier even runs on NVIDIA GPUs in Google Cloud under Private Cloud Compute. The on-device models are the part that stays on your Mac.

Which Macs can use it

The command line tool, fm, is pre-installed with macOS 27 (Golden Gate, released September 14, 2026). So the question is mostly which Macs can run macOS 27, and that is Apple silicon only:

Intel Macs are out entirely. Two caveats:

My machine is an M4 Mac mini with 16 GB, running macOS 27, which clears every bar above.

Using it from Terminal

First-time setup: accept the license

Open Terminal and run this once before anything else:

sudo fm license

It asks for your Mac password (that is the sudo), then shows the Legal Notice & Terms. Type yes to accept. You only need to do this the first time, and fm will not respond to prompts until it is done.

Now type fm on its own. You get a list of subcommands:

Try it

First, check that the model is there:

$ fm available
System model available

Then ask it something:

$ fm respond "Explain what a launchd agent is in two sentences."
A launchd agent is a process that runs in the background on a macOS or iOS device to perform specific tasks at defined intervals or in response to system events. It is typically managed through the launchd service and can be configured to start, stop, or monitor certain operations.

And see what that prompt cost against the context window:

$ fm count-tokens "Explain what a launchd agent is in two sentences."
12

Getting your own text in (the gotcha)

My first attempt at a summarizer was the obvious one: pipe a file in and give the prompt as an argument. The sample notes below are made up.

$ cat notes.txt | fm respond "Summarize this in one sentence."
The text discusses the importance of communication in the workplace.

That sentence is not in the notes. When a prompt argument is present, the piped text never reaches the model, and the model happily answered about nothing. There is no error, which is the dangerous part. A small model will make something plausible up rather than say it saw no input.

There are two ways that do work. Pipe the text on its own and put the task in --instructions:

$ cat notes.txt | fm respond --instructions "Summarize the text you are given in one sentence."
Beta shipped Tuesday, two open bugs in sync, next review Friday, vendor contract renewal to confirm.

Or pass the text explicitly with --text:

$ fm respond "Summarize this in one sentence." --text "$(cat notes.txt)"
Beta shipped Tuesday, two bugs open, next review Friday, vendor contract renewal needed.

If a summary looks too generic, suspect the plumbing before the model. A quick test is to put a made-up fact in the input and check that it comes back out.

Structured output for scripts

The feature that turns this from a chat toy into a building block is the schema. You describe the shape of the answer, and fm returns JSON that matches it. fm schema writes the schema file:

$ fm schema object --name ActionItems --string items --array > schema.json
$ cat schema.json
{
  "additionalProperties" : false,
  "title" : "ActionItems",
  "properties" : {
    "items" : {
      "type" : "array",
      "items" : {
        "type" : "string"
      }
    }
  },
  "x-order" : [
    "items"
  ],
  "required" : [
    "items"
  ],
  "type" : "object"
}

Then hand it to respond:

$ fm respond "List the action items in these notes." --text "$(cat notes.txt)" --schema schema.json
{"items": ["Ship the beta on Tuesday.", "Address two open bugs, both in sync.", "Schedule the next review for Friday.", "Confirm the vendor contract renewal."]}

The JSON shape is guaranteed, which makes it safe to pipe into jq or a script. The content is not: it listed "ship the beta" as an action item even though the notes say that already happened. Treat the output as a first draft.

Apple's own demo uses the same pattern to sort a folder into final and draft files by name, which is exactly the kind of fuzzy job that is miserable to write with regular expressions.

Other options

fm respond --help lists more than I have used. The ones worth knowing about:

Apple's WWDC demo shows a --model pcc option for the larger Private Cloud Compute model. On my machine, fm respond --help lists only the on-device system model, so everything on this page ran locally and I have not used the cloud option.

How fast it is

I timed it on the Mac mini (M4, 16 GB, macOS 27.0.1, plugged in) by running fm serve on a Unix socket, so I could stream the replies and read the server's own token counts. Every prompt is made up. Each one ran once to warm up and then five times; the numbers are medians.

PromptTokens inTokens outFirst tokenTotalTokens per second
One-sentence answer69290.34 s0.86 s34
About 120 words741490.39 s3.6 s41
About 300 words876270.43 s13.8 s46
Structured JSON from a short note154751.8 s1.8 s42
One sentence about a 570-token text571350.62 s1.0 s34

What the numbers say:

Limits worth knowing

Where I already use it

The voice memo router from the Voice memos that file themselves lab report transcribes each recording locally on the Mac, with no cloud service and no cost. That transcription step is a macOS Shortcut, and the Shortcut runs on AFM. So the same model family that answers fm respond is the one turning my spoken memos into text.

The natural next step is to pass each transcript through fm respond with a schema, to pull out a title, a topic and any action items, all still on my own hardware.

Where it ended up

I now have a free, private, always-available language model one keystroke away, and it slots into the same shell scripts and launchd jobs I already run. For small jobs it is the first thing I reach for. For anything long or hard, I still use a bigger model, and I check its output against the input before I trust it.

Sources: Apple Machine Learning Research and WWDC26 session 334, Build AI-powered scripts with the fm CLI and Python SDK. There is also a Python SDK, apple_fm_sdk, if you would rather script it from Python.

This is entry 24 in the AI Collaboration log.