Memory Metadata Search

basicmachines-co/basic-memory-skills/.agents/skills/memory-metadata-search

by basicmachines-co6d2b1d426d0dacf020aef45f029768c9d8c1e5e5No license24 starsListed Oct 9, 2026Updated Oct 9, 2026Repository updated 5 months ago

Structured metadata search for Basic Memory: query notes by custom frontmatter fields using equality, range, array, and nested filters. Use when finding notes by status, priority, confidence, or any custom YAML field rather than free-text content.

Instructions onlyProductivity & Workflow
AI-generated overview

Guides structured metadata search in Basic Memory, querying notes by custom frontmatter fields with equality, range, array and nested filters.

What it does
This skill documents how to find notes in Basic Memory by their structured YAML frontmatter fields rather than by free-text content. It explains the filter syntax for equality, array-contains, $in, comparison, $between and nested dot-notation queries, and shows how to use the search_by_metadata and search_notes tools, including tag and status shortcuts. It produces query patterns and examples for retrieving notes by fields such as status, priority, confidence or any custom key.
When to use it
Use it when you need to locate notes by a known frontmatter value, such as status, priority, confidence or a custom YAML field. It also fits cases that combine a text query with structured constraints, or that filter by tags or nested schema fields.
Requirements
Requires a Basic Memory environment exposing the search_by_metadata and search_notes tools. It ships no scripts and is instructions only.

Memory Metadata Search

Find notes by their structured frontmatter fields instead of (or in addition to) free-text content. Any custom YAML key in a note's frontmatter beyond the standard set (title, type, tags, permalink, schema) is automatically indexed as entity_metadata and becomes queryable.

When to Use

  • Filtering by status or priority — find all notes with status: draft or priority: high
  • Querying custom fields — any frontmatter key you invent is searchable
  • Range queries — find notes with confidence > 0.7 or score between 0.3 and 0.8
  • Combining text + metadata — narrow a text search with structured constraints
  • Tag-based filtering — find notes tagged with specific frontmatter tags
  • Schema-aware queries — filter by nested schema fields using dot notation

Two Tools, Two Patterns

ToolUse When
search_by_metadataMetadata filters only, no text query needed
search_notesCombining a text query with metadata filters

Both accept the same filter syntax.

Filter Syntax

Filters are a JSON dictionary. Each key targets a frontmatter field; the value specifies the match condition. Multiple keys combine with AND logic.

Equality

json
{"status": "active"}

Array Contains (all listed values must be present)

json
{"tags": ["security", "oauth"]}

$in (match any value in list)

json
{"priority": {"$in": ["high", "critical"]}}

Comparisons ($gt, $gte, $lt, $lte)

json
{"confidence": {"$gt": 0.7}}

Numeric values use numeric comparison; strings use lexicographic comparison.

$between (inclusive range)

json
{"score": {"$between": [0.3, 0.8]}}

Nested Access (dot notation)

json
{"schema.version": "2"}

Quick Reference

OperatorSyntaxExample
Equality{"field": "value"}{"status": "active"}
Array contains{"field": ["a", "b"]}{"tags": ["security", "oauth"]}
$in{"field": {"$in": [...]}}{"priority": {"$in": ["high", "critical"]}}
$gt / $gte{"field": {"$gt": N}}{"confidence": {"$gt": 0.7}}
$lt / $lte{"field": {"$lt": N}}{"score": {"$lt": 0.5}}
$between{"field": {"$between": [lo, hi]}}{"score": {"$between": [0.3, 0.8]}}
Nested{"a.b": "value"}{"schema.version": "2"}

Rules:

  • Keys must match [A-Za-z0-9_-]+ (dots separate nesting levels)
  • Operator dicts must contain exactly one operator
  • $in and array-contains require non-empty lists
  • $between requires exactly [min, max]

Using search_by_metadata

Metadata-only search. Results are scoped to entity-level items.

python
# All notes with status "in-progress"search_by_metadata(filters={"status": "in-progress"})
# High-priority specs in a specific projectsearch_by_metadata(    filters={"type": "spec", "priority": {"$in": ["high", "critical"]}},    project="research",    limit=10,)
# Notes with confidence above a thresholdsearch_by_metadata(filters={"confidence": {"$gt": 0.7}})
# Paginate through resultssearch_by_metadata(filters={"type": "meeting"}, limit=10, offset=20)

Using search_notes with Metadata

Combine text search with structured filters by passing metadata_filters, tags, or status alongside the text query.

python
# Text search narrowed by metadatasearch_notes("authentication", metadata_filters={"status": "draft"})
# Filter-only (empty query string)search_notes("", metadata_filters={"type": "spec"})
# Convenience shortcuts for tags and statussearch_notes("planning", status="active")search_notes("", tags=["security", "oauth"])
# Mix text, tag shortcut, and advanced filtersearch_notes(    "oauth flow",    tags=["security"],    metadata_filters={"confidence": {"$gt": 0.7}},)

Merging rules: tags and status are convenience shortcuts merged into metadata_filters via setdefault. If the same key exists in metadata_filters, the explicit filter wins.

Tag Search Shorthand

The tag: prefix in a query converts to a tag filter automatically:

python
# These are equivalent:search_notes("tag:tier1")search_notes("", tags=["tier1"])
# Multiple tags (comma or space separated) — all must match:search_notes("tag:tier1,alpha")

Example: Custom Frontmatter in Practice

A note with custom fields:

markdown
---title: Auth Designtype: spectags: [security, oauth]status: in-progresspriority: highconfidence: 0.85---
# Auth Design
## Observations- [decision] Use OAuth 2.1 with PKCE for all client types #security- [requirement] Token refresh must be transparent to the user
## Relations- implements [[Security Requirements]]

Queries that find it:

python
# By status and typesearch_by_metadata(filters={"status": "in-progress", "type": "spec"})
# By numeric thresholdsearch_by_metadata(filters={"confidence": {"$gt": 0.7}})
# By priority setsearch_by_metadata(filters={"priority": {"$in": ["high", "critical"]}})
# By tag shorthandsearch_notes("tag:security")
# Combined text + metadatasearch_notes("OAuth", metadata_filters={"status": "in-progress"})

Guidelines

  • Use metadata search for structured queries. If you're looking for notes by a known field value (status, priority, type), metadata filters are more precise than text search.
  • Use text search for content queries. If you're looking for notes about something, text search is better. Combine both when you need precision.
  • Custom fields are free. Any YAML key you put in frontmatter becomes queryable — no schema or configuration required.
  • Multiple filters are AND. {"status": "active", "priority": "high"} requires both conditions.
  • Prefer search_by_metadata for filter-only queries. It's purpose-built and returns entity-level results. Use search_notes with empty query only when you also need text search features.
  • Dot notation for nesting. Access nested YAML structures with dots: {"schema.version": "2"} queries the version key inside a schema object.
  • Tags shortcut is convenient but limited. tags and status are sugar for common fields. For anything else, use metadata_filters directly.

Source and attribution

Source:basicmachines-co/basic-memory-skillsin.agents/skills/memory-metadata-searchat commit6d2b1d4

License: No license

Content belongs to its original authors. SourceWeft indexes it from a public repository.

Report or request removal