Guide

fazm.ai GitHub: a four-language repo tour of mediar-ai/fazm

Every top result for fazm.ai github stops at the three-line README Structure block. This guide walks the actual mediar-ai/fazm tree: nine Swift Package Manager deps feeding one executable target, a 2,772-line Node sidecar, a Rust backend deploying to Cloud Run via Workload Identity Federation, and a second Swift SPM package for the installer. MIT. 146 stars.

M
Matthew Diakonov
9 min read
4.8from 146 stars, 17 forks on github.com/mediar-ai/fazm
4 languages: Swift, TypeScript, Rust, Shell
9 Swift deps + 4 runtime npm deps
Signed DMG via tag-driven Codemagic
Desktop/Package.swift9 Swift depsexecutableTarget 'Fazm'macOS 14.0+acp-bridge/src/index.ts2,772 lines@playwright/mcp@0.0.68@agentclientprotocol/claude-agent-acp@0.29.2Backend/ in RustCloud Run us-east5Workload Identity FederationInstaller/Package.swiftdmg-assets/codemagic.yaml.mcp.json at rootCHANGELOG.jsonREADME line 5: 'Fully open source'MIT licensev2.3.2+2003002-macos146 stars

The anchor fact SERP never mentions

Here is the repo in six numbers, each pulled from a specific file or the GitHub API. The Structure block in README stops at three directories. The real layout has four languages and two SPM packages.

0Swift deps in Desktop/Package.swift
0Lines in acp-bridge/src/index.ts
0Swift bytes (GitHub Languages API)
0Languages: Swift / TS / Rust / Shell
MIT

Free to start. Fully open source. Fully local.

README.md line 5, github.com/mediar-ai/fazm

What SERP shows you vs. what the repo actually contains

The README Structure block (lines 31-35) names three directories. The real repo root has twelve. Toggle to see what actually ships.

# Naive "ship a Mac AI app" on GitHub . ├── MacApp.xcodeproj ├── Sources/ │ ├── AgentLoop.swift # screenshots + coords │ ├── OpenAIClient.swift │ └── ToolExecutor.swift ├── README.md └── .github/workflows/build.yml # 1 language. 1 process. 1 way to test. # No MCP. No separate bridge. No centralized backend. # Everything lives in one Swift binary.

  • One language, one binary
  • No MCP bridge on disk
  • No centralized backend in the tree
  • No separate installer package

Desktop/: the Swift app

This is 74% of the source by bytes. Opening Desktop/Package.swift tells you the whole dependency graph in 49 lines. Nine external packages, one executable target named Fazm, macOS 14.0 floor, two resource paths (the bundled skills directory and a processed Resources folder).

Desktop/Package.swift

acp-bridge/: why the Swift app needs a Node subprocess

The bridge is not a style choice. MCP (Model Context Protocol) and the ACP SDK only ship as npm packages. The Swift app spawns node dist/index.js as a sidecar so it can host Playwright MCP, the bundled mcp-server-macos-use binary, and the Agent Client Protocol session.

acp-bridge/package.json

Backend/: the Rust service and its CI secret

Local-first does not mean no cloud. The Rust service in Backend/ handles centralized key distribution and licensing. The reason the app feels instantly responsive even on the first call is the inline comment on the deploy workflow: keep one instance warm so /v1/keys never cold-starts and the bridge never falls back to personal OAuth.

.github/workflows/deploy-backend.yml

All twelve top-level entries, one card each

Running curl api.github.com/repos/mediar-ai/fazm/contents returns 27 entries at the repo root. These are the eight that actually produce the shipped product.

Desktop/

Swift/SwiftUI macOS app. SPM package with 9 external deps feeding a single executable target 'Fazm'. 95 .swift files under Sources. macOS 14.0+.

acp-bridge/

TypeScript ACP bridge. Node sidecar launched by the Swift app. src/index.ts is 2,772 lines. @playwright/mcp@0.0.68 + @agentclientprotocol/claude-agent-acp@0.29.2.

Backend/

Rust service. Deployed to Cloud Run us-east5 via Workload Identity Federation. --min-instances=1 to avoid /v1/keys cold starts.

Installer/

Second Swift SPM package. The UI inside the DMG. InstallerApp.swift, InstallManager.swift, DownloadManager.swift.

Sources/protobuf

Shared protobuf schema used across Swift, TypeScript, and Rust clients.

.github/workflows

Deploy Rust Backend on push to main under Backend/. Workload Identity Federation, no static keys committed.

dmg-assets/

DMG background, volume icon, and layout plist. Referenced by the codemagic.yaml tag-driven signed build.

CHANGELOG.json

Structured release notes at the repo root. Latest: v2.3.2+2003002-macos, published 2026-04-16T01:26:06Z.

How the four layers actually talk

The Swift app in Desktop/ owns the UI and accessibility pre-flight. It launches acp-bridge/ as a Node subprocess. The bridge hosts all MCP tools. The Rust service in Backend/ serves centralized credentials. Installer/ never runs after first launch.

mediar-ai/fazm layer topology

User
Desktop/ (Swift)
acp-bridge/
Playwright MCP
mcp-server-macos-use
Backend/ (Rust)
Claude ACP session

A prompt from UI to action, traced across four directories

This is the sequence you can read yourself by opening three files in order: Desktop/Sources/Chat/ChatProvider.swift, acp-bridge/src/index.ts, and the bundled mcp-server-macos-use binary registered inside it.

Seven steps across four languages

1

1. User prompt enters Desktop/

ChatProvider.swift assembles the session prompt and pushes it over stdio to the already-spawned Node process. This is pure Swift, no network yet.

2

2. acp-bridge/src/index.ts receives session/prompt

The 2,772-line index.ts routes the call. If the prompt involves a browser, it reaches for the Playwright MCP server. If it touches a native app, it reaches for mcp-server-macos-use.

3

3. Bridge calls /v1/keys on Backend/ when credentials expire

The Rust service in Cloud Run, authenticated via Workload Identity Federation, signs a short-lived credential. --min-instances=1 keeps this under 100 ms.

4

4. Bridge invokes an MCP tool

click_and_traverse, type_and_traverse, or navigate depending on intent. The tool-result filter at index.ts line ~2273 strips images so only text flows back.

5

5. Tool returns action + fresh AX tree

The same MCP reply carries the post-action accessibility tree, so the next model turn has ground truth without a second screenshot call.

6

6. Bridge streams tool_result back to Desktop/

Over ACP. Swift renders the assistant message using swift-markdown-ui, one of the nine SPM deps on line 14 of Package.swift.

7

7. PostHog logs the event, Sentry catches exceptions

Both declared as Swift deps on Package.swift lines 10-11. Firebase handles auth via line 15. Sparkle on line 13 prompts the next update on the next launch.

Verifiable claims in this page

  • README line 5 reads 'Free to start. Fully open source. Fully local.' verbatim
  • Desktop/Package.swift line 5 sets name to 'Fazm'
  • Desktop/Package.swift line 7 sets macOS floor to 14.0
  • Desktop/Package.swift lines 10-18 declare exactly 9 external deps
  • Desktop/Package.swift line 27 declares one executableTarget named 'Fazm'
  • acp-bridge/package.json lists @playwright/mcp@^0.0.68 and @agentclientprotocol/claude-agent-acp@^0.29.2
  • acp-bridge/src/index.ts is exactly 2,772 lines
  • .github/workflows/deploy-backend.yml uses Workload Identity Federation
  • api.github.com/repos/mediar-ai/fazm/languages returns Swift 2,144,955 bytes
  • Latest release tag is v2.3.2+2003002-macos, published 2026-04-16T01:26:06Z

Clone and build, step by step

The repo ships two entry points: ./run.sh (build and launch) and ./reset-and-run.sh (clean onboarding, permissions, UserDefaults). Both live at the repo root and take the same fazm_acquire_lock path.

Clone, inspect, build
run.sh

A naive "Mac AI app on GitHub" vs. mediar-ai/fazm

Most Mac agent repos compress into one Swift binary with a screenshot loop. Fazm splits into four layers because each layer answers a different hard question: Swift for OS-level accessibility, TypeScript because MCP is Node-native, Rust for a cheap stateless credential service, and a second Swift package for the DMG UX.

# Naive "ship a Mac AI app" on GitHub
.
├── MacApp.xcodeproj
├── Sources/
│   ├── AgentLoop.swift       # screenshots + coords
│   ├── OpenAIClient.swift
│   └── ToolExecutor.swift
├── README.md
└── .github/workflows/build.yml

# 1 language. 1 process. 1 way to test.
# No MCP. No separate bridge. No centralized backend.
# Everything lives in one Swift binary.
-127% more directories, each owning one layer

What the top fazm.ai github SERP results actually cover

Every result for the query is either the GitHub page itself (which shows a three-line Structure block), the homepage (no repo content), or a Fazm blog post mentioning other GitHub projects. None walk the real four-language layout.

FeatureTop 5 SERP resultsThis guide
Enumerates the 9 Swift Package Manager depsNoYes - lines 10-18 of Desktop/Package.swift
Names the 4 runtime npm deps in acp-bridge/NoYes - @playwright/mcp, claude-agent-acp, ws, zod
Explains why the Swift app needs a Node subprocessNoYes - MCP and ACP SDK ship only as npm packages
Shows the Rust Backend/ CI and Cloud Run regionNoYes - .github/workflows/deploy-backend.yml
Cites the GitHub Languages API byte splitNoYes - Swift 2,144,955 / TS 275,012 / Rust 127,450
Notes the separate Installer/ Swift SPM packageNoYes - InstallerApp.swift, InstallManager.swift
Cites the actual licenseSometimesMIT, README.md line 52
Links to the repo at github.com/mediar-ai/fazmYesYes
Reports current star and fork count from the APINo (one SERP result hallucinated 3,000+)146 stars, 17 forks as of 2026-04-18

Want a walkthrough of the repo with the people who wrote it?

Book 30 minutes to see the Swift / TypeScript / Rust split running live on a real Mac.

Frequently asked questions

Where is the fazm.ai GitHub repo and what license is it?

The repo lives at github.com/mediar-ai/fazm. The default branch is main and the license is MIT per the README line 52. As of the last pushed_at timestamp 2026-04-18T21:13:31Z the repo weighs 78.94 MB with 146 stars and 17 forks. The README at the repo root states verbatim 'Free to start. Fully open source. Fully local.' on line 5 and points to the homepage as fazm.ai/gh. The primary marketed artifact is a signed, notarized macOS DMG, but every source file that produces that DMG is public under MIT.

What is the directory structure inside mediar-ai/fazm?

The README at line 31-35 lists three: Desktop/ (Swift/SwiftUI macOS app, SPM package), acp-bridge/ (ACP bridge for Claude integration, TypeScript), and dmg-assets/ (DMG installer resources). But the repo root also contains Backend/ (a Rust service deploying to Cloud Run), Installer/ (a second Swift SPM package for a custom installer app), Sources/ (protobuf definitions shared across clients), .github/workflows/ (CI for the Rust backend and monorepo syncs), web/, inbox/, and scripts/. A curl against api.github.com/repos/mediar-ai/fazm/contents returns 27 top-level entries including .mcp.json at the root so any agent can discover the installed MCP servers. The canonical four-language split is Desktop in Swift, acp-bridge in TypeScript, Backend in Rust, and Installer in Swift.

Why does the Swift app need a TypeScript subprocess at all?

Because MCP (Model Context Protocol) is Node-native. The acp-bridge/ directory ships a src/index.ts that is exactly 2,772 lines and declares four runtime deps in package.json: @playwright/mcp at ^0.0.68, @agentclientprotocol/claude-agent-acp at ^0.29.2, ws at ^8.20.0, and zod at ^4.0.0. The Swift app launches node against dist/index.js as a sidecar subprocess at app startup, then talks to it over the Agent Client Protocol. All MCP tools (Playwright browser control, the bundled mcp-server-macos-use binary for accessibility, any custom stdio/http servers configured in .mcp.json) live inside that Node process. It is not a stylistic choice, it is a protocol requirement: MCP servers and the ACP SDK only ship as TypeScript packages on npm.

Exactly what dependencies does Desktop/Package.swift pull in?

Nine external Swift packages plus one local package. Opening Desktop/Package.swift shows lines 10-18: PostHog/posthog-ios from 3.0.0 for analytics, getsentry/sentry-cocoa pinned 8.57.3..<8.58.0 for crash reporting, groue/GRDB.swift from 6.24.0 for the local SQLite database, sparkle-project/Sparkle from 2.9.0 for auto-updates, gonzalezreal/swift-markdown-ui from 2.4.0 for rendering assistant messages, firebase/firebase-ios-sdk from 11.0.0 for auth, m13v/macos-session-replay from 0.7.0 for local session recording, a path-package for LocalPackages/Highlightr for syntax coloring, and m13v/ai-browser-profile-swift-light from 0.1.0 for browser profile capture. Line 27 declares one executableTarget named 'Fazm' that consumes all of them, plus an ObjCExceptionCatcher target on line 22. Platform floor is macOS 14.0 per line 7. That is the whole graph.

How do I build it locally from the GitHub checkout?

Clone the repo, then from the root run ./run.sh. The first few lines of run.sh source scripts/fazm-lock.sh and call fazm_acquire_lock 300 so concurrent builds from parallel agents do not corrupt each other. The script falls back to gtimeout or /opt/homebrew/opt/coreutils/libexec/gnubin/timeout if macOS timeout is missing, unsets OPENAI_API_KEY to let .env take precedence, and unsets TOOLCHAINS so Xcode's default toolchain matches the SDK version. Under the hood it runs swift build against Desktop/Package.swift, compiles the TypeScript bridge in acp-bridge/, copies patched-acp-entry.mjs next to dist/index.js, and launches the signed Fazm.app. You need macOS 14.0 or later, Xcode, and code-signing with an Apple Developer ID per README line 40.

What is the Rust Backend/ directory actually doing?

Backend/ is a Rust service deployed to Google Cloud Run in region us-east5 under service name fazm-backend. The deployment lives in .github/workflows/deploy-backend.yml and fires on push to main when any file under Backend/ changes. Auth uses Workload Identity Federation, not a static key: the workflow uses google-github-actions/auth@v2 with workload_identity_provider set to projects/472661769323/locations/global/workloadIdentityPools/github-actions-pool/providers/github-actions-provider and service_account github-actions-deploy@fazm-prod.iam.gserviceaccount.com. The flags line adds --min-instances=1 with an inline comment explaining that cold starts on /v1/keys would cause ensureKeys timeouts in the bridge and force a fallback to personal OAuth. This is the centralized-cloud layer of an otherwise local-first app.

What is Installer/ and why is it a separate Swift package?

Installer/ is its own SPM package at Installer/Package.swift containing a tiny SwiftUI app. Its Sources include InstallerApp.swift, InstallerView.swift, ManifestLoader.swift, InstallManager.swift, and DownloadManager.swift. It is the UI you see inside the DMG before the main app copies itself into /Applications. Keeping it in a separate package means it compiles without the Desktop target's nine-dep graph (no Firebase, no GRDB, no Sparkle), ships as a lightweight binary on the mounted volume, and can be notarized independently of the main app. The dmg-assets/ directory alongside it holds the DMG background, volume icon, and layout plist referenced by the build script.

What does the GitHub Languages API say about the byte split?

A curl against api.github.com/repos/mediar-ai/fazm/languages returns Swift 2,144,955 bytes, TypeScript 275,012, Shell 162,689, Rust 127,450, JavaScript 34,642, Dockerfile 665, Objective-C 641, and CSS 586. The Objective-C 641 bytes is the ObjCExceptionCatcher target declared in Desktop/Package.swift line 22-25, required because Swift cannot catch Objective-C exceptions natively and the Accessibility API occasionally throws them. The JavaScript 34,642 bytes is mostly the browser-overlay-init script the acp-bridge injects into Chrome when running browser automation. Swift is 74% of the source, TypeScript is 9%, and Rust is 4% by bytes.

How is a release cut and shipped from GitHub?

Releases are cut by pushing a tag of the form v*-macos, which triggers Codemagic (configured in codemagic.yaml at the repo root) to build, sign, and notarize the DMG. The three most recent releases listed via api.github.com/repos/mediar-ai/fazm/releases are v2.3.2+2003002-macos published 2026-04-16T01:26:06Z, v2.3.1+2003001-macos on 2026-04-15T23:19:41Z, and v2.3.0+2003000-macos on 2026-04-15T00:36:13Z. The CHANGELOG.json file at the repo root is the structured source of release notes. The repo explicitly avoids local release.sh in favor of the tag-driven Codemagic path so every shipped build has a verifiable commit, tag, and signing chain.

Is there a Package.swift manifest I can depend on from another Swift project?

Desktop/Package.swift declares the product as an executableTarget, not a library, so you cannot `import Fazm` from another SPM package. However the individual Swift dependencies Fazm consumes are all public libraries you can pick up directly: m13v/macos-session-replay (session recording on macOS), m13v/ai-browser-profile-swift-light (browser profile capture), gonzalezreal/swift-markdown-ui (markdown rendering), groue/GRDB.swift (SQLite), and sparkle-project/Sparkle (auto-update). If what you want is the accessibility-API tool layer, that lives outside this repo as a bundled Mach-O binary called mcp-server-macos-use, which the Swift app launches as an MCP subprocess.

Does the GitHub repo include the cloud API keys or Firebase config?

No. Backend/vertex-ai-sa-key.json and acp-bridge/vertex-ai-sa-key.json paths exist in the local checkout but are gitignored at the repo root. The Rust backend in Cloud Run reads its service account via Workload Identity Federation, which is exactly why the GitHub Actions workflow requests id-token: write in its permissions block. Firebase client config is bundled into the Swift target via .process('Resources') per Desktop/Package.swift line 44. There are no live secrets in the checked-in tree.

Where should a first-time contributor look to understand how a single user prompt becomes an action?

Three files, in this order. First, Desktop/Sources/Chat/ChatProvider.swift in the Swift app builds the prompt and hands it to the ACP session. Second, acp-bridge/src/index.ts (the 2,772-line sidecar) receives the session call, routes tool invocations, and owns the MCP tool-result filter that keeps screenshots out of the context. Third, the bundled mcp-server-macos-use binary (registered in acp-bridge/src/index.ts) executes the actual AX tree walk and returns the post-action tree. CLAUDE.md at the repo root links the flow end-to-end for contributors and is exactly the file GitHub search indexes under the query 'fazm.ai github CLAUDE.md'.

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.