# Global Scope vs Project Scope in AI-Memory `memory_query`: A Complete Comparison

> Understand global scope vs project scope in AI-Memory memory_query. Learn how project scope searches your workspace and global scope searches all projects for efficient FTS5 queries.

- Repository: [Fabio Akita/ai-memory](https://github.com/akitaonrails/ai-memory)
- Tags: deep-dive
- Published: 2026-08-20

---

**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`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-mcp/src/server.rs), this mode automatically unions results from two sources:

1. **Your current project** — pages matching the three-tuple `workspace_id`, `project_id`, `path`
2. **The reserved `_global` preferences 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.

```rust
// 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`](https://github.com/akitaonrails/ai-memory/blob/main/docs/ARCHITECTURE.md), this union happens at lines 13-14 of the architecture specification and is implemented at lines 2002-2004 of [`server.rs`](https://github.com/akitaonrails/ai-memory/blob/main/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 `scopes` array listing specific projects, you must manually add `"_global"` to include preferences
- **Pure global search**: When `global=true` is set, the entire project-resolution step is bypassed

```rust
// 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`](https://github.com/akitaonrails/ai-memory/blob/main/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 `workspace` and `project` annotations
- **Does NOT merge `_global` preferences** — the result set contains only indexed page content

```rust
// 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`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/scope.rs)** — Implements `lookup_global_scope` and `create_global_scope`, the storage layer for the reserved `_global` preferences scope
- **[`crates/ai-memory-mcp/src/server.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-mcp/src/server.rs)** — Handles `global_scope_hits` merging for default queries and routes `global=true` to the pure FTS5 path
- **[`docs/marker-file.md`](https://github.com/akitaonrails/ai-memory/blob/main/docs/marker-file.md)** — Documents edge cases where unscoped queries default to `global=true` when no project marker exists

## Summary

- **Project scope** is the default: it searches your current workspace/project and automatically unions the `_global` preferences scope as `global_scope_hits`
- **Explicit scopes** override the default and exclude `_global` unless 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/search` endpoint 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`](https://github.com/akitaonrails/ai-memory/blob/main/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`](https://github.com/akitaonrails/ai-memory/blob/main/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.