Local Claude desktop agentAgent SDK as a subprocessSource-verified, April 19 2026

A local Claude desktop agent that actually uses your Mac, not just your chat window

Claude Desktop can reach MCP servers if you hand-edit claude_desktop_config.json. Fazm ships a signed Mac app that spawns the Claude Agent SDK as a local Node.js subprocess, pre-wired with four native MCP servers so Claude can read your focused window, click a real button by role, and reply to a WhatsApp thread, all without a screenshot and without you editing a config file. The subprocess literally runs on your host.

F
Fazm
12 min read
4.9from 200+
Claude Agent SDK hosted in a Node subprocess on your Mac, not a tab
Four native MCP servers bundled: playwright, macos-use, whatsapp, google-workspace
Every file, line number, and timeout in this page is verifiable in the open-source repo
4 MCP

acp-bridge/package.json line 15 depends on @agentclientprotocol/claude-agent-acp ^0.29.2. At startup, Swift's ACPBridge calls findNodeBinary(), then spawns `node --max-old-space-size=256 --max-semi-space-size=16 acp-bridge/dist/index.js` (ACPBridge.swift line 343). The bridge resolves Contents/MacOS/mcp-server-macos-use (index.ts line 63) and, if existsSync() is true, registers it as the MCP server `macos-use`. All session/request_permission calls are auto-approved inside index.ts lines 573-585. Tool watchdog budgets: 10s internal / 120s MCP / 300s default (index.ts lines 77-79).

acp-bridge and Desktop/Sources/Chat/ACPBridge.swift in the Fazm open-source repo

Apps a local Claude desktop agent can reach on Fazm

Any app that implements macOS Accessibility. The macos-use MCP hands Claude the focused window's AX tree. The whatsapp MCP drives the Catalyst app directly. The google-workspace MCP hits Gmail, Drive, and Calendar under your own Google account. No special integration required per app.

MailCalendarNotesMessagesRemindersSafariChromeFinderXcodeNumbersKeynotePagesSystem SettingsSlackDiscordNotionLinearFigmaZoomVS CodeTerminaliTermWhatsAppGmailDriveDocs

The bridge is a subprocess, not a library

Swift does not link the Agent SDK. It spawns it. That isolation is what makes the watchdog and auto-approve work. Here is what the process graph looks like once Fazm is up.

What Fazm spawns when you press Download and open the app

FazmApp (Swift)
Onboarding UI
Floating control bar
Mic + keyboard input
ACPBridge (Node child)
mcp-server-macos-use
whatsapp-mcp
google-workspace-mcp
playwright MCP
fazm_tools socket
api.anthropic.com
0Native MCP servers bundled in the app
0MB Node heap budget for the bridge
0Second timeout for internal tools
0Second timeout for external tools
0auth modes: personalOAuth or bundledKey
0JSON line per tool event, on stdout
0API keys required to try Fazm with your Claude Max

The one dependency line that makes Fazm a Claude agent

Open the repo, read the package.json of the bridge, you see which SDK is doing the real work. Fazm is not reimplementing Claude Code. It is running the same agent SDK that Claude Code uses, wrapped in an ACP connection so Swift can stream events from it.

acp-bridge/package.json

The Swift call that spawns your local Claude

This is the real call. The flags are real. A 256 MB heap is deliberate, it keeps the agent's memory footprint under control while still leaving headroom for tool result buffers. The env switch below the Process spawn is how Fazm decides whether to use your Claude Max subscription or the bundled key.

Desktop/Sources/Chat/ACPBridge.swift, lines 341-353

The five MCP servers every new install gets for free

There is nothing to configure. The bridge walks its own app bundle on startup, and for every binary it finds at an expected path, it registers that binary as an MCP server over stdio. No UI, no JSON editor, no clipboard-pasted tokens.

playwright

Real Chromium with an extension hook. Fazm's default browser MCP when Claude needs a web surface. Spawned from node_modules/@playwright/mcp/cli.js inside the app bundle.

macos-use

A bundled Go binary at Contents/MacOS/mcp-server-macos-use. Exposes the live AXUIElement tree as MCP tools. Claude can read the focused window, click by role, type into fields, without ever taking a screenshot.

whatsapp

Contents/MacOS/whatsapp-mcp. Drives the native WhatsApp Catalyst app through accessibility APIs. Claude can search chats, open a thread, read messages, and send a reply.

google-workspace

Python MCP server at Contents/Resources/google-workspace-mcp. PYTHONHOME is pinned to the bundled .venv so it runs without any system Python. Claude reads Gmail, Drive, Calendar, Docs from your own Google account.

fazm_tools

Unix-socket MCP server Swift exposes for in-app operations: capturing the active window with ScreenCaptureKit, reading clipboard, triggering recordings, manipulating skills. Claude calls it like any other MCP tool.

Your own MCP servers

Drop JSON into ~/.fazm/mcp-servers.json and the bridge appends them at startup. Same schema as Claude Code's mcpServers. Your custom stdio or HTTP MCPs sit next to the bundled ones with no UI work.

How macos-use gets added to the local Claude's toolbelt

One existsSync check. One push. The rest is the Agent SDK's MCP plumbing. If you drop a JSON entry into ~/.fazm/mcp-servers.json, the loop beneath this block appends your server next to the bundled ones on the very next restart.

acp-bridge/src/index.ts, lines 1056-1064

What Fazm does in the first 400 milliseconds after launch

The sequence is linear and deterministic. Nothing depends on a user toggling a setting. This is why the agent reaches every MCP tool the first time you type a prompt, not after a restart.

1

1. Locate a bundled Node runtime

Swift's findNodeBinary() picks a Node runtime shipped inside the signed app bundle. No Homebrew, no nvm, no user-installed Node on PATH. ACPBridge.swift line 1443.

2

2. Spawn the bridge with a 256 MB heap

Swift runs node --max-old-space-size=256 --max-semi-space-size=16 against acp-bridge/dist/index.js. A tight heap so the agent does not eat your laptop. ACPBridge.swift line 343.

3

3. Pick the auth mode

personalOAuth strips ANTHROPIC_API_KEY from the subprocess env so the local Claude Agent SDK reaches Anthropic over the user's own OAuth, i.e. their Claude Pro or Max subscription. bundledKey sets ANTHROPIC_API_KEY for direct API billing. ACPBridge.swift lines 193-204, 349-353.

4

4. Boot the patched ACP entry

Node loads patched-acp-entry.mjs, which imports ClaudeAcpAgent and runAcp from @agentclientprotocol/claude-agent-acp@^0.29.2, then monkey-patches createSession and prompt to surface real token cost, rate-limit events, compaction boundaries, and tool progress. acp-bridge/src/patched-acp-entry.mjs.

5

5. Register four native MCP servers

The bridge walks the Contents/Resources and Contents/MacOS directories of the app bundle, checks existsSync() on each binary, and registers four MCP servers in one shot: playwright, macos-use (accessibility), whatsapp (Catalyst), google-workspace (Python). acp-bridge/src/index.ts lines 1049-1100.

6

6. Auto-approve tool permissions

When the ACP agent sends session/request_permission, the bridge replies with outcome.selected using the first allow_always or allow_once option. This matches Claude Code's bypassPermissions behaviour so the agent finishes tasks without prompting every 10 seconds. acp-bridge/src/index.ts lines 573-585.

The path a single prompt takes through the local agent

Prompt goes in. Token deltas and tool calls come out. Everything between those two events happens on your Mac, with one exception, the HTTPS round trip to Anthropic's model endpoint.

Prompt to action, inside Fazm

1

Your prompt

Typed into the Fazm chat, or spoken into the mic

2

Swift ACPBridge

Passes the prompt to the Node subprocess as JSON lines over stdin

3

Patched ACP agent

ClaudeAcpAgent.prompt() runs inside the local subprocess

4

Claude API call

Anthropic over HTTPS, billed to your Claude Max or Fazm's key

5

Tool use round

Claude emits a tool_use targeting one of the bundled MCP servers

6

macos-use or fazm_tools

Executes locally on your Mac, returns structured text or AX data

7

Result stream

Token deltas, thinking, tool progress forward to the Fazm UI

Why the agent does not prompt you on every tool call

If you have tried to automate a macOS workflow with Claude Desktop, you have seen the approval dialog. Fazm removes the dialog the same way Claude Code's bypassPermissions flag does: the bridge intercepts the JSON-RPC session/request_permission call and returns the first allow_always option. You can still stop an agent run from the Fazm UI at any time.

acp-bridge/src/index.ts, lines 573-585

What the startup log looks like on a real Mac

The bridge writes one line per MCP registration and one line per tool decision. Tail the log file and you can watch the local Claude agent boot, load its servers, and respond to the first prompt.

/tmp/fazm-dev.log

Fazm vs Claude Desktop, for using your Mac

Both run locally. One of them is built to reach your apps out of the box.

FeatureClaude DesktopFazm local Claude agent
Where Claude actually runsA chat window that talks to api.anthropic.com from a renderer processA signed Mac app that spawns @agentclientprotocol/claude-agent-acp as a child process on your Mac
How Claude reaches macOS appsIt does not, unless the user configures MCP servers themselvesBundled mcp-server-macos-use binary reads the live AXUIElement tree over an MCP stdio socket
Permission to act on your behalfPer-tool approval dialog on every callAll session/request_permission calls auto-approved in the bridge (bypassPermissions equivalent)
Runaway-tool safetyNo budget: tools can hang foreverTool timeout watchdog: 10s internal, 120s MCP, 300s default, user-overridable via FAZM_TOOL_TIMEOUT_SECONDS
AuthOne mode: your Claude account via Anthropic's first-party OAuthTwo modes, both local: personalOAuth (your Claude Pro/Max) or bundledKey (Fazm's Anthropic key)
MCP configuration surfaceHand-edit claude_desktop_config.json and restartFour servers pre-wired out of the box; ~/.fazm/mcp-servers.json for extras
Shape of the deliverableOfficial Mac .dmg but MCP servers are your problemSigned, notarized DMG. Double-click install

Claude Desktop is excellent at what it does, which is conversation plus optional MCP. Fazm's angle is the pre-wired agent-over-subprocess shape.

What the local Claude desktop agent actually does, after boot

Every behavior below is a line in the repo. Click any and the FAQ points you to the file.

Runtime behaviors shipped in every Fazm install

  • Reads the focused window's AX tree without screenshots
  • Clicks by role and description, not by pixel
  • Stays on your Mac between model calls (AX stays local)
  • Runs concurrent sessions with per-session ContinuationBox
  • Survives stuck tools via a per-tool wall-clock watchdog
  • Forwards compaction, rate limits, and task events to the UI
  • Accepts user MCP servers from ~/.fazm/mcp-servers.json
  • Uses Playwright MCP extension mode against real Chrome

Questions worth answering before you install

Frequently asked questions

What does 'local Claude desktop agent' actually mean in Fazm?

It means Claude's agent loop runs as a child process on your Mac, not in a web tab. Fazm ships a bundled Node.js runtime, and Swift spawns node --max-old-space-size=256 against acp-bridge/dist/index.js. The bridge imports ClaudeAcpAgent from @agentclientprotocol/claude-agent-acp@^0.29.2 (see acp-bridge/package.json line 15) and hosts the agent on your box. All MCP servers it talks to are also local processes on the same machine. The only thing that leaves your Mac is the actual HTTPS call to Anthropic's model endpoint.

How is this different from just opening Claude Desktop and editing claude_desktop_config.json?

Claude Desktop is a chat app that can call MCP servers you configure yourself. Fazm ships the Claude Agent SDK (the same subprocess-oriented runtime Claude Code uses) plus four native MCP servers pre-wired: mcp-server-macos-use for accessibility, whatsapp-mcp, google-workspace-mcp, and Playwright MCP. No config editing, no path juggling, no missing binaries. The agent also auto-approves tool permissions inside the bridge (session/request_permission is answered with the first allow_always option, see acp-bridge/src/index.ts lines 573-585), so it finishes multi-step tasks without prompting you on every tool call.

Which MCP servers are bundled, and where are they on disk?

Five in total. playwright from node_modules/@playwright/mcp/cli.js inside the bundle. macos-use as a Go binary at Contents/MacOS/mcp-server-macos-use. whatsapp at Contents/MacOS/whatsapp-mcp. google-workspace as a Python server at Contents/Resources/google-workspace-mcp with its own .venv. fazm_tools as a Unix-socket server Swift exposes for in-app operations. The registration code is in acp-bridge/src/index.ts, the BUILTIN_MCP_NAMES set on line 1266 names them all.

Do I need an Anthropic API key?

No. Fazm ships with two auth modes. personalOAuth uses your own Claude account via Anthropic's OAuth (your Pro or Max subscription covers the usage). bundledKey uses Fazm's Anthropic key. The mode is picked inside ACPBridge.swift at lines 193-204 and applied to the subprocess environment at lines 349-353. When personalOAuth is selected, ANTHROPIC_API_KEY is explicitly removed from the env so the SDK falls back to OAuth.

Does the agent hang forever if a tool call gets stuck?

No. The bridge runs a watchdog per tool call. TOOL_TIMEOUT_INTERNAL_MS is 10 seconds for ToolSearch and similar lookups. TOOL_TIMEOUT_MCP_MS is 120 seconds for anything starting with mcp__. TOOL_TIMEOUT_DEFAULT_MS is 300 seconds otherwise. On timeout the bridge synthesizes a completed-with-error event so Claude can recover, and the Swift side unblocks. You can override the budget via the Settings > Advanced > Tool Timeout control, which sets FAZM_TOOL_TIMEOUT_SECONDS. See acp-bridge/src/index.ts lines 77-120.

Where does my screen data go?

Nowhere by default. macos-use reads the live AXUIElement tree on your Mac, so what the agent sees is a structured string graph, not a bitmap. Only when a tool explicitly asks for a screenshot does ScreenCaptureManager in the Swift side grab a window capture, and that still only leaves your Mac if Claude includes it in the next model call. The AX tree never leaves your Mac. You can tail /tmp/fazm.log to audit every tool invocation.

Can I run two Claude tasks at once in one Fazm instance?

Yes. The Swift ACPBridge keeps per-session continuation boxes, pending message queues, interrupt flags, and tool counters. ACPBridge.swift lines 272-285 hold those maps. Each call to query() gets its own ContinuationBox, so a long-running automation in one session does not block a quick Q&A in another. The ACP subprocess routes responses back by sessionId.

How is this different from Claude's computer-use model?

Computer-use is a vision-based agent that sees a screenshot and outputs coordinates. Fazm's local Claude desktop agent uses tool calls into mcp-server-macos-use and talks to the real AXUIElement tree. No screenshot round trip, no pixel coordinates, no resolution dependence. You still get the computer-use model as a fallback when you ask for it, but it is the exception, not the default.

Can I drop my own MCP server in without rebuilding Fazm?

Yes. Put a JSON entry into ~/.fazm/mcp-servers.json using the same schema as Claude Code's mcpServers block: command, args, env, enabled. On next bridge start, the loop in acp-bridge/src/index.ts lines 1102-1130 appends your server to the four bundled ones and exposes its tools to the local Claude agent.

Is any of this open source so I can verify the claims?

Yes. Fazm is MIT licensed at github.com/mediar-ai/fazm. Every file and line number cited on this page exists in that repo on 2026-04-19. The ACP bridge lives in acp-bridge/src/. The Swift bridge lives in Desktop/Sources/Chat/ACPBridge.swift. The package.json declaring @agentclientprotocol/claude-agent-acp@^0.29.2 is at acp-bridge/package.json line 15.

Try the local Claude desktop agent

A signed Mac app, a Node subprocess running the Claude Agent SDK, and four bundled MCP servers. Bring your Claude Pro or Max subscription, or let Fazm use its own key. Read the source on github.com/mediar-ai/fazm.

Download Fazm for Mac
fazm.AI Computer Agent for macOS
© 2026 fazm. All rights reserved.

How did this page land for you?

React to reveal totals

Comments ()

Leave a comment to see what others are saying.

Public and anonymous. No signup.