Loom: One Registry, Six AI Coding Assistants
February 9, 2026·6 min read
Every AI coding assistant wants MCP, but they all want it differently:
- different config formats (JSON vs TOML),
- different config locations (repo vs
$HOME), - different secret mechanisms (env vars vs keychain),
- different lifecycle hooks and “auto-run” behaviors.
If you manage more than one assistant, the failure mode is boring and constant: config drift. Something works in one tool, breaks in another, and you spend time debugging “why does this one not see the server?” instead of shipping.
This post is about the feature that finally made that pain go away in my setup: a single canonical MCP registry + multi-platform sync, implemented in services/loom-core and surfaced in services/loom (the VS Code extension).
TL;DR
- Keep a single canonical registry at
platform/gitops/mcp/context/registry.yaml. - Generate platform configs from that registry with
loom(the CLI in loom-core), then sync them into each platform’s home config location. - Use Loom’s Sync Dashboard to see drift at a glance and fix it with one click.
- Current registry in this workspace defines 39 MCP servers, with platform-specific overrides where needed.
Why Someone Would Try Loom
You should try Loom if any of these are true:
- You bounce between assistants (Codex for fast edits, Claude for longform, Gemini for research) and you’re tired of one “not seeing” the same tools.
- You work across multiple machines or environments and want MCP to be reproducible, not artisanal.
- You have more than a handful of MCP servers and you want to manage them as inventory (with policy), not as one-off config snippets.
- You care about secrets hygiene and want config generation to use
${env:...}/${keychain:...}indirections instead of leaking tokens into dotfiles.
What you get is not magic. It’s a boring operational guarantee:
- One canonical registry
- One generator
- One sync loop
- Drift becomes visible
That’s enough to make MCP setups actually stick.
What You Get On Day 1
The “value per minute” features that matter immediately:
loom sync statustells you which platforms are drifting.loom sync all --regenpulls everything back into alignment.- The Loom Sync Dashboard (extension) turns drift into a UI you can fix without memorizing paths/commands.
- You can start with “just configs” and adopt
loomd/loom-mode later. - The Agent HUD gives you a single command center for agents, tasks, workflows, memory, and server health. On macOS you can optionally enable the native overlay (a floating strip) and toggle it globally with
Cmd+Shift+L.
The Problem: MCP Drift Is Guaranteed
If you’ve ever hand-edited:
.codex/config.toml.claude/mcp.json.gemini/settings.json.vscode/mcp.json.antigravity/mcp.json.kilocode/config.toml
you know what happens next: six sources of truth, six slightly different syntaxes, and an inevitable mismatch.
Even if the server definitions are “the same,” the platform details aren’t. A few examples that show up immediately in practice:
- Codex wants TOML and tends to prefer keychain-backed secrets.
- VS Code/Antigravity use JSON and run servers as stdio processes.
- Some tools need different env var substitution patterns to stay secret-safe.
Loom’s goal is simple: make it hard to end up in a broken state.
Try It In 10 Minutes (No Daemon Required)
This is the quickest way to evaluate Loom without committing to any deeper architecture:
- Start from a clean reference: make sure
platform/gitops/mcp/context/registry.yamlreflects what you want available everywhere. - Generate + sync configs:
cd services/loom-core
make build
./bin/loom sync all --regen
./bin/loom sync status
- If you’re using the VS Code extension (
services/loom), open the Sync Dashboard and verify everything issynced.
That loop is the whole feature: edit registry -> sync -> verify.
If you want an “always-on” view into what your agents are doing, the HUD is the next easiest win:
cd services/loom-core
./bin/loom hud --port 3333
(Pinning a port makes it easier to bookmark and enables loom agent ... commands to talk to the HUD API consistently.)
The Core Feature: A Canonical Registry
The single source of truth is platform/gitops/mcp/context/registry.yaml. Each server definition has:
- a platform-agnostic
commondefinition (command/args/env/timeout) - optional
targetsoverrides (codex, vscode, claude, gemini, kilocode, etc.) - an
always_allowlist (tools that are safe to auto-approve)
Here’s what a real entry looks like (trimmed for clarity):
servers:
- name: gitlab
categories: [devops, scm]
common:
command: '${repo}/services/loom-core/bin/mcp-gitlab'
timeout: 60
always_allow:
- list_projects
- get_project
- list_merge_requests
env:
GITLAB_API_URL: '${env:GITLAB_API_URL:-https://gitlab.flexinfer.ai/api/v4}'
GITLAB_PERSONAL_ACCESS_TOKEN: '${env:GITLAB_PERSONAL_ACCESS_TOKEN}'
targets:
codex:
env:
GITLAB_PERSONAL_ACCESS_TOKEN: '${keychain:GITLAB_PERSONAL_ACCESS_TOKEN}'
You can see the intent:
- Common defaults are portable.
- Platform overrides are explicit, minimal, and localized.
How It Actually Gets Used: Generate, Sync, Verify
From loom-core’s architecture perspective, the pipeline is:
- edit
registry.yaml - generate configs into
generated/ - sync configs into each platform’s home config path
- reload
loomd(if you’re using loom-mode)
The “happy path” is intentionally one command (from the loom-core repo):
cd services/loom-core
./bin/loom sync all --regen
And for quick drift checks:
cd services/loom-core
./bin/loom sync status
Under the hood, loom-core’s sync command supports:
--regento re-generate from registry before syncing--repo-onlywhen you only want to update the repo artifacts--loom-modewhen you want a single “loom proxy” entry instead of N local servers--resolve-secretswhen you need to materialize templates (use with care)
Skills are part of the same loop:
cd services/loom-core
./bin/loom sync skills all
The UI Layer: Loom Extension Sync Dashboard
The VS Code extension (currently services/loom v0.9.0) surfaces this as a first-class workflow:
- it continuously checks enabled platforms
- hashes server lists (not full configs) to avoid false positives from placeholder differences
- shows a grid of platforms with:
synced,out-of-sync,missing,error - wires “Sync” actions to
loom sync <platform> --regen
This is the key move: drift detection becomes ambient, not an “oh no” moment after something breaks.
HUD + Native Overlay (macOS)
Loom also ships an Agent HUD in loom-core: a local web dashboard that talks to the running daemon and gives you real-time visibility into:
- MCP server health
- active agent sessions and tasks
- workflows and approvals
- memory tiers and recent context entries
Launch it like this:
cd services/loom-core
./bin/loom hud --port 3333
On macOS there’s an extra mode that makes the HUD worth trying even if you never open the full dashboard: a native overlay panel. It’s a borderless, edge-anchored strip that stays available while you work, with a system-wide hotkey:
- Toggle overlay:
Cmd+Shift+L - Enable overlay:
cd services/loom-core
./bin/loom hud --overlay --port 3333
You can customize the overlay’s placement and feel:
cd services/loom-core
./bin/loom hud --overlay --edge right --width 380 --opacity 0.92 --corner-radius 12 --port 3333
This is the UX version of the “ambient drift detection” idea: you don’t have to context-switch into a tool to learn what’s happening. You just glance, and keep going.
What This Replaces (In Practice)
The old workflow is “copy snippets around until it works.” The new workflow is “treat MCP like config.”
A concrete example:
- You add a server to
platform/gitops/mcp/context/registry.yaml(say,mcp-loki). - Codex immediately works because you ran
loom sync all --regen, but Gemini still has the old server list. - Loom shows Gemini as
out-of-sync(server mismatch), and you fix it with a singleSyncaction.
The important shift: you stop debugging “what is the right file path for this platform” and instead debug the registry entry (command/env/allowlist), which is the only place that should matter.
What I Learned Shipping It (v0.7.0 -> v0.9.0)
Looking at the project state today:
- loom-core v0.7.0 was where multi-platform sync really landed.
- loom v0.7.0 added the first Sync Dashboard and platform views.
- loom v0.8.0 made it survivable day-to-day: drift detection, offline mode, bulk operations.
- loom v0.9.0 made it adoptable: onboarding wizard, metrics, deep search, and better UI polish.
The progression matters: sync isn’t a one-shot command, it’s an operational loop. The dashboard and drift detection are what make it stick.
Practical Workflow: Adding a Server Without Breaking Everything
Here’s the concrete loop I follow now:
- Add or edit a server in
platform/gitops/mcp/context/registry.yaml. - Run
cd services/loom-core && ./bin/loom sync all --regen(or use the extension’s “Sync All”). - Run
cd services/loom-core && ./bin/loom sync statusand fix any drift. - If using
loomd, reload it (cd services/loom-core && ./bin/loom reload).
That’s it. No copy/paste between six config files.
Takeaways
- Central registries are only useful if they’re enforced by tooling. Loom’s value is not the YAML file, it’s the generator + sync + drift detection loop.
- Platform differences are real; model them instead of hiding them. The
targetsoverrides keep the common definition clean. - Make safety explicit.
always_allowis a policy surface: you can define what’s auto-approved versus what must be interactive.
Next up: I’m going to write about the other half of the system, loomd as a local router and lifecycle manager (and why “loom-mode” changes the failure modes in a good way).
Related Articles
Comments
Join the discussion. Be respectful.