Skip to main content

LLM Integrations

Add persistent memory to any LLM - no-code with MCP or custom code integrations.

Overview

There are two ways to add Trix memory to your LLM workflows:

  • No-code with MCP - Use Claude Desktop, Cursor, Windsurf, or other MCP clients
  • Code integration - Build custom applications with any LLM provider

No-Code Setup with MCP

The easiest way to add memory to your LLM is through the Model Context Protocol (MCP). No coding required - just configure and start chatting.

Supported Clients

ClientLLMUse Case
Claude DesktopClaude (Anthropic)General assistant with memory
CursorClaude / GPTAI coding with project memory
WindsurfClaude / GPTAI coding assistant
ContinueAnyOpen-source AI coding
ZedClaude / GPTFast editor with AI

Quick Setup (Claude Desktop)

1. Open your Claude Desktop config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

2. Add the Trix MCP server:

claude_desktop_config.json
{
  "mcpServers": {
    "trix": {
      "command": "npx",
      "args": ["-y", "@trix/mcp"],
      "env": {
        "TRIX_API_KEY": "your_api_key_here"
      }
    }
  }
}

3. Restart Claude Desktop. That's it!

Now you can say things like "Remember that I prefer Python over JavaScript" or "What do you know about my coding preferences?" and Claude will use Trix to store and recall information.

What You Can Say

  • "Remember that..." - Stores information for later
  • "What do you remember about...?" - Recalls relevant memories
  • "Forget what I told you about..." - Removes specific memories
  • "List everything you know about me" - Shows all stored memories

For detailed MCP configuration including Cursor, Windsurf, and advanced options, see the full MCP Server documentation.

Code Integrations

For custom applications, you can integrate Trix directly with any LLM provider. The pattern is the same across all providers:

  1. Recall relevant memories before calling the LLM
  2. Include memories in the system prompt or context
  3. Store important information from the conversation

OpenAI (ChatGPT)

Integrate Trix with OpenAI's GPT models:

import OpenAI from 'openai';
import { Trix } from '@trixdb/client';

const openai = new OpenAI();
const trix = new Trix();

async function chatWithMemory(userMessage: string, userId: string): Promise<string> {
  const results = await trix.memories.list({ q: userMessage, spaceId: userId, limit: 5 });
  const memoryContext = results.data.length > 0
    ? results.data.map(m => `- ${m.content}`).join('\n')
    : 'No relevant memories.';

  const response = await openai.chat.completions.create({
    model: 'gpt-4o',
    messages: [
      { role: 'system', content: `You are a helpful assistant with memory.

Here's what you remember about this user:
${memoryContext}

Use this context to personalize your responses.` },
      { role: 'user', content: userMessage }
    ]
  });

  const assistantMessage = response.choices[0].message.content!;
  await trix.memories.create({
    content: `User asked: ${userMessage}\nAssistant answered: ${assistantMessage.slice(0, 200)}`,
    spaceId: userId,
    metadata: { source: 'conversation' }
  });
  return assistantMessage;
}

Anthropic (Claude)

Integrate Trix with Claude models:

import Anthropic from '@anthropic-ai/sdk';
import { Trix } from '@trixdb/client';

const anthropic = new Anthropic();
const trix = new Trix();

async function chatWithMemory(userMessage: string, userId: string): Promise<string> {
  const results = await trix.memories.list({ q: userMessage, spaceId: userId, limit: 5 });
  const memoryContext = results.data.length > 0
    ? results.data.map(m => `- ${m.content}`).join('\n')
    : 'No relevant memories.';

  const response = await anthropic.messages.create({
    model: 'claude-sonnet-4-20250514',
    max_tokens: 1024,
    system: `You are a helpful assistant with memory.

Here's what you remember about this user:
${memoryContext}

Use this context to personalize your responses.`,
    messages: [{ role: 'user', content: userMessage }]
  });

  const assistantMessage = response.content[0].type === 'text' ? response.content[0].text : '';
  await trix.memories.create({
    content: `User: ${userMessage}\nAssistant: ${assistantMessage.slice(0, 200)}`,
    spaceId: userId,
    metadata: { model: 'claude-sonnet-4-20250514' }
  });
  return assistantMessage;
}

Google (Gemini)

Integrate Trix with Google's Gemini models:

import { GoogleGenerativeAI } from '@google/generative-ai';
import { Trix } from '@trixdb/client';

const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY!);
const model = genAI.getGenerativeModel({ model: 'gemini-1.5-pro' });
const trix = new Trix();

async function chatWithMemory(userMessage: string, userId: string): Promise<string> {
  const results = await trix.memories.list({ q: userMessage, spaceId: userId, limit: 5 });
  const memoryContext = results.data.length > 0
    ? results.data.map(m => `- ${m.content}`).join('\n')
    : 'No relevant memories.';

  const prompt = `You are a helpful assistant with memory.

Here's what you remember about this user:
${memoryContext}

User message: ${userMessage}

Respond helpfully using your memories when relevant.`;

  const result = await model.generateContent(prompt);
  return result.response.text();
}

Mistral

Integrate Trix with Mistral models:

import { Mistral } from '@mistralai/mistralai';
import { Trix } from '@trixdb/client';

const mistral = new Mistral({ apiKey: process.env.MISTRAL_API_KEY });
const trix = new Trix();

async function chatWithMemory(userMessage: string, userId: string): Promise<string> {
  const results = await trix.memories.list({ q: userMessage, spaceId: userId, limit: 5 });
  const memoryContext = results.data.length > 0
    ? results.data.map(m => `- ${m.content}`).join('\n')
    : 'No relevant memories.';

  const response = await mistral.chat.complete({
    model: 'mistral-large-latest',
    messages: [
      { role: 'system', content: `You are a helpful assistant with memory.

Here's what you remember about this user:
${memoryContext}

Use this context to personalize your responses.` },
      { role: 'user', content: userMessage }
    ]
  });
  return response.choices![0].message.content as string;
}

xAI (Grok)

xAI's API is OpenAI-compatible — point the OpenAI SDK at https://api.x.ai/v1:

import OpenAI from 'openai';
import { Trix } from '@trixdb/client';

const grok = new OpenAI({ apiKey: process.env.XAI_API_KEY, baseURL: 'https://api.x.ai/v1' });
const trix = new Trix();

async function chatWithMemory(userMessage: string, userId: string): Promise<string> {
  const results = await trix.memories.list({ q: userMessage, spaceId: userId, limit: 5 });
  const memoryContext = results.data.length > 0
    ? results.data.map(m => `- ${m.content}`).join('\n')
    : 'No relevant memories.';

  const response = await grok.chat.completions.create({
    model: 'grok-2-latest',
    messages: [
      { role: 'system', content: `You are a helpful assistant with memory.

Here's what you remember about this user:
${memoryContext}

Use this context to personalize your responses.` },
      { role: 'user', content: userMessage }
    ]
  });
  return response.choices[0].message.content as string;
}

Common Patterns

Selective Memory Storage

Not every message needs to be stored. Use the LLM to decide what's worth remembering:

async function extractMemories(conversation: string, userId: string): Promise<void> {
  const response = await openai.chat.completions.create({
    model: 'gpt-4o-mini',
    messages: [
      { role: 'system', content: `Extract key facts worth remembering from this conversation.
Return a JSON array of strings, each being a fact to remember.
Only include lasting preferences, important facts, or useful context.
Return [] if nothing is worth remembering.` },
      { role: 'user', content: conversation }
    ],
    response_format: { type: 'json_object' }
  });
  const content = response.choices[0].message.content || '{}';
  const facts: string[] = JSON.parse(content).facts || [];
  for (const fact of facts) {
    await trix.memories.create({ content: fact, spaceId: userId, metadata: { extracted: true } });
  }
}

Smart Context Window

Balance memory relevance with token limits:

async function getMemoryContext(
  query: string, userId: string, maxTokens: number = 500
): Promise<string> {
  const results = await trix.memories.list({ q: query, spaceId: userId, limit: 20 });
  const contextParts: string[] = [];
  let currentTokens = 0;
  for (const memory of results.data) {
    const memoryTokens = Math.floor(memory.content.length / 4);
    if (currentTokens + memoryTokens > maxTokens) break;
    contextParts.push(`- ${memory.content}`);
    currentTokens += memoryTokens;
  }
  return contextParts.length > 0 ? contextParts.join('\n') : 'No relevant memories.';
}

Organizing with Spaces

Use spaces to organize memories by category or purpose:

await trix.memories.create({
  content: 'User prefers dark mode',
  spaceId: 'preferences'
});

await trix.memories.create({
  content: 'User is working on a React project',
  spaceId: 'projects'
});

const preferences = await trix.memories.list({ q: query, spaceId: 'preferences' });

Best Practices

  • Use sessions for user isolation - Always include a user identifier to keep memories separate between users
  • Be selective about what to store - Not every message needs to be remembered. Focus on preferences, facts, and useful context
  • Keep memories concise - Store summarized facts rather than full conversation logs
  • Use metadata for filtering - Tag memories with source, type, or confidence to enable smarter recall
  • Respect token limits - Don't stuff too many memories into context. 5-10 relevant memories is usually enough

The key to effective LLM memory is quality over quantity. A few highly relevant memories are more valuable than many tangentially related ones.