Skip to main content
Glama
leog25

MCP Memory Server

by leog25
README.md
# MCP Memory Server

A streamable HTTPS (SSE) MCP server with personal memory layer using AWS ECS Fargate, RDS PostgreSQL, and OpenSearch Serverless for vector search.

## Features

- **MCP Tools**: `find_person`, `get_profile`, `remember_note`, `semantic_search`
- **SSE Transport**: Streaming responses over HTTPS
- **Relational Storage**: AWS RDS PostgreSQL for structured data
- **Vector Search**: OpenSearch Serverless with k-NN for semantic search
- **Embeddings**: AWS Bedrock Titan for text embeddings
- **Secure**: Bearer token auth, VPC isolation, IAM roles

## Quick Start

### Local Development

1. **Install dependencies**:
```bash
npm install
```

2. **Start PostgreSQL**:
```bash
docker-compose up -d postgres
```

3. **Run migrations**:
```bash
docker exec -i mcp-postgres psql -U postgres -d memory < sql/001_schema.sql
docker exec -i mcp-postgres psql -U postgres -d memory < sql/002_seed_data.sql
```

4. **Configure environment**:
```bash
cp .env.example .env
# Edit .env with your AWS credentials
```

5. **Start dev server**:
```bash
npm run dev
```

### AWS Deployment

1. **Configure AWS SSO**:
```bash
aws sso login --profile leogao
```

2. **Build and push Docker image**:
```bash
# Get AWS account ID
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
AWS_REGION=us-east-1

# Build image
docker build -t mcp-memory:latest .

# Login to ECR
aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com

# Create repository (if needed)
aws ecr create-repository --repository-name mcp-memory-prod-app --region $AWS_REGION

# Push image
docker tag mcp-memory:latest $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/mcp-memory-prod-app:latest
docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/mcp-memory-prod-app:latest
```

3. **Deploy infrastructure with Terraform**:
```bash
cd terraform

# Initialize Terraform
terraform init

# Create terraform.tfvars
cp terraform.tfvars.example terraform.tfvars
# Edit terraform.tfvars with your values

# Plan deployment
terraform plan

# Apply infrastructure
terraform apply
```

4. **Update ECS service** (for subsequent deployments):
```bash
./scripts/deploy.sh
```

## Connecting from Claude

Configure your Claude client with the MCP SSE endpoint:

```json
{
  "mcpServers": {
    "mcp-memory": {
      "transport": {
        "type": "sse",
        "url": "https://your-domain.com/mcp/sse",
        "accessToken": "your-auth-token"
      }
    }
  }
}
```

## Architecture

```
┌─────────────┐     ┌─────────────┐     ┌──────────────┐
│   Claude    │────▶│     ALB     │────▶│  ECS Fargate │
└─────────────┘     └─────────────┘     └──────────────┘
                           │                     │
                           │              ┌──────▼──────┐
                           │              │     RDS     │
                           │              │  PostgreSQL │
                           │              └─────────────┘
                           │                     │
                           │              ┌──────▼──────┐
                           │              │  OpenSearch │
                           │              │  Serverless │
                           │              └─────────────┘
                           │                     │
                           │              ┌──────▼──────┐
                           └──────────────│   Bedrock   │
                                         │   Titan     │
                                         └─────────────┘
```

## Available Tools

### find_person
Search for people by name, email, or organization.

### get_profile
Retrieve detailed profile with attributes and recent notes.

### remember_note
Add a note to an entity and index it for semantic search.

### semantic_search
Search notes semantically using vector similarity.

## Environment Variables

- `PORT`: Server port (default: 8080)
- `AUTH_TOKEN`: Bearer token for authentication
- `PG_URL`: PostgreSQL connection string
- `OPENSEARCH_URL`: OpenSearch endpoint
- `OPENSEARCH_INDEX`: Index name for vector search
- `BEDROCK_REGION`: AWS region for Bedrock
- `AWS_PROFILE`: AWS profile for local development

## Monitoring

- **CloudWatch Logs**: `/ecs/mcp-memory-prod`
- **ECS Console**: Monitor service health and tasks
- **RDS Metrics**: Database performance insights
- **ALB Target Health**: Check target group health

## Security Considerations

- All traffic encrypted with TLS
- Private subnets for compute and data
- IAM roles with least privilege
- Secrets in AWS Secrets Manager
- VPC security groups restrict access

## Troubleshooting

### Stream drops after ~60s
Increase ALB idle timeout in Terraform:
```hcl
idle_timeout = 300  # 5 minutes
```

### 401 Unauthorized
Check AUTH_TOKEN in Secrets Manager matches client config.

### OpenSearch returns empty
Verify index created with k-NN enabled and embeddings are being generated.

## License

MIT

Maintenance

ActivityInactive
ResponsivenessNo issues