How `ai-memory install-hooks --session-aware` Enables Per-Session Auto-Scope Isolation
ai-memory install-hooks --session-aware installs a stdio-to-HTTP bridge that forwards Claude Code's session ID via a custom header, allowing the MCP server to isolate each concurrent session into its own auto-scope workspace.
The ai-memory CLI provides hook installation for AI agents like Claude Code, but concurrent sessions can collide when sharing the same workspace and project mappings. The --session-aware flag solves this by injecting session metadata into every MCP request, enabling true per-session isolation. According to the akitaonrails/ai-memory source code, this mechanism relies on a hidden bridge subcommand and custom HTTP headers to route each Claude Code window to a distinct auto-scope.
What --session-aware Adds to Normal Hook Installation
Without the flag, ai-memory install-hooks simply writes lifecycle hooks into the agent's settings file (e.g., ~/.claude/settings.json). Adding --session-aware triggers two additional behaviors:
- Registers the
mcp-bridgesubcommand as part of the install flow - Configures the bridge to capture and forward session identifiers
The bridge acts as a transparent proxy between Claude Code's stdio and the remote ai-memory HTTP MCP server. This design allows the server to distinguish requests originating from different Claude Code windows—even when they target the same repository.
The Session-Aware Bridge Implementation
The core logic resides in crates/ai-memory-cli/src/commands/mcp_bridge.rs【/crates/ai-memory-cli/src/commands/mcp_bridge.rs】. This file implements the hidden mcp-bridge command that install-hooks --session-aware configures Claude Code to invoke.
Capturing the Claude Session ID
Claude Code sets the environment variable CLAUDE_CODE_SESSION_ID when launching a hook subprocess. The bridge reads this variable and attaches it to every outgoing HTTP request:
// Constant defined at crates/ai-memory-cli/src/commands/mcp_bridge.rs#L19-L20
const ACTOR_SESSION_HEADER: &str = "X-Memory-Actor-Session-Id";
The upstream_config helper function (lines 64-80) constructs the transport configuration by inserting this header along with optional authentication:
// From crates/ai-memory-cli/src/commands/mcp_bridge.rs#L64-L80
fn upstream_config(server_url: &str, token: Option<&str>) -> TransportConfig {
let mut headers = HeaderMap::new();
if let Some(session_id) = std::env::var("CLAUDE_CODE_SESSION_ID").ok() {
headers.insert(
ACTOR_SESSION_HEADER,
HeaderValue::from_str(&session_id).unwrap(),
);
}
// ... bearer token handling ...
TransportConfig::Http { url: server_url.parse().unwrap(), headers }
}
This ensures every tool call, observation, and handoff carries the originating session's identity.
How the MCP Server Uses Session Headers
When the ai-memory server receives a request with X-Memory-Actor-Session-Id, it tags all associated operations with that session identifier. The routing module in ai-memory-core/src/routing_snippet.rs【/crates/ai-memory-core/src/routing_snippet.rs】 then combines this tag with workspace/project resolution to compute the final auto-scope.
The routing snippet explicitly references this mode:
// Comment at crates/ai-memory-core/src/routing_snippet.rs#L46-L47
// When using session-aware bridge:
// [auto_scope] mode = "per_session"
Setting mode = "per_session" instructs the router to include the session ID as a scope boundary. This prevents concurrent Claude Code sessions from seeing each other's memory entries, even when working in the same directory.
Practical Usage Examples
Installing Session-Aware Hooks for Claude Code
ai-memory install-hooks --agent claude-code --apply --session-aware
This command:
- Writes the hook configuration to
~/.claude/settings.json - Includes the bridge invocation in Claude Code's MCP server settings
- Prints a confirmation that session-aware mode is active
Manual Bridge Startup (Debugging/Development)
If you need to run the bridge independently—for debugging or custom server URLs:
ai-memory mcp-bridge --server-url http://127.0.0.1:49374/mcp
The bridge will:
- Read
CLAUDE_CODE_SESSION_IDfrom its environment - Connect to the specified ai-memory server
- Proxy all stdio MCP traffic with the session header injected
Verifying Session Header Extraction
From the bridge test code, here's how the server side extracts the session identifier:
let session = context
.extensions
.get::<axum::http::request::Parts>()
.and_then(|parts| parts.headers.get(&ACTOR_SESSION_HEADER))
.and_then(|value| value.to_str().ok())
.map(str::to_string);
This pattern appears in crates/ai-memory-cli/src/commands/mcp_bridge.rs【/crates/ai-memory-cli/src/commands/mcp_bridge.rs#L73-L78】, demonstrating the end-to-end header propagation.
Key Source Files for the Session-Aware Flow
| File | Role in Session Isolation |
|---|---|
crates/ai-memory-cli/src/cli.rs |
Defines the --session-aware flag and mcp-bridge subcommand registration |
crates/ai-memory-cli/src/commands/install_hooks.rs |
Propagates the flag to bridge configuration during hook installation |
crates/ai-memory-cli/src/commands/mcp_bridge.rs |
Implements stdio-to-HTTP bridging with session header injection |
crates/ai-memory-core/src/routing_snippet.rs |
Documents per_session auto-scope mode for session-tagged requests |
Summary
--session-awareactivates themcp-bridgehidden subcommand during hook installation- The bridge captures
CLAUDE_CODE_SESSION_IDand forwards it asX-Memory-Actor-Session-Id - The MCP server tags all operations with the session header for routing decisions
[auto_scope] mode = "per_session"isolates each Claude Code window's memory independently- Concurrent sessions no longer collide when sharing the same workspace or project
Frequently Asked Questions
What happens if I run --session-aware but Claude Code isn't running?
The bridge will start but fail to detect CLAUDE_CODE_SESSION_ID in its environment. It will operate in non-session-aware mode, forwarding requests without the custom header. The MCP server will fall back to standard workspace/project resolution, and you won't get per-session isolation.
Can I use --session-aware with agents other than Claude Code?
Currently, the bridge specifically looks for CLAUDE_CODE_SESSION_ID. Other agents would need to set this variable (or a configurable equivalent) for the session header injection to function. The architecture in mcp_bridge.rs supports extending this to other session identifier sources.
Does --session-aware affect where memory files are stored on disk?
No. The session header affects logical scope resolution within the ai-memory server's routing layer, not physical file paths. The [auto_scope] mode = "per_session" setting ensures the server computes distinct scope identifiers for each session, but the underlying storage mechanism remains unchanged.
Can multiple --session-aware sessions share some memory while isolating others?
Not directly. The per_session mode creates complete isolation at the auto-scope level. To share memory across sessions, you would need to use explicit workspace or project identifiers that bypass the auto-scope mechanism, or switch to a different routing mode for those specific operations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →