Skip to content

v1.4.0 — the hooks can finally reach the gateway

Choose a tag to compare

@philipp-berger philipp-berger released this 29 Jul 00:55
· 95 commits to master since this release

The headline fix

The hook layer could never authenticate on a machine installed with claude mcp add. That path writes the gateway URL and virtual key into ~/.claude.json; hooks are separate processes that read only process.env, so every lookup came back empty. The background refresh never ran, and skill, memory and tool context were silently absent from every session — while the static guidance kept printing, so the install looked healthy.

Hooks now fall back to the MCP server entry when the environment does not carry the credential. This adds a new file dependency: the plugin reads ~/.claude.json.

What that unlocked

Three things were already being fetched and thrown away:

  • Tool roster. Discovery walked the full code-mode catalog and returned two regex hits from it — and only walked it when a capability was missing, so on a gateway where skills and memory both resolve flat it was never fetched at all. On a reference gateway that hid 251 tools across 13 servers.
  • Skill discovery, now search-first with worked examples, and telling the model to judge what comes back rather than defer to it.
  • Memory, advertised with both its read and its write call, fenced as untrusted data.

New

  • Periodic memory check-in (Stop, async) writing to a local, git-ignored .bifrost/candidates.md, with /bifrost-candidates to review and promote. Deliberately not straight to shared memory: memory_search has no tag or state filter, so anything written there is recalled by every colleague immediately as settled knowledge.
  • Usage counter (PostToolUse/PostToolUseFailure, async) — counts only, no queries or content, never leaves the machine. SessionStart adapts: an agent already searching gets the calls without the argument; one that has not searched in N sessions is told so.
  • bifrost-code-mode skill, verified against a live gateway. Two things in the old guidance were wrong: readToolFile takes fileName, not path, and top-level for/if need no def wrapper.
  • SECURITY.md and CONTRIBUTING.md.

Security and correctness

  • URL and key are always taken from the same source, so a stale BIFROST_URL cannot pair with a configured key and send it to an unintended host.
  • The gateway URL printed into context is reduced to scheme, host and path — an MCP endpoint may carry credentials in userinfo or the query string.
  • Flat tool names resolve on the matched token rather than a guessed hyphen; resolution is deterministic.
  • Degraded refreshes no longer blank a good cache or resurrect a revoked capability.
  • Hooks drain stdout before exit (pipe writes are async on Windows).

Breaking-ish

The endpoint-migration notice no longer ships a hostname list. Set BIFROST_LEGACY_HOSTS to re-enable it; BIFROST_CANONICAL_URL defaults to https://bifrost.culture4.life/mcp. See README, "Running your own gateway".


130 tests, mutation-verified. Full detail in CHANGELOG.md.