@nacho-labs/mcp-semantic-search 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nacho Labs LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,174 @@
1
+ # @nacho-labs/mcp-semantic-search
2
+
3
+ MCP server that gives AI coding tools persistent semantic memory. Index
4
+ decisions, patterns, and project context — recall them by meaning, not keywords.
5
+
6
+ Powered by [@nacho-labs/nachos-embeddings](https://github.com/nacho-labs-llc/nachos-embeddings).
7
+ Runs entirely locally with [Transformers.js](https://huggingface.co/docs/transformers.js) —
8
+ no API keys, no cloud, no costs.
9
+
10
+ ## Prerequisites
11
+
12
+ - **Node.js 18+**
13
+ - **Internet on first run** to download the embedding model (~25MB, cached permanently)
14
+
15
+ ## Quick start
16
+
17
+ ### Claude Code
18
+
19
+ ```bash
20
+ claude mcp add --transport stdio semantic-search -- npx @nacho-labs/mcp-semantic-search
21
+ ```
22
+
23
+ ### Cursor / VS Code / any MCP client
24
+
25
+ Add to your MCP config (`.mcp.json`, `mcp.json`, or client-specific config):
26
+
27
+ ```json
28
+ {
29
+ "mcpServers": {
30
+ "semantic-search": {
31
+ "type": "stdio",
32
+ "command": "npx",
33
+ "args": ["@nacho-labs/mcp-semantic-search"]
34
+ }
35
+ }
36
+ }
37
+ ```
38
+
39
+ That's it. Your AI tool now has six semantic memory tools.
40
+
41
+ ## Tools
42
+
43
+ | Tool | Description |
44
+ | ---- | ----------- |
45
+ | `semantic_search` | Search indexed documents by meaning |
46
+ | `semantic_index` | Add a document to the index |
47
+ | `semantic_index_batch` | Add multiple documents at once |
48
+ | `semantic_remove` | Remove a document by ID |
49
+ | `semantic_stats` | Get index size, store location, and config |
50
+ | `semantic_clear` | Remove all documents (requires confirmation) |
51
+
52
+ ## What it does
53
+
54
+ ```text
55
+ You ask Claude: "How do we handle rate limiting?"
56
+ |
57
+ Claude calls: semantic_search("rate limiting")
58
+ |
59
+ Server embeds: query -> 384-dimension vector
60
+ |
61
+ Cosine search: against all indexed vectors
62
+ |
63
+ Returns: "We throttle API requests using sliding windows..."
64
+ (matched by meaning, not keywords)
65
+ ```
66
+
67
+ The embedding model understands meaning:
68
+
69
+ | Query | Finds |
70
+ | ----- | ----- |
71
+ | "rate limiting" | "We throttle API requests using sliding windows" |
72
+ | "how to deploy" | "Production runs via docker compose up with..." |
73
+ | "error handling" | "We use Result types instead of try/catch for..." |
74
+
75
+ ## What to index
76
+
77
+ High-value content for project memory:
78
+
79
+ **Architecture decisions** — "We chose PostgreSQL over DynamoDB because we need
80
+ complex joins for the reporting module."
81
+
82
+ **Code patterns** — "Authentication middleware is in src/middleware/auth.ts.
83
+ Uses JWT with RS256, tokens expire after 1 hour, refresh tokens after 30 days."
84
+
85
+ **Conventions** — "All API endpoints return { data, error, meta } shape.
86
+ Errors use RFC 7807 problem details format."
87
+
88
+ **Debugging insights** — "If the worker queue backs up, check Redis memory.
89
+ The default maxmemory-policy is noeviction which causes write failures."
90
+
91
+ ## Configuration
92
+
93
+ ### CLI arguments
94
+
95
+ ```bash
96
+ npx @nacho-labs/mcp-semantic-search \
97
+ --store /path/to/store.json \
98
+ --similarity 0.5 \
99
+ --model Xenova/all-mpnet-base-v2 \
100
+ --cache-dir /tmp/models
101
+ ```
102
+
103
+ ### Environment variables
104
+
105
+ | Variable | Description | Default |
106
+ | -------- | ----------- | ------- |
107
+ | `MCP_SEMANTIC_STORE` | Path to persistence file | `.semantic-store.json` |
108
+ | `MCP_SEMANTIC_SIMILARITY` | Min similarity threshold (0-1) | `0.6` |
109
+ | `MCP_SEMANTIC_MODEL` | Embedding model | `Xenova/all-MiniLM-L6-v2` |
110
+ | `MCP_SEMANTIC_CACHE_DIR` | Model cache directory | `.cache/transformers` |
111
+
112
+ ### With environment variables in MCP config
113
+
114
+ ```json
115
+ {
116
+ "mcpServers": {
117
+ "semantic-search": {
118
+ "type": "stdio",
119
+ "command": "npx",
120
+ "args": ["@nacho-labs/mcp-semantic-search"],
121
+ "env": {
122
+ "MCP_SEMANTIC_STORE": "/home/user/.semantic-memory/project.json",
123
+ "MCP_SEMANTIC_SIMILARITY": "0.5"
124
+ }
125
+ }
126
+ }
127
+ }
128
+ ```
129
+
130
+ ## Performance
131
+
132
+ | Operation | Time |
133
+ | --------- | ---- |
134
+ | Server startup (model cached) | ~500ms |
135
+ | Server startup (first run) | ~2-5s |
136
+ | Index a document | ~10-50ms |
137
+ | Search 1000 documents | ~5-10ms |
138
+
139
+ **Memory:** ~100MB for model + ~1.5KB per document.
140
+
141
+ The in-memory store works well up to ~10K documents. Beyond that, consider a
142
+ dedicated vector database.
143
+
144
+ ## Persistence
145
+
146
+ The index is saved to disk automatically after every write operation (index,
147
+ remove, clear). On startup, the server loads the existing store if present.
148
+
149
+ Default location: `.semantic-store.json` in the working directory.
150
+
151
+ ## How it's built
152
+
153
+ This MCP server is a thin wrapper around two packages:
154
+
155
+ - **[@nacho-labs/nachos-embeddings](https://www.npmjs.com/package/@nacho-labs/nachos-embeddings)** — Local vector embeddings and semantic search
156
+ - **[@modelcontextprotocol/sdk](https://www.npmjs.com/package/@modelcontextprotocol/sdk)** — Official MCP TypeScript SDK
157
+
158
+ The embeddings package can also be used directly in your own code. See its
159
+ [README](https://github.com/nacho-labs-llc/nachos-embeddings) for the
160
+ standalone API.
161
+
162
+ ## Development
163
+
164
+ ```bash
165
+ git clone https://github.com/nacho-labs-llc/mcp-semantic-search.git
166
+ cd mcp-semantic-search
167
+ npm install
168
+ npm run build
169
+ npm start
170
+ ```
171
+
172
+ ## License
173
+
174
+ MIT
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * MCP Semantic Search Server
4
+ *
5
+ * Gives AI tools (Claude Code, Cursor, etc.) persistent semantic memory
6
+ * powered by local vector embeddings. No API keys, no cloud, no costs.
7
+ *
8
+ * Usage:
9
+ * npx @nacho-labs/mcp-semantic-search
10
+ * npx @nacho-labs/mcp-semantic-search --store /path/to/store.json
11
+ * npx @nacho-labs/mcp-semantic-search --similarity 0.5
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;GAUG"}
package/dist/index.js ADDED
@@ -0,0 +1,241 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * MCP Semantic Search Server
4
+ *
5
+ * Gives AI tools (Claude Code, Cursor, etc.) persistent semantic memory
6
+ * powered by local vector embeddings. No API keys, no cloud, no costs.
7
+ *
8
+ * Usage:
9
+ * npx @nacho-labs/mcp-semantic-search
10
+ * npx @nacho-labs/mcp-semantic-search --store /path/to/store.json
11
+ * npx @nacho-labs/mcp-semantic-search --similarity 0.5
12
+ */
13
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
14
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
15
+ import { z } from 'zod';
16
+ import { SemanticSearch } from '@nacho-labs/nachos-embeddings';
17
+ import { readFile, writeFile, mkdir } from 'node:fs/promises';
18
+ import { existsSync } from 'node:fs';
19
+ import { dirname, resolve } from 'node:path';
20
+ // --- Configuration via CLI args and env vars ---
21
+ function getConfig() {
22
+ const args = process.argv.slice(2);
23
+ function getArg(name, fallback) {
24
+ const idx = args.indexOf(`--${name}`);
25
+ if (idx !== -1 && idx + 1 < args.length) {
26
+ return args[idx + 1];
27
+ }
28
+ return fallback;
29
+ }
30
+ const storePath = resolve(process.env['MCP_SEMANTIC_STORE'] ??
31
+ getArg('store', '.semantic-store.json'));
32
+ const minSimilarity = parseFloat(process.env['MCP_SEMANTIC_SIMILARITY'] ??
33
+ getArg('similarity', '0.6'));
34
+ const model = process.env['MCP_SEMANTIC_MODEL'] ??
35
+ getArg('model', 'Xenova/all-MiniLM-L6-v2');
36
+ const cacheDir = process.env['MCP_SEMANTIC_CACHE_DIR'] ??
37
+ getArg('cache-dir', '.cache/transformers');
38
+ return { storePath, minSimilarity, model, cacheDir };
39
+ }
40
+ const config = getConfig();
41
+ // --- Initialize search engine ---
42
+ const search = new SemanticSearch({
43
+ minSimilarity: config.minSimilarity,
44
+ model: config.model,
45
+ cacheDir: config.cacheDir,
46
+ });
47
+ try {
48
+ await search.init();
49
+ }
50
+ catch (err) {
51
+ console.error('Failed to load embedding model.', 'An internet connection is required on first run to download the model (~25MB).', err);
52
+ process.exit(1);
53
+ }
54
+ // Load persisted index
55
+ if (existsSync(config.storePath)) {
56
+ try {
57
+ const raw = await readFile(config.storePath, 'utf-8');
58
+ const data = JSON.parse(raw);
59
+ if (Array.isArray(data)) {
60
+ search.import(data);
61
+ }
62
+ }
63
+ catch (err) {
64
+ console.error(`Warning: Failed to load store from ${config.storePath}:`, err);
65
+ }
66
+ }
67
+ async function persist() {
68
+ const dir = dirname(config.storePath);
69
+ if (!existsSync(dir)) {
70
+ await mkdir(dir, { recursive: true });
71
+ }
72
+ await writeFile(config.storePath, JSON.stringify(search.export()));
73
+ }
74
+ // --- MCP Server ---
75
+ const server = new McpServer({
76
+ name: 'mcp-semantic-search',
77
+ version: '0.1.0',
78
+ }, {
79
+ capabilities: {
80
+ logging: {},
81
+ },
82
+ });
83
+ // Tool: Semantic search
84
+ server.registerTool('semantic_search', {
85
+ title: 'Semantic Search',
86
+ description: 'Search indexed documents by meaning. Finds relevant content even when the wording differs from the query. Use this to recall past decisions, find related code patterns, or look up previously indexed context.',
87
+ inputSchema: z.object({
88
+ query: z.string().describe('Natural language search query'),
89
+ limit: z
90
+ .number()
91
+ .optional()
92
+ .default(5)
93
+ .describe('Maximum number of results to return'),
94
+ }),
95
+ }, async ({ query, limit }) => {
96
+ const results = await search.search(query, { limit });
97
+ if (results.length === 0) {
98
+ return {
99
+ content: [{ type: 'text', text: 'No relevant results found.' }],
100
+ };
101
+ }
102
+ const formatted = results
103
+ .map((r, i) => `${i + 1}. [${(r.similarity * 100).toFixed(0)}% match] ${r.text}` +
104
+ (r.metadata && Object.keys(r.metadata).length > 0
105
+ ? `\n metadata: ${JSON.stringify(r.metadata)}`
106
+ : ''))
107
+ .join('\n\n');
108
+ return {
109
+ content: [
110
+ { type: 'text', text: `Found ${results.length} result(s):\n\n${formatted}` },
111
+ ],
112
+ };
113
+ });
114
+ // Tool: Index a document
115
+ server.registerTool('semantic_index', {
116
+ title: 'Index Document',
117
+ description: 'Add a document to the semantic search index for later recall. Use this to remember decisions, patterns, file summaries, conventions, debugging insights, or any context worth recalling later. Documents persist across sessions.',
118
+ inputSchema: z.object({
119
+ id: z
120
+ .string()
121
+ .describe('Unique document ID. Use descriptive IDs like "adr-012", "auth-pattern", "deploy-steps"'),
122
+ text: z.string().describe('The text content to index and make searchable'),
123
+ metadata: z
124
+ .record(z.string())
125
+ .optional()
126
+ .describe('Optional key-value metadata (e.g. {"kind": "decision", "date": "2026-02-22"})'),
127
+ }),
128
+ }, async ({ id, text, metadata }) => {
129
+ await search.addDocument({ id, text, metadata });
130
+ await persist();
131
+ return {
132
+ content: [
133
+ {
134
+ type: 'text',
135
+ text: `Indexed "${id}" (${search.size()} total documents in store)`,
136
+ },
137
+ ],
138
+ };
139
+ });
140
+ // Tool: Batch index multiple documents
141
+ server.registerTool('semantic_index_batch', {
142
+ title: 'Batch Index Documents',
143
+ description: 'Add multiple documents to the index at once. More efficient than indexing one at a time.',
144
+ inputSchema: z.object({
145
+ documents: z.array(z.object({
146
+ id: z.string().describe('Unique document ID'),
147
+ text: z.string().describe('Text content to index'),
148
+ metadata: z
149
+ .record(z.string())
150
+ .optional()
151
+ .describe('Optional key-value metadata'),
152
+ })).describe('Array of documents to index'),
153
+ }),
154
+ }, async ({ documents }) => {
155
+ await search.addDocuments(documents);
156
+ await persist();
157
+ return {
158
+ content: [
159
+ {
160
+ type: 'text',
161
+ text: `Indexed ${documents.length} documents (${search.size()} total in store)`,
162
+ },
163
+ ],
164
+ };
165
+ });
166
+ // Tool: Remove a document
167
+ server.registerTool('semantic_remove', {
168
+ title: 'Remove Document',
169
+ description: 'Remove a document from the semantic search index by its ID.',
170
+ inputSchema: z.object({
171
+ id: z.string().describe('Document ID to remove'),
172
+ }),
173
+ }, async ({ id }) => {
174
+ const removed = search.remove(id);
175
+ if (removed)
176
+ await persist();
177
+ return {
178
+ content: [
179
+ {
180
+ type: 'text',
181
+ text: removed
182
+ ? `Removed "${id}" (${search.size()} documents remaining)`
183
+ : `Document "${id}" not found in index`,
184
+ },
185
+ ],
186
+ };
187
+ });
188
+ // Tool: Get index stats
189
+ server.registerTool('semantic_stats', {
190
+ title: 'Index Stats',
191
+ description: 'Get information about the semantic search index: document count and storage location.',
192
+ inputSchema: z.object({}),
193
+ }, async () => ({
194
+ content: [
195
+ {
196
+ type: 'text',
197
+ text: [
198
+ `Documents indexed: ${search.size()}`,
199
+ `Store location: ${config.storePath}`,
200
+ `Model: ${config.model}`,
201
+ `Min similarity: ${config.minSimilarity}`,
202
+ ].join('\n'),
203
+ },
204
+ ],
205
+ }));
206
+ // Tool: Clear all documents
207
+ server.registerTool('semantic_clear', {
208
+ title: 'Clear Index',
209
+ description: 'Remove ALL documents from the semantic search index. This is irreversible.',
210
+ inputSchema: z.object({
211
+ confirm: z
212
+ .boolean()
213
+ .describe('Must be true to confirm clearing all documents'),
214
+ }),
215
+ }, async ({ confirm }) => {
216
+ if (!confirm) {
217
+ return {
218
+ content: [
219
+ {
220
+ type: 'text',
221
+ text: 'Clear cancelled. Set confirm: true to clear all documents.',
222
+ },
223
+ ],
224
+ };
225
+ }
226
+ const count = search.size();
227
+ search.clear();
228
+ await persist();
229
+ return {
230
+ content: [
231
+ {
232
+ type: 'text',
233
+ text: `Cleared ${count} documents from the index.`,
234
+ },
235
+ ],
236
+ };
237
+ });
238
+ // --- Start server ---
239
+ const transport = new StdioServerTransport();
240
+ await server.connect(transport);
241
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@nacho-labs/mcp-semantic-search",
3
+ "version": "0.1.0",
4
+ "description": "MCP server for local semantic search — give Claude Code, Cursor, and other AI tools persistent memory powered by nachos-embeddings",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "mcp-semantic-search": "./dist/index.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "server.json",
20
+ "README.md",
21
+ "LICENSE"
22
+ ],
23
+ "scripts": {
24
+ "build": "tsc",
25
+ "dev": "tsc --watch",
26
+ "start": "node dist/index.js",
27
+ "typecheck": "tsc --noEmit",
28
+ "clean": "rm -rf dist *.tsbuildinfo",
29
+ "prepublishOnly": "npm run build",
30
+ "version:patch": "npm version patch",
31
+ "version:minor": "npm version minor",
32
+ "version:major": "npm version major",
33
+ "publish:npm": "npm publish --access public",
34
+ "release:patch": "npm run version:patch && npm run publish:npm",
35
+ "release:minor": "npm run version:minor && npm run publish:npm",
36
+ "release:major": "npm run version:major && npm run publish:npm"
37
+ },
38
+ "keywords": [
39
+ "mcp",
40
+ "model-context-protocol",
41
+ "semantic-search",
42
+ "embeddings",
43
+ "vector-search",
44
+ "claude",
45
+ "claude-code",
46
+ "ai-memory",
47
+ "local",
48
+ "privacy"
49
+ ],
50
+ "author": "Nate Richardson <hello@naterichardson.com> (https://naterichardson.com)",
51
+ "license": "MIT",
52
+ "engines": {
53
+ "node": ">=18.0.0"
54
+ },
55
+ "repository": {
56
+ "type": "git",
57
+ "url": "git+https://github.com/nacho-labs-llc/mcp-semantic-search.git"
58
+ },
59
+ "dependencies": {
60
+ "@modelcontextprotocol/sdk": "^1.0.0",
61
+ "@nacho-labs/nachos-embeddings": "^0.1.0",
62
+ "zod": "^3.23.0"
63
+ },
64
+ "devDependencies": {
65
+ "@types/node": "^22.0.0",
66
+ "typescript": "^5.7.0"
67
+ }
68
+ }
package/server.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
+ "name": "io.github.nacho-labs-llc/mcp-semantic-search",
4
+ "description": "Local semantic search for AI coding tools. Index decisions, patterns, and context — recall them by meaning, not keywords. Powered by nachos-embeddings (Transformers.js). No API keys, no cloud, no costs.",
5
+ "title": "Semantic Search MCP Server",
6
+ "version": "0.1.0",
7
+ "repository": {
8
+ "url": "https://github.com/nacho-labs-llc/mcp-semantic-search",
9
+ "source": "github"
10
+ },
11
+ "packages": [
12
+ {
13
+ "registryType": "npm",
14
+ "identifier": "@nacho-labs/mcp-semantic-search",
15
+ "version": "0.1.0",
16
+ "transport": {
17
+ "type": "stdio"
18
+ },
19
+ "environmentVariables": [
20
+ {
21
+ "name": "MCP_SEMANTIC_STORE",
22
+ "description": "Path to the JSON file where the index is persisted. Defaults to .semantic-store.json in the working directory.",
23
+ "isRequired": false,
24
+ "isSecret": false,
25
+ "format": "string"
26
+ },
27
+ {
28
+ "name": "MCP_SEMANTIC_SIMILARITY",
29
+ "description": "Minimum similarity threshold (0-1). Defaults to 0.6.",
30
+ "isRequired": false,
31
+ "isSecret": false,
32
+ "format": "string"
33
+ },
34
+ {
35
+ "name": "MCP_SEMANTIC_MODEL",
36
+ "description": "Embedding model to use. Defaults to Xenova/all-MiniLM-L6-v2.",
37
+ "isRequired": false,
38
+ "isSecret": false,
39
+ "format": "string"
40
+ }
41
+ ]
42
+ }
43
+ ]
44
+ }