Node.js / TypeScript SDK

    The official Memorystack SDK for Node.js and TypeScript. Build memory-enabled applications with full type safety and modern async/await patterns.

    ✓ Full TypeScript Support✓ Node.js 16+✓ Promise-based API✓ Zero Dependencies

    Installation

    Install the SDK using your preferred package manager. TypeScript definitions are included automatically.

    npm install @memorystack/sdk

    Memory Operations

    Create, update, delete, and retrieve memories with full CRUD support

    Hybrid Search

    Vector + text search for best accuracy and relevance

    Agent Support

    Auto-detection and scoping for multi-agent systems

    Batch Operations

    Bulk operations with 50% cost savings via batch API

    Auto-Maintenance

    Automated consolidation, reflection, and optimization

    Memory Lineage

    Complete provenance tracking and history

    Contradiction Detection

    Automatic conflict resolution and belief updating

    Export/Import

    Backup and migration support (JSON/CSV)

    Quick Start

    Get started in 30 seconds. The SDK has just 2 main methods: add() and search().

    import { MemoryStackClient } from '@memorystack/sdk';
    
    const client = new MemoryStackClient({
      apiKey: process.env.MEMORYSTACK_API_KEY
    });
    
    // Store a memory
    await client.add('User prefers dark mode');
    
    // Store a conversation
    await client.add([
      { role: 'user', content: 'I love TypeScript' },
      { role: 'assistant', content: 'Great choice!' }
    ]);
    
    // Search memories
    const results = await client.search('user preferences');
    console.log(results.results);

    Code Examples

    Basic Usage

    Store and search memories in 30 seconds

    import { MemoryStackClient } from '@memorystack/sdk';
    
    const client = new MemoryStackClient({
      apiKey: process.env.MEMORYSTACK_API_KEY!
    });
    
    // Store a memory
    await client.add('User prefers dark mode');
    
    // Store a conversation
    await client.add([
      { role: 'user', content: 'I love TypeScript' },
      { role: 'assistant', content: 'Great choice!' }
    ]);
    
    // Search memories
    const results = await client.search('user preferences');
    results.results.forEach(m => {
      console.log(`- ${m.content}`);
    });

    Configuration

    Constructor Options

    ParameterTypeRequiredDescription
    apiKeystringRequiredYour Memorystack API key
    baseUrlstringOptionalCustom API base URL (for self-hosted)

    Example with Custom Base URL

    const client = new MemoryStackClient({
      apiKey: process.env.MEMORYSTACK_API_KEY,
      baseUrl: 'https://your-domain.com/api/v1'
    });

    API Reference

    Core Methods

    add()

    Store memories. Accepts a simple string or an array of conversation messages.

    Signature

    add(content: string | Message[], options?: AddOptions): Promise<AddResponse>

    Parameters

    FieldTypeRequiredDescription
    contentstring | Message[]YesText or conversation messages
    options.userIdstringNoEnd-user ID for B2B apps
    options.metadataobjectNoCustom metadata to attach

    Examples

    // Simple text
    await client.add('User prefers dark mode');
    
    // With user ID (for B2B apps)
    await client.add('User likes TypeScript', { userId: 'user_123' });
    
    // Conversation format
    await client.add([
      { role: 'user', content: 'What is my favorite color?' },
      { role: 'assistant', content: 'Based on our conversations, you prefer blue!' }
    ]);
    
    // With metadata
    await client.add('Important deadline is Friday', {
      userId: 'user_123',
      metadata: { category: 'work', priority: 'high' }
    });

    search()

    Find relevant memories using semantic search. Results are ranked by relevance.

    Signature

    search(query: string, options?: SearchOptions): Promise<SearchResponse>

    Parameters

    FieldTypeRequiredDescription
    querystringYesNatural language search query
    options.userIdstringNoFilter by user ID
    options.limitnumberNoMax results (default: 10)

    Examples

    // Simple search
    const results = await client.search('user preferences');
    
    // With user ID filter
    const userResults = await client.search('favorite color', { userId: 'user_123' });
    
    // Limit results
    const topResults = await client.search('meetings', { limit: 5 });
    
    // Process results
    results.results.forEach(m => {
      console.log(`- ${m.content}`);
    });

    getStats()

    Get usage statistics for your account including API calls, memory count, and plan limits.

    Example

    const stats = await client.getStats();
    
    console.log(`Plan: ${stats.plan_tier}`);
    console.log(`API Calls: ${stats.usage.api_calls_used}`);
    console.log(`Total Memories: ${stats.totals.memories}`);

    Additional Methods

    While add() and search() cover most needs, these methods are also available:

    listMemories()

    List all memories with pagination.

    const memories = await client
      .listMemories({ limit: 50 });

    updateMemory()

    Update an existing memory.

    await client.updateMemory(
      'memory-id',
      { content: 'Updated content' }
    );

    deleteMemory()

    Delete a memory by ID.

    await client.deleteMemory(
      'memory-id'
    );

    getStats()

    Get usage statistics.

    const stats = await client
      .getStats();

    Error Handling

    try {
      await client.addMessage("Hello world");
    } catch (error: any) {
      console.error('Error:', error.message);
      console.error('Status:', error.status);
      console.error('Details:', error.details);
    }

    Common Error Codes

    • 401 - Invalid or missing API key
    • 429 - Rate limit exceeded
    • 400 - Invalid request payload
    • 500 - Internal server error

    Best Practices

    Use Environment Variables

    Store API keys in environment variables, never in code.

    Handle Errors Gracefully

    Always wrap SDK calls in try-catch blocks.

    Use Pagination

    For large datasets, use cursor-based pagination.

    Add Metadata

    Include context with metadata for better organization.

    Multi-Agent Systems

    Build collaborative agent systems with memory scoping, agent handoffs, and team coordination.

    Memory Scoping

    Control memory access with personal, team, and project-level scopes:

    import { MemoryStackClient } from '@memorystack/sdk';
    
    // Create agents with different scopes
    const writer = new MemoryStackClient({
      apiKey: process.env.MEMORYSTACK_API_KEY!,
      agentName: 'Content Writer',
      projectName: 'content_team',
      teamName: 'editorial'
    });
    
    const researcher = new MemoryOSClient({
      apiKey: process.env.MEMORY_OS_API_KEY!,
      agentName: 'Researcher',
      projectName: 'content_team',
      teamName: 'editorial'
    });
    
    // Personal memory (private to agent)
    await writer.createMemory({
      content: 'My writing style: conversational and data-driven',
      memoryType: 'preference',
      scope: 'personal'  // Only this agent can access
    });
    
    // Team memory (shared with team)
    await researcher.createMemory({
      content: 'Team research: AI market to reach $1.8T by 2030',
      memoryType: 'fact',
      scope: 'team'  // All editorial team members can access
    });
    
    // Project memory (shared across project)
    await writer.createMemory({
      content: 'Company brand voice: professional yet approachable',
      memoryType: 'guideline',
      scope: 'project'  // All agents in project can access
    });
    
    // Search by scope
    const personalMemories = await writer.searchMemories({ 
      query: '', 
      scope: 'personal' 
    });
    const teamMemories = await writer.searchMemories({ 
      query: '', 
      scope: 'team' 
    });
    const projectMemories = await writer.searchMemories({ 
      query: '', 
      scope: 'project' 
    });

    🔒 Personal Scope

    Private memories accessible only by the creating agent

    👥 Team Scope

    Shared memories within the same team

    🏢 Project Scope

    Accessible to all agents in the project

    Agent Handoffs

    Transfer conversations between agents with full context preservation:

    // Support agent handles initial inquiry
    const supportAgent = new MemoryStackClient({
      apiKey: process.env.MEMORYSTACK_API_KEY!,
      agentName: 'Support Agent',
      sessionId: 'customer_123'
    });
    
    // Store conversation context
    await supportAgent.createMemory({
      content: 'Customer issue: billing discrepancy for invoice #4521',
      memoryType: 'issue',
      metadata: { priority: 'high', category: 'billing' }
    });
    
    // Prepare handoff context
    const handoffContext = {
      fromAgent: 'Support Agent',
      toAgent: 'Billing Specialist',
      reason: 'Requires billing system access',
      customerId: 'customer_123',
      issueSummary: 'Billing discrepancy for invoice #4521'
    };
    
    // Billing specialist takes over with full context
    const billingAgent = new MemoryStackClient({
      apiKey: process.env.MEMORYSTACK_API_KEY!,
      agentName: 'Billing Specialist',
      sessionId: 'customer_123'  // Same session for continuity
    });
    
    // Access previous conversation context
    const previousContext = await billingAgent.searchMemories({
      query: 'billing discrepancy',
      limit: 10
    });
    
    // Continue conversation with context
    await billingAgent.createMemory({
      content: 'Resolved: Invoice #4521 corrected, refund processed',
      memoryType: 'resolution',
      metadata: { handoffFrom: 'Support Agent' }
    });

    💡 Handoff Best Practices

    • • Use the same sessionId for context continuity
    • • Store handoff metadata for tracking and analytics
    • • Include issue summary and priority in handoff context
    • • Search previous memories before responding

    Team Collaboration

    Build collaborative workflows with shared team knowledge:

    // Research agent gathers information
    const researcher = new MemoryStackClient({
      apiKey: process.env.MEMORYSTACK_API_KEY!,
      agentName: 'Researcher',
      projectName: 'content_creation',
      teamName: 'editorial'
    });
    
    await researcher.createMemory({
      content: 'Research finding: 73% of users prefer AI recommendations',
      memoryType: 'research',
      scope: 'team'  // Share with editorial team
    });
    
    // Writer accesses team research
    const writer = new MemoryStackClient({
      apiKey: process.env.MEMORYSTACK_API_KEY!,
      agentName: 'Writer',
      projectName: 'content_creation',
      teamName: 'editorial'  // Same team
    });
    
    // Access team research
    const teamResearch = await writer.searchMemories({
      query: 'research finding',
      scope: 'team',
      limit: 10
    });
    
    // Writer creates draft
    await writer.createMemory({
      content: 'Draft: AI Recommendations article ready for review',
      memoryType: 'status',
      scope: 'team'
    });
    
    // Editor reviews
    const editor = new MemoryStackClient({
      apiKey: process.env.MEMORYSTACK_API_KEY!,
      agentName: 'Editor',
      projectName: 'content_creation',
      teamName: 'editorial'
    });
    
    // Check team drafts
    const drafts = await editor.searchMemories({
      query: 'draft status',
      scope: 'team'
    });
    
    // Provide feedback
    await editor.createMemory({
      content: 'Feedback: Add more concrete examples in section 2',
      memoryType: 'feedback',
      scope: 'team'
    });

    LangGraph Integration

    Integrate Memorystack with LangGraph for stateful multi-agent workflows:

    import { StateGraph } from "@langchain/langgraph";
    import { MemoryStackClient } from "@memorystack/sdk";
    
    // Initialize Memorystack client
    const memoryClient = new MemoryStackClient({
      apiKey: process.env.MEMORYSTACK_API_KEY!,
      projectName: 'research_workflow'
    });
    
    // Define agent nodes
    async function researchNode(state: any) {
      // Research and store findings
      await memoryClient.createMemory({
        content: `Research findings: ${state.topic}`,
        memoryType: 'research',
        scope: 'team'
      });
      
      return { ...state, researchComplete: true };
    }
    
    async function writeNode(state: any) {
      // Retrieve research from memory
      const research = await memoryClient.searchMemories({
        query: state.topic,
        scope: 'team',
        limit: 5
      });
      
      // Write content using research
      return { ...state, content: 'Article content...' };
    }
    
    // Build workflow graph
    const workflow = new StateGraph({
      channels: {
        topic: null,
        researchComplete: null,
        content: null
      }
    });
    
    workflow.addNode("research", researchNode);
    workflow.addNode("write", writeNode);
    workflow.addEdge("research", "write");
    workflow.setEntryPoint("research");
    
    // Execute workflow
    const app = workflow.compile();
    const result = await app.invoke({ topic: "AI trends" });

    Next Steps