Skip to main content

MCP Server: Cross-Application Memory

Last Updated: 2025-10-28

Share Cortex memory across all your AI tools with the Model Context Protocol server.

Overview

The Cortex MCP (Model Context Protocol) Server enables your AI memory to follow you everywhere. Whether you're using Cursor IDE, Claude Desktop, or custom AI tools, they all share the same persistent memory through a standard protocol.

The Problem:

  • Cursor remembers your coding preferences
  • Claude remembers your writing style
  • ChatGPT remembers your project details
  • But they don't share memory - you repeat yourself constantly! ❌

The Solution:

  • Cortex MCP Server runs locally (or in cloud)
  • All AI tools connect to it
  • They all share one memory store ✅
  • Tell one tool something, all tools remember it!

Quick Start

Installation

# Install globally
npm install -g @cortex-platform/mcp-server

# Or use npx (no install)
npx @cortex-platform/mcp-server

Start Server

# With your Convex URL
cortex-mcp-server --convex-url=https://your-project.convex.cloud

# Server starts on http://localhost:3000

Configure AI Clients

Cursor IDE:

Create .cursor/mcp-config.json:

{
"memory": {
"provider": "cortex",
"endpoint": "http://localhost:3000",
"user_id": "your-email@example.com"
}
}

Claude Desktop:

Edit ~/Library/Application Support/Claude/claude_desktop_config.json:

{
"mcpServers": {
"cortex": {
"url": "http://localhost:3000"
}
}
}

That's it! Now Cursor and Claude share memory via Cortex.

How It Works

Architecture

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│ Cursor IDE │ │ Claude Desktop │ │ Custom Tool │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
└───────────────────────┼───────────────────────┘

HTTP/JSON (MCP Protocol)


┌──────────────────────────────┐
│ Cortex MCP Server │
│ (localhost:3000) │
└──────────────┬───────────────┘


┌──────────────────────────────┐
│ Cortex SDK │
│ (Memory Operations) │
└──────────────┬───────────────┘


┌──────────────────────────────┐
│ Your Convex Instance │
│ (Data Storage) │
└──────────────────────────────┘

Example Flow

  1. In Cursor: You say "I prefer TypeScript for backend"
  2. Cursor → MCP: POST /add_memories with the message
  3. MCP → Cortex: Stores in Convex via SDK
  4. Later, in Claude: You ask about coding advice
  5. Claude → MCP: POST /search_memory for "coding preferences"
  6. MCP → Cortex: Searches and returns "User prefers TypeScript"
  7. Claude: Uses that fact to personalize response ✅

Result: Claude knows your preferences without you repeating them!

MCP Endpoints

add_memories

Store new memories from conversation:

POST /add_memories
Content-Type: application/json

{
"messages": [
{ "role": "user", "content": "I like dark mode" },
{ "role": "assistant", "content": "Noted!" }
],
"user_id": "user-123"
}

// Response
{
"success": true,
"memory_ids": ["mem_abc", "mem_def"]
}

Or store single memory:

{
"memory": "User prefers dark mode",
"user_id": "user-123",
"metadata": {
"source": "cursor",
"importance": 70
}
}

search_memory

Find relevant memories:

POST /search_memory
Content-Type: application/json

{
"query": "user preferences",
"user_id": "user-123",
"limit": 5
}

// Response
{
"results": [
{
"id": "mem_abc",
"memory": "User prefers dark mode",
"score": 0.92,
"metadata": { "importance": 70 },
"created_at": "2025-10-28T10:00:00Z"
}
]
}

list_memories

Get recent memories:

GET /list_memories?user_id=user-123&limit=20

// Response
{
"results": [
{
"id": "mem_xyz",
"memory": "User prefers TypeScript",
"created_at": "2025-10-28T09:00:00Z"
},
// ... more memories
],
"total": 45,
"has_more": true
}

delete_all_memories

Clear all memories for a user:

POST /delete_all_memories
Content-Type: application/json

{
"user_id": "user-123"
}

// Response
{
"success": true,
"deleted_count": 45
}

User and Session Isolation

Multi-User Support

Each user has isolated memories:

// User A's memory
POST /add_memories
{
"memory": "I prefer light mode",
"user_id": "alice@example.com"
}

// User B's memory
POST /add_memories
{
"memory": "I prefer dark mode",
"user_id": "bob@example.com"
}

// Searches are isolated
POST /search_memory
{
"query": "theme preference",
"user_id": "alice@example.com"
}
// Returns: "I prefer light mode" (Alice's only) ✅

Session Scoping

Temporary context that doesn't persist across sessions:

POST /add_memories
{
"memory": "Currently working on feature-branch-123",
"user_id": "user-123",
"session_id": "session-abc" // Session-specific
}

// Search within session
POST /search_memory
{
"query": "current work",
"user_id": "user-123",
"session_id": "session-abc"
}

// Different session doesn't see it
POST /search_memory
{
"query": "current work",
"user_id": "user-123",
"session_id": "session-xyz" // Different session
}
// Returns: [] (empty)

Client Integration

Cursor IDE

Cursor automatically integrates with MCP servers.

Setup:

  1. Start Cortex MCP Server:
cortex-mcp-server --convex-url=$CONVEX_URL --port=3000
  1. Create .cursor/mcp-config.json in your project:
{
"memory": {
"provider": "cortex",
"endpoint": "http://localhost:3000",
"user_id": "${USER_EMAIL}"
}
}

Usage:

  • Cursor will automatically store context as you code
  • Ask Cursor about preferences: "What's my preferred framework?"
  • Cursor retrieves from MCP: "User prefers React with TypeScript"

Claude Desktop

Setup:

  1. Start Cortex MCP Server (if not running)

  2. Edit Claude's config:

# macOS
~/Library/Application Support/Claude/claude_desktop_config.json

# Windows
%APPDATA%\Claude\claude_desktop_config.json

# Linux
~/.config/Claude/claude_desktop_config.json
  1. Add Cortex:
{
"mcpServers": {
"cortex": {
"url": "http://localhost:3000"
}
}
}
  1. Restart Claude Desktop

Usage:

  • Tell Claude: "Remember that I prefer formal communication"
  • Later, switch to different conversation
  • Claude maintains the preference across all chats ✅

Custom Integration

// Your application
import axios from "axios";

const MCP_ENDPOINT = "http://localhost:3000";
const USER_ID = "user-123";

// Store memory
async function rememberInMCP(content: string) {
await axios.post(`${MCP_ENDPOINT}/add_memories`, {
memory: content,
user_id: USER_ID,
metadata: {
source: "my-app",
importance: 70,
},
});
}

// Retrieve context
async function getRelevantContext(query: string) {
const response = await axios.post(`${MCP_ENDPOINT}/search_memory`, {
query,
user_id: USER_ID,
limit: 5,
});

return response.data.results.map((r) => r.memory);
}

// Usage in your AI agent
const userQuery = "What should I work on?";
const context = await getRelevantContext(userQuery);

const llmResponse = await yourLLM.complete({
messages: [
{ role: "system", content: `Context: ${context.join("; ")}` },
{ role: "user", content: userQuery },
],
});

Advanced Configuration

Environment Variables

# Required
CONVEX_URL=https://your-project.convex.cloud

# Optional
MCP_PORT=3000
MCP_LOG_LEVEL=info # debug, info, warn, error
MCP_AUTH_ENABLED=false
MCP_API_KEY=secret-key

# Optional: Embedding (for semantic search)
OPENAI_API_KEY=sk-...

# Optional: Fact extraction
MCP_EXTRACT_FACTS=false
MCP_FACT_MIN_CONFIDENCE=0.7

# Optional: Graph DB
GRAPH_DB_ENABLED=false
GRAPH_DB_URI=bolt://localhost:7687
GRAPH_DB_USER=neo4j
GRAPH_DB_PASSWORD=password

Programmatic Control

import { CortexMCPServer } from "@cortex-platform/mcp-server";

const server = new CortexMCPServer({
port: 3000,
convexUrl: process.env.CONVEX_URL,

// Optional features
auth: {
enabled: true,
apiKey: "secret-key-here",
},

cors: {
enabled: true,
origins: ["http://localhost:*"],
},

logging: {
enabled: true,
verbose: false,
logFile: "cortex-mcp.log",
},

embedding: {
provider: "openai",
apiKey: process.env.OPENAI_API_KEY,
},

factExtraction: {
enabled: true,
autoExtract: false, // Manual trigger only
},
});

await server.start();

console.log("MCP Server ready on http://localhost:3000");

Cloud Mode: Premium MCP

Hosted MCP Endpoint

Instead of running locally, use Cortex Cloud's managed MCP:

// No local server needed!
// Configure clients to use Cloud MCP

// Cursor: .cursor/mcp-config.json
{
"memory": {
"provider": "cortex-cloud",
"endpoint": "https://mcp.cortex.cloud/v1",
"api_key": "cortex_sk_your_api_key_here",
"user_id": "${USER_EMAIL}"
}
}

// Claude Desktop
{
"mcpServers": {
"cortex-cloud": {
"url": "https://mcp.cortex.cloud/v1",
"auth": {
"type": "bearer",
"token": "cortex_sk_your_api_key_here"
}
}
}
}

Premium Features via MCP

Auto-Embeddings:

// Client request
POST https://mcp.cortex.cloud/v1/add_memories
{
"memory": "User prefers React",
"user_id": "user-123",
"auto_embed": true // ← Cortex Cloud generates embedding
}

// No OPENAI_API_KEY needed! ✅

Auto-Fact-Extraction:

POST https://mcp.cortex.cloud/v1/add_memories
{
"messages": [
{ "role": "user", "content": "I work at Acme Corp as a senior engineer" }
],
"user_id": "user-123",
"auto_extract_facts": true // ← Cortex extracts facts automatically
}

// Cortex Cloud:
// 1. Stores raw in ACID
// 2. Extracts facts: "User works at Acme Corp", "User's role: Senior Engineer"
// 3. Stores facts in immutable + vector
// 4. Returns memory IDs

GDPR Cascade:

POST https://mcp.cortex.cloud/v1/delete_all_memories
{
"user_id": "user-123",
"cascade": true // ← Deletes from ALL stores (Cloud Mode only)
}

// Removes data from conversations, immutable, mutable, vector ✅

Graph Queries (Graph-Premium):

POST https://mcp.cortex.cloud/v1/graph/traverse
{
"start": { "type": "user", "id": "user-123" },
"relationships": ["CREATED", "TRIGGERED"],
"max_depth": 5,
"user_id": "user-123"
}

// Returns connected entities from graph DB

Premium Benefits

FeatureFree (Localhost)Premium (Cloud)
AvailabilityOnly when local server runningAlways available (99.9% uptime)
SetupMust run server locallyZero setup (cloud endpoint)
EmbeddingBring your own API keyAuto-generated (no key needed)
Fact ExtractionManual (DIY)Automatic
GDPR CascadeManual deletionOne-click cascade
Graph QueriesIf you run graph DBIncluded (Graph-Premium tier)
Team SharingSingle user (localhost)Organization-wide memory
AuthenticationOptional localAPI key + SSO/SAML
AnalyticsNoneFull dashboard
SupportCommunityPriority email

Pricing:

  • Free: Open-source server (Direct Mode)
  • Pro: $49/month (includes Cloud MCP endpoint)
  • Scale: $199/month (team collaboration features)
  • Enterprise: $999/month (SSO, unlimited, SLA)

Protocol Specification

Request Format

All endpoints accept JSON POST (or GET where noted):

// Standard fields
{
"user_id": string, // Required: User identifier
"agent_id"?: string, // Optional: Agent scope (default: 'mcp-agent')
"session_id"?: string, // Optional: Session scope
"metadata"?: object // Optional: Custom metadata
}

Response Format

// Success response
{
"success": true,
"data": { /* endpoint-specific data */ }
}

// Error response
{
"success": false,
"error": "Error message",
"code": "ERROR_CODE"
}

Supported Endpoints

EndpointMethodPurposeAuth
/healthGETServer healthNo
/add_memoriesPOSTStore memoriesOptional
/search_memoryPOSTSearchOptional
/list_memoriesGETList all/recentOptional
/delete_all_memoriesPOSTClear user memoriesOptional
/get_memoryGETGet by IDOptional
/update_memoryPOSTUpdate specific memoryOptional
/delete_memoryDELETEDelete specific memoryOptional

Data Isolation

Per-User Memory

// User A stores preference
POST /add_memories
{
"memory": "I prefer vim keybindings",
"user_id": "alice@example.com"
}

// User B stores different preference
POST /add_memories
{
"memory": "I prefer VS Code keybindings",
"user_id": "bob@example.com"
}

// Searches are isolated
POST /search_memory
{
"query": "keybinding preference",
"user_id": "alice@example.com"
}
// Returns: "I prefer vim keybindings" (Alice's only) ✅

POST /search_memory
{
"query": "keybinding preference",
"user_id": "bob@example.com"
}
// Returns: "I prefer VS Code keybindings" (Bob's only) ✅

Per-Agent Memory (Optional)

// Coding assistant memory
POST /add_memories
{
"memory": "User prefers React",
"user_id": "user-123",
"agent_id": "code-assistant"
}

// Writing assistant memory
POST /add_memories
{
"memory": "User prefers formal tone",
"user_id": "user-123",
"agent_id": "writing-assistant"
}

// Search scoped to agent
POST /search_memory
{
"query": "user preferences",
"user_id": "user-123",
"agent_id": "code-assistant"
}
// Returns: "User prefers React" (code-assistant's memory)

Security

Local Security (Free)

Localhost binding:

  • Server binds to 127.0.0.1 only by default
  • Only local applications can access
  • No password needed (trusted local environment)

Optional authentication:

# Start with auth enabled
cortex-mcp-server --convex-url=$CONVEX_URL --auth --api-key=secret-key

# Clients must provide API key
curl -H "Authorization: Bearer secret-key" \
-X POST http://localhost:3000/search_memory \
-d '{"query": "...", "user_id": "..."}'

Cloud Security (Premium)

API Key Authentication:

{
"mcpServers": {
"cortex-cloud": {
"url": "https://mcp.cortex.cloud/v1",
"auth": {
"type": "bearer",
"token": "cortex_sk_abc123..."
}
}
}
}

SSO/SAML (Enterprise):

  • Organization-wide authentication
  • Okta, Azure AD, Google Workspace
  • Role-based access control
  • Audit logging of all MCP requests

Performance

Local MCP Server

Latency:

  • add_memories: 20-50ms
  • search_memory: 50-150ms (depends on embedding)
  • list_memories: 10-30ms
  • delete_all: 50-200ms

Throughput:

  • ~100-200 requests/second (single process)
  • Can run multiple instances if needed

Caching:

  • Search results cached for 60s
  • Embeddings cached (common queries)
  • Reduces Convex queries

Cloud MCP Endpoint

Latency:

  • add_memories: 100-200ms (includes auto-embed if enabled)
  • search_memory: 80-150ms (auto-embed + search)
  • Global CDN reduces network latency

Scalability:

  • Auto-scales to demand
  • No query limits
  • Built-in rate limiting

Monitoring

Local Server Logs

# Start with verbose logging
cortex-mcp-server --convex-url=$CONVEX_URL --log-level=debug

# Logs show:
[MCP] POST /add_memories - user: user-123
[MCP] Stored memory: mem_abc123
[MCP] POST /search_memory - user: user-123, query: "preferences"
[MCP] Found 3 results in 45ms

Metrics Endpoint

# Get server stats
curl http://localhost:3000/metrics

{
"uptime": 3600,
"total_requests": 1543,
"requests_by_endpoint": {
"/add_memories": 890,
"/search_memory": 543,
"/list_memories": 110
},
"unique_users": 12,
"avg_response_time": 67,
"cache_hit_rate": 0.34
}

Cloud Mode Analytics

Premium users get full analytics dashboard:

  • Request volume over time
  • Popular queries
  • User engagement
  • Storage usage
  • Cost attribution
  • Error rates

Use Cases

Use Case 1: Cross-IDE Preferences

Scenario: Use multiple coding tools

1. In Cursor: "I prefer 2-space indentation"
→ Stores in MCP

2. Later, in Windsurf: Ask AI to generate code
→ Windsurf queries MCP, gets "2-space indentation" preference
→ Generates code with correct indentation ✅

3. In Claude: "Help me write a config file"
→ Claude queries MCP, knows your preferences
→ Suggests 2-space indent ✅

Use Case 2: Personal Knowledge Base

Scenario: Accumulate knowledge across tools

Day 1 (Cursor): "I'm working on Project Apollo, a React app"
Day 3 (Claude): "Project Apollo uses PostgreSQL database"
Day 7 (Custom tool): "Apollo's API is at api.apollo.com"

Day 10 (Any tool): "Tell me about Project Apollo"
→ MCP returns all accumulated facts:
- React app
- PostgreSQL database
- API endpoint

All tools have complete context! ✅

Use Case 3: Team Collaboration (Premium)

Scenario: Shared team memory

Setup: Team members all use Premium MCP with org account

Engineer A (Cursor): "We decided to use TypeScript for backend"
→ Stores in team's shared Cortex

Engineer B (Claude): "What's our backend tech stack?"
→ Claude queries team MCP
→ Returns: "Team decided to use TypeScript for backend"
→ Consistent team knowledge ✅

PM (Custom tool): Search for "technical decisions"
→ Gets all team's engineering decisions
→ Aligned context across team ✅

Limitations and Considerations

Local Server Limitations

Must be running:

  • Server must be active for AI tools to access memory
  • If server stops, tools lose memory access
  • Consider running as system service (systemd, launchd)

Single machine:

  • Localhost server = single machine only
  • Can't share across devices
  • (Use Cloud Mode for cross-device memory)

No automatic sync:

  • Each machine runs separate MCP server
  • Memories don't sync between machines
  • (Use Cloud Mode for unified memory everywhere)

Performance Considerations

Embedding generation:

  • Requires API key (OpenAI, etc.) for semantic search
  • Without embeddings, falls back to keyword search (less accurate)
  • Cloud Mode handles embeddings automatically

Storage costs:

  • All data stored in your Convex instance
  • Grows with usage (typical: 1-10MB per user)
  • Monitor Convex usage and costs

Rate limits:

  • Convex has rate limits (usually generous)
  • If many AI tools hitting MCP simultaneously, could hit limits
  • Cloud Mode has higher limits

Troubleshooting

Server Won't Start

Check Convex URL:

# Test Convex connectivity
curl https://your-project.convex.cloud/api/query

# If fails, check CONVEX_URL is correct

Check port availability:

# Port 3000 already in use?
lsof -i :3000

# Use different port
cortex-mcp-server --port=3001

AI Client Can't Connect

Verify server running:

curl http://localhost:3000/health

# Should return:
{"status": "ok", "version": "1.0.0"}

Check client configuration:

  • Ensure endpoint URL is correct (http://localhost:3000, not https)
  • Verify user_id is set
  • Check client supports MCP (Cursor, Claude Desktop do)

Test directly:

# Add a memory
curl -X POST http://localhost:3000/add_memories \
-H "Content-Type: application/json" \
-d '{"memory": "test memory", "user_id": "test-user"}'

# Search for it
curl -X POST http://localhost:3000/search_memory \
-H "Content-Type: application/json" \
-d '{"query": "test", "user_id": "test-user"}'

# Should return the memory

Check user_id:

  • Ensure same user_id used for add and search
  • MCP isolates by user_id strictly

Best Practices

1. Use Meaningful user_id

// ✅ Good: Stable identifier
user_id: "alice@example.com";
user_id: "user-stable-uuid-123";

// ❌ Bad: Changing identifier
user_id: "session-temp-abc"; // Changes each session
user_id: Math.random(); // Different every time

2. Add Metadata for Context

// Enrich memories with metadata
POST /add_memories
{
"memory": "User prefers TypeScript",
"user_id": "user-123",
"metadata": {
"source": "cursor",
"project": "apollo",
"importance": 80,
"tags": ["preference", "programming"]
}
}

// Filter searches by metadata
POST /search_memory
{
"query": "programming preferences",
"user_id": "user-123",
"metadata": {
"project": "apollo" // Only project-specific prefs
}
}

3. Periodic Cleanup

// Clean up old session-specific memories
async function cleanupOldSessions() {
// Get sessions older than 30 days
const oldSessions = await cortex.memory.list("mcp-agent", {
metadata: {
temporary: true,
expiresAt: { $lt: Date.now() },
},
});

// Delete them
for (const memory of oldSessions.memories) {
await cortex.memory.delete("mcp-agent", memory.id);
}
}

// Run daily
setInterval(cleanupOldSessions, 24 * 60 * 60 * 1000);

4. Monitor Usage

# Check metrics regularly
curl http://localhost:3000/metrics

# Watch for:
# - High request rates (might need scaling)
# - Low cache hit rate (tune cache settings)
# - High error rate (investigate issues)

Advanced Features

Custom MCP Client

Build your own MCP client:

class CortexMCPClient {
constructor(
private endpoint: string,
private userId: string,
) {}

async addMemory(content: string, metadata?: any) {
const response = await fetch(`${this.endpoint}/add_memories`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
memory: content,
user_id: this.userId,
metadata,
}),
});

return await response.json();
}

async search(query: string, limit = 5) {
const response = await fetch(`${this.endpoint}/search_memory`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
query,
user_id: this.userId,
limit,
}),
});

const data = await response.json();
return data.results;
}

async list(limit = 50) {
const response = await fetch(
`${this.endpoint}/list_memories?user_id=${this.userId}&limit=${limit}`,
);

return await response.json();
}

async deleteAll() {
const response = await fetch(`${this.endpoint}/delete_all_memories`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
user_id: this.userId,
}),
});

return await response.json();
}
}

// Usage
const mcp = new CortexMCPClient("http://localhost:3000", "user-123");

await mcp.addMemory("I like TypeScript");
const results = await mcp.search("programming preferences");
console.log(results);

Running as System Service

macOS (launchd):

<!-- ~/Library/LaunchAgents/com.cortex.mcp.plist -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.cortex.mcp</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/cortex-mcp-server</string>
<string>--convex-url=https://your-project.convex.cloud</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
# Load service
launchctl load ~/Library/LaunchAgents/com.cortex.mcp.plist

# Start
launchctl start com.cortex.mcp

Linux (systemd):

# /etc/systemd/system/cortex-mcp.service
[Unit]
Description=Cortex MCP Server
After=network.target

[Service]
Type=simple
User=your-user
Environment="CONVEX_URL=https://your-project.convex.cloud"
ExecStart=/usr/bin/cortex-mcp-server
Restart=always

[Install]
WantedBy=multi-user.target
# Enable and start
sudo systemctl enable cortex-mcp
sudo systemctl start cortex-mcp

# Check status
sudo systemctl status cortex-mcp

Roadmap

Current (v1.0)

  • ✅ Core MCP endpoints (add, search, list, delete)
  • ✅ Free local server
  • ✅ Basic authentication
  • ✅ Cursor and Claude compatibility

Near-Term (v1.1)

  • Premium Cloud endpoint
  • Auto-embedding support
  • Fact extraction integration
  • Enhanced metadata filtering
  • Server-Sent Events (SSE) for real-time updates

Future (v2.0)

  • Graph query pass-through (if graph DB connected)
  • Team collaboration features (Premium)
  • Cross-device sync
  • Mobile app support
  • Browser extension

Next Steps


Questions? Ask in GitHub Discussions or Discord.