Signed-off-by: phernandez <paul@basicmachines.co>
5.2 KiB
Simplified Local/Cloud Routing
Context
Basic Memory now uses explicit, project-aware routing without a global cloud-mode toggle.
Routing is determined by command-level flags and project mode, not by a global cloud_mode state.
This document is the canonical contract for local/cloud routing behavior in CLI, MCP, and API-adjacent clients.
Goals
- Remove global
cloud_modefrom runtime/routing semantics. - Keep MCP HTTP/SSE local-only; let stdio honor per-project routing.
- Make CLI routing explicit and easy to reason about.
- Support projects that exist in both local and cloud without ambiguity.
Routing Contract
Routing is resolved in this order:
- Injected client factory (for composition/integration contexts)
- Explicit routing override (
--local/--cloudor env vars below) - Project-scoped routing (
project.mode) when a project is known - Default local routing
Routing Environment Variables
BASIC_MEMORY_FORCE_LOCAL=true: force local transportBASIC_MEMORY_FORCE_CLOUD=true: force cloud proxy transportBASIC_MEMORY_EXPLICIT_ROUTING=true: marks routing as explicitly chosen for this command
When explicit routing is active, project mode does not override the selected route.
Config Semantics
project.modeis the only config-based routing signal for project-scoped operations.- Legacy
cloud_modevalues may be encountered during migration/loading but are not used for routing behavior. - Normalization saves remove stale
cloud_modefrom~/.basic-memory/config.json.
Example Config
{
"projects": {
"main": {
"path": "/Users/me/basic-memory",
"mode": "local",
"local_sync_path": null,
"bisync_initialized": false,
"last_sync": null
},
"specs": {
"path": "specs",
"mode": "cloud",
"local_sync_path": "/Users/me/dev/specs",
"bisync_initialized": true,
"last_sync": "2026-02-06T17:36:38.544153"
}
},
"default_project": "main",
"cloud_api_key": "bmc_abc123...",
"cloud_host": "https://cloud.basicmemory.com"
}
Cloud Commands Are Auth-Only
bm cloud login, bm cloud logout, and bm cloud status manage authentication state.
bm cloud login- performs OAuth device flow
- stores/refreshes token material
- may verify cloud health/subscription
- does not change routing defaults
bm cloud logout- removes stored OAuth session tokens
- does not change routing defaults
bm cloud status- reports auth state (API key, OAuth token validity)
- runs health checks only when credentials are available
MCP Transport Routing
Stdio (default)
bm mcp --transport stdio uses natural per-project routing.
- Local-mode projects route through the in-process ASGI transport.
- Cloud-mode projects route to the cloud proxy with Bearer auth (API key).
- No explicit routing env vars are injected by the CLI command.
- Externally-set env vars are honored (e.g.
BASIC_MEMORY_FORCE_CLOUD=truefor cloud deployments). - Users who need all projects forced local can set
BASIC_MEMORY_FORCE_LOCAL=trueexternally.
HTTP and SSE Transports
bm mcp --transport streamable-http and bm mcp --transport sse always route locally.
These transports set explicit local routing (BASIC_MEMORY_FORCE_LOCAL=true and
BASIC_MEMORY_EXPLICIT_ROUTING=true) before starting the server. This prevents cloud
routing regardless of project mode, since HTTP/SSE serve as local API endpoints.
Project List UX for Dual Presence
Projects may exist in both local and cloud. bm project list should display that clearly in one row per logical
project identity, with explicit source/target signals.
Recommended display contract:
- Keep one row per normalized project name/permalink.
- Show both local and cloud presence as separate columns/indicators.
- Show an explicit
MCP (stdio)target column that always resolves tolocal. - Keep CLI route semantics explicit:
- no flags: default local for non-project commands
--cloud: force cloud--local: force local
Project LS Targeting
bm project ls should clearly identify which project instance is being listed.
Targeting rules:
- No routing flags: list local project files.
--cloud: list cloud project files.--local: list local project files (explicit override).- Output should label the active target (
LOCALorCLOUD) in heading or status line.
Runtime Mode
Runtime mode is no longer a cloud/local routing switch for local app flows.
resolve_runtime_mode(is_test_env)resolves to:TESTwhen running in test environmentLOCALotherwise
RuntimeMode.CLOUDmay remain for compatibility with existing tests/call sites but is not selected by normal local runtime resolution.
Verification Checklist
- Loading config with legacy
cloud_modesucceeds. - Saving config strips legacy
cloud_mode. --local/--cloudalways override per-project mode for that command.- No-project + no-flags commands route local by default.
bm cloud login/logoutdo not toggle routing behavior.bm mcpstdio routes per-project mode; HTTP/SSE remain local-forced.bm project listcommunicates dual local/cloud presence without ambiguity.bm project lsoutput identifies route target explicitly.