> ## Documentation Index
> Fetch the complete documentation index at: https://docs.openmem.blog/llms.txt
> Use this file to discover all available pages before exploring further.

# Scopes: organizing and controlling memory access

> Scopes are slash-delimited namespaces that group memories hierarchically and power OMP's fine-grained access control and filtering grammar.

Every memory in OMP can carry a `scope` — a hierarchical path that tells the system where that memory belongs and who is allowed to touch it. Scopes serve two purposes simultaneously: they organize memories into logical namespaces, and they form the basis of OMP's access-control grammar so you can grant or restrict access at exactly the right level of granularity.

## What is a scope?

A scope is a slash-delimited string that places a memory in a hierarchy. Think of it like a file path: the segments to the left are broader categories, and segments to the right are more specific. For example:

| Scope                | Meaning                              |
| -------------------- | ------------------------------------ |
| `coding/preferences` | Tooling and style choices for coding |
| `coding/languages`   | Programming language preferences     |
| `health/symptoms`    | Health-related notes                 |
| `ui/preferences`     | Interface and display preferences    |
| `work/meetings`      | Notes from work meetings             |

Scopes are optional — if you omit `scope` on a memory, it has no namespace and can only be retrieved by direct ID or unscoped queries.

## Wildcard matching

You can use a trailing `*` wildcard to match an entire subtree. The pattern `coding/*` matches `coding/preferences`, `coding/languages`, `coding/tools`, and any other path that begins with `coding/`.

This is the same wildcard syntax used in both data queries and access-control grants.

## Adding memories with a scope

Pass `scope` as a keyword argument to `mem.add()`:

```python theme={null}
mem.add(
    content="User prefers pnpm over npm",
    user_id="u1",
    scope="coding/preferences",
    tags=["tooling", "nodejs"],
)

mem.add(
    content="User experiences migraines triggered by bright light",
    user_id="u1",
    scope="health/symptoms",
)
```

## Filtering by scope in search and list

Both `mem.search()` and `mem.list()` accept a `scope` parameter. When you provide a scope, results are restricted to memories whose scope matches exactly or falls within the wildcard pattern.

```python theme={null}
# Exact match — only memories with scope="coding/preferences"
results = mem.search("package manager", user_id="u1", scope="coding/preferences")

# Wildcard — memories under any coding/ sub-scope
results = mem.search("editor setup", user_id="u1", scope="coding/*")

# List with exact scope filter
page = mem.list("u1", scope="coding/preferences")

# List with wildcard
page = mem.list("u1", scope="coding/*")
```

## Access control with scopes

OMP's authorization model uses a `<verb>:<scope-path>` grammar to express what an application is permitted to do. An app's grant lists the specific verbs and scopes it may access.

```
read:coding/*          # read anything under coding/
write:coding/preferences  # write only to coding/preferences
delete:health/*        # delete anything under health/
read:*                 # read all scopes (full read)
```

A user sees a consent prompt like this before an app is granted access:

```
Cursor is requesting access to your memory:
  ✓ read:coding/*
  ✓ write:coding/*
  ✗ read:health
  ✗ read:finance
Duration: 90 days
[ Allow ]   [ Deny ]   [ Customize ]
```

When an app attempts to access a scope it was not granted, the SDK raises `ScopeDeniedError` with a clear message identifying the missing grant.

## Best practices

<Tip>
  Design your scope hierarchy with broad categories at the top level (`coding`, `health`, `work`) and progressively specific categories as you descend (`coding/preferences`, `coding/languages/python`). This lets you grant coarse access (`read:coding/*`) or fine-grained access (`read:coding/preferences`) without redesigning the hierarchy later.
</Tip>

A few guidelines:

* **One concept per leaf.** Keep the final segment focused on a single topic rather than mixing unrelated data under the same path.
* **Match access boundaries.** Draw scope boundaries where you expect to draw access boundaries — if `health` data should always require separate consent from `work` data, keep them as distinct top-level scopes.
* **Avoid deep nesting.** More than three segments (`a/b/c`) rarely adds value and makes wildcard grants harder to reason about.

<Note>
  Not all providers support scopes natively. Some simulate scope filtering by mapping scope values to tags internally. Call `mem.capabilities()` and check `caps.features.scopes` — the value will be `"native"`, `"tags"`, or `"none"` — to understand what your current provider supports before designing a scope-heavy architecture.
</Note>
