Consumer config surface17 bundled skillsApril 2026 release

The Anthropic Claude Code April 2026 update that most writeups miss: skills and MCP config as a consumer surface

Every recap of the April 2026 Anthropic release covers the same five headlines: Opus 4.7 in the CLI on April 16, the Visualizations renderer, Cowork going GA on macOS and Windows, Managed Agents in public beta, and a few percentage points of benchmark movement. The change that matters to a non-developer is quieter and lives one directory deeper: ~/.claude/skills/ and a mcpServers JSON config became the primary customization surfaces, and for anyone not already comfortable with a terminal they are effectively invisible.

Fazm is a consumer Mac app that runs Anthropic's ACP agent on the inside and manages both of those surfaces on the outside. 17 Claude Code skills ship in the app bundle. A GUI edits the MCP server config. On every app launch a SHA-256 hash of each bundled skill is compared to the user's ~/.claude/skills/ and the installed file is rewritten if they differ. No JSON editing, no cp from a gist, no README that expires in six months.

M
Matthew Diakonov
9 min read
4.8from App Store reviews
17 SKILL.md files installed into ~/.claude/skills/ on first run
sha256-driven update on every app launch, no version bump required
Native Settings UI for ~/.fazm/mcp-servers.json in Claude Code's own format

The headlines are about the model. This is about the directory.

Opus 4.7 got the press. The change that turns Claude Code into something a paying consumer can meaningfully customize lives at ~/.claude/skills/.

Try Fazm on macOS
0Skills bundled into the app
v0.2ACP agent version shipping
0Days between v0.25.0 and v0.29.2
0Obsolete skill removed each launch

Two layers shipped in April. Only one of them had a launch post.

The launch-post layer is the CLI: Opus 4.7, Visualizations, Cowork, Managed Agents. That is what Anthropic talks about. The other layer is the agent SDK and its adjacent config surfaces: the ~/.claude/skills/ directory, the mcpServers config key that tells the agent which external tool servers to spawn, and the dynamic models_available notification that replaced hard-coded model lists inside embedding apps.

Most existing write-ups about this release either cover the first layer only, or they dive into the second layer from a framework-author perspective (how does ACP work, how do I stream events, etc.). Almost none answer the practical question for a paying non-developer: who actually decides what lives in my ~/.claude/ directory? With Fazm the answer is the app. That is what this page is about.

How Fazm writes into ~/.claude/ on your behalf

App bundle
Installer state
User MCP config
Fazm app launch
~/.claude/skills/*/SKILL.md
Agent spawn args
Toast + Settings UI

17 skills, one directory, zero manual steps

Here is the full list of .skill.md files that Fazm installs into ~/.claude/skills/ on first run. Each one is a single Markdown file with YAML frontmatter and a body. When a user asks Fazm to draft a slide deck, the pptx skill is auto-loaded by the agent. When they ask for a trip plan, travel-planner. These are the same skills a power user would hand-copy from a gist or GitHub; Fazm ships the file already.

ai-browser-profile

Personal context from browser autofill

canvas-design

Posters, PDFs, static design artifacts

deep-research

Multi-source research with citations

doc-coauthoring

Structured drafting for long docs

docx

Create and edit Word documents

find-skills

Discover and install other skills

frontend-design

Production-grade UI design

google-workspace-setup

Gmail, Calendar, Drive, Docs, Sheets

pdf

Read, extract, merge, split PDFs

pptx

Slide decks and presentations

social-autoposter

Cross-platform social posting

social-autoposter-setup

One-time social account setup

telegram

Send and read Telegram messages

travel-planner

Full trip itineraries and budgets

video-edit

Cut videos via ffmpeg + transcript

web-scraping

Playwright-based data extraction

xlsx

Spreadsheet create, read, edit

What one of these files actually looks like

A skill is not a binary, a plugin, or a private API. It is a Markdown file with a short frontmatter block. The agent picks it up from ~/.claude/skills/deep-research/SKILL.md at session start and inlines the body into its planning context when the task description matches.

~/.claude/skills/deep-research/SKILL.md

The anchor fact: updates are driven by SHA-256, not by a version field

There is one short function that does all of the work. On every launch, for every bundled .skill.md, it hashes the bundled file and the installed file, and rewrites the installed one if the hashes differ. No timestamps, no semver, no user prompt. If the bundled content changed between app versions, the user's copy changes on the next launch.

Desktop/Sources/SkillInstaller.swift

The hash function itself lives at SkillInstaller.sha256(of:) around line 58: it opens the file with FileManager.default.contents(atPath:), feeds the bytes through CryptoKit.SHA256, and returns the hex digest. The same function runs against both the bundle path and the installed path, so a byte-identical file never triggers a rewrite. That is how hundreds of thousands of launches stay quiet on machines where nothing has changed.

Install flow per skill, every launch

1

App bundle

2

SkillInstaller.install()

3

sha256 diff per file

4

~/.claude/skills/<name>/SKILL.md

What this looks like in your log

Same machine, two launches. First run installs everything. A later launch after a Fazm app update only touches the files whose bundled content changed.

~/Library/Logs/Fazm/app.log

The other surface: a GUI over Claude Code's own mcpServers JSON

The second customization surface this release makes more relevant is mcpServers: the JSON key Claude Code reads to decide which external tool servers to spawn. Fazm stores user-added entries at ~/.fazm/mcp-servers.json using the same shape Anthropic uses, so anything a power user would paste into the official config works verbatim inside Fazm. The edit sheet in MainWindow/Pages/MCPServerEditSheet.swift is just a visual wrapper around that file.

~/.fazm/mcp-servers.json

Add a server

Settings > MCP Servers > + opens a sheet with four inputs: name, command, args, env. Save writes an atomic replace of the JSON file via Data.write(to:options:) with .atomic.

Toggle without deleting

A per-server enabled boolean means you can keep a server configured but off. The ACP bridge filters disabled servers at spawn time so the config stays persistent between sessions.

Built-ins stay readable

The live view shows both built-in servers (Playwright, Fazm tools) and user-added ones in one list, with a builtin flag. User entries are editable; built-ins are not.

How the release landed on Fazm, day by day

This is the April 2026 timeline from inside a consumer app that had to absorb every change without asking the user to do anything manual.

1

April 7 — ACP v0.25.0

First Anthropic Claude Code agent-protocol bump in April. Credit-exhaustion and rate-limit handling improved. Fazm ships it as v2.1.2 the same day, mostly for the onboarding fix where credits running out no longer silently breaks the first-run chat.

2

April 16 — Opus 4.7 goes live

Anthropic rolls Opus 4.7 into the CLI. Fazm users running v2.3.2 see the new model appear in their picker with zero app update because the picker is already populated from the agent's models_available notification. Same day, Fazm ships v2.3.2 to tighten privacy language in onboarding from 'nothing leaves your device' to 'local-first'.

3

April 20 — ACP v0.29.2 and Fazm v2.4.0

The big one. Agent protocol moves to v0.29.2. Fazm ships v2.4.0 the same day, which includes the custom MCP server support via ~/.fazm/mcp-servers.json, a Settings UI for editing it, and the patched-acp-entry.mjs upgrades. The bundled-skills list also gets a refresh; the checksum installer detects the diff on next launch and overwrites the affected SKILL.md files without asking.

4

April 22 — Fazm v2.4.1

No Anthropic release, but the rollout window of a new model leaves partial models_available payloads arriving for some users, which broke the label mapping (Smart drifting to Sonnet when Opus was momentarily missing). v2.4.1 anchors the Smart label to the 'opus' substring specifically, so a payload with no Opus leaves Smart undefined instead of relabeling another model.

What gets different when the app owns these files

Most articles comparing Claude Code against a consumer AI app stop at "one runs in the terminal, the other has a window". The more useful difference is who owns the files under ~/.claude/.

FeatureDefault Claude Code CLI usageFazm
How do skills get onto your machineManually copy SKILL.md files into ~/.claude/skills/ per the docs; update by hand when authors ship new versions17 SKILL.md files bundled in the app, installed on first run into ~/.claude/skills/; updated via SHA-256 diff on every launch
When the author ships a new version of a skillYou don't hear about it; you re-read the README, re-download, overwriteApp update lands, next launch detects the hash mismatch, overwrites the file, toasts '<name> updated'
Removed or deprecated skillsThe old SKILL.md sits in ~/.claude/skills/ forever unless you delete itNames in SkillInstaller.obsoleteSkills get deleted from ~/.claude/skills/ on every launch (current list: hindsight-memory)
How do you add an MCP serverEdit the mcpServers JSON config by hand, restart the host, hope the stdio command path is rightSettings > MCP Servers > + shows a sheet with name, command, args, env, enabled toggle; file writes to ~/.fazm/mcp-servers.json atomically
Distinguishing built-in servers from user serversOne flat JSON object; provenance is lostActiveServer.builtin flag lights up the UI; built-ins are not editable, user-added are fully editable and toggleable
Input to the agent when acting on a Mac appScreenshot pipeline pays OCR and re-segmentation on every turnAXUIElement accessibility tree for the frontmost app handed over as structured text

Why ship it this way at all

There is a reasonable counterargument that says: if the user is paying for a consumer app, why expose ~/.claude/skills/ at all? Hide it. Own it completely. The answer is that the release in April made both directions cheap, and the open direction is the one that keeps the app honest. A user's skills remain files on their own machine, readable with any text editor, and usable with any future Claude-based app that respects the same convention. Fazm's only claim on them is a SHA-256 comparison to a bundled file; delete Fazm and the files stay, because they are yours now.

The same logic applies to ~/.fazm/mcp-servers.json. Writing it in Anthropic's own format instead of a custom schema means that if a user outgrows Fazm, the file works unchanged inside any other tool that reads the same JSON shape. That portability is the single most important design choice this update made possible. It is also the one thing the CLI-focused writeups of this release do not even try to explain.

The stack, in one scroll

~/.claude/skills/~/.fazm/mcp-servers.jsonSKILL.mdsha256 hash diffSkillInstaller.swiftMCPServerManager.swift17 bundled skillsACP v0.29.2Opus 4.7AXUIElement inputToast on skill updateSettings > MCP Servers

Five things most April write-ups got wrong about this release

Skills arrive with the app, not with a README

Desktop/Sources/BundledSkills holds 17 .skill.md files. SkillInstaller.bundledSkillNames auto-discovers them at launch by filtering the bundle resource directory for *.skill.md. Adding a skill is one file drop at build time — no code change, no migration, no feature flag.

Updates land by hash, not by timestamp

SHA-256 of the bundled file compared to SHA-256 of ~/.claude/skills/<name>/SKILL.md. Equal: skip. Different: overwrite and toast. No mtime heuristic, no version field to bump, no accidental downgrade.

Deprecations are self-garbage-collecting

obsoleteSkills is a hard-coded array in SkillInstaller.swift. Each name in that array is FileManager.removeItem'd under ~/.claude/skills/ on every launch. Ships a skill today, removes it cleanly in six months.

User MCP servers use Claude Code's own JSON shape

RawServerConfig in MCPServerManager.swift has exactly the fields Claude Code reads: command, args, env, enabled. Drop a server block in ~/.fazm/mcp-servers.json, restart the chat, it is live. No Fazm-specific wrapper format.

Built-in vs user servers stay distinguishable

ActiveServer struct carries a builtin boolean. The Settings UI greys out the edit affordance on built-ins and opens the edit sheet on user-added ones. You cannot accidentally delete a server the app needs to boot.

0
skills land in ~/.claude/skills/ the first time you open Fazm

From one app launch. Without editing a config file, without downloading anything from a gist, without a README that will be out of date in six weeks. Every launch afterwards, any of those 17 files whose bundled content has changed quietly overwrites in place, and a single toast tells you which names moved.

Want Claude Code skills without editing ~/.claude yourself?

Book 15 minutes. We'll walk through how Fazm ships, updates, and garbage-collects skills + MCP servers so your Mac is the surface, not your shell.

Frequently asked questions

What actually shipped in the Anthropic Claude Code April 2026 update?

Two layers shipped together. The CLI layer: Opus 4.7 on April 16, the Visualizations renderer inside Claude's responses, Cowork going generally available on macOS and Windows, and Managed Agents entering public beta. The SDK layer (less covered): @agentclientprotocol/claude-agent-acp moved from v0.25.0 on April 7 to v0.29.2 on April 20, which reworked how embedding apps consume session events, how the model picker is populated, and how custom MCP servers get loaded. The two layers share one customization surface that paying consumers rarely see: ~/.claude/skills/ for reusable instruction files and a mcpServers JSON config for tool servers.

What is ~/.claude/skills/ and why did it become more important in the April 2026 update?

Each subdirectory under ~/.claude/skills/ holds a single SKILL.md with YAML frontmatter (name, description) and body instructions. The agent reads the directory at session start and auto-loads any skill whose description matches the current task. Before v0.29, skills were mostly a developer surface for people already living in ~/.claude/. The April 2026 SDK exposes enough session metadata for a host app to show a consumer exactly which skill is active at any moment, which turned ~/.claude/skills/ from a power-user feature into something a consumer app could meaningfully manage. Fazm ships 17 .skill.md files in its app bundle and installs them on first run.

Where are Fazm's bundled skills stored in the source tree?

In /Users/matthewdi/fazm/Desktop/Sources/BundledSkills, one file per skill, ending in .skill.md. The current set is: ai-browser-profile, canvas-design, deep-research, doc-coauthoring, docx, find-skills, frontend-design, google-workspace-setup, pdf, pptx, social-autoposter, social-autoposter-setup, telegram, travel-planner, video-edit, web-scraping, xlsx. SkillInstaller.bundledSkillNames auto-discovers them at launch by enumerating any file ending in .skill.md. Adding a new skill is a build-time-only change: drop the file in, rebuild, ship. No code change required.

How does Fazm decide whether to overwrite a file under ~/.claude/skills/ on app launch?

SkillInstaller runs once per launch. For every bundled .skill.md it computes SHA-256 of the source file in Resources/BundledSkills, computes SHA-256 of the installed file at ~/.claude/skills/<name>/SKILL.md, and compares. Same hash: skip. Different hash: delete the installed file, copy the bundled file, append the name to an updated[] list. No installed file yet: create the directory and copy it fresh, append to installed[]. At the end, if updated[] is non-empty, a ToastManager notification fires with the list of updated skill names. The hash function lives at SkillInstaller.swift line 58 and the compare runs inside the per-skill loop at lines 117-122.

What happens to old skills that Fazm used to ship but no longer does?

SkillInstaller.obsoleteSkills is a hard-coded list of skill names that were previously bundled and should now be removed from ~/.claude/skills/ on every launch. The current list has one entry: hindsight-memory. On every app launch, the installer calls FileManager.removeItem on ~/.claude/skills/hindsight-memory. That is how the consumer app stays in sync with deprecations on the Anthropic side without requiring a manual cleanup. If Anthropic ever renames a core skill convention or Fazm drops a bundled skill, the name goes into the obsoleteSkills array and it is garbage-collected on the next launch.

What is the mcpServers config and where does Fazm store the user-defined version?

mcpServers is the JSON key Claude Code reads to decide which external tool servers to spawn alongside the agent. The format is { "<name>": { "command": "...", "args": [...], "env": {...} } }. The system-wide version lives where Anthropic's tools look for it. Fazm stores its user-defined additions at ~/.fazm/mcp-servers.json using the same shape, and merges them with its built-in server list at bridge startup. The storage and merge live in MCPServerManager.swift: the configURL is built with appendingPathComponent(".fazm").appendingPathComponent("mcp-servers.json"), and load() decodes it as [String: RawServerConfig] where RawServerConfig mirrors Claude Code's server entry shape one-to-one.

Is there a GUI for editing MCP servers in Fazm, or do you still have to edit JSON by hand?

GUI. The v2.4.0 release notes on April 20 call it out: "Added custom MCP server support via ~/.fazm/mcp-servers.json with Settings UI to add, edit, and toggle servers." The sheet is implemented in MainWindow/Pages/MCPServerEditSheet.swift. You open Settings, you see a list where each row shows the server name, its command, and a builtin flag that distinguishes Fazm's built-in servers from user-added ones. addServer, removeServer, updateServer, and toggleServer all call save() which encodes [String: RawServerConfig] back to disk as pretty-printed sorted JSON. The ACP bridge picks up the change on next session start.

How does the dynamic models_available payload from v0.29.2 connect to the consumer picker?

Before v0.29.2, an embedding app had to ship a hard-coded list of Claude model IDs and update it every time Anthropic released a new one. After v0.29.2, the agent emits a session/update notification with method "models_available" whose payload contains the list of models the user's account has access to, scoped to the credit pool they are using. Fazm's v2.4.0 release notes say: "Available AI models now populate dynamically from the agent, so newly released Claude models appear without an app update." When Anthropic flipped Opus 4.7 live on April 16, Fazm users saw it in their model picker the same day without installing anything.

Does this update change anything about how Fazm reads what is on your screen?

No. Fazm hands the macOS accessibility tree (AXUIElement structures for the frontmost app) to the agent as structured context, not screenshots. That input strategy is independent of the Anthropic Claude Code update. When Opus 4.7 got smarter at reasoning about structured application state on April 16, Fazm's input quality stayed the same and the model got better at acting on it. Visualizations is an output feature (Claude renders charts and diagrams inside its response), so it also does not alter the input path. Screenshot-based tools do benefit from better vision in the model but still pay the per-turn OCR and re-segmentation cost that an accessibility-tree pipeline avoids.

If I already have ~/.claude/skills/ populated, does installing Fazm overwrite my skills?

Only if a name collision exists. SkillInstaller iterates the bundled skill names, not the user's directory. It touches ~/.claude/skills/<bundled-name>/SKILL.md and nothing else under ~/.claude/skills/. If you have your own skill at ~/.claude/skills/my-workflow/, Fazm never looks at it. The one case to know about: if you hand-edited ~/.claude/skills/deep-research/SKILL.md, the next launch of Fazm will detect a hash mismatch between your edit and the bundled version, and it will overwrite. The fix is to copy your edit to a different skill name under ~/.claude/skills/.

Where can I see which skills Fazm shipped in this release, if I don't want to install it?

Read the directory listing of Desktop/Sources/BundledSkills in the Fazm source and read the frontmatter of each .skill.md. The SkillInstaller.categoryMap constant maps each skill to an onboarding category: pdf, docx, xlsx, pptx go to Documents; video-edit, frontend-design, canvas-design, doc-coauthoring go to Creation; deep-research, travel-planner, web-scraping go to Research & Planning; social-autoposter, social-autoposter-setup go to Social Media; find-skills goes to Discovery; ai-browser-profile goes to Personal; google-workspace-setup and telegram go to Productivity. This is the exact grouping users see in the in-app onboarding flow.