Repository navigation
Changes
Robustness fixes: config data loss, unmounting, hung backends, CLI and mbro bugs (#21)
Date: Sat Sep 26 09:28:09 2026 -0700
- Add backend_init_timeout setting
- Stop config saves from silently deleting user data
- A config.json that fails to parse is no longer overwritten by the next
save; the save is refused and the file left as-is. An empty file is
still treated as new. - Server entries that fail validation, and top-level settings like
self_prefix, are written back unchanged instead of being dropped. - The reloader now reads the file with the same loader as
ConfigManager, so its cached config includes kits and settings. With
auto-reload on (the default), the first save from a running server
used to erase the kits section. - ServerConfig, KitConfig, AuthConfig and BearerAuthConfig are plain
models. As BaseSettings with no env prefix they read unrelated env
vars like PREFIX (set by Termux), URI, ENV and KEY_PATH, which made
valid servers fail to load and then get dropped on save. - Config and auth.json writes go through a temp file and rename, keeping
the existing file's mode and following symlinks. - The watchdog handler also reacts to files created or renamed over the
config, which is how many editors and tools save. - A disabled server without a command or uri no longer blocks every
subsequent reload.
- Fix auth CLI crashes and harden server search
Auth:
magg auth initcreates missing parent dirs (e.g. no ~/.ssh) and
reports "key already exists" as an error instead of a traceback.- The private key file is created 0600 rather than chmod'ed after write.
--key-pathis saved to auth.json; previously only a custom issuer or
audience was, so auth status/token couldn't find the new key.auth private-key --exportquotes the key so the output can be eval'd.auth statusno longer prints the MAGG_PRIVATE_KEY line twice.
Search:
- A GitHub repo with a null description, or an npm package with a null
author, no longer throws away all results from that source. - Sources are searched concurrently, with a 15s session timeout instead
of aiohttp's 300s default, and proxy env vars are honored. - The ranking bonus for Glama results now matches their source name.
- Make documented kit and reload settings real; fix docs that drifted
- Kits in a kit.d next to the config file are found even when the config
is set with MAGG_CONFIG_PATH or --config, as the docs described. - MAGG_RELOAD_USE_WATCHDOG was documented but ignored; false now forces
polling, which helps where file notifications don't arrive (network
filesystems, Docker Desktop bind mounts). - Docs: --env-pass/--env-set are global options (magg --env-pass serve);
kit discovery uses MAGG_PATH, not the nonexistent MAGG_KITD_PATH; an
omitted prefix means no prefix, not the server name; MAGG_PREFIX_SEP
only applies to Magg's own tools; magg_check's timeout default is 2.5;
the kit example is valid JSON; document MAGG_BACKEND_INIT_TIMEOUT and
how reload treats invalid files.
- Report invalid MAGG_* settings without a traceback
A bad value such as MAGG_AUTO_RELOAD=maybe or MAGG_SELF_PREFIX=my_prefix
used to print a pydantic traceback on every command, including
--version. The CLI now prints one line per invalid field naming the
environment variable to fix, and exits 1. python -m magg goes through the
same path.
- Fix mbro argument parsing, error handling, and connection bugs
- call/prompt keep a JSON object argument as raw text (quoted or not),
and scripts join JSON objects that span lines until braces balance - key=value values are decoded as JSON with a raw-string fallback,
keeping string-typed schema params as strings (no more 007 -> 7 or
ValueError on 10-20); prompt accepts key=value - Non-interactive runs (-n, -X, -) exit 1 when any command fails;
per-command errors are contained and later commands keep running,
with --fail-fast to stop at the first failure; quit stops scripts - status takes args and checks for a connection; None descriptions no
longer crash tools/prompts/search filtering or JSON search output - script run/dump with a missing script report an error instead of
exiting; resource/prompt tracebacks only print with -v - Connection errors carry the real reason (including duplicate names);
connects time out after --timeout seconds (default 30) - Only bare URLs get /mcp/ appended; /mcp and /sse paths are kept
- mbro - runs non-interactively; --repl without arepl returns cleanly
- help lists status and script instead of the nonexistent refresh;
unknown tools get "Did you mean" suggestions - Remove unused JsonArgParser
- Align mbro docs with actual commands and options
Replace nonexistent --connect/--call-tool flags and mbro scripts,
document disconnect <name>, script subcommands, script discovery
paths, JSON/key=value value handling, exit status, --fail-fast,
--timeout, URL defaults, and fix the REPL example.
- Fix server robustness bugs: unmount, hung backends, signals, read-only, auth
- Unmount on fastmcp 3: track the provider each mount adds and remove it
from mcp.providers, so disable/remove/update actually drop or replace a
backend's tools (previously a no-op that kept stale providers). - Hung backends: pass backend_init_timeout to backend clients and resolve
Magg's own tools/resources/prompts locally first, so one unresponsive
backend no longer blocks list_tools or Magg's tools. - Suppress backend stderr via the stdio transport's log_file; drop the
stdio_client monkeypatch that fastmcp bypassed. - Per-server env now overrides --env-pass/--env-set.
- magg_add_server: accept uri (AnyUrl -> str), require command or uri,
report the mount failure cause, roll back the mount if saving fails. - magg_check: use MountedServer.client (it crashed with any mount) and
iterate over a snapshot of mounted servers. - Read-only mode is checked up front in add/remove/enable/disable, kit
load/unload, and non-report check actions. - Refuse to serve HTTP/hybrid when a configured private key can't be
loaded instead of silently running without auth. - Runner: use loop signal handlers so SIGTERM wakes an idle stdio loop,
bound the wait on the cancelled server task, exit via the signal once
cleanup is done, force exit on a second signal, and restore SIG_DFL. - Proxy tool: path is required for 'info' (fix description).
- Allow check remount/unmount in read-only mode; fix Python 3.12.3 CLI parsing
- magg_check's remount and unmount actions only affect the running
process, so they stay available in read-only mode; disable still
refuses since it writes the config. - On Python 3.12.3 (Ubuntu 24.04's system Python), argparse treated
magg server update --envas an ambiguous abbreviation of the global
--env-pass/--env-set options. Disable abbreviations on the top-level
parser. - magg_add_server's prefix description matches actual behavior: no
prefix by default.
- Make new tests check behavior instead of internals
- Backend stderr: assert what actually reaches stderr (via capfd) with
suppression on and off, instead of checking a transport attribute. - Reload: rename a real file over the watched config and check the
reload fires; check Magg's own atomic save doesn't trigger a reload
while the next outside edit still does; check polling mode without
watchdog by observing a detected change. - Placeholder and unparseable-file reload tests go through
reload_config() rather than private helpers. - Hung backend test fails with a timeout instead of hanging on
regression, and no longer inspects private client attributes. - --key-path test checks that
auth tokenworks afterwards, which was
the user-facing failure. - Search concurrency is proven with a barrier instead of timing.
- Settings: a bad value no longer skips later valid settings.
- Remove tests that couldn't fail: a tool description string check, and
a timeout-0 check that fastmcp already guarantees.
- Test that mbro --timeout 0 disables the connect timeout
fastmcp treats an init_timeout of 0 as disabled, so passing it through
already matches the documented behavior. The test fails if 0 ever turns
into an immediate timeout.
- Bump version to 1.3.0
- Add a version bump script and drop the server.json tests
scripts/bump_version.py bumps the version with uv version (which
updates pyproject.toml and re-locks uv.lock) and copies it into
server.json. With --check it only verifies that server.json matches
pyproject.toml, for CI to run instead of the tests.
The server.json tests in test_registry_search.py checked release
metadata rather than code behavior, so they're removed.
- Enhance CI with version consistency check job
Added version consistency check for server.json and pyproject.toml.
Merge pull request #18 from sitbon/claude/magg-features-cli-r92ff7
Date: Sun Aug 2 13:56:21 2026 -0700
Gate PR Docker image publishing behind push-image label; add GHCR cleanup
Gate PR image publishing behind push-image label; add GHCR cleanup
Date: Sun Aug 2 20:26:12 2026 +0000
- PR runs now build and test images without publishing. Adding the
'push-image' label to a same-repo PR publishes the pr-NN / pr-NN-dev
tags (the 'labeled' event re-triggers the workflow). Fork PRs never
push - their GITHUB_TOKEN cannot write packages, which previously
would have failed the job outright. - Set retention-days: 1 on the dev-image tar artifacts, which are only
consumed by the next job in the same run. - Add a weekly ghcr-cleanup workflow that deletes ephemeral pr-* tags
and untagged manifests older than a week, complementing the post-push
cleanup-untagged job (which never runs on PR events). Version and
branch tags are never touched, so pinned deployments are unaffected.
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_011JFaNeMxJCxXhQ3J9RQACR
Document label-gated PR image publishing in readme
Date: Sun Aug 2 20:23:31 2026 +0000
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_011JFaNeMxJCxXhQ3J9RQACR
Installation
uv add magg==1.3.0