feat(memory): env-aware backend + memory in default plugin set - #44
Merged
Conversation
Makes the Memory Pack a zero-config default. The MCP server now picks
the right backend based on what's in the environment, and exposes the
agentmark_memory_* tools whether or not SaaS creds are present.
Detection cascade in detectMemoryBackend():
- All three of THINKFLEET_BASE_URL + THINKFLEET_PROJECT_ID +
THINKFLEET_API_KEY present → ActivepiecesMemoryBackend (memory
flows to SaaS; available across machines + AI tools).
- None present → LocalFileMemoryBackend (legacy default, on-disk,
offline-safe).
- Some-but-not-all present → throw MemoryBackendConfigError.
Refusing to silently fall back to local matters: a typo in one
variable shouldn't quietly demote a user from "memory syncs to my
team" to "memory only on my disk".
- Malformed API key (no sk- prefix) → throw; truncated to first 4
chars in the error so secrets don't leak into logs.
Dispatcher integration:
- createDispatcherState() now always builds a memory plugin and
adds it to the default plugin set alongside web + pdf + desktop.
- On misconfiguration, memory is disabled and the reason logged
to stderr; the rest of the server stays alive. MCP clients
(Claude Code, Cursor, …) surface stderr so users see the
misconfiguration.
- Selected backend is logged at startup via describeMemoryBackend()
— credential-free description, safe for any log sink.
Threat model:
- API key only ever lives in process env. Callers (ThinkFleet
Desktop installer in upcoming PRs) should pass it from an OS
keychain, not persist it in a plain settings file.
- The MCP install CLI's --env support (PR β) is the supported
transport into a client's MCP config.
Tests:
- test/memory/detect-backend.test.ts — 16 cases covering each
branch of the detection cascade, error-message sanitization,
whitespace handling.
- test/mcp/default-memory-plugin.test.ts — 5 cases covering
dispatcher integration: tools register, partial creds disable
cleanly, malformed keys don't leak to logs.
540 tests pass. Typecheck clean. Backwards-compat: callers passing
an explicit `plugins` array to createMcpServer() see no change;
default callers get the memory tools.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR α of the ThinkFleet Memory Bridge slice. Makes the Memory Pack a zero-config default — the MCP server now picks the right backend based on what's in the environment, and exposes
agentmark_memory_*tools whether or not SaaS creds are present.This is the foundation for: install ThinkFleet Desktop → log in → every AI tool (Claude Code, Cursor, Codex, Copilot, Windsurf) gets persistent hierarchical memory automatically.
What's in
detectMemoryBackend()— env-aware cascadeTHINKFLEET_BASE_URL+THINKFLEET_PROJECT_ID+THINKFLEET_API_KEYsetActivepiecesMemoryBackendLocalFileMemoryBackendMemoryBackendConfigErrorsk-prefixRefusing to silently fall back to local on partial creds matters: a typo in one variable shouldn't quietly demote a user from "memory syncs to my team" to "memory only on my disk."
Dispatcher integration
createDispatcherState()always builds a memory plugin alongside web + pdf + desktop.describeMemoryBackend()— credential-free description, safe for any log sink.Threat model (codified in the docstrings)
Tests
test/memory/detect-backend.test.ts— 16 cases covering each branch of the cascade, error-message sanitization, whitespace handling.test/mcp/default-memory-plugin.test.ts— 5 cases covering dispatcher integration: tools register, partial creds disable cleanly, malformed keys don't leak to logs.Full suite: 540 passed, 10 pre-existing skips. Typecheck clean.
Backwards compatibility
Strictly additive:
pluginsarray tocreateMcpServer()see no change.LocalFileMemoryBackendbehavior unchanged when env is unset.Next PRs
agentmark-mcp install --env KEY=VALso the install CLI can write env into client config blocks safely.thinkfleet-memory.skill.yaml+ per-tool skill installer (Claude Code skills, Cursor rules, etc.) so agents are taught the protocol, not just given the tools.🤖 Generated with Claude Code