Filter memories using container tags and metadata. The filtering system uses SQL query construction, so you need to structure your filters like database queries.

Filter by Container Tags

Container tags use exact array matching - memories must have the exact same tags in the same order.
// Single tag - matches memories with exactly ["user_123"]
const userMemories = await client.memories.list({
  containerTags: ["user_123"]
});

// Multiple tags - matches memories with exactly ["user_123", "project_ai"]
const projectMemories = await client.memories.list({
  containerTags: ["user_123", "project_ai"]
});

Metadata Filtering with SQL Logic

The filters parameter allows filtering by metadata fields using SQL-like query structures. Since we use SQL query construction in the backend, you need to structure your filters like database queries with explicit AND/OR logic.

Why This Structure?

In SQL databases, AND has higher precedence than OR. Without explicit grouping, a query like:
category = 'programming' OR framework = 'react' AND difficulty = 'advanced'
Is interpreted as:
category = 'programming' OR (framework = 'react' AND difficulty = 'advanced')
The JSON structure forces explicit grouping to prevent unexpected results.
Filter Structure Rules:
  • Always wrap conditions in AND or OR arrays (even single conditions)
  • Use JSON.stringify() to convert the filter object to a string
  • Each condition needs key, value, and negate properties
  • negate: false for normal matching, negate: true for exclusion

Simple Metadata Filter

// Filter by single metadata field
const programmingMemories = await client.memories.list({
  filters: JSON.stringify({
    AND: [
      { key: "category", value: "programming", negate: false }
    ]
  })
});

Multiple Conditions (AND Logic)

// All conditions must match
const reactTutorials = await client.memories.list({
  filters: JSON.stringify({
    AND: [
      { key: "category", value: "tutorial", negate: false },
      { key: "framework", value: "react", negate: false },
      { key: "difficulty", value: "beginner", negate: false }
    ]
  })
});

Alternative Conditions (OR Logic)

// Any condition can match
const frontendMemories = await client.memories.list({
  filters: JSON.stringify({
    OR: [
      { key: "framework", value: "react", negate: false },
      { key: "framework", value: "vue", negate: false },
      { key: "framework", value: "angular", negate: false }
    ]
  })
});

Complex Nested Logic

// Complex logic: programming AND (react OR advanced difficulty)
const advancedContent = await client.memories.list({
  filters: JSON.stringify({
    AND: [
      { key: "category", value: "programming", negate: false },
      {
        OR: [
          { key: "framework", value: "react", negate: false },
          { key: "difficulty", value: "advanced", negate: false }
        ]
      }
    ]
  })
});

Array Contains Filtering

Filter memories that contain specific values in array fields like participants, tags, or team members.

Basic Array Contains

// Find memories where john.doe participated
const meetingMemories = await client.memories.list({
  filters: JSON.stringify({
    AND: [
      {
        key: "participants",
        value: "john.doe",
        filterType: "array_contains",
        negate: false
      }
    ]
  })
});

Array Contains with Exclusion

// Find memories that don't include a specific team member
const filteredMemories = await client.memories.list({
  filters: JSON.stringify({
    AND: [
      {
        key: "reviewers",
        value: "external.consultant",
        filterType: "array_contains",
        negate: true  // Exclude memories with external consultants
      },
      {
        key: "project_tags",
        value: "internal-only",
        filterType: "array_contains",
        negate: false
      }
    ]
  })
});

Multiple Array Contains (OR Logic)

// Find memories involving any of several team leads
const leadershipMemories = await client.memories.list({
  filters: JSON.stringify({
    OR: [
      {
        key: "attendees",
        value: "engineering.lead",
        filterType: "array_contains"
      },
      {
        key: "attendees",
        value: "product.lead",
        filterType: "array_contains"
      },
      {
        key: "attendees",
        value: "design.lead",
        filterType: "array_contains"
      }
    ]
  }),
  sort: "updatedAt",
  order: "desc"
});

Combined Container Tags + Metadata Filtering

const filteredMemories = await client.memories.list({
  containerTags: ["user_123"],
  filters: JSON.stringify({
    AND: [
      { key: "category", value: "tutorial", negate: false },
      { key: "framework", value: "react", negate: false }
    ]
  }),
  sort: "updatedAt",
  order: "desc",
  limit: 50
});
Common Mistakes:
  • Using bare condition objects: {"key": "category", "value": "programming"}
  • Forgetting JSON.stringify: passing objects instead of strings
  • Missing negate property: always include "negate": false or "negate": true
Container Tags vs Metadata Filtering:
  • Container tags: Exact array matching for organizational grouping
  • Metadata filters: SQL-like queries on custom metadata fields with complex logic
  • Both can be combined for powerful filtering capabilities