diff --git a/README.md b/README.md
index fd05660..50d1a4c 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
-
+
@@ -80,8 +80,8 @@ Add to your Claude Desktop or VS Code settings:
{
"mcpServers": {
"cortex": {
- "command": "bun",
- "args": ["run", "/path/to/Cortex/packages/mcp-server/dist/mcp-server.js"]
+ "command": "npx",
+ "args": ["-y", "@ecuabyte/cortex-mcp-server"]
}
}
}
diff --git a/packages/mcp-server/README.md b/packages/mcp-server/README.md
new file mode 100644
index 0000000..4a0386a
--- /dev/null
+++ b/packages/mcp-server/README.md
@@ -0,0 +1,60 @@
+# Cortex MCP Server
+
+The **Model Context Protocol (MCP)** server for [Cortex](https://github.com/EcuaByte-lat/Cortex).
+
+Connects your AI tools (Claude Desktop, Cursor, Zed, etc.) to your project's persistent memory.
+
+## 🚀 Usage
+
+### Quick Start (npx)
+
+The easiest way to run the server is with `npx`:
+
+```bash
+npx -y @ecuabyte/cortex-mcp-server
+```
+
+### via Claude Desktop
+
+Add this to your `claude_desktop_config.json`:
+
+```json
+{
+ "mcpServers": {
+ "cortex": {
+ "command": "npx",
+ "args": ["-y", "@ecuabyte/cortex-mcp-server"]
+ }
+ }
+}
+```
+
+### via Cursor / Windsurf
+
+1. Go to **Settings** > **MCP**
+2. Add new server:
+ - **Type**: `command`
+ - **Command**: `npx`
+ - **Args**: `-y @ecuabyte/cortex-mcp-server`
+
+## 🛠️ Tools
+
+This server provides the following MCP tools to your AI agent:
+
+- `cortex_search`: Search project memories (facts, decisions, code patterns)
+- `cortex_add`: Add a new memory
+- `cortex_list`: List recent memories
+- `cortex_context`: Get intelligent context for a specific task
+- `cortex_scan`: Scan the current project to extract context automatically
+
+## 📦 Installation
+
+```bash
+npm install -g @ecuabyte/cortex-mcp-server
+# or
+bun add -g @ecuabyte/cortex-mcp-server
+```
+
+## 📄 License
+
+MIT
diff --git a/packages/mcp-server/package.json b/packages/mcp-server/package.json
index 7b87a35..8e56681 100644
--- a/packages/mcp-server/package.json
+++ b/packages/mcp-server/package.json
@@ -12,7 +12,7 @@
"dev": "bun run --watch src/mcp-server.ts",
"start": "bun run dist/mcp-server.js",
"typecheck": "bunx tsc --noEmit",
- "generate-config": "bun run scripts/generate-config.ts"
+ "generate-config": "bun run src/mcp-server.ts generate-config"
},
"keywords": [
"mcp",
diff --git a/packages/mcp-server/scripts/generate-config.ts b/packages/mcp-server/scripts/generate-config.ts
deleted file mode 100644
index a8f17ef..0000000
--- a/packages/mcp-server/scripts/generate-config.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/env bun
-import { parseArgs } from 'node:util';
-
-// Define supported targets
-type Target = 'claude' | 'cursor' | 'windsurf' | 'goose';
-
-const targets: Target[] = ['claude', 'cursor', 'windsurf', 'goose'];
-
-// Parse arguments
-const { values } = parseArgs({
- args: Bun.argv,
- options: {
- target: {
- type: 'string',
- },
- },
- strict: true,
- allowPositionals: true,
-});
-
-const target = values.target as Target | undefined;
-
-if (!target || !targets.includes(target)) {
- console.error(`Usage: bun run generate-config --target <${targets.join('|')}>`);
- process.exit(1);
-}
-
-// Get the absolute path to the MCP server package (assuming installed globally or resolving relative)
-// For this script, we'll assume the user wants to use "npx -y @ecuabyte/cortex-mcp-server" for portability
-// But since we are "generating" it, we can also offer a local path version if running from source.
-// For simplicity in the universal guide, we default to the npx version which is most robust.
-
-const command = 'npx';
-const args = ['-y', '@ecuabyte/cortex-mcp-server'];
-
-// Generate config based on target
-let config: Record;
-
-switch (target) {
- case 'claude':
- config = {
- mcpServers: {
- cortex: {
- command,
- args,
- },
- },
- };
- break;
-
- case 'cursor':
- case 'windsurf':
- // Cursor/Windsurf typically use a simpler structure or just the command in their settings UI
- // But they also support an `mcp.json` in project root or settings.
- // Here we output the object structure they expect in their config file.
- config = {
- cortex: {
- type: 'command',
- command: command,
- args: args,
- },
- };
- break;
-
- case 'goose':
- console.log(`Run this command to configure Goose:`);
- console.log(`goose configure mcp add cortex "${command} ${args.join(' ')}"`);
- process.exit(0);
-}
-
-console.log(JSON.stringify(config, null, 2));
diff --git a/packages/mcp-server/src/mcp-server.ts b/packages/mcp-server/src/mcp-server.ts
index d8a16c8..a858b8b 100644
--- a/packages/mcp-server/src/mcp-server.ts
+++ b/packages/mcp-server/src/mcp-server.ts
@@ -14,6 +14,73 @@ const store = new MemoryStore();
const router = new ContextRouter(store);
const guard = new ContextGuard();
+// CLI Argument Handling for `generate-config`
+import { parseArgs } from 'node:util';
+
+try {
+ const args = process.argv.slice(2);
+ if (args[0] === 'generate-config') {
+ const { values } = parseArgs({
+ args: args,
+ options: {
+ target: {
+ type: 'string',
+ },
+ },
+ strict: false, // allow params we don't know yet (though we should know them)
+ });
+
+ const target = values.target as string | undefined;
+ const targets = ['claude', 'cursor', 'windsurf', 'goose'];
+
+ if (!target || !targets.includes(target)) {
+ console.error(`Usage: cortex-mcp generate-config --target <${targets.join('|')}>`);
+ process.exit(1);
+ }
+
+ const command = 'npx';
+ const cmdArgs = ['-y', '@ecuabyte/cortex-mcp-server'];
+ let config: Record = {};
+
+ switch (target) {
+ case 'claude':
+ config = {
+ mcpServers: {
+ cortex: {
+ command,
+ args: cmdArgs,
+ },
+ },
+ };
+ break;
+ case 'cursor':
+ case 'windsurf':
+ config = {
+ cortex: {
+ type: 'command',
+ command,
+ args: cmdArgs,
+ },
+ };
+ break;
+ case 'goose':
+ console.log(`Run this command to configure Goose:`);
+ console.log(`goose configure mcp add cortex "${command} ${cmdArgs.join(' ')}"`);
+ process.exit(0);
+ }
+
+ console.log(JSON.stringify(config, null, 2));
+ process.exit(0);
+ }
+} catch (e) {
+ // If parsing fails or other issues, just ignore and proceed to server start
+ // or print error if it was clearly a CLI attempt
+ if (process.argv[2] === 'generate-config') {
+ console.error('Error generating config:', e);
+ process.exit(1);
+ }
+}
+
// Initialize embedding provider if available (Ollama or OpenAI)
let embeddingInitialized = false;
(async () => {
diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json
index bc096cd..ed023d0 100644
--- a/packages/vscode-extension/package.json
+++ b/packages/vscode-extension/package.json
@@ -56,7 +56,7 @@
],
"devDependencies": {
"@types/sql.js": "^1.4.9",
- "@types/vscode": "^1.85.0",
+ "@types/vscode": "^1.107.0",
"@vscode/vsce": "^3.7.1",
"@ecuabyte/cortex-shared": "workspace:*"
},
diff --git a/packages/vscode-extension/src/extension.ts b/packages/vscode-extension/src/extension.ts
index 87247d7..beea1cc 100644
--- a/packages/vscode-extension/src/extension.ts
+++ b/packages/vscode-extension/src/extension.ts
@@ -1,3 +1,4 @@
+import { setDefaultAutoSelectFamilyAttemptTimeout } from 'node:net';
import type { Memory } from '@ecuabyte/cortex-shared';
import * as vscode from 'vscode';
import { ContextObserver } from './contextObserver';
@@ -9,6 +10,14 @@ import { CortexTaskProvider } from './taskProvider';
import type { Tool } from './toolScanner';
import { ToolTreeProvider } from './toolTreeProvider';
+// Set default timeout for IPv4/IPv6 family auto-selection to avoid long delays
+// This fixes: Set default auto-select family attempt timeout to 1000ms
+try {
+ setDefaultAutoSelectFamilyAttemptTimeout(1000);
+} catch (e) {
+ console.warn('[Cortex] Failed to set auto-select family timeout:', e);
+}
+
export async function activate(context: vscode.ExtensionContext) {
try {
console.log('[Cortex] Extension activation started');
diff --git a/packages/vscode-extension/src/storage.ts b/packages/vscode-extension/src/storage.ts
index b717834..3617d52 100644
--- a/packages/vscode-extension/src/storage.ts
+++ b/packages/vscode-extension/src/storage.ts
@@ -99,6 +99,19 @@ export class MemoryStore implements IMemoryStore {
END
`);
+ // Fix for "no such module: fts5" error
+ // If the DB was created by the CLI/Core (which uses Bun:sqlite with FTS5),
+ // the triggers will exist but sql.js (wasm) might not support FTS5.
+ // We safely drop them here to allow basic CRUD operations to work.
+ try {
+ const triggers = ['memories_ai', 'memories_ad', 'memories_bu', 'memories_au'];
+ for (const trigger of triggers) {
+ this.db.run(`DROP TRIGGER IF EXISTS ${trigger}`);
+ }
+ } catch (e) {
+ console.warn('[Cortex] Failed to clean up FTS5 triggers:', e);
+ }
+
this.saveToFile();
} catch (error) {
console.error('[Cortex] Failed to initialize MemoryStore:', error);