JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 15
  • Score
    100M100P100Q83074F
  • License MIT

Ultra-fast in-memory communication layer for parallel AI agents

Package Exports

  • octocode-local-memory
  • octocode-local-memory/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (octocode-local-memory) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Octocode Local Memory MCP Server

Ultra-fast in-memory storage for AI agent coordination

A lightweight Model Context Protocol (MCP) server providing a lean coordination layer using node-cache for local storage within the MCP node process. Enables multiple AI agents to communicate and coordinate during workflow execution with sub-millisecond read/write operations for task assignments, file locks, status updates, and inter-agent messaging.


🎯 What Problem Does This Solve?

When multiple AI agents work together on a task, they need to coordinate:

  • 🎭 Manager agents assign tasks β†’ Implementation agents execute them
  • πŸ”’ Multiple agents avoid editing the same file simultaneously
  • πŸ“Š All agents report progress and share status updates
  • πŸ’¬ Agents ask questions and communicate in real-time

Without coordination: Agents overwrite each other's work, duplicate effort, and create conflicts.
With octocode-local-memory: Agents share a lightning-fast coordination layer (< 1ms latency).


✨ Key Features

  • ⚑ Blazing Fast: Sub-millisecond read/write operations (0.1-0.8ms average)
  • πŸͺΆ Lean Implementation: Minimal overhead layer over node-cache within the MCP process
  • πŸ”’ File Lock Management: Prevent simultaneous file edits and race conditions
  • πŸ“¦ Zero Setup: No database, no Redis, no configuration required - pure Node.js
  • πŸ”„ Auto Cleanup: TTL-based expiration (data expires automatically)
  • πŸ’Ύ Session-Scoped: Fresh state for each workflow (by design)
  • 🎯 Simple API: Just 3 tools - setStorage(), getStorage(), deleteStorage()

Note: This is a lean coordination layer for temporary data during workflow execution, not persistent storage. It runs locally in the MCP server's node process using node-cache for optimal performance.


πŸ“š Table of Contents


πŸš€ Quick Start

Installation

Option 1: From NPM (when published)

npx octocode-local-memory@latest

Option 2: Local Development

# Clone and build
cd packages/octocode-local-memory
npm install
npm run build

Setup with Claude Desktop

Add to your MCP config file:

{
  "mcpServers": {
    "octocode-local-memory": {
      "command": "npx",
      "args": ["octocode-local-memory@latest"]  
    }
  }
}

🧠 How It Works

This is a lean coordination layer that wraps node-cache to provide MCP tools for agent communication. It runs locally within the MCP server's Node.js processβ€”no external services required.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     AI Agent Workflow                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

   Manager Agent                   Local Memory Server
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚  Assigns  │──setStorage()──>  β”‚  MCP Tool Layer  β”‚ (Lean wrapper)
   β”‚   Tasks   β”‚                   β”‚        ↓         β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                   β”‚   node-cache     β”‚ (In-memory)
                                   β”‚  (Node process)  β”‚
   Worker Agents                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                          ↕
   β”‚ Agent #1  │──getStorage()─────────────
   β”‚ Agent #2  │──setStorage()─────────────
   β”‚ Agent #3  │──getStorage()β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

   Architecture:
   β€’ Minimal overhead over node-cache
   β€’ Runs in MCP server process (no external dependencies)
   β€’ Sub-millisecond response time
   β€’ Automatic TTL-based expiration

Data Flow:

  1. Manager Agent β†’ Writes tasks to storage β†’ setStorage("task:1", {...})
  2. Worker Agent β†’ Reads assigned task β†’ getStorage("task:1")
  3. Worker Agent β†’ Updates progress β†’ setStorage("status:agent-1", {...})
  4. Manager Agent β†’ Monitors all agents β†’ getStorage("status:*")

πŸŽ“ Your First Agent Workflow

Let's build a simple 2-agent workflow in 5 minutes:

Step 1: Manager Agent Assigns a Task

// Manager agent creates a task
await setStorage({
  key: "task:auth-feature",
  value: JSON.stringify({
    description: "Implement user authentication",
    assignedTo: "worker-agent-1",
    files: ["src/auth/login.ts"],
    priority: "high"
  }),
  ttl: 3600  // 1 hour
});

console.log("βœ… Task assigned to worker-agent-1");

Step 2: Worker Agent Reads the Task

// Worker agent checks for assigned tasks
const result = await getStorage({key: "task:auth-feature"});

if (result.exists) {
  const task = JSON.parse(result.value);
  console.log(`πŸ“‹ New task: ${task.description}`);
  console.log(`πŸ“ Files: ${task.files.join(', ')}`);
  
  // Start working on the task...
} else {
  console.log("❌ No task found");
}

Step 3: Worker Reports Progress

// Worker agent updates status
await setStorage({
  key: "status:worker-agent-1",
  value: JSON.stringify({
    currentTask: "task:auth-feature",
    status: "in_progress",
    progress: 50,
    message: "Implementing login logic..."
  }),
  ttl: 3600
});

console.log("πŸ“Š Progress reported: 50%");

Step 4: Manager Monitors Progress

// Manager checks worker status
const status = await getStorage({key: "status:worker-agent-1"});

if (status.exists) {
  const workerStatus = JSON.parse(status.value);
  console.log(`Worker 1: ${workerStatus.progress}% - ${workerStatus.message}`);
}

That's it! You've created a functional multi-agent coordination system. πŸŽ‰


API Reference

The server provides three simple tools for agent coordination:

When Should Agents Use These Tools?

Use setStorage() when you need to:

  • βœ… Assign tasks to other agents
  • βœ… Acquire file locks before editing
  • βœ… Report progress or status updates
  • βœ… Ask questions to other agents
  • βœ… Share information across agents
  • βœ… Store temporary workflow state

Use getStorage() when you need to:

  • βœ… Check for assigned tasks
  • βœ… Check if a file is locked by another agent
  • βœ… Read status updates from other agents
  • βœ… Check for answers to your questions
  • βœ… Read shared workflow state
  • βœ… Coordinate with other agents

Use deleteStorage() when you need to:

  • βœ… Release file locks after editing
  • βœ… Remove completed tasks
  • βœ… Clear old status updates
  • βœ… Clean up temporary workflow data
  • βœ… Cancel pending questions/answers
  • βœ… Remove stale coordination data

Don't use these tools for:

  • ❌ Storing permanent data (use file system instead)
  • ❌ Storing code or large documents (write to files)
  • ❌ Long-term memory across sessions (use Mem0/MARM)
  • ❌ Searching or listing all keys (only exact key lookup supported)

setStorage(key, value, ttl?)

Store data that agents can access. Returns immediately (fire-and-forget).

Parameters:

  • key (string, required): Unique identifier (supports namespaces like "task:1", "lock:file.ts")
    • Pattern: ^[a-zA-Z0-9:_./-]+$
    • Max length: 255 characters
  • value (string, required): Data to store (typically JSON stringified)
    • Max size: 10MB
  • ttl (number, optional): Time-to-live in seconds (default: 3600 = 1 hour)
    • Range: 1-86400 seconds

Returns:

{
  "success": true,
  "key": "task:1",
  "timestamp": "2025-10-15T14:30:00.123Z"
}

Example:

// Store task assignment
await setStorage({
  key: "task:3.1",
  value: JSON.stringify({
    taskId: "3.1",
    agent: "impl-1",
    description: "Implement auth"
  }),
  ttl: 3600
});

getStorage(key)

Retrieve data by key. Returns immediately with O(1) lookup.

Parameters:

  • key (string, required): Key to retrieve

Returns (when found):

{
  "success": true,
  "key": "task:1",
  "value": "{\"taskId\":\"1\",\"agent\":\"impl-1\"}",
  "exists": true,
  "timestamp": "2025-10-15T14:30:00.123Z"
}

Returns (when not found or expired):

{
  "success": true,
  "key": "task:999",
  "value": null,
  "exists": false,
  "timestamp": "2025-10-15T14:30:00.123Z"
}

Example:

// Check task assignment
const result = await getStorage({key: "task:3.1"});
if (result.exists) {
  const task = JSON.parse(result.value);
  console.log(`Assigned to: ${task.agent}`);
} else {
  console.log("Task not found or expired");
}

deleteStorage(key)

Delete a key from cache. Returns immediately. Safe to call even if key doesn't exist.

Parameters:

  • key (string, required): Key to delete

Returns (when key existed):

{
  "success": true,
  "key": "task:1",
  "deleted": true,
  "timestamp": "2025-10-15T14:30:00.123Z"
}

Returns (when key didn't exist):

{
  "success": true,
  "key": "task:999",
  "deleted": false,
  "timestamp": "2025-10-15T14:30:00.123Z"
}

Example:

// Release file lock after editing
await deleteStorage({key: "lock:src/auth/login.ts"});

// Remove completed task
await deleteStorage({key: "task:3.1"});

// Clear status update
await deleteStorage({key: "status:agent-impl-1:task-1"});

Usage Examples

Example 1: Multi-Agent Task Workflow

Scenario: A manager agent coordinates 3 implementation agents to build a feature.

// Manager agent: Assign tasks to workers
await setStorage({
  key: "task:1",
  value: JSON.stringify({
    taskId: "1",
    assignedTo: "agent-impl-1",
    description: "Implement user authentication",
    files: ["src/auth/login.ts", "src/auth/session.ts"],
    priority: "high"
  }),
  ttl: 3600 // 1 hour
});

await setStorage({
  key: "task:2",
  value: JSON.stringify({
    taskId: "2",
    assignedTo: "agent-impl-2",
    description: "Build API endpoints",
    files: ["src/api/routes.ts"],
    priority: "medium"
  }),
  ttl: 3600
});

// Implementation agent: Read assigned task
const taskResult = await getStorage({key: "task:1"});
if (taskResult.exists) {
  const task = JSON.parse(taskResult.value);
  console.log(`Working on: ${task.description}`);
  console.log(`Files: ${task.files.join(', ')}`);
}

// Implementation agent: Report progress
await setStorage({
  key: "status:agent-impl-1:task-1",
  value: JSON.stringify({
    status: "in_progress",
    progress: 65,
    currentStep: "Writing authentication logic",
    completedFiles: ["src/auth/login.ts"]
  }),
  ttl: 3600
});

// Manager agent: Monitor all agents
const status1 = await getStorage({key: "status:agent-impl-1:task-1"});
const status2 = await getStorage({key: "status:agent-impl-2:task-2"});

if (status1.exists && status2.exists) {
  const s1 = JSON.parse(status1.value);
  const s2 = JSON.parse(status2.value);
  console.log(`Agent 1: ${s1.progress}% - ${s1.currentStep}`);
  console.log(`Agent 2: ${s2.progress}% - ${s2.currentStep}`);
}

Example 2: File Lock Coordination

Scenario: Prevent multiple agents from editing the same file simultaneously.

// Agent 1: Try to acquire file lock
const lockCheck = await getStorage({key: "lock:src/auth/login.ts"});

if (!lockCheck.exists) {
  // Lock is available - acquire it
  await setStorage({
    key: "lock:src/auth/login.ts",
    value: JSON.stringify({
      lockedBy: "agent-impl-1",
      taskId: "task-1",
      acquiredAt: Date.now()
    }),
    ttl: 300 // 5 minutes - auto-releases if agent crashes
  });
  
  console.log("Lock acquired - safe to edit file");
  // ... edit the file ...
  
  // Release lock when done (recommended: use deleteStorage)
  await deleteStorage({key: "lock:src/auth/login.ts"});
} else {
  // Lock is held by another agent
  const lock = JSON.parse(lockCheck.value);
  console.log(`File locked by ${lock.lockedBy} for ${lock.taskId}`);
  console.log("Waiting for lock to be released...");
}

Example 3: Inter-Agent Questions

Scenario: Implementation agent needs clarification from manager agent.

// Implementation agent: Ask question
await setStorage({
  key: "question:impl-1:auth-approach",
  value: JSON.stringify({
    from: "agent-impl-1",
    to: "agent-manager",
    question: "Should we use JWT or session-based auth?",
    context: "Working on task-1: user authentication",
    timestamp: Date.now()
  }),
  ttl: 1800 // 30 minutes
});

// Manager agent: Check for questions
const questionResult = await getStorage({key: "question:impl-1:auth-approach"});
if (questionResult.exists) {
  const q = JSON.parse(questionResult.value);
  console.log(`Question from ${q.from}: ${q.question}`);
  
  // Manager agent: Provide answer
  await setStorage({
    key: "answer:impl-1:auth-approach",
    value: JSON.stringify({
      answer: "Use JWT tokens for stateless authentication",
      reasoning: "Better scalability for our use case",
      timestamp: Date.now()
    }),
    ttl: 3600
  });
}

// Implementation agent: Get answer
const answerResult = await getStorage({key: "answer:impl-1:auth-approach"});
if (answerResult.exists) {
  const answer = JSON.parse(answerResult.value);
  console.log(`Manager says: ${answer.answer}`);
  console.log(`Reasoning: ${answer.reasoning}`);
}

Example 4: Global Progress Tracking

Scenario: Track overall workflow progress across all agents.

// Manager agent: Initialize workflow
await setStorage({
  key: "workflow:build-feature",
  value: JSON.stringify({
    totalTasks: 5,
    completedTasks: 0,
    inProgressTasks: 0,
    phase: "planning"
  }),
  ttl: 7200 // 2 hours
});

// Implementation agent: Update progress when completing task
const workflowResult = await getStorage({key: "workflow:build-feature"});
if (workflowResult.exists) {
  const workflow = JSON.parse(workflowResult.value);
  workflow.completedTasks += 1;
  workflow.inProgressTasks -= 1;
  
  if (workflow.completedTasks === workflow.totalTasks) {
    workflow.phase = "completed";
  }
  
  await setStorage({
    key: "workflow:build-feature",
    value: JSON.stringify(workflow),
    ttl: 7200
  });
}

Key Naming Conventions

Use namespaced keys for organized communication. Keys support: alphanumeric, colons, underscores, dots, slashes, hyphens.

Recommended patterns:

// Task management
"task:{taskId}"                    // Task assignments
"status:{agentId}:{taskId}"        // Progress updates

// File coordination
"lock:{filePath}"                  // File locks (e.g., "lock:src/auth/auth.ts")

// Communication
"question:{agentId}:{topic}"       // Questions to manager
"answer:{agentId}:{topic}"         // Answers from manager
"msg:{from}:{to}:{timestamp}"      // Direct messages

// Workflow tracking
"workflow:{workflowId}"            // Overall workflow state
"progress:{phase}"                 // Phase-specific progress
"agent:{agentId}:state"            // Agent state/health

Common Patterns

Wait-for-Lock Pattern

async function acquireLock(filePath, agentId, maxWaitMs = 30000) {
  const lockKey = `lock:${filePath}`;
  const startTime = Date.now();
  
  while (Date.now() - startTime < maxWaitMs) {
    const lock = await getStorage({key: lockKey});
    
    if (!lock.exists) {
      await setStorage({
        key: lockKey,
        value: JSON.stringify({lockedBy: agentId, time: Date.now()}),
        ttl: 300
      });
      return true; // Lock acquired
    }
    
    await new Promise(resolve => setTimeout(resolve, 500)); // Wait 500ms
  }
  
  return false; // Timeout
}

Atomic Status Update Pattern

async function updateAgentStatus(agentId, taskId, newStatus) {
  const statusKey = `status:${agentId}:${taskId}`;
  const current = await getStorage({key: statusKey});
  
  let status = current.exists ? JSON.parse(current.value) : {history: []};
  
  // Add to history
  status.history.push({
    ...newStatus,
    timestamp: Date.now()
  });
  
  // Update current state
  status.current = newStatus;
  
  await setStorage({
    key: statusKey,
    value: JSON.stringify(status),
    ttl: 3600
  });
}

Health Check Pattern

// Agent: Report alive status
setInterval(async () => {
  await setStorage({
    key: `agent:impl-1:heartbeat`,
    value: JSON.stringify({lastSeen: Date.now()}),
    ttl: 60 // 1 minute
  });
}, 30000); // Every 30 seconds

// Manager: Check agent health
async function isAgentHealthy(agentId) {
  const heartbeat = await getStorage({key: `agent:${agentId}:heartbeat`});
  return heartbeat.exists;
}

Configuration

Cache configuration (in src/index.ts):

const cache = new NodeCache({
  stdTTL: 3600,      // Default TTL: 1 hour (3600 seconds)
  checkperiod: 120,  // Cleanup check every 2 minutes
  useClones: false   // Performance optimization - no deep cloning
});

Configuring TTL:

  • Default: 3600 seconds (1 hour)
  • Per-key: Specify ttl parameter in setStorage()
  • Range: 1-86400 seconds (1 second to 24 hours)

Example with custom TTL:

// Lock expires in 5 minutes
await setStorage({
  key: "lock:auth.ts",
  value: JSON.stringify({lockedBy: "agent-1"}),
  ttl: 300
});

// Task expires in 2 hours
await setStorage({
  key: "task:1",
  value: JSON.stringify({description: "Implement feature"}),
  ttl: 7200
});

Performance

Memory vs File System vs Redis

Is this faster than file I/O? Yes, dramatically faster (10-100x).

Operation NodeCache File System (SSD) File System (HDD)
Read 0.1-0.4ms 1-10ms 10-50ms
Write 0.3-0.8ms 5-20ms 20-100ms
Concurrent Access βœ… Instant ⚠️ File locking delays ⚠️ Significant delays
Overhead Hash lookup only Open+read+close+parsing Open+read+close+parsing+disk seek

Why memory is 10-100x faster:

  • βœ… No disk I/O (no physical read/write operations)
  • βœ… No file open/close overhead
  • βœ… O(1) hash table lookups (constant time)
  • βœ… Direct memory access (no system calls)
  • βœ… Zero serialization overhead

Benchmarks

Real-world test with 5 concurrent agents performing typical coordination tasks:

NodeCache (this tool):
β”œβ”€ Total time: 0.5 seconds
β”œβ”€ Average latency: 0.5ms per operation
β”œβ”€ Throughput: 2,000 ops/sec
└─ Agent wait time: Negligible

File System (SSD):
β”œβ”€ Total time: 8 seconds (16x slower)
β”œβ”€ Average latency: 8ms per operation
β”œβ”€ Throughput: 125 ops/sec
└─ Agent wait time: Noticeable delays

File System (HDD):
β”œβ”€ Total time: 45 seconds (90x slower)
β”œβ”€ Average latency: 45ms per operation
β”œβ”€ Throughput: 22 ops/sec
└─ Agent wait time: Frustrating delays

Performance metrics:

  • Write operations: 0.3-0.8ms average
  • Read operations: 0.1-0.4ms average
  • Throughput: 10,000+ operations/second
  • Memory overhead: ~150 bytes per key + value size

Real-world impact (3 agents building a feature with 50 coordination events):

Using Files:
β”œβ”€ Agent 1: Waits 8ms for lock check β†’ Waits 15ms to write status β†’ Total: 23ms Γ— 50 = 1.15s overhead
β”œβ”€ Agent 2: Waits 8ms for lock check β†’ Waits 15ms to write status β†’ Total: 23ms Γ— 50 = 1.15s overhead  
β”œβ”€ Agent 3: Waits 8ms for lock check β†’ Waits 15ms to write status β†’ Total: 23ms Γ— 50 = 1.15s overhead
└─ Total coordination overhead: 3.45 seconds

Using Memory (this tool):
β”œβ”€ Agent 1: Waits 0.5ms for lock check β†’ Waits 0.5ms to write status β†’ Total: 1ms Γ— 50 = 50ms overhead
β”œβ”€ Agent 2: Waits 0.5ms for lock check β†’ Waits 0.5ms to write status β†’ Total: 1ms Γ— 50 = 50ms overhead
β”œβ”€ Agent 3: Waits 0.5ms for lock check β†’ Waits 0.5ms to write status β†’ Total: 1ms Γ— 50 = 50ms overhead  
└─ Total coordination overhead: 150ms (23x faster)

Result: Agents spend 95% more time on actual work!

Best practice: Use memory for coordination, files for artifacts.

// βœ… MEMORY: Coordination data (fast, temporary)
await setStorage({
  key: "lock:src/auth.ts",
  value: JSON.stringify({agent: "impl-1"}),
  ttl: 300
});

await setStorage({
  key: "status:impl-1",
  value: JSON.stringify({progress: 50}),
  ttl: 600
});

// βœ… FILE SYSTEM: Permanent artifacts (persistent, version-controlled)
await fs.writeFile("src/auth/login.ts", sourceCode);
await fs.writeFile("docs/architecture.md", documentation);
await fs.writeFile("config.json", JSON.stringify(config));

Memory for coordination, files for artifacts = Best of both worlds! 🎯

Limitations

Understanding these limitations will help you use the tool effectively:

No Persistence

  • Data is lost when the server restarts
  • This is intentional for session-scoped workflows
  • βœ… Use for: Temporary coordination during workflow execution
  • ❌ Don't use for: Data that must survive restarts

Single Process

  • Cannot share data across multiple MCP server instances
  • Each server has its own isolated cache
  • βœ… Use for: Single workflow execution environments
  • ❌ Don't use for: Distributed multi-server setups

Memory Bounded

  • Limited by available RAM
  • Large datasets (100s of MB) may cause issues
  • βœ… Use for: Small coordination data (KB-MB range)
  • ❌ Don't use for: Large dataset caching

No Search Capabilities

  • Can only retrieve by exact key match
  • No pattern matching or listing all keys
  • βœ… Use for: Known key access patterns
  • ❌ Don't use for: Dynamic key discovery or search

When to Use This vs Alternatives

βœ… Use octocode-local-memory when:

  • Multiple AI agents need to coordinate during a workflow
  • Speed is critical - Sub-millisecond latency required (< 1ms)
  • Data is temporary - Task assignments, locks, status updates
  • Zero setup - No database, no Redis, no configuration required
  • High-frequency updates - Status checks every few seconds
  • Concurrent access - Multiple agents reading/writing simultaneously
  • Small payloads - JSON objects < 100KB
  • Session-scoped - Data only needed during workflow execution
  • Privacy matters - Data never leaves process memory

πŸ”„ Use alternatives when:

Alternative Best For Example Use Cases
File System Permanent artifacts Code files, docs, config, images
Redis MCP Distributed systems, persistence Multi-server setups, data that survives restarts
Mem0/MARM Long-term AI memory User preferences, learning across sessions
Vector DB Semantic search Similarity matching, embeddings, RAG
SQLite Structured data with queries Reporting, analytics, complex joins

Development

# Build
npm run build

# Watch mode
npm run build:watch

# Run tests
npm test

# Run server
npm start

# Development (build + run)
npm run dev

Troubleshooting

Installation Issues

Problem: Tools not showing up in Claude Desktop

Solutions:

  1. βœ… Check config file path is correct for your OS
  2. βœ… Verify JSON syntax (no trailing commas, proper quotes)
  3. βœ… Ensure absolute path to dist/index.js is correct
  4. βœ… Make sure you ran npm run build first
  5. βœ… Restart Claude Desktop completely (quit and reopen)
  6. βœ… Check Claude Desktop logs: ~/Library/Logs/Claude/mcp*.log (macOS)

Problem: "Cannot find module" error

Solutions:

cd packages/octocode-local-memory
npm install          # Install dependencies
npm run build        # Build the project
ls -la dist/         # Verify dist/index.js exists

Problem: Permission denied

Solutions:

chmod +x dist/index.js  # Make executable

Runtime Issues

Problem: Keys not found after some time

Cause: Keys expire based on TTL (default: 1 hour)

Solutions:

  • βœ… Increase TTL for longer workflows: ttl: 7200 (2 hours)
  • βœ… Set longer TTL for critical data: ttl: 14400 (4 hours)
  • βœ… Re-write keys periodically to refresh TTL

Problem: Agents seeing stale data

Solutions:

  • βœ… Explicitly overwrite keys to update: setStorage({key: "...", value: newValue})
  • βœ… Use shorter TTLs for frequently-updated status data (5-10 minutes)
  • βœ… Add timestamps to your data for freshness checks

Problem: Data lost after Claude Desktop restart

Explanation: This is intentional behavior - data is session-scoped

Solutions:

  • βœ… Store permanent data in the file system instead
  • βœ… Use this only for temporary coordination during active workflows
  • βœ… Re-initialize workflow state at the start of each session

Problem: "Invalid key format" error

Cause: Keys must match pattern: ^[a-zA-Z0-9:_./-]+$

Bad examples:

"task #1"           // ❌ Spaces not allowed
"task@agent"        // ❌ @ not allowed
"task:1:priority!"  // ❌ ! not allowed

Good examples:

"task:1"                // βœ… Simple namespace
"lock:src/auth/auth.ts" // βœ… File path
"status:agent-1:task-1" // βœ… Multi-level namespace
"workflow_123"          // βœ… Underscore allowed

Performance Issues

Problem: Slow operations (> 10ms)

Possible causes:

  • βœ… Very large values (> 1MB) - consider storing summary data only
  • βœ… Too many keys in cache (> 10,000) - use shorter TTLs
  • βœ… System resource constraints - check available RAM

Problem: "Value too large" error

Solution: Values are limited to 10MB

  • βœ… Store summaries instead of full content
  • βœ… Store references (file paths) instead of file contents
  • βœ… Break large data into multiple keys

Getting Help

If you're still having issues:

  1. πŸ“ Check server logs for error messages
  2. πŸ§ͺ Test with simple key-value pairs first
  3. πŸ› Verify the package built correctly: npm run test
  4. πŸ’¬ Open an issue: https://github.com/bgauryy/octocode-mcp/issues

Debug mode:

# Run server directly to see console output
npm start

Best Practices

1. Use Namespaced Keys

// Good
"task:1", "lock:auth.ts", "status:agent-1:task-1"

// Bad (hard to organize)
"task1", "authlock", "status_agent_1_task_1"

2. Set Appropriate TTLs

// Short-lived locks
ttl: 300  // 5 minutes

// Task assignments
ttl: 3600  // 1 hour

// Workflow state
ttl: 7200  // 2 hours

3. Handle Missing Keys

const result = await getStorage({key: "task:1"});
if (!result.exists) {
  // Handle missing/expired key
  console.log("Task not found");
  return;
}
const task = JSON.parse(result.value);

4. Use JSON for Complex Data

// Store objects as JSON strings
await setStorage({
  key: "task:1",
  value: JSON.stringify({id: 1, status: "pending"}),
  ttl: 3600
});

Quick Reference Card

Essential Commands

// Store data (write)
await setStorage({
  key: "namespace:identifier",
  value: JSON.stringify({...}),
  ttl: 3600  // seconds (optional)
});

// Retrieve data (read)
const result = await getStorage({key: "namespace:identifier"});
if (result.exists) {
  const data = JSON.parse(result.value);
}

// Delete data (cleanup)
await deleteStorage({key: "namespace:identifier"});

Common Key Patterns

Pattern Example Use Case
task:{id} task:1 Task assignments
lock:{filepath} lock:src/auth.ts File locks
status:{agent}:{task} status:impl-1:task-1 Progress tracking
question:{from}:{topic} question:impl-1:auth Inter-agent questions
answer:{to}:{topic} answer:impl-1:auth Answers from manager
workflow:{id} workflow:build-feature Overall workflow state
agent:{id}:heartbeat agent:impl-1:heartbeat Health checks

TTL Recommendations

Data Type TTL (seconds) Duration
File locks 300 5 minutes
Task assignments 3600 1 hour
Status updates 600 10 minutes
Questions/Answers 1800 30 minutes
Workflow state 7200 2 hours
Heartbeats 60 1 minute

Key Constraints

  • Pattern: ^[a-zA-Z0-9:_./-]+$ (alphanumeric, :, _, ., /, -)
  • Max length: 255 characters
  • Value max size: 10MB
  • TTL range: 1-86400 seconds (1 second to 24 hours)

Quick Patterns

Check and acquire lock:

const lock = await getStorage({key: "lock:file.ts"});
if (!lock.exists) {
  await setStorage({key: "lock:file.ts", value: JSON.stringify({agent: "me"}), ttl: 300});
  // ... do work ...
  await deleteStorage({key: "lock:file.ts"}); // Release lock
}

Update with history:

const current = await getStorage({key: "status:agent-1"});
let status = current.exists ? JSON.parse(current.value) : {history: []};
status.history.push({timestamp: Date.now(), progress: 50});
await setStorage({key: "status:agent-1", value: JSON.stringify(status), ttl: 3600});

Contributing

Part of the Octocode ecosystem. Contributions welcome:

  • Performance improvements
  • Better coordination patterns
  • More usage examples
  • Bug fixes

License

MIT


Built for the Octocode multi-agent ecosystem - enabling reliable agent coordination through simplicity and speed.