brewale
v0.4.1
Published
Set up the Brewale MCP server for your coding agents — Claude Code, OpenAI Codex CLI, Cursor, VS Code, and Zed.
Readme
brewale
Connect your coding agents to your organization's Brewale MCP server in seconds:
npx brewale@latestSupported agents: Claude Code, the OpenAI Codex CLI, Cursor, VS Code, and Zed. The command:
- Writes/registers the Brewale MCP server config for each detected agent, and
- with separate consent, adds a managed instruction block to the agent's
instructions file (
CLAUDE.md/AGENTS.md) so agents actually consult Brewale.
Nothing is written without showing you the exact bytes (or the exact command)
first. Re-running is idempotent. npx brewale uninstall reverses everything.
It then offers to install your skills locally: each skill is written into
the agents' own skill folders (~/.claude/skills, ~/.agents/skills, …), so
agents discover them when a session starts and they show up as /slug
commands. See Local skills.
Commands
| Command | What it does |
| ------------------------- | -------------------------------------------------------------- |
| npx brewale (or init) | interactive setup |
| npx brewale login | sign this machine in for local skills (browser approval) |
| npx brewale sync | install/update your skills in the agents' skill folders |
| npx brewale logout | forget this machine's sign-in keys |
| npx brewale uninstall | remove the config entries and instruction blocks it added |
| npx brewale status | read-only health report + connectivity probe (alias: doctor) |
Flags
| Flag | Meaning |
| ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| --agent <ids> | claude-code (alias claude), codex, cursor, vscode (alias code), zed; repeatable or comma-separated. Default: detected agents |
| --project / --global | config scope (default: project). Codex MCP config is always global |
| --auth <oauth\|token> | default oauth (recommended; no secret stored anywhere) |
| --token <tok> | Brewale API token — warning: flags can end up in shell history |
| --token-stdin | read the token from stdin (CI) |
| --url <mcp-url> | advanced: non-default server URL |
| --project-id <owner/repo> | scope the connection to a Brewale project (project scope only). Has no effect if Projects isn't enabled on your organization. Default: derive owner/repo from the git remote and ask |
| --no-project-id | don't scope to a project; skip the git-remote prompt |
| --no-instructions / --instructions-only | skip or only manage the instruction block |
| --yes / -y | accept defaults; required when stdin isn't a TTY |
| --dry-run | preview everything, write nothing |
| --no-verify | skip post-install verification |
| --quiet / --verbose | less / more output |
| --no-local-skills | init: don't offer to install skills locally |
| --code <bwc_…> | sync: sign in with a single-use code (from the web page or the agent's sync_local_skills tool), then sync |
| --mode <live\|copy\|org> | sync/login: live writes small stubs that load the skill from Brewale; copy writes the full skill and its files; org follows your organization's default. Saved per machine |
| --global-only | sync: skip this repository's project skills |
| --hook | sync: session-start mode — silent, 3-second timeouts, always exits 0 |
| --no-browser | login: print the sign-in URL and paste the code instead of the loopback redirect |
| --org <slug> | logout: only forget this organization's key |
login, sync and logout also read the server URL from $BREWALE_MCP_URL
when --url isn't given.
Exit codes: 0 success or clean decline · 1 failure · 2 usage error ·
130 interrupted.
What we write where (the trust surface)
| Target | When | Content |
| ------------------------------------------------------------------------------------------------------------ | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ./.mcp.json | Claude Code, project scope | mcpServers.brewale entry ("type": "http"). Token auth references ${BREWALE_MCP_TOKEN:-} — the raw token is never written to any project file. Other entries, unknown keys, and indentation are preserved; unparseable JSON is refused, never clobbered |
| ~/.claude.json | Claude Code, --global | never edited directly — we shell out to claude mcp add --scope user. With token auth the token is stored in plaintext there by the claude CLI (you're warned, file named) |
| ~/.codex/config.toml | Codex | never edited directly — we shell out to codex mcp add (token auth passes only the env-var name). Codex older than 0.45 gets a printed manual snippet instead |
| ./.cursor/mcp.json, ~/.cursor/mcp.json | Cursor | mcpServers.brewale entry (url-only for OAuth). Token auth references ${env:BREWALE_MCP_TOKEN} at both scopes — the raw token is written nowhere. Cursor older than 1.6 (no env interpolation) gets a printed manual snippet for token auth |
| ./.vscode/mcp.json | VS Code, project scope | servers.brewale entry ("type": "http"). Token auth uses a ${input:brewale-token} password prompt — VS Code asks once on first server start and stores the value outside the repo |
| VS Code user-profile mcp.json | VS Code, --global | never written directly for installs — we shell out to code --add-mcp (targets the right profile). With token auth the token is stored in plaintext there (you're warned). Uninstall edits the default-profile file, and only when it holds our entry |
| ./.zed/settings.json, ~/.config/zed/settings.json | Zed | context_servers.brewale entry, edited comment-preservingly (Zed settings are JSONC). Zed has no env-var interpolation: token auth is refused at project scope (plaintext would be committed) and stored plaintext-with-warning at global scope. Zed < 0.214 gets an mcp-remote snippet; 0.214–0.229 can't run the OAuth flow and is told to upgrade or use a token |
| ~/.claude/skills, ~/.agents/skills, ~/.cursor/skills, <repo>/.claude/skills, <repo>/.agents/skills | login / sync | one folder per skill (SKILL.md, plus bundled files in copy mode). Only folders brewale created are ever changed or deleted |
| <repo> git info/exclude | sync inside a repo | a # brewale:start … # brewale:end block listing the local skill folders |
| ~/.claude/settings.json | init, with consent | a hooks.SessionStart entry running brewale sync --hook; other settings and hooks are kept |
| ~/.brewale/ | login / sync | credentials.json (device keys, 0600) and state.json (which folders brewale owns) |
| ./CLAUDE.md, ~/.claude/CLAUDE.md, ./AGENTS.md, ~/.codex/AGENTS.md, ~/.config/zed/AGENTS.md | with separate consent | one managed block between <!-- brewale:start … --> / <!-- brewale:end --> markers. Cursor, VS Code, and Zed read the shared project AGENTS.md (Zed prefers .rules-style files when present — we warn; Cursor and VS Code have no global instructions file on disk). Content outside the markers is never touched; malformed markers are refused |
Local skills
npx brewale login opens a Brewale page where you approve this device for one
organization (run it again for another). The approval is sent back to a
one-time listener on 127.0.0.1 and checked with PKCE; without a browser, the
page shows a code to paste instead. The resulting key only works for skills
sync — Brewale refuses it on the MCP endpoint — and you can revoke it under
Account → Devices on brewale.dev.
npx brewale sync then asks Brewale for your skills and writes one folder per
skill:
| Set | Skills | Folders |
| ------ | ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| Global | your organization's general skills, your subscriptions, personal skills | ~/.claude/skills (Claude Code), ~/.agents/skills (Codex), ~/.cursor/skills (Cursor) |
| Local | this repository's project skills (from the origin remote) | <repo>/.claude/skills (Claude Code), <repo>/.agents/skills (Codex, Cursor, VS Code Copilot) |
Only folders for detected agents are used (Zed has no skills support and keeps
using the MCP server). With no agent detected, ~/.agents/skills and
~/.claude/skills are used.
- Live mode (the default) writes a short
SKILL.mdstub: the agent sees the name and description, and loads the current procedure from Brewale when it uses the skill, so edits reach agents within ~5 seconds. - Copy mode writes the full skill and its bundled files. It is as fresh as the last sync, and the files stay on disk if access is revoked.
- Ownership: brewale only changes or deletes folders it created (tracked
in
~/.brewale/state.json). An existing folder with the same name is skipped with a warning; a name used by another organization becomes<org>-<name>. - Git: local skill folders are hidden from git through a marked block in
the repository's
info/excludefile (worktree-aware); nothing is committed. - Revoked or unpaid access stops the sync for that organization and leaves its files as they are.
- Staying fresh: with your consent,
initadds a Claude CodeSessionStarthook to~/.claude/settings.jsonthat runsnpx -y brewale@0 sync --hook || trueat every session start. A regularsyncupdates a hook installed by an earlier version. In a repo whose.npmrcsets an npmmin-release-agecooldown, the hook picks up a new CLI version once it is older than the cooldown. Other agents: runnpx brewale sync, or ask the agent to "update my local skills".
Secret handling:
- All terminal output is passed through a redactor (
lore-mcp_…andBearer …patterns are masked). - The authenticated connectivity probe only ever runs against the default
Brewale host, so a malicious
--urlcannot be used to exfiltrate a token. - Known limitation: during
claude mcp add --scope userandcode --add-mcpwith token auth, the token is briefly visible in the child process argv (e.g. inps). - Local skills keys live in
~/.brewale/credentials.json(file0600, folder0700) and are only ever sent to the server they were issued by.$BREWALE_MCP_TOKENis only used for sync against the default host. - Zero telemetry. Network calls: the optional verification probe, and — for local skills only — sign-in, the skills download, and a sync receipt that lets Brewale tell you when your local skills are out of date.
Development
This package lives in the Brewale monorepo but is intentionally standalone:
- Must run under plain Node >= 18.17 (npx) — no
bun:*APIs, no@abtion/*/@repo/*runtime imports (enforced by eslint). - Tests run under vitest on Node (
bun run test), notbun testlike sibling packages — runtime parity with what npx executes. bun run buildbundles everything intodist/index.jswith zero runtime dependencies (tsup,noExternal).
Publishing is part of the production release: tagging v* deploys the
servers, then stages this package if its version isn't on npm yet and tags
the commit brewale-vX.Y.Z (.github/workflows/deploy-prod.yml). A maintainer
approves the staged version with npm stage approve <stage-id> (2FA) to make it
live; the stage id is in the workflow run's summary. To ship CLI
changes, bump version in package.json and VERSION in
src/core/constants.ts (a test keeps them equal) before tagging the release.
