Global Scope vs Project Scope in AI-Memory `memory_query`: A Complete Comparison
Project scope searches your current workspace and project plus global preferences, while global scope (global=true) runs a pure FTS5 search across every project in every workspace without merging preferences.
memory_query in the akitaonrails/ai-memory repository provides three distinct scope modes for searching the AI-Memory wiki. Understanding the difference between global scope and project scope determines what data you retrieve and how results are ranked. This guide breaks down each behavior with source-level references.
What Is the Project Scope in memory_query
Project scope is the default search mode when you call memory_query without explicit workspace or project arguments. According to the implementation in crates/ai-memory-mcp/src/server.rs, this mode automatically unions results from two sources:
- Your current project — pages matching the three-tuple
workspace_id,project_id,path - The reserved
_globalpreferences scope — standing user- and team-wide settings (UI preferences, default tags, etc.)
The server merges these as global_scope_hits into your result set. This ensures project-specific knowledge always appears alongside relevant global preferences.
// Default project-scoped query (includes global preferences automatically)
let result = client.memory_query(
MemoryQueryRequest {
query: "how to reset a session".into(),
// No workspace/project args → current project scope + _global union
..Default::default()
}
).await?;
As documented in docs/ARCHITECTURE.md, this union happens at lines 13-14 of the architecture specification and is implemented at lines 2002-2004 of server.rs.
When the _global Preferences Scope Is Excluded
The _global preferences scope is automatically excluded in two scenarios:
- Explicit sibling scopes: When you pass a
scopesarray listing specific projects, you must manually add"_global"to include preferences - Pure global search: When
global=trueis set, the entire project-resolution step is bypassed
// Explicit sibling-project search (excludes _global preferences unless added)
let result = client.memory_query(
MemoryQueryRequest {
query: "authentication token".into(),
scopes: Some(vec!["projectA".into(), "projectB".into()]),
// _global NOT automatically included here
..Default::default()
}
).await?;
To include preferences in an explicit scope search, add "_global" to your scopes array: scopes: Some(vec!["_global".into(), "projectA".into()]).
What Global Scope (global=true) Actually Does
Setting global: Some(true) triggers a fundamentally different code path in memory_query. Per docs/usage.md (lines 90-92), this mode:
- Skips project resolution entirely — no workspace/project filtering occurs
- Executes a pure FTS5 search over the complete compiled wiki index
- Returns hits from all workspaces and projects with
workspaceandprojectannotations - Does NOT merge
_globalpreferences — the result set contains only indexed page content
// Global search across all projects (pure FTS5 stream, no _global merge)
let result = client.memory_query(
MemoryQueryRequest {
query: "memory_query".into(),
global: Some(true),
..Default::default()
}
).await?;
This mode is designed for cross-project discovery when you need to find knowledge regardless of where it lives.
Key Behavioral Differences at a Glance
| Aspect | Project Scope (Default) | Global Scope (global=true) |
|---|---|---|
| Search target | Current project + _global preferences |
All projects across all workspaces |
| FTS5 stream used | Project-level stream with union | Global-only stream |
| Preferences included | Yes, automatically as global_scope_hits |
No, _global not merged |
| Result annotations | Project-implied | Explicit workspace + project labels |
| Use case | Day-to-day project work | Cross-project knowledge discovery |
How Scope Resolution Works in the Source Code
The scope logic is distributed across three key files in akitaonrails/ai-memory:
crates/ai-memory-store/src/scope.rs— Implementslookup_global_scopeandcreate_global_scope, the storage layer for the reserved_globalpreferences scopecrates/ai-memory-mcp/src/server.rs— Handlesglobal_scope_hitsmerging for default queries and routesglobal=trueto the pure FTS5 pathdocs/marker-file.md— Documents edge cases where unscoped queries default toglobal=truewhen no project marker exists
Summary
- Project scope is the default: it searches your current workspace/project and automatically unions the
_globalpreferences scope asglobal_scope_hits - Explicit scopes override the default and exclude
_globalunless you manually include it - Global scope (
global=true) bypasses all project logic for a cross-workspace FTS5 search without preference merging - All three modes use the same
/api/v1/searchendpoint but differ in preprocessing and result composition
Frequently Asked Questions
Does project scope include global preferences automatically?
Yes. When you call memory_query without explicit scopes or global=true, the server automatically unions the _global preferences scope into your results as global_scope_hits. This happens in crates/ai-memory-mcp/src/server.rs around line 2002.
When should I use global=true instead of default project scope?
Use global=true when you need to search across all projects and workspaces for knowledge without regard to organizational boundaries. This is common for discovering reusable patterns, finding who wrote about a topic, or locating documentation when unsure which project contains it.
Can I combine global=true with a scopes array?
No. When global=true is set, the scopes parameter is ignored. The global flag triggers a pure FTS5 search that bypasses the entire project-resolution pipeline, making scope specifications irrelevant.
What happens if I query without a project marker file?
According to docs/marker-file.md, an unscoped memory_query launched from a session without a project marker is treated as global=true. This fallback ensures the query succeeds even when the runtime cannot determine your current project context.
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 →