summaryrefslogtreecommitdiff
path: root/mcp-servers/memory-mcp-server/CLAUDE.md
blob: a9e969a9e55ba4896c6909d8dd2b12af366d48a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
# Memory MCP Server Development Assistant

You are an expert in building production MCP (Model Context Protocol) servers with memory persistence, vector search capabilities, and AI companion systems. You have deep expertise in PostgreSQL, pgvector, Drizzle ORM, and the MCP SDK.

## Memory Integration

This CLAUDE.md follows official Claude Code patterns for MCP server development:

- **MCP protocol compliance** - Follows @modelcontextprotocol/sdk standards
- **Project memory** - Instructions shared with development team
- **Tool integration** - Works with Claude Code's MCP commands
- **Automated discovery** - Available when MCP server is configured

## MCP Configuration

To use this server with Claude Code:

```bash
# Add local MCP server
claude mcp add memory-server -- npx memory-mcp-server

# Add with environment variables  
claude mcp add memory-server --env DATABASE_URL=your_db_url --env OPENAI_API_KEY=your_key -- npx memory-mcp-server

# Check server status
claude mcp list
```

## Available MCP Tools

When connected, provides these tools to Claude Code:

- `memory.create` - Store new memory with vector embedding
- `memory.search` - Semantic search through stored memories  
- `memory.update` - Update existing memory content
- `memory.delete` - Remove memories by ID
- `memory.list` - List memories for user/companion
- `memory.consolidate` - Merge similar memories

## Project Context

This is a Memory MCP Server project focused on:

- **Persistent memory storage** with PostgreSQL and pgvector
- **Semantic search** using OpenAI embeddings
- **Multi-tenant architecture** for AI companions
- **Production deployment** with monitoring and scaling
- **MCP protocol compliance** using @modelcontextprotocol/sdk

## Technology Stack

### Core Technologies

- **TypeScript** - Type-safe development
- **Node.js** - Runtime environment
- **@modelcontextprotocol/sdk** - MCP implementation
- **PostgreSQL 17** - Primary database
- **Neon** - Serverless PostgreSQL hosting

### Database & ORM

- **Drizzle ORM v0.44.4** - Type-safe database access
- **pgvector v0.8.0** - Vector similarity search
- **@neondatabase/serverless** - Serverless PostgreSQL client

### Vector Search

- **OpenAI Embeddings** - text-embedding-3-small model
- **HNSW Indexes** - High-performance similarity search
- **Hybrid Search** - Combining vector and keyword search

## Architecture Patterns

### Memory System Design

```typescript
// Memory schema with vector embeddings
export const memories = pgTable('memories', {
  id: uuid('id').primaryKey().defaultRandom(),
  userId: text('user_id').notNull(),
  companionId: text('companion_id').notNull(),
  content: text('content').notNull(),
  embedding: vector('embedding', { dimensions: 1536 }),
  metadata: jsonb('metadata'),
  importance: real('importance').default(0.5),
  lastAccessed: timestamp('last_accessed'),
  createdAt: timestamp('created_at').defaultNow(),
}, (t) => ({
  embeddingIdx: index().using('hnsw', t.embedding.op('vector_cosine_ops')),
  userCompanionIdx: index().on(t.userId, t.companionId),
}));
```

### MCP Server Implementation

```typescript
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

const server = new Server({
  name: 'memory-server',
  version: '1.0.0',
}, {
  capabilities: {
    resources: {},
    tools: {},
  },
});

// Tool handlers
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  // Implementation
});

// Start server
const transport = new StdioServerTransport();
await server.connect(transport);
```

## Critical Implementation Details

### 1. Vector Search Optimization

```typescript
// Efficient similarity search with pgvector
const similar = await db
  .select()
  .from(memories)
  .where(
    and(
      eq(memories.userId, userId),
      sql`${memories.embedding} <=> ${embedding} < 0.5`
    )
  )
  .orderBy(sql`${memories.embedding} <=> ${embedding}`)
  .limit(10);
```

### 2. Memory Lifecycle Management

- **Consolidation**: Merge similar memories periodically
- **Decay**: Reduce importance over time without access
- **Archival**: Move old memories to cold storage
- **Deduplication**: Prevent duplicate memory storage

### 3. Multi-tenant Isolation

```typescript
// Row-level security for tenant isolation
ALTER TABLE memories ENABLE ROW LEVEL SECURITY;

CREATE POLICY tenant_isolation ON memories
  FOR ALL
  USING (user_id = current_setting('app.user_id')::text);
```

### 4. Error Handling

```typescript
// Comprehensive error handling
try {
  const result = await operation();
  return { content: [{ type: 'text', text: JSON.stringify(result) }] };
} catch (error) {
  if (error instanceof ZodError) {
    return { error: { code: 'INVALID_PARAMS', message: error.message } };
  }
  logger.error('Operation failed', { error, context });
  return { error: { code: 'INTERNAL_ERROR', message: 'Operation failed' } };
}
```

## Performance Optimization

### Database Indexing

```sql
-- HNSW index for vector search
CREATE INDEX memories_embedding_idx ON memories 
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);

-- B-tree indexes for filtering
CREATE INDEX memories_user_companion_idx ON memories(user_id, companion_id);
CREATE INDEX memories_created_at_idx ON memories(created_at DESC);
```

### Connection Pooling

```typescript
// Neon serverless with connection pooling
import { neon } from '@neondatabase/serverless';

const sql = neon(process.env.DATABASE_URL, {
  poolQueryViaFetch: true,
  fetchConnectionCache: true,
});
```

### Caching Strategy

- **Embedding Cache**: Cache frequently used embeddings
- **Query Cache**: Cache common search results
- **Connection Cache**: Reuse database connections

## Security Best Practices

### Input Validation

```typescript
// Zod schemas for all inputs
const CreateMemorySchema = z.object({
  content: z.string().min(1).max(10000),
  metadata: z.record(z.unknown()).optional(),
  importance: z.number().min(0).max(1).optional(),
});

// Validate before processing
const validated = CreateMemorySchema.parse(input);
```

### Authentication & Authorization

```typescript
// JWT-based authentication
const token = request.headers.authorization?.split(' ')[1];
const payload = jwt.verify(token, process.env.JWT_SECRET);

// Role-based access control
if (!payload.roles.includes('memory:write')) {
  throw new ForbiddenError('Insufficient permissions');
}
```

### Data Encryption

- Encrypt sensitive memory content at rest
- Use TLS for all connections
- Implement field-level encryption for PII

## Testing Strategy

### Unit Tests

```typescript
// Test memory operations
describe('MemoryService', () => {
  it('should create memory with embedding', async () => {
    const memory = await service.create({
      content: 'Test memory',
      userId: 'test-user',
    });
    expect(memory.embedding).toBeDefined();
    expect(memory.embedding.length).toBe(1536);
  });
});
```

### Integration Tests

```typescript
// Test MCP server
describe('MCP Server', () => {
  it('should handle memory.create tool', async () => {
    const response = await server.handleRequest({
      method: 'tools/call',
      params: {
        name: 'memory.create',
        arguments: { content: 'Test' },
      },
    });
    expect(response.content[0].type).toBe('text');
  });
});
```

## Deployment Configuration

### Docker Setup

```dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
RUN npm run build
CMD ["node", "dist/index.js"]
```

### Environment Variables

```env
DATABASE_URL=postgresql://user:pass@host/db?sslmode=require
OPENAI_API_KEY=sk-...
MCP_SERVER_PORT=3000
NODE_ENV=production
LOG_LEVEL=info
```

## Monitoring & Observability

### Structured Logging

```typescript
import pino from 'pino';

const logger = pino({
  level: process.env.LOG_LEVEL || 'info',
  formatters: {
    level: (label) => ({ level: label }),
  },
});
```

### Metrics Collection

```typescript
// Prometheus metrics
import { register, Counter, Histogram } from 'prom-client';

const memoryCreated = new Counter({
  name: 'memory_created_total',
  help: 'Total number of memories created',
});

const searchDuration = new Histogram({
  name: 'memory_search_duration_seconds',
  help: 'Duration of memory search operations',
});
```

## Common Commands

```bash
# Development
npm run dev           # Start development server
npm run build         # Build for production
npm run test          # Run tests
npm run lint          # Lint code

# Database
npm run db:migrate    # Run migrations
npm run db:push       # Push schema changes
npm run db:studio     # Open Drizzle Studio

# MCP Testing
npm run mcp:test      # Test MCP server
npm run mcp:debug     # Debug MCP protocol
```

## Resources

- [MCP Documentation](https://modelcontextprotocol.io)
- [pgvector Documentation](https://github.com/pgvector/pgvector)
- [Drizzle ORM Documentation](https://orm.drizzle.team)
- [Neon Documentation](https://neon.tech/docs)

Remember: **Performance, Security, and Reliability** are critical for production MCP servers!