Skip to content

Releases: PyModel/claude-agy-mcp

v3.1.0

Choose a tag to compare

@elkaix elkaix released this 12 Sep 20:43
29f5b5c

Read-only runs are now enforced on macOS: plan-mode delegations run under sandbox-exec, which blocks writes into their roots and renames of any directory above them. Linux still watches read-only runs; AGY_READ_ONLY_ENFORCEMENT=require refuses them there. agy's "authentication failed" error now classifies as unauthenticated.

v3.0.4 — ignored files are watched too

Choose a tag to compare

@elkaix elkaix released this 12 Sep 19:40
5838e36

Ignored files are watched too, and the build is one tool

  • A plan-mode run that writes a git-ignored file is now seen. The fingerprint hashes the mode, size and mtime of every ignored entry and walks ignored directories up to 1,000 entries each. Dependency and build trees at the repository top (node_modules, .venv, venv, __pycache__, .next, dist) count as one entry. An entry that vanishes while the snapshot is being taken makes the tree uncovered rather than "changed".
  • Cost measured. About 150 ms per snapshot on a clean 3,500-file repository and about 1.1 s with 300 modified and 3,000 untracked files, on an Apple M5 Max.
  • Plan mode is advisory with the permission bypass off as well as on. Verified against agy 1.2.2; the docs no longer tie the caveat to AGY_SKIP_PERMISSIONS.
  • Build is esbuild alone. tsup and the esbuild override are gone.
  • os: [darwin, linux]. The bridge kills process groups, which has no Windows equivalent, so npm refuses the install there instead of the bridge misbehaving at run time.
  • CI tests on macOS as well as Linux. An untracked nested repository or a file name with a newline no longer drops the fingerprint to the metadata scan.

Update the skills with:

npx --package @pymodel/claude-agy-mcp claude-agy-mcp-install-skills

Full changelog: v3.0.3...v3.0.4

v3.0.3 — the bridge holds up at its edges

Choose a tag to compare

@elkaix elkaix released this 12 Sep 19:04
6cbf208

The bridge holds up at its edges

An end-to-end audit drove the stdio server against real agy and a hostile fake, and found about fifty ways it could leak work, repeat a write, or report the wrong thing. Each fix ships with a test that failed before it.

  • Disconnect and SIGTERM now kill running agy. Before, a client that quit left detached agy runs going with permissions skipped. The bridge also exits when stdin closes.
  • A run is repeated only if the tree is provably unchanged. Network retries, quota failover and warm-session fallbacks used to re-send a write that may already have landed. They now report Not retried or Not failed over instead.
  • The read-only check sees more. It fingerprints contents, modes and untracked files across cwd and every added directory. Files git ignores are still not covered.
  • AGY_ALLOWED_ROOTS resolves paths the way the OS does. root/link/.. can no longer escape through a symlink.
  • Errors say what happened. A missing cwd is no longer reported as agy not installed, and a stray 429 or 401 in agy's log no longer triggers quota or login handling.
  • Inputs are bounded. Blank prompts, prompts too large for argv, ids starting with -, oversized fan-outs and timeouts too large for Node's timers are rejected up front.
  • Smaller fixes. A 60s floor on quota cooldowns, a pinned model bypasses its cooldown, usage of failed attempts is counted, logs live in a private per-process directory, and the cooldown store survives concurrent writers.

Update the skills with:

npx --package @pymodel/claude-agy-mcp claude-agy-mcp-install-skills

Full changelog: v3.0.2...v3.0.3

v3.0.2 — a follow-up that did not resume now says so

Choose a tag to compare

@elkaix elkaix released this 12 Sep 18:09
bfb4dcf

A follow-up that did not resume now says so

agy answers --conversation <id> for an id it cannot find from a brand-new conversation and exits 0, only warning on the side. Through 3.0.1, a follow_up with a stale or mistyped session id therefore returned an answer with none of the earlier history and reported it as a normal continuation.

The bridge now compares the conversation a call asked for with the one agy reports, on both the warm and cold paths. A mismatch adds a line to the fenced header:

[claude-agy-mcp 1a2b3c] SESSION NOT RESUMED — you asked to continue <old-id>, but agy answered from a different conversation (<new-id>), so this answer has none of that history. …

Structured responses carry resumed: false. When agy reports no id, nothing is claimed either way.

Also

  • CI now rejects either broken npx install form from v3.0.0, via a test in the repo rather than an external check.
  • The bundled skills and CLAUDE.md explain the new warning.

Install or update the skills with:

npx --package @pymodel/claude-agy-mcp claude-agy-mcp-install-skills

Full changelog: v3.0.1...v3.0.2

v3.0.1 — the install command actually runs

Choose a tag to compare

@elkaix elkaix released this 12 Sep 17:44
01547b8

First npm release of the 3.x line. Install the skills with this, not the command printed in v3.0.0:

npx --package @pymodel/claude-agy-mcp claude-agy-mcp-install-skills

Fixes

  • The v3.0.0 install command does not run. npx @pymodel/claude-agy-mcp-install-skills reads as a package name to npx and 404s. npx @pymodel/claude-agy-mcp install-skills starts the stdio server with a stray argument and hangs. The bin is a package selection, so the working form names the package and the bin separately.
  • The handshake version is derived, not restated. It reads package.json at module init instead of duplicating the number in source. Verified against the installed tarball, not the source tree: driving initialize over stdio against a temp install returns the right version from the bundled entry.
  • The installer no longer clobbers a symlink. Pointing a skill at a checkout you edit is a supported setup, so a symlinked destination is skipped with a message. --force replaces it deliberately.
  • A timing-dependent concurrency test is now deterministic. It waited one macrotask tick for the semaphore to fill, which is not enough under load.

Everything in v3.0.0 ships here too: read-only violation detection, strict config parsing, quota and lifecycle hardening, and the bundled skills.

Full changelog: v3.0.0...v3.0.1

v3.0.0 — read-only is watched, and the skill ships in the box

Choose a tag to compare

@elkaix elkaix released this 12 Sep 17:28
3f049c2

This version was never published to npm. Install v3.0.1, which carries everything below plus a working install command.

A full hardening pass over the bridge, plus the delegate skill bundled into the package so installing the server is enough.

Read-only was decorative

agy ignores --mode plan while --dangerously-skip-permissions is on, which is the default. Verified live against agy 1.2.2: a delegate call with write omitted created a file, a follow_up created another, and neither reported anything. The real argv confirmed both flags ship together on every read-only call.

The bridge cannot make agy honour plan mode, so it watches instead. Every plan-mode run is fingerprinted before and after, and a READ-ONLY VIOLATION line in the response header reports a tree that moved. A tree that cannot be fingerprinted reports unknown, never "nothing happened".

Also fixed

  • Config parses through one strict parser. AGY_SKIP_PERMISSIONS and AGY_SANDBOX bypassed it, so 0 and 1 were silently ignored on the two settings that decide how much authority a run gets.
  • Quota is one regex with day-aware resets and no lost 429. The poller banks its last read before the settled check, timed-out runs are still classified, an unparseable reset reports unknown, and a quota seen on stderr records a cooldown.
  • Containment validates what agy actually receives. Roots derived from file arguments went unvalidated. The machine-global conversation-cache fallback is deleted rather than patched.
  • Redaction runs before truncation at one exit, covering the warm paths, structured output, progress notifications and error text. Stripe, GitLab, npm and connection-string credentials are recognised.
  • Lifecycle: a dead session's stdin could take the bridge down through an unhandled stream error, and shutdown was never wired, so detached agy processes outlived the server.
  • Cancelling a queued call leaves the queue, the budget is re-checked inside the admission gate, a rejected model name re-reads the listing once, an interrupted warm turn reports uncertainty instead of being replayed, and a restriction the installed agy cannot enforce refuses the call.

The skill ships in the box

Both skills live under skills/. Install them with:

npx --package @pymodel/claude-agy-mcp claude-agy-mcp-install-skills

It detects Claude Code, the agents hub, Pi and zcode, and writes only into directories that already exist. --list previews, --dir names one explicitly. A test validates their frontmatter and internal links, so a broken skill fails the build rather than a user's install.

Breaking changes

  • An unrecognised value for any AGY_* environment variable stops the server naming the variable, instead of falling back to a default.
  • AGY_SKIP_PERMISSIONS and AGY_SANDBOX honour every documented boolean spelling, not only false and true.
  • follow_up requires a session id the bridge itself returned.
  • A run asking for --mode plan or --sandbox on an agy build lacking the flag fails instead of running unrestricted.

Full changelog: v2.1.0...v3.0.0

v2.1.0

Choose a tag to compare

@elkaix elkaix released this 11 Sep 23:43
0ca41c5

What changed

Features

  • set_model + ask-once gate (AGY_ASK_MODEL, default on). On first use the server asks the user through MCP elicitation — "Proceed with the default — Gemini 3.8 Flash (High) at high effort — or change?" with model and effort pickers. Accept unchanged records the default; decline delegates nothing. Saved to ~/.config/claude-agy-mcp/preferences.json, shared by every client on the machine, asked once. Clients without elicitation get the same question as error text and call set_model (no args = default). Fan-out is gated too.
  • Gemini Flash High leads every chain. deep_search/web_lookup fall back to Medium; review and council tools to Pro then Claude.

Fixes

  • --effort was rejected by agy 1.2.1 for every tiered model name, so every tool that set its own tier failed with "invalid model selection". Effort now selects the sibling tier (Flash (High) + medium → Flash (Medium)); --effort only reaches untiered models. Tools no longer carry a separate effort.
  • README claimed --mode plan proved a run changed nothing. Verified false on agy 1.2.1 with the bypass on (agy wrote a file in plan mode, with and without slash-command expansion); without the bypass headless agy denies even read_file and returns empty. Docs now say what the grant means.

Hardening (from an agy review of this branch, each with a test)

  • stream-json envelopes were never parsed. Every run with a progress token (Claude Code always sends one) got raw NDJSON back as the answer, zero usage, no denied actions, no structured output, and a conversation id from the shared cache file. Text-mode output is no longer scanned for an envelope either, so a JSON line in a plain answer cannot forge one.
  • Effort applies to the primary model only. Re-tiering the whole chain turned the Flash (Medium) fallback back into the Flash (High) that had just 429'd; cooldowns were keyed on the pre-tier name.
  • Resident sessions are bounded by the run timeout and cancellation (a stalled turn held its admission slot forever), run cold when the call pins a model/effort or writes, carry the delegation-depth env, respect warmMax when every session is busy, read on close not exit, and record per-turn usage — agy reports the conversation's running total on every result (verified on 1.2.1), which compounded the budget.
  • Runner gives a killed child a bounded chance to exit before taking its output and removing its log. Cooldown file saves merge across processes and keep entries in memory when the cache dir is read-only. Elicitation is offered only to form-capable clients. Progress notifications no longer become unhandled rejections. AGY_ALLOWED_ROOTS uses the platform delimiter and follows symlinks. Fan-out with every leg failed gets the strict-mode note. CapabilityCache and the unused per-tool effort field are gone.

Chores

  • CI's test job hung for hours: the cooldown-store test used /proc/nope/nope as an unwritable dir, and on Linux Node's recursive mkdir loops forever under procfs. It now uses a regular file in the directory's place.
  • Lockfile refreshed past hono, fast-uri, qs advisories (supersedes #28). Deps to zod 4.6.2, lint-staged 17.5.1, @types/node 26.5.1, vitest 5 (supersedes #29).
  • README: CI/npm-version/node/license badges removed, remaining badges flat; screenshot of the form added.

Also carries the JSON-envelope hardening this branch started with.

v2.0.0 — Gemini 3.7 Flash (High) default

Choose a tag to compare

@elkaix elkaix released this 14 Aug 06:00
a27c4cb

Breaking

  • Default model and all tool routing chains now target Gemini 3.7 Flash (High) (previously Gemini 3.6 Flash). Setups relying on the old chains against agy listings without 3.7 models will resolve differently.

Changed

  • analyze_files, deep_search, web_lookup, adversarial_review, delegate chains updated to Gemini 3.7 Flash
  • AGY_DEFAULT_MODEL fallback default → Gemini 3.7 Flash (High)
  • README: benchmark highlights, MCP stack guide, updated routing tables
  • New banner and benchmarks assets

Full Changelog: v1.0.3...v2.0.0

v1.0.3

Choose a tag to compare

@elkaix elkaix released this 14 Aug 02:47
d8089f3

Ships dependency upgrades to npm.

  • zod 3 → 4 (#5)
  • @modelcontextprotocol/sdk 1.29 → 1.30 (#6)
  • transitive lockfile sweep, actions/setup-node v7, actions/checkout v7 (#2, #15)

No behaviour changes; tool schemas verified over a live stdio handshake.

v1.0.2

Choose a tag to compare

@elkaix elkaix released this 14 Aug 02:33
55ed650

Listed on the official MCP Registry as io.github.PyModel/claude-agy-mcp.

  • chore: align mcpName and server.json with the registry-granted namespace casing (#14)

No runtime changes from 1.0.1.