@twelvehart/supermemory-runtime 1.0.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +57 -0
- package/README.md +374 -0
- package/dist/index.js +189 -0
- package/dist/mcp/index.js +1132 -0
- package/docker-compose.prod.yml +91 -0
- package/docker-compose.yml +358 -0
- package/drizzle/0000_dapper_the_professor.sql +159 -0
- package/drizzle/0001_api_keys.sql +51 -0
- package/drizzle/meta/0000_snapshot.json +1532 -0
- package/drizzle/meta/_journal.json +13 -0
- package/drizzle.config.ts +20 -0
- package/package.json +114 -0
- package/scripts/add-extraction-job.ts +122 -0
- package/scripts/benchmark-pgvector.ts +122 -0
- package/scripts/bootstrap.sh +209 -0
- package/scripts/check-runtime-pack.ts +111 -0
- package/scripts/claude-mcp-config.ts +336 -0
- package/scripts/docker-entrypoint.sh +183 -0
- package/scripts/doctor.ts +377 -0
- package/scripts/init-db.sql +33 -0
- package/scripts/install.sh +1110 -0
- package/scripts/mcp-setup.ts +271 -0
- package/scripts/migrations/001_create_pgvector_extension.sql +31 -0
- package/scripts/migrations/002_create_memory_embeddings_table.sql +75 -0
- package/scripts/migrations/003_create_hnsw_index.sql +94 -0
- package/scripts/migrations/004_create_memory_embeddings_standalone.sql +70 -0
- package/scripts/migrations/005_create_chunks_table.sql +95 -0
- package/scripts/migrations/006_create_processing_queue.sql +45 -0
- package/scripts/migrations/generate_test_data.sql +42 -0
- package/scripts/migrations/phase1_comprehensive_test.sql +204 -0
- package/scripts/migrations/run_migrations.sh +286 -0
- package/scripts/migrations/test_hnsw_index.sql +255 -0
- package/scripts/pre-commit-secrets +282 -0
- package/scripts/run-extraction-worker.ts +46 -0
- package/scripts/run-phase1-tests.sh +291 -0
- package/scripts/setup.ts +222 -0
- package/scripts/smoke-install.sh +12 -0
- package/scripts/test-health-endpoint.sh +328 -0
- package/src/api/index.ts +2 -0
- package/src/api/middleware/auth.ts +80 -0
- package/src/api/middleware/csrf.ts +308 -0
- package/src/api/middleware/errorHandler.ts +166 -0
- package/src/api/middleware/rateLimit.ts +360 -0
- package/src/api/middleware/validation.ts +514 -0
- package/src/api/routes/documents.ts +286 -0
- package/src/api/routes/profiles.ts +237 -0
- package/src/api/routes/search.ts +71 -0
- package/src/api/stores/index.ts +58 -0
- package/src/config/bootstrap-env.ts +3 -0
- package/src/config/env.ts +71 -0
- package/src/config/feature-flags.ts +25 -0
- package/src/config/index.ts +140 -0
- package/src/config/secrets.config.ts +291 -0
- package/src/db/client.ts +92 -0
- package/src/db/index.ts +73 -0
- package/src/db/postgres.ts +72 -0
- package/src/db/schema/chunks.schema.ts +31 -0
- package/src/db/schema/containers.schema.ts +46 -0
- package/src/db/schema/documents.schema.ts +49 -0
- package/src/db/schema/embeddings.schema.ts +32 -0
- package/src/db/schema/index.ts +11 -0
- package/src/db/schema/memories.schema.ts +72 -0
- package/src/db/schema/profiles.schema.ts +34 -0
- package/src/db/schema/queue.schema.ts +59 -0
- package/src/db/schema/relationships.schema.ts +42 -0
- package/src/db/schema.ts +223 -0
- package/src/db/worker-connection.ts +47 -0
- package/src/index.ts +235 -0
- package/src/mcp/CLAUDE.md +1 -0
- package/src/mcp/index.ts +1380 -0
- package/src/mcp/legacyState.ts +22 -0
- package/src/mcp/rateLimit.ts +358 -0
- package/src/mcp/resources.ts +309 -0
- package/src/mcp/results.ts +104 -0
- package/src/mcp/tools.ts +401 -0
- package/src/queues/config.ts +119 -0
- package/src/queues/index.ts +289 -0
- package/src/sdk/client.ts +225 -0
- package/src/sdk/errors.ts +266 -0
- package/src/sdk/http.ts +560 -0
- package/src/sdk/index.ts +244 -0
- package/src/sdk/resources/base.ts +65 -0
- package/src/sdk/resources/connections.ts +204 -0
- package/src/sdk/resources/documents.ts +163 -0
- package/src/sdk/resources/index.ts +10 -0
- package/src/sdk/resources/memories.ts +150 -0
- package/src/sdk/resources/search.ts +60 -0
- package/src/sdk/resources/settings.ts +36 -0
- package/src/sdk/types.ts +674 -0
- package/src/services/chunking/index.ts +451 -0
- package/src/services/chunking.service.ts +650 -0
- package/src/services/csrf.service.ts +252 -0
- package/src/services/documents.repository.ts +219 -0
- package/src/services/documents.service.ts +191 -0
- package/src/services/embedding.service.ts +404 -0
- package/src/services/extraction.service.ts +300 -0
- package/src/services/extractors/code.extractor.ts +451 -0
- package/src/services/extractors/index.ts +9 -0
- package/src/services/extractors/markdown.extractor.ts +461 -0
- package/src/services/extractors/pdf.extractor.ts +315 -0
- package/src/services/extractors/text.extractor.ts +118 -0
- package/src/services/extractors/url.extractor.ts +243 -0
- package/src/services/index.ts +235 -0
- package/src/services/ingestion.service.ts +177 -0
- package/src/services/llm/anthropic.ts +400 -0
- package/src/services/llm/base.ts +460 -0
- package/src/services/llm/contradiction-detector.service.ts +526 -0
- package/src/services/llm/heuristics.ts +148 -0
- package/src/services/llm/index.ts +309 -0
- package/src/services/llm/memory-classifier.service.ts +383 -0
- package/src/services/llm/memory-extension-detector.service.ts +523 -0
- package/src/services/llm/mock.ts +470 -0
- package/src/services/llm/openai.ts +398 -0
- package/src/services/llm/prompts.ts +438 -0
- package/src/services/llm/types.ts +373 -0
- package/src/services/memory.repository.ts +1769 -0
- package/src/services/memory.service.ts +1338 -0
- package/src/services/memory.types.ts +234 -0
- package/src/services/persistence/index.ts +295 -0
- package/src/services/pipeline.service.ts +509 -0
- package/src/services/profile.repository.ts +436 -0
- package/src/services/profile.service.ts +560 -0
- package/src/services/profile.types.ts +270 -0
- package/src/services/relationships/detector.ts +1128 -0
- package/src/services/relationships/index.ts +268 -0
- package/src/services/relationships/memory-integration.ts +459 -0
- package/src/services/relationships/strategies.ts +132 -0
- package/src/services/relationships/types.ts +370 -0
- package/src/services/search.service.ts +761 -0
- package/src/services/search.types.ts +220 -0
- package/src/services/secrets.service.ts +384 -0
- package/src/services/vectorstore/base.ts +327 -0
- package/src/services/vectorstore/index.ts +444 -0
- package/src/services/vectorstore/memory.ts +286 -0
- package/src/services/vectorstore/migration.ts +295 -0
- package/src/services/vectorstore/mock.ts +403 -0
- package/src/services/vectorstore/pgvector.ts +695 -0
- package/src/services/vectorstore/types.ts +247 -0
- package/src/startup.ts +389 -0
- package/src/types/api.types.ts +193 -0
- package/src/types/document.types.ts +103 -0
- package/src/types/index.ts +241 -0
- package/src/types/profile.base.ts +133 -0
- package/src/utils/errors.ts +447 -0
- package/src/utils/id.ts +15 -0
- package/src/utils/index.ts +101 -0
- package/src/utils/logger.ts +313 -0
- package/src/utils/sanitization.ts +501 -0
- package/src/utils/secret-validation.ts +273 -0
- package/src/utils/synonyms.ts +188 -0
- package/src/utils/validation.ts +581 -0
- package/src/workers/chunking.worker.ts +242 -0
- package/src/workers/embedding.worker.ts +358 -0
- package/src/workers/extraction.worker.ts +346 -0
- package/src/workers/indexing.worker.ts +505 -0
- package/tsconfig.json +38 -0
package/.env.example
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Supermemory Clone - Environment Configuration
|
|
2
|
+
# Copy to `.env` and adjust for your local setup.
|
|
3
|
+
|
|
4
|
+
# -----------------------------------------------------------------------------
|
|
5
|
+
# Core runtime (PostgreSQL required outside tests)
|
|
6
|
+
# -----------------------------------------------------------------------------
|
|
7
|
+
DATABASE_URL=postgresql://supermemory:supermemory_secret@localhost:15432/supermemory
|
|
8
|
+
API_HOST=localhost
|
|
9
|
+
API_PORT=13000
|
|
10
|
+
API_HOST_PORT=13000
|
|
11
|
+
LOG_LEVEL=info
|
|
12
|
+
|
|
13
|
+
# -----------------------------------------------------------------------------
|
|
14
|
+
# Optional REST API auth (disabled by default)
|
|
15
|
+
# -----------------------------------------------------------------------------
|
|
16
|
+
AUTH_ENABLED=false
|
|
17
|
+
AUTH_TOKEN=
|
|
18
|
+
|
|
19
|
+
# Optional CSRF hardening secret (recommended when auth is enabled)
|
|
20
|
+
CSRF_SECRET=
|
|
21
|
+
ALLOWED_ORIGINS=http://localhost:13000,http://localhost:15173
|
|
22
|
+
|
|
23
|
+
# -----------------------------------------------------------------------------
|
|
24
|
+
# Optional async pipeline (Redis/BullMQ)
|
|
25
|
+
# -----------------------------------------------------------------------------
|
|
26
|
+
REDIS_URL=redis://localhost:16379
|
|
27
|
+
POSTGRES_HOST_PORT=15432
|
|
28
|
+
REDIS_HOST_PORT=16379
|
|
29
|
+
BULLMQ_CONCURRENCY_EXTRACTION=5
|
|
30
|
+
BULLMQ_CONCURRENCY_CHUNKING=3
|
|
31
|
+
BULLMQ_CONCURRENCY_EMBEDDING=2
|
|
32
|
+
BULLMQ_CONCURRENCY_INDEXING=1
|
|
33
|
+
|
|
34
|
+
# -----------------------------------------------------------------------------
|
|
35
|
+
# Embeddings / LLM extraction (all optional)
|
|
36
|
+
# -----------------------------------------------------------------------------
|
|
37
|
+
OPENAI_API_KEY=
|
|
38
|
+
ANTHROPIC_API_KEY=
|
|
39
|
+
|
|
40
|
+
EMBEDDING_MODEL=text-embedding-3-small
|
|
41
|
+
EMBEDDING_DIMENSIONS=1536
|
|
42
|
+
|
|
43
|
+
# LLM provider: empty | openai | anthropic | mock
|
|
44
|
+
LLM_PROVIDER=
|
|
45
|
+
LLM_MODEL=
|
|
46
|
+
LLM_MAX_TOKENS=2000
|
|
47
|
+
LLM_TEMPERATURE=0.1
|
|
48
|
+
LLM_TIMEOUT_MS=30000
|
|
49
|
+
LLM_MAX_RETRIES=3
|
|
50
|
+
LLM_CACHE_ENABLED=true
|
|
51
|
+
LLM_CACHE_TTL_MS=900000
|
|
52
|
+
|
|
53
|
+
# -----------------------------------------------------------------------------
|
|
54
|
+
# API protections
|
|
55
|
+
# -----------------------------------------------------------------------------
|
|
56
|
+
RATE_LIMIT_REQUESTS=100
|
|
57
|
+
RATE_LIMIT_WINDOW_MS=60000
|
package/README.md
ADDED
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
# Supermemory Clone
|
|
2
|
+
|
|
3
|
+
Local-first memory service for developers and coding agents.
|
|
4
|
+
|
|
5
|
+
It stores documents, extracts memories, indexes embeddings, and serves search/profile APIs plus an MCP server for agent workflows.
|
|
6
|
+
|
|
7
|
+
## What It Does
|
|
8
|
+
|
|
9
|
+
- Ingests text and files into documents.
|
|
10
|
+
- Extracts memory units and profile facts.
|
|
11
|
+
- Supports semantic, memory, and hybrid search.
|
|
12
|
+
- Exposes REST API (`/api/v1/*`) and MCP tools (`supermemory_*`).
|
|
13
|
+
- Runs with PostgreSQL + pgvector; Redis is optional (queue path) because inline fallback is built in.
|
|
14
|
+
|
|
15
|
+
## Architecture (High Level)
|
|
16
|
+
|
|
17
|
+
- `src/index.ts`: Hono API server, middleware stack, route mounting.
|
|
18
|
+
- `src/api/routes/*`: documents, search, profiles endpoints.
|
|
19
|
+
- `src/services/*`: document processing, memory extraction, search, profile logic.
|
|
20
|
+
- `src/mcp/*`: MCP server, tools, resources, rate limiting.
|
|
21
|
+
- `src/db/*`: database client routing (PostgreSQL in runtime; SQLite only for tests).
|
|
22
|
+
- `src/queues/*` + `src/workers/*`: BullMQ pipeline (`extraction -> chunking -> embedding -> indexing`).
|
|
23
|
+
|
|
24
|
+
## Requirements
|
|
25
|
+
|
|
26
|
+
- Node.js >= 20
|
|
27
|
+
- Docker + Docker Compose
|
|
28
|
+
- PostgreSQL with pgvector
|
|
29
|
+
- Redis (optional but recommended for async workers)
|
|
30
|
+
|
|
31
|
+
## Quick Start (Turnkey)
|
|
32
|
+
|
|
33
|
+
Primary path for first-time users:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npx -y @twelvehart/supermemory@latest full --dir ./supermemory --mcp project
|
|
37
|
+
cd ./supermemory
|
|
38
|
+
claude
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
That command unpacks the runtime into `./supermemory`, runs the canonical `scripts/install.sh` from the final directory, registers Claude MCP against that final path, and prints only the next steps a new user can actually take.
|
|
42
|
+
|
|
43
|
+
The npx installer supports:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npx -y @twelvehart/supermemory@latest agent --dir ./supermemory-agent --mcp project
|
|
47
|
+
npx -y @twelvehart/supermemory@latest api --dir ./supermemory-api
|
|
48
|
+
npx -y @twelvehart/supermemory@latest full --dir ./supermemory --mcp project --skip-api-keys
|
|
49
|
+
npx -y @twelvehart/supermemory@latest full --dir ./supermemory --source-path "$(pwd)"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Maintainer-only override for a non-empty target directory:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npx -y @twelvehart/supermemory@latest full --dir ./supermemory --source-path "$(pwd)" --update
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Fallback transport for users who prefer reviewing remote scripts first:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
curl -fsSL https://raw.githubusercontent.com/ASRagab/supermemory-clone/main/scripts/bootstrap.sh | less
|
|
62
|
+
curl -fsSL https://raw.githubusercontent.com/ASRagab/supermemory-clone/main/scripts/bootstrap.sh | bash
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Local clone + canonical installer (fallback for contributors and maintainers):
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
git clone https://github.com/ASRagab/supermemory-clone.git
|
|
69
|
+
cd supermemory-clone
|
|
70
|
+
./scripts/install.sh full --scope project
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The in-repo shell installer remains canonical. `@twelvehart/supermemory` is the default transport and zero-knowledge entrypoint.
|
|
74
|
+
|
|
75
|
+
The canonical installer still supports explicit modes:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
./scripts/install.sh # same as: install --mode agent
|
|
79
|
+
./scripts/install.sh agent # agent-first MCP workflow
|
|
80
|
+
./scripts/install.sh api # REST API workflow
|
|
81
|
+
./scripts/install.sh full # both surfaces, explicit all-in path
|
|
82
|
+
./scripts/install.sh update --mode api
|
|
83
|
+
./scripts/install.sh agent --env-file /tmp/supermemory-agent.env
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Mode behavior:
|
|
87
|
+
|
|
88
|
+
- `agent`: installs dependencies, creates `.env`, starts PostgreSQL, builds the project, and prepares MCP usage without auto-starting the API.
|
|
89
|
+
- `api`: installs dependencies, creates `.env`, starts PostgreSQL + Redis + API, builds the project, and verifies API health.
|
|
90
|
+
- `full`: explicit all-surfaces install path. In the current implementation it shares the same container startup set as `api` but prints both API and MCP next steps.
|
|
91
|
+
|
|
92
|
+
The install/update flow handles:
|
|
93
|
+
|
|
94
|
+
- prerequisite checks (Node/Docker/Compose)
|
|
95
|
+
- `npm install`
|
|
96
|
+
- `.env` creation from `.env.example`
|
|
97
|
+
- optional API key prompts (or you can skip and configure later)
|
|
98
|
+
- mode-aware Docker startup + migrations
|
|
99
|
+
- non-conflicting local host ports by default (`13000`, `15432`, `16379`)
|
|
100
|
+
- build + optional Claude Code MCP registration
|
|
101
|
+
- connectivity check (`npm run doctor`)
|
|
102
|
+
|
|
103
|
+
Installer lifecycle commands:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
./scripts/install.sh install # default if command is omitted; defaults to --mode agent
|
|
107
|
+
./scripts/install.sh update # clean reinstall of app components; preserves postgres/redis data and attempts migrations
|
|
108
|
+
./scripts/install.sh uninstall # removes generated artifacts and stops local services
|
|
109
|
+
./scripts/install.sh uninstall --purge
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Optional flags:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
./scripts/install.sh --skip-api-keys --skip-mcp
|
|
116
|
+
./scripts/install.sh update --skip-docker
|
|
117
|
+
./scripts/install.sh install --mode api --skip-api-start
|
|
118
|
+
./scripts/install.sh --register-mcp --scope project
|
|
119
|
+
./scripts/install.sh --non-interactive # does not register MCP unless --scope or --register-mcp is also passed
|
|
120
|
+
./scripts/install.sh uninstall --purge # also removes env files, Claude MCP registrations, and docker volumes
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Manual path (if you skip parts of installer):
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
cp .env.example .env
|
|
127
|
+
npm run stack:up
|
|
128
|
+
./scripts/migrations/run_migrations.sh
|
|
129
|
+
npm run build
|
|
130
|
+
npm run doctor
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
After a clone-based `./scripts/install.sh agent` install, the API is not running yet. To start the MCP server manually:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
npm run mcp
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
If you want the REST API instead, use API mode:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
./scripts/install.sh api
|
|
143
|
+
curl http://localhost:13000/health
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
If you already installed in `api` or `full` mode, the API is running in Docker and ready to use:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
curl http://localhost:13000/health
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
If you prefer local watch mode instead of Docker for API runtime:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
docker compose stop api
|
|
156
|
+
npm run dev
|
|
157
|
+
curl http://localhost:13000/health
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Configuration
|
|
161
|
+
|
|
162
|
+
Copy `.env.example` to `.env` and set values.
|
|
163
|
+
|
|
164
|
+
Env file precedence is:
|
|
165
|
+
|
|
166
|
+
1. CLI `--env-file` for supported scripts
|
|
167
|
+
2. `SUPERMEMORY_ENV_FILE`
|
|
168
|
+
3. `.env.local`
|
|
169
|
+
4. `.env`
|
|
170
|
+
|
|
171
|
+
The API and MCP runtime honor `SUPERMEMORY_ENV_FILE`, then fall back to `.env.local`, then `.env`.
|
|
172
|
+
|
|
173
|
+
Examples:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
SUPERMEMORY_ENV_FILE=~/.config/supermemory/config.env npm run doctor -- --mode agent
|
|
177
|
+
npm run mcp:setup -- --env-file /tmp/supermemory-agent.env
|
|
178
|
+
./scripts/install.sh agent --env-file /tmp/supermemory-agent.env
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Required:
|
|
182
|
+
|
|
183
|
+
- `DATABASE_URL` (must be `postgres://` or `postgresql://` outside tests)
|
|
184
|
+
|
|
185
|
+
Optional:
|
|
186
|
+
|
|
187
|
+
- `AUTH_ENABLED`, `AUTH_TOKEN` (minimal bearer token auth)
|
|
188
|
+
- `REDIS_URL` (queues; if unavailable, ingestion falls back inline)
|
|
189
|
+
- `OPENAI_API_KEY` (embeddings)
|
|
190
|
+
- `LLM_PROVIDER`, `ANTHROPIC_API_KEY` (LLM extraction)
|
|
191
|
+
- `CSRF_SECRET`, `ALLOWED_ORIGINS` (hardening)
|
|
192
|
+
|
|
193
|
+
No external API keys are required for basic local operation.
|
|
194
|
+
Fresh installs leave provider keys and `LLM_PROVIDER` blank until you set real credentials.
|
|
195
|
+
|
|
196
|
+
## Auth and CSRF
|
|
197
|
+
|
|
198
|
+
- API auth is optional.
|
|
199
|
+
- `AUTH_ENABLED=false` (default): pass-through auth context.
|
|
200
|
+
- `AUTH_ENABLED=true`: requires `Authorization: Bearer <AUTH_TOKEN>`.
|
|
201
|
+
- CSRF protection is applied to API state-changing routes; use `GET /api/v1/csrf-token` first for browser clients.
|
|
202
|
+
|
|
203
|
+
## REST API Surface
|
|
204
|
+
|
|
205
|
+
Base path: `/api/v1`
|
|
206
|
+
|
|
207
|
+
- `POST /documents`
|
|
208
|
+
- `GET /documents`
|
|
209
|
+
- `GET /documents/:id`
|
|
210
|
+
- `PUT /documents/:id`
|
|
211
|
+
- `DELETE /documents/:id`
|
|
212
|
+
- `POST /documents/file`
|
|
213
|
+
- `POST /documents/bulk-delete`
|
|
214
|
+
- `POST /search`
|
|
215
|
+
- `GET /profiles`
|
|
216
|
+
- `GET /profiles/:tag`
|
|
217
|
+
- `PUT /profiles/:tag`
|
|
218
|
+
- `DELETE /profiles/:tag`
|
|
219
|
+
|
|
220
|
+
## MCP for Coding Agents
|
|
221
|
+
|
|
222
|
+
### Quick Setup
|
|
223
|
+
|
|
224
|
+
First-time user path:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
npx -y @twelvehart/supermemory@latest full --dir ./supermemory --mcp project
|
|
228
|
+
cd ./supermemory
|
|
229
|
+
claude
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Clone-based maintainer path:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
npm run mcp:setup
|
|
236
|
+
npm run mcp:setup -- --scope project --non-interactive --register-mcp
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Installation Options
|
|
240
|
+
|
|
241
|
+
**Option A — npx-first install**
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
npx -y @twelvehart/supermemory@latest full --dir ./supermemory --mcp project
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Option B — Manual registration with the setup helper**
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
npm run mcp:setup
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
**Option C — Project-scope registration**
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
npm run build
|
|
257
|
+
npm run mcp:setup -- --scope project --non-interactive --register-mcp
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**Option D — Direct Claude CLI registration**
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
npm run build
|
|
264
|
+
claude mcp add supermemory --scope user -- node "$(pwd)/dist/mcp/index.js"
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**Option E — Direct MCP package execution**
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
claude mcp add supermemory -- npx supermemory-mcp
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Prerequisites
|
|
274
|
+
|
|
275
|
+
- Node.js >= 20
|
|
276
|
+
- PostgreSQL with pgvector running (`docker compose up -d postgres`)
|
|
277
|
+
- Project built (`npm run build`)
|
|
278
|
+
|
|
279
|
+
### Environment Variables
|
|
280
|
+
|
|
281
|
+
| Variable | Required | Description |
|
|
282
|
+
|----------|----------|-------------|
|
|
283
|
+
| `DATABASE_URL` | Yes | PostgreSQL connection string |
|
|
284
|
+
| `OPENAI_API_KEY` | No | Enables embeddings and LLM features |
|
|
285
|
+
| `REDIS_URL` | No | Enables async queue workers |
|
|
286
|
+
| `LOG_LEVEL` | No | Logging verbosity (default: `info`) |
|
|
287
|
+
|
|
288
|
+
### Verification
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
npm run doctor -- --mode agent
|
|
292
|
+
npm run doctor -- --mode api
|
|
293
|
+
claude mcp get supermemory
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Troubleshooting
|
|
297
|
+
|
|
298
|
+
| Symptom | Fix |
|
|
299
|
+
|---------|-----|
|
|
300
|
+
| `dist/mcp/index.js` not found | Run `npm run build` |
|
|
301
|
+
| PostgreSQL connection refused | Start the container: `docker compose up -d postgres` |
|
|
302
|
+
| Port already in use | Check `API_PORT` in `.env` (default 13000) |
|
|
303
|
+
| MCP tools not appearing | Re-register: `npm run mcp:setup` |
|
|
304
|
+
|
|
305
|
+
### MCP Tools
|
|
306
|
+
|
|
307
|
+
- `supermemory_add`
|
|
308
|
+
- `supermemory_search`
|
|
309
|
+
- `supermemory_profile`
|
|
310
|
+
- `supermemory_list`
|
|
311
|
+
- `supermemory_delete`
|
|
312
|
+
- `supermemory_remember`
|
|
313
|
+
- `supermemory_recall`
|
|
314
|
+
|
|
315
|
+
## Development Commands
|
|
316
|
+
|
|
317
|
+
- `npm run dev` - API with watch mode
|
|
318
|
+
- `npm run build` - TypeScript build
|
|
319
|
+
- `npm run build:install` - Build `packages/install`
|
|
320
|
+
- `npm run start` - Run built API
|
|
321
|
+
- `npm run mcp:dev` - MCP with tsx
|
|
322
|
+
- `npm run mcp` - Run built MCP server
|
|
323
|
+
- `npm run stack:up` - Start API + Postgres + Redis containers
|
|
324
|
+
- `npm run stack:down` - Stop and remove stack containers
|
|
325
|
+
- `npm run stack:logs` - Tail API container logs
|
|
326
|
+
- `npm run test:run` - Full tests once
|
|
327
|
+
- `npm run test:install` - Installer-specific tests
|
|
328
|
+
- `npm run lint` - ESLint
|
|
329
|
+
- `npm run typecheck` - TS checks
|
|
330
|
+
- `npm run typecheck:install` - Installer package TS checks
|
|
331
|
+
- `npm run pack:check:runtime` - Verify the runtime npm tarball contents
|
|
332
|
+
- `npm run validate` - typecheck + lint + format + tests
|
|
333
|
+
|
|
334
|
+
## Testing
|
|
335
|
+
|
|
336
|
+
- Unit/integration tests: `vitest`
|
|
337
|
+
- Typical focused run:
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
npx vitest run tests/services/search.service.test.ts
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
- Database regression flow:
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
npm run db:test:phase1
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
## Publish and Smoke Release
|
|
350
|
+
|
|
351
|
+
Publish order:
|
|
352
|
+
|
|
353
|
+
1. Publish `@twelvehart/supermemory-runtime` from the repo root after `npm run build` and `npm run pack:check:runtime`.
|
|
354
|
+
2. Publish `@twelvehart/supermemory` from `packages/install` after `npm run build:install`, `npm run typecheck:install`, and `npm run test:install`.
|
|
355
|
+
|
|
356
|
+
Smoke-release procedure for the freshly published packages:
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
bash scripts/smoke-install.sh ./supermemory-smoke
|
|
360
|
+
cd ./supermemory-smoke
|
|
361
|
+
curl http://localhost:13000/health
|
|
362
|
+
claude
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
## Project Policy
|
|
366
|
+
|
|
367
|
+
Repository documentation is intentionally consolidated into only:
|
|
368
|
+
|
|
369
|
+
- `README.md` (project/system/operator reference)
|
|
370
|
+
- `AGENTS.md` (agent/contributor implementation reference)
|
|
371
|
+
|
|
372
|
+
## License
|
|
373
|
+
|
|
374
|
+
MIT
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import './config/bootstrap-env.js';
|
|
2
|
+
import { serve } from '@hono/node-server';
|
|
3
|
+
import { Hono } from 'hono';
|
|
4
|
+
import { cors } from 'hono/cors';
|
|
5
|
+
import { logger } from 'hono/logger';
|
|
6
|
+
import { prettyJSON } from 'hono/pretty-json';
|
|
7
|
+
import { timing } from 'hono/timing';
|
|
8
|
+
import pkg from 'pg';
|
|
9
|
+
import { config } from './config/index.js';
|
|
10
|
+
import { getDatabase } from './db/client.js';
|
|
11
|
+
// Import route modules
|
|
12
|
+
import { documentsRouter } from './api/routes/documents.js';
|
|
13
|
+
import { searchRouter } from './api/routes/search.js';
|
|
14
|
+
import { profilesRouter } from './api/routes/profiles.js';
|
|
15
|
+
import { authMiddleware } from './api/middleware/auth.js';
|
|
16
|
+
import { errorHandlerMiddleware } from './api/middleware/errorHandler.js';
|
|
17
|
+
import { standardRateLimit } from './api/middleware/rateLimit.js';
|
|
18
|
+
import { setCsrfCookie, csrfProtection } from './api/middleware/csrf.js';
|
|
19
|
+
import { initializeAndValidate } from './startup.js';
|
|
20
|
+
const { Pool } = pkg;
|
|
21
|
+
// Initialize database
|
|
22
|
+
const db = getDatabase();
|
|
23
|
+
let healthPool = null;
|
|
24
|
+
function getHealthPool() {
|
|
25
|
+
if (!healthPool) {
|
|
26
|
+
healthPool = new Pool({
|
|
27
|
+
connectionString: config.databaseUrl,
|
|
28
|
+
max: 1,
|
|
29
|
+
idleTimeoutMillis: 30000,
|
|
30
|
+
connectionTimeoutMillis: 2000,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return healthPool;
|
|
34
|
+
}
|
|
35
|
+
// Create Hono app
|
|
36
|
+
const app = new Hono();
|
|
37
|
+
// ============================================================================
|
|
38
|
+
// Global Middleware
|
|
39
|
+
// ============================================================================
|
|
40
|
+
// Error handler (must be first to catch all errors)
|
|
41
|
+
app.use('*', errorHandlerMiddleware);
|
|
42
|
+
// Request logging
|
|
43
|
+
app.use('*', logger());
|
|
44
|
+
// CORS configuration
|
|
45
|
+
app.use('*', cors({
|
|
46
|
+
origin: ['http://localhost:3000', 'http://localhost:5173'],
|
|
47
|
+
allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
|
48
|
+
allowHeaders: ['Content-Type', 'Authorization', 'X-Request-ID', 'X-CSRF-Token'],
|
|
49
|
+
exposeHeaders: ['X-RateLimit-Limit', 'X-RateLimit-Remaining', 'X-RateLimit-Reset'],
|
|
50
|
+
credentials: true,
|
|
51
|
+
maxAge: 86400,
|
|
52
|
+
}));
|
|
53
|
+
// Pretty JSON responses in development
|
|
54
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
55
|
+
app.use('*', prettyJSON());
|
|
56
|
+
}
|
|
57
|
+
// Request timing
|
|
58
|
+
app.use('*', timing());
|
|
59
|
+
// ============================================================================
|
|
60
|
+
// Health Check (No Auth Required)
|
|
61
|
+
// ============================================================================
|
|
62
|
+
app.get('/health', async (c) => {
|
|
63
|
+
const checks = {
|
|
64
|
+
status: 'healthy',
|
|
65
|
+
version: '1.0.0',
|
|
66
|
+
timestamp: new Date().toISOString(),
|
|
67
|
+
};
|
|
68
|
+
try {
|
|
69
|
+
const pool = getHealthPool();
|
|
70
|
+
await pool.query('SELECT 1');
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
checks.status = 'unhealthy';
|
|
74
|
+
}
|
|
75
|
+
const statusCode = checks.status === 'healthy' ? 200 : 503;
|
|
76
|
+
return c.json(checks, statusCode);
|
|
77
|
+
});
|
|
78
|
+
app.get('/', (c) => {
|
|
79
|
+
return c.json({
|
|
80
|
+
name: 'Supermemory Clone API',
|
|
81
|
+
version: '1.0.0',
|
|
82
|
+
description: 'Personal AI memory assistant with semantic search',
|
|
83
|
+
endpoints: {
|
|
84
|
+
documents: '/api/v1/documents',
|
|
85
|
+
search: '/api/v1/search',
|
|
86
|
+
profiles: '/api/v1/profiles',
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
// CSRF token endpoint for SPA clients
|
|
91
|
+
// Apply CSRF cookie middleware to provide token
|
|
92
|
+
app.get('/api/v1/csrf-token', setCsrfCookie(), (c) => {
|
|
93
|
+
const csrfToken = c.get('csrfToken');
|
|
94
|
+
return c.json({
|
|
95
|
+
csrfToken,
|
|
96
|
+
expiresIn: 3600, // 1 hour in seconds
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
// ============================================================================
|
|
100
|
+
// API Routes (Auth Required)
|
|
101
|
+
// ============================================================================
|
|
102
|
+
const api = new Hono();
|
|
103
|
+
// Apply middleware stack to all API routes
|
|
104
|
+
// Order: auth → CSRF → rate limit → routes
|
|
105
|
+
api.use('*', authMiddleware);
|
|
106
|
+
api.use('*', setCsrfCookie());
|
|
107
|
+
api.use('*', csrfProtection({
|
|
108
|
+
allowedOrigins: process.env.ALLOWED_ORIGINS?.split(',') || ['http://localhost:3000', 'http://localhost:5173'],
|
|
109
|
+
}));
|
|
110
|
+
api.use('*', standardRateLimit);
|
|
111
|
+
// Mount route modules
|
|
112
|
+
api.route('/documents', documentsRouter);
|
|
113
|
+
api.route('/search', searchRouter);
|
|
114
|
+
api.route('/profiles', profilesRouter);
|
|
115
|
+
// Mount API under versioned path
|
|
116
|
+
app.route('/api/v1', api);
|
|
117
|
+
// ============================================================================
|
|
118
|
+
// 404 Handler
|
|
119
|
+
// ============================================================================
|
|
120
|
+
app.notFound((c) => {
|
|
121
|
+
return c.json({
|
|
122
|
+
error: {
|
|
123
|
+
code: 'NOT_FOUND',
|
|
124
|
+
message: `Route ${c.req.method} ${c.req.path} not found`,
|
|
125
|
+
},
|
|
126
|
+
status: 404,
|
|
127
|
+
}, 404);
|
|
128
|
+
});
|
|
129
|
+
// ============================================================================
|
|
130
|
+
// Error Handler
|
|
131
|
+
// ============================================================================
|
|
132
|
+
app.onError((err, c) => {
|
|
133
|
+
console.error('Unhandled error:', err);
|
|
134
|
+
return c.json({
|
|
135
|
+
error: {
|
|
136
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
137
|
+
message: process.env.NODE_ENV === 'development' ? err.message : 'An unexpected error occurred',
|
|
138
|
+
},
|
|
139
|
+
status: 500,
|
|
140
|
+
}, 500);
|
|
141
|
+
});
|
|
142
|
+
// ============================================================================
|
|
143
|
+
// Start Server
|
|
144
|
+
// ============================================================================
|
|
145
|
+
const port = config.apiPort;
|
|
146
|
+
const host = config.apiHost;
|
|
147
|
+
console.log(`
|
|
148
|
+
================================================
|
|
149
|
+
Supermemory Clone API Server
|
|
150
|
+
================================================
|
|
151
|
+
Version: 1.0.0
|
|
152
|
+
Port: ${port}
|
|
153
|
+
Host: ${host}
|
|
154
|
+
Environment: ${process.env.NODE_ENV ?? 'development'}
|
|
155
|
+
================================================
|
|
156
|
+
|
|
157
|
+
Available endpoints:
|
|
158
|
+
GET / - API info
|
|
159
|
+
GET /health - Health check
|
|
160
|
+
|
|
161
|
+
POST /api/v1/documents - Create document
|
|
162
|
+
GET /api/v1/documents - List documents
|
|
163
|
+
GET /api/v1/documents/:id - Get document
|
|
164
|
+
PUT /api/v1/documents/:id - Update document
|
|
165
|
+
DELETE /api/v1/documents/:id - Delete document
|
|
166
|
+
POST /api/v1/documents/file - Upload file
|
|
167
|
+
POST /api/v1/documents/bulk-delete - Bulk delete
|
|
168
|
+
|
|
169
|
+
POST /api/v1/search - Search documents
|
|
170
|
+
|
|
171
|
+
GET /api/v1/profiles - List profiles
|
|
172
|
+
GET /api/v1/profiles/:tag - Get profile
|
|
173
|
+
PUT /api/v1/profiles/:tag - Update profile
|
|
174
|
+
DELETE /api/v1/profiles/:tag - Delete profile
|
|
175
|
+
`);
|
|
176
|
+
async function startServer() {
|
|
177
|
+
await initializeAndValidate();
|
|
178
|
+
serve({
|
|
179
|
+
fetch: app.fetch,
|
|
180
|
+
port,
|
|
181
|
+
hostname: host,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
startServer().catch((error) => {
|
|
185
|
+
console.error('Failed to start API server:', error);
|
|
186
|
+
process.exit(1);
|
|
187
|
+
});
|
|
188
|
+
export { app, db };
|
|
189
|
+
//# sourceMappingURL=index.js.map
|