mirror of
https://github.com/samvallad33/vestige.git
synced 2026-04-25 00:36:22 +02:00
feat: v2.0 distribution — IDE integrations, zero-config installer, README overhaul
- Add integration guides for Xcode 26.3, Cursor, VS Code, JetBrains, Windsurf - First cognitive memory server with documented Xcode 26.3 MCP support - Add npx @vestige/init — zero-config CLI that auto-detects IDEs and injects config - Overhaul README: "The open-source cognitive engine for AI" - Add "Why Not Just Use RAG?" comparison and cognitive science stack docs - Update license badge to AGPL-3.0
This commit is contained in:
parent
04a3062328
commit
3fce1f0b70
8 changed files with 1378 additions and 92 deletions
232
README.md
232
README.md
|
|
@ -1,28 +1,34 @@
|
|||
# Vestige
|
||||
|
||||
**Memory that fades like yours does.**
|
||||
**The open-source cognitive engine for AI.**
|
||||
|
||||
[](https://github.com/samvallad33/vestige)
|
||||
[](https://github.com/samvallad33/vestige/releases/latest)
|
||||
[](LICENSE)
|
||||
[](LICENSE)
|
||||
[](https://modelcontextprotocol.io)
|
||||
|
||||
> The only MCP memory server built on cognitive science. FSRS-6 spaced repetition, spreading activation, synaptic tagging—all running 100% local.
|
||||
> Your AI forgets everything between sessions. Vestige fixes that. Built on 130 years of memory research — FSRS-6 spaced repetition, prediction error gating, synaptic tagging — all running in a single Rust binary, 100% local.
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
## Give Your AI a Brain in 30 Seconds
|
||||
|
||||
### 1. Download
|
||||
|
||||
**macOS (Apple Silicon):**
|
||||
```bash
|
||||
# 1. Install
|
||||
curl -L https://github.com/samvallad33/vestige/releases/latest/download/vestige-mcp-aarch64-apple-darwin.tar.gz | tar -xz
|
||||
sudo mv vestige-mcp vestige vestige-restore /usr/local/bin/
|
||||
|
||||
# 2. Connect
|
||||
claude mcp add vestige vestige-mcp -s user
|
||||
|
||||
# 3. Test
|
||||
# "Remember that I prefer TypeScript over JavaScript"
|
||||
# New session → "What are my coding preferences?"
|
||||
# It remembers.
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Other platforms</summary>
|
||||
<summary>Other platforms & install methods</summary>
|
||||
|
||||
**macOS (Intel):**
|
||||
```bash
|
||||
|
|
@ -42,120 +48,138 @@ sudo mv vestige-mcp vestige vestige-restore /usr/local/bin/
|
|||
```bash
|
||||
git clone https://github.com/samvallad33/vestige && cd vestige
|
||||
cargo build --release
|
||||
sudo cp target/release/vestige-mcp /usr/local/bin/
|
||||
sudo cp target/release/{vestige-mcp,vestige,vestige-restore} /usr/local/bin/
|
||||
```
|
||||
|
||||
**npm:**
|
||||
```bash
|
||||
npm install -g vestige-mcp
|
||||
```
|
||||
</details>
|
||||
|
||||
### 2. Connect to Claude
|
||||
---
|
||||
|
||||
```bash
|
||||
claude mcp add vestige vestige-mcp -s user
|
||||
```
|
||||
## Works Everywhere
|
||||
|
||||
### 3. Restart & Test
|
||||
Vestige speaks MCP — the universal protocol for AI tools. One brain, every IDE.
|
||||
|
||||
Restart Claude, then:
|
||||
| IDE | Setup |
|
||||
|-----|-------|
|
||||
| **Claude Code** | `claude mcp add vestige vestige-mcp -s user` |
|
||||
| **Claude Desktop** | [2-min setup](docs/CONFIGURATION.md#claude-desktop-macos) |
|
||||
| **Xcode 26.3** | [Integration guide](docs/integrations/xcode.md) |
|
||||
| **Cursor** | [Integration guide](docs/integrations/cursor.md) |
|
||||
| **VS Code (Copilot)** | [Integration guide](docs/integrations/vscode.md) |
|
||||
| **JetBrains** | [Integration guide](docs/integrations/jetbrains.md) |
|
||||
| **Windsurf** | [Integration guide](docs/integrations/windsurf.md) |
|
||||
|
||||
> "Remember that I prefer TypeScript over JavaScript"
|
||||
|
||||
New session:
|
||||
|
||||
> "What are my coding preferences?"
|
||||
|
||||
**It remembers.**
|
||||
Fix a bug in VS Code. Open Xcode. Your AI already knows about the fix.
|
||||
|
||||
---
|
||||
|
||||
## Why Vestige?
|
||||
## Why Not Just Use RAG?
|
||||
|
||||
| Problem | Solution |
|
||||
|---------|----------|
|
||||
| AI forgets between sessions | Persistent memory with intelligent retrieval |
|
||||
| RAG dumps irrelevant context | **Prediction Error Gating** auto-decides CREATE/UPDATE/SUPERSEDE |
|
||||
| Memory bloat eats tokens | **FSRS-6 decay** naturally fades unused memories |
|
||||
| No idea what AI "knows" | `search` tool lets you query anytime |
|
||||
| Privacy concerns | **100% local** after initial setup |
|
||||
RAG is a dumb bucket. Vestige is an active organ.
|
||||
|
||||
| | RAG / Vector Store | Vestige |
|
||||
|---|---|---|
|
||||
| **Storage** | Store everything, retrieve everything | **Prediction Error Gating** — only stores what's surprising or new |
|
||||
| **Retrieval** | Nearest-neighbor similarity | **Spreading activation** — finds related memories through association chains |
|
||||
| **Decay** | Nothing ever expires | **FSRS-6** — memories fade like yours do, keeping context lean |
|
||||
| **Duplicates** | Manual dedup or none | **Self-healing** — automatically merges "likes dark mode" + "prefers dark themes" |
|
||||
| **Importance** | All memories are equal | **Synaptic tagging** — retroactively strengthens memories that turn out to matter |
|
||||
| **Privacy** | Usually cloud-dependent | **100% local** — your data never leaves your machine |
|
||||
|
||||
---
|
||||
|
||||
## The Cognitive Science Stack
|
||||
|
||||
This isn't a key-value store with an embedding model bolted on. Vestige implements real neuroscience:
|
||||
|
||||
**Prediction Error Gating** — The bouncer for your brain. When new information arrives, Vestige compares it against existing memories. Redundant? Merged. Contradictory? Superseded. Novel? Stored. Just like the hippocampus.
|
||||
|
||||
**FSRS-6 Spaced Repetition** — 21 parameters governing the mathematics of forgetting. Frequently-used memories stay strong. Unused memories naturally decay. Your context window stays clean.
|
||||
|
||||
**Synaptic Tagging** — A memory that seemed trivial this morning can be retroactively tagged as critical tonight. Based on [Frey & Morris, 1997](https://doi.org/10.1038/385533a0).
|
||||
|
||||
**Spreading Activation** — Search for "auth bug" and find the related memory about the JWT library update you saved last week. Memories form a graph, not a flat list. Based on [Collins & Loftus, 1975](https://doi.org/10.1037/0033-295X.82.6.407).
|
||||
|
||||
**Dual-Strength Model** — Every memory has two values: storage strength (how well it's encoded) and retrieval strength (how easily it surfaces). A memory can be deeply stored but temporarily hard to retrieve — just like real forgetting. Based on [Bjork & Bjork, 1992](https://doi.org/10.1016/S0079-7421(08)60016-9).
|
||||
|
||||
**Memory States** — Active, Dormant, Silent, Unavailable. Memories transition between states based on usage patterns, exactly like human cognitive architecture.
|
||||
|
||||
[Full science documentation →](docs/SCIENCE.md)
|
||||
|
||||
---
|
||||
|
||||
## Tools
|
||||
|
||||
| Tool | Description |
|
||||
| Tool | What It Does |
|
||||
|------|-------------|
|
||||
| `search` | Unified search (keyword + semantic + hybrid) |
|
||||
| `smart_ingest` | Intelligent ingestion with duplicate detection |
|
||||
| `ingest` | Simple memory storage |
|
||||
| `search` | Hybrid search — keyword + semantic + RRF fusion |
|
||||
| `smart_ingest` | Intelligent storage with automatic CREATE/UPDATE/SUPERSEDE |
|
||||
| `ingest` | Direct memory storage |
|
||||
| `memory` | Get, delete, or check memory state |
|
||||
| `codebase` | Remember patterns and architectural decisions |
|
||||
| `intention` | Set reminders and future triggers |
|
||||
| `promote_memory` | Mark memory as helpful (strengthens) |
|
||||
| `demote_memory` | Mark memory as wrong (weakens) |
|
||||
| `session_checkpoint` | Batch-save an entire session's work |
|
||||
| `promote_memory` / `demote_memory` | Feedback loop — strengthen or weaken memories |
|
||||
| `find_duplicates` | Self-healing — detect and merge redundant memories |
|
||||
| `consolidate` | Run FSRS-6 decay and maintenance |
|
||||
| `importance_score` | 4-channel importance scoring (novelty, arousal, reward, attention) |
|
||||
| `memory_timeline` | Browse memories chronologically |
|
||||
| `health_check` | System health with warnings and recommendations |
|
||||
|
||||
---
|
||||
|
||||
## Make Claude Use Vestige Automatically
|
||||
## Make Your AI Use Vestige Automatically
|
||||
|
||||
Add this to your `CLAUDE.md`:
|
||||
Add this to your `CLAUDE.md` and your AI becomes proactive:
|
||||
|
||||
```markdown
|
||||
## Vestige Memory System
|
||||
## Memory
|
||||
|
||||
At the start of every conversation, check Vestige for context:
|
||||
1. Recall user preferences and instructions
|
||||
2. Recall relevant project context
|
||||
3. Operate in proactive memory mode - save important info without being asked
|
||||
At the start of every session:
|
||||
1. Search Vestige for user preferences and project context
|
||||
2. Save bug fixes, decisions, and patterns without being asked
|
||||
3. Create reminders when the user mentions deadlines
|
||||
```
|
||||
|
||||
### Trigger Words
|
||||
|
||||
| User Says | Claude Does |
|
||||
|-----------|-------------|
|
||||
| "Remember this" | `smart_ingest` immediately |
|
||||
| "I prefer..." / "I always..." | Save as preference |
|
||||
| "Remind me..." | Create `intention` |
|
||||
| "This is important" | `smart_ingest` + `promote_memory` |
|
||||
| You Say | AI Does |
|
||||
|---------|---------|
|
||||
| "Remember this" | Saves immediately |
|
||||
| "I prefer..." / "I always..." | Saves as preference |
|
||||
| "Remind me..." | Creates a future trigger |
|
||||
| "This is important" | Saves + strengthens |
|
||||
|
||||
[Full CLAUDE.md templates →](docs/CLAUDE-SETUP.md)
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
## CLI
|
||||
|
||||
<details>
|
||||
<summary>"Command not found" after installation</summary>
|
||||
|
||||
Ensure `vestige-mcp` is in PATH:
|
||||
```bash
|
||||
which vestige-mcp
|
||||
vestige stats # Memory statistics
|
||||
vestige stats --tagging # Retention distribution
|
||||
vestige stats --states # Cognitive state breakdown
|
||||
vestige health # System health check
|
||||
vestige consolidate # Run memory maintenance
|
||||
vestige restore <file> # Restore from backup
|
||||
```
|
||||
|
||||
Or use full path in Claude config:
|
||||
```bash
|
||||
claude mcp add vestige /full/path/to/vestige-mcp -s user
|
||||
```
|
||||
</details>
|
||||
---
|
||||
|
||||
<details>
|
||||
<summary>Model cache location</summary>
|
||||
## Technical Details
|
||||
|
||||
The embedding model (~130MB) is cached in platform-specific directories:
|
||||
- **macOS**: `~/Library/Caches/com.vestige.core/fastembed`
|
||||
- **Linux**: `~/.cache/vestige/fastembed`
|
||||
- **Windows**: `%LOCALAPPDATA%\vestige\cache\fastembed`
|
||||
|
||||
Override with: `export FASTEMBED_CACHE_PATH=/custom/path`
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Model download fails</summary>
|
||||
|
||||
First run requires internet (~130MB). If behind proxy:
|
||||
```bash
|
||||
export HTTPS_PROXY=your-proxy:port
|
||||
```
|
||||
</details>
|
||||
|
||||
[More troubleshooting →](docs/FAQ.md#troubleshooting)
|
||||
- **Language:** Rust (42,000 lines)
|
||||
- **Binary size:** ~20MB
|
||||
- **Embeddings:** Nomic Embed Text v1.5 (768-dim, local ONNX inference via fastembed)
|
||||
- **Vector search:** USearch HNSW (20x faster than FAISS)
|
||||
- **Storage:** SQLite + FTS5 (optional SQLCipher encryption)
|
||||
- **Transport:** MCP stdio (JSON-RPC 2.0)
|
||||
- **Dependencies:** Zero runtime dependencies beyond the binary
|
||||
- **First run:** Downloads embedding model (~130MB), then fully offline
|
||||
- **Platforms:** macOS (ARM/Intel), Linux (x86_64), Windows
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -164,32 +188,56 @@ export HTTPS_PROXY=your-proxy:port
|
|||
| Document | Contents |
|
||||
|----------|----------|
|
||||
| [FAQ](docs/FAQ.md) | 30+ answers to common questions |
|
||||
| [How It Works](docs/SCIENCE.md) | FSRS-6, dual-strength memory, the neuroscience |
|
||||
| [Storage Modes](docs/STORAGE.md) | Global, per-project, multi-Claude setup |
|
||||
| [CLAUDE.md Setup](docs/CLAUDE-SETUP.md) | Templates for proactive memory use |
|
||||
| [How It Works](docs/SCIENCE.md) | The neuroscience behind every feature |
|
||||
| [Storage Modes](docs/STORAGE.md) | Global, per-project, multi-instance setup |
|
||||
| [CLAUDE.md Setup](docs/CLAUDE-SETUP.md) | Templates for proactive memory |
|
||||
| [Configuration](docs/CONFIGURATION.md) | CLI commands, environment variables |
|
||||
| [Integrations](docs/integrations/) | Xcode, Cursor, VS Code, JetBrains, Windsurf |
|
||||
| [Changelog](CHANGELOG.md) | Version history |
|
||||
|
||||
---
|
||||
|
||||
## CLI Commands
|
||||
## Troubleshooting
|
||||
|
||||
<details>
|
||||
<summary>"Command not found" after installation</summary>
|
||||
|
||||
Ensure `vestige-mcp` is in your PATH:
|
||||
```bash
|
||||
vestige stats # Memory statistics
|
||||
vestige health # System health check
|
||||
vestige consolidate # Run memory maintenance
|
||||
vestige restore <file> # Restore from backup
|
||||
which vestige-mcp
|
||||
```
|
||||
|
||||
Or use the full path:
|
||||
```bash
|
||||
claude mcp add vestige /usr/local/bin/vestige-mcp -s user
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Embedding model download fails</summary>
|
||||
|
||||
First run downloads ~130MB from Hugging Face. If behind a proxy:
|
||||
```bash
|
||||
export HTTPS_PROXY=your-proxy:port
|
||||
```
|
||||
|
||||
Cache locations:
|
||||
- **macOS**: `~/Library/Caches/com.vestige.core/fastembed`
|
||||
- **Linux**: `~/.cache/vestige/fastembed`
|
||||
- **Windows**: `%LOCALAPPDATA%\vestige\cache\fastembed`
|
||||
</details>
|
||||
|
||||
[More troubleshooting →](docs/FAQ.md#troubleshooting)
|
||||
|
||||
---
|
||||
|
||||
## Contributing
|
||||
|
||||
Issues and PRs welcome! See [CONTRIBUTING.md](CONTRIBUTING.md).
|
||||
Issues and PRs welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).
|
||||
|
||||
## License
|
||||
|
||||
MIT OR Apache-2.0 (dual-licensed)
|
||||
AGPL-3.0 — free to use, modify, and self-host. If you offer Vestige as a network service, you must open-source your modifications.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
142
docs/integrations/cursor.md
Normal file
142
docs/integrations/cursor.md
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
# Cursor
|
||||
|
||||
> Give Cursor a brain that remembers between sessions.
|
||||
|
||||
Cursor has native MCP support. Add Vestige and your AI assistant remembers your architecture, preferences, and past fixes across every session.
|
||||
|
||||
---
|
||||
|
||||
## Setup
|
||||
|
||||
### 1. Create or edit the config file
|
||||
|
||||
**Global (all projects):**
|
||||
|
||||
| Platform | Path |
|
||||
|----------|------|
|
||||
| macOS / Linux | `~/.cursor/mcp.json` |
|
||||
| Windows | `%USERPROFILE%\.cursor\mcp.json` |
|
||||
|
||||
```bash
|
||||
# macOS / Linux
|
||||
mkdir -p ~/.cursor
|
||||
open -e ~/.cursor/mcp.json
|
||||
```
|
||||
|
||||
### 2. Add Vestige
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"vestige": {
|
||||
"command": "/usr/local/bin/vestige-mcp",
|
||||
"args": [],
|
||||
"env": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> **Use absolute paths.** Cursor does not reliably resolve relative paths or `~`. Run `which vestige-mcp` to find your binary location.
|
||||
|
||||
**Windows:**
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"vestige": {
|
||||
"command": "C:\\Users\\you\\.cargo\\bin\\vestige-mcp.exe",
|
||||
"args": [],
|
||||
"env": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Restart Cursor
|
||||
|
||||
Fully quit and reopen Cursor. The MCP server loads on startup.
|
||||
|
||||
### 4. Verify
|
||||
|
||||
Open Cursor's AI chat and ask:
|
||||
|
||||
> "What MCP tools do you have access to?"
|
||||
|
||||
You should see Vestige's tools listed (search, smart_ingest, memory, etc.).
|
||||
|
||||
---
|
||||
|
||||
## First Use
|
||||
|
||||
Ask Cursor's AI:
|
||||
|
||||
> "Remember that this project uses React with TypeScript and Tailwind CSS"
|
||||
|
||||
Start a **new chat session**, then:
|
||||
|
||||
> "What tech stack does this project use?"
|
||||
|
||||
It remembers.
|
||||
|
||||
---
|
||||
|
||||
## Project-Specific Memory
|
||||
|
||||
To isolate memory per project, use `--data-dir`:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"vestige": {
|
||||
"command": "/usr/local/bin/vestige-mcp",
|
||||
"args": ["--data-dir", "/Users/you/projects/my-app/.vestige"],
|
||||
"env": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Or place a `.cursor/mcp.json` in the project root for project-level config.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
<details>
|
||||
<summary>Vestige tools not appearing</summary>
|
||||
|
||||
1. Verify the binary exists:
|
||||
```bash
|
||||
which vestige-mcp
|
||||
```
|
||||
2. Test the binary manually:
|
||||
```bash
|
||||
echo '{}' | vestige-mcp
|
||||
```
|
||||
3. Check the config is valid JSON:
|
||||
```bash
|
||||
cat ~/.cursor/mcp.json | python3 -m json.tool
|
||||
```
|
||||
4. Fully restart Cursor (Cmd+Q / Alt+F4, not just close window).
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Silent failures</summary>
|
||||
|
||||
Cursor does not surface MCP server errors in the UI. Test by running the command directly in your terminal to see actual error output.
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## Also Works With
|
||||
|
||||
| IDE | Guide |
|
||||
|-----|-------|
|
||||
| Xcode 26.3 | [Setup](./xcode.md) |
|
||||
| VS Code (Copilot) | [Setup](./vscode.md) |
|
||||
| JetBrains | [Setup](./jetbrains.md) |
|
||||
| Windsurf | [Setup](./windsurf.md) |
|
||||
| Claude Code | [Setup](../CONFIGURATION.md#claude-code-one-liner) |
|
||||
| Claude Desktop | [Setup](../CONFIGURATION.md#claude-desktop-macos) |
|
||||
|
||||
Your AI remembers everything, everywhere.
|
||||
129
docs/integrations/jetbrains.md
Normal file
129
docs/integrations/jetbrains.md
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
# JetBrains (IntelliJ, WebStorm, PyCharm, etc.)
|
||||
|
||||
> Give your JetBrains AI assistant a brain that remembers.
|
||||
|
||||
JetBrains IDEs (2025.2+) have built-in MCP support. Vestige integrates through the MCP server settings, giving your AI assistant persistent memory across sessions.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **JetBrains IDE 2025.2+** (IntelliJ IDEA, WebStorm, PyCharm, GoLand, etc.)
|
||||
- **vestige-mcp** binary installed ([Installation guide](../../README.md#quick-start))
|
||||
|
||||
---
|
||||
|
||||
## Setup
|
||||
|
||||
### Option A: Auto-Configure (Recommended)
|
||||
|
||||
JetBrains can auto-configure MCP servers for connected clients:
|
||||
|
||||
1. Open **Settings** (`Cmd+,` / `Ctrl+Alt+S`)
|
||||
2. Navigate to **Tools > MCP Server**
|
||||
3. Click **"+"** to add a new MCP server
|
||||
4. Configure:
|
||||
- **Name:** `vestige`
|
||||
- **Command:** `/usr/local/bin/vestige-mcp`
|
||||
- **Arguments:** (leave empty)
|
||||
5. Click **Apply**
|
||||
|
||||
### Option B: Junie AI Config
|
||||
|
||||
If using JetBrains Junie AI, add Vestige to the Junie MCP config:
|
||||
|
||||
**User-level (all projects):**
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.junie/mcp
|
||||
```
|
||||
|
||||
Edit `~/.junie/mcp/mcp.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"vestige": {
|
||||
"command": "/usr/local/bin/vestige-mcp",
|
||||
"args": [],
|
||||
"env": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Project-level:**
|
||||
|
||||
Create `.junie/mcp/mcp.json` in your project root with the same format.
|
||||
|
||||
### Option C: Via External Client
|
||||
|
||||
JetBrains exposes its own tools via MCP. You can also use Vestige through an external client (Claude Code, Cursor) that connects to JetBrains:
|
||||
|
||||
1. In JetBrains: **Settings > Tools > MCP Server**
|
||||
2. Click **Auto-Configure** for your preferred client
|
||||
3. Add Vestige to that client's config (see [Cursor](./cursor.md), [VS Code](./vscode.md))
|
||||
|
||||
---
|
||||
|
||||
## Verify
|
||||
|
||||
After configuration, the MCP server should appear in **Settings > Tools > MCP Server** with a green status indicator.
|
||||
|
||||
Test by asking your AI assistant:
|
||||
|
||||
> "Remember that this project uses Spring Boot with Kotlin and follows hexagonal architecture"
|
||||
|
||||
---
|
||||
|
||||
## Project-Specific Memory
|
||||
|
||||
Isolate memory per project:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"vestige": {
|
||||
"command": "/usr/local/bin/vestige-mcp",
|
||||
"args": ["--data-dir", "/Users/you/projects/my-app/.vestige"],
|
||||
"env": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
<details>
|
||||
<summary>MCP server not appearing in settings</summary>
|
||||
|
||||
1. Verify your IDE version is 2025.2 or later.
|
||||
2. Check that the binary path is absolute:
|
||||
```bash
|
||||
which vestige-mcp
|
||||
```
|
||||
3. Restart the IDE after adding the configuration.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Finding your client's config file</summary>
|
||||
|
||||
In **Settings > Tools > MCP Server**, click the expansion arrow next to your client, then select **"Open Client Settings File"** to see the exact config path.
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## Also Works With
|
||||
|
||||
| IDE | Guide |
|
||||
|-----|-------|
|
||||
| Xcode 26.3 | [Setup](./xcode.md) |
|
||||
| Cursor | [Setup](./cursor.md) |
|
||||
| VS Code (Copilot) | [Setup](./vscode.md) |
|
||||
| Windsurf | [Setup](./windsurf.md) |
|
||||
| Claude Code | [Setup](../CONFIGURATION.md#claude-code-one-liner) |
|
||||
| Claude Desktop | [Setup](../CONFIGURATION.md#claude-desktop-macos) |
|
||||
|
||||
Your AI remembers everything, everywhere.
|
||||
160
docs/integrations/vscode.md
Normal file
160
docs/integrations/vscode.md
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
# VS Code (GitHub Copilot)
|
||||
|
||||
> Give Copilot a brain that remembers between sessions.
|
||||
|
||||
VS Code supports MCP servers through GitHub Copilot's agent mode. Vestige plugs directly in, giving Copilot persistent memory across every coding session.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **VS Code 1.99+** (or latest stable)
|
||||
- **GitHub Copilot** extension installed and active
|
||||
- **vestige-mcp** binary installed ([Installation guide](../../README.md#quick-start))
|
||||
|
||||
---
|
||||
|
||||
## Setup
|
||||
|
||||
### 1. Create the config file
|
||||
|
||||
**Workspace (recommended — shareable with team):**
|
||||
|
||||
Create `.vscode/mcp.json` in your project root:
|
||||
|
||||
```bash
|
||||
mkdir -p .vscode
|
||||
```
|
||||
|
||||
**User-level (all projects):**
|
||||
|
||||
Open Command Palette (`Cmd+Shift+P`) and run:
|
||||
|
||||
```
|
||||
MCP: Open User Configuration
|
||||
```
|
||||
|
||||
### 2. Add Vestige
|
||||
|
||||
Note: VS Code uses `"servers"` (not `"mcpServers"`).
|
||||
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"vestige": {
|
||||
"command": "/usr/local/bin/vestige-mcp",
|
||||
"args": [],
|
||||
"env": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> **Use absolute paths.** Run `which vestige-mcp` to find your binary.
|
||||
|
||||
**Windows:**
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"vestige": {
|
||||
"command": "C:\\Users\\you\\.cargo\\bin\\vestige-mcp.exe",
|
||||
"args": [],
|
||||
"env": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Verify
|
||||
|
||||
VS Code auto-detects config changes — no restart needed.
|
||||
|
||||
Open **Copilot Chat** (agent mode) and ask:
|
||||
|
||||
> "What MCP tools do you have?"
|
||||
|
||||
Vestige's tools (search, smart_ingest, memory, etc.) should appear.
|
||||
|
||||
---
|
||||
|
||||
## First Use
|
||||
|
||||
In Copilot Chat:
|
||||
|
||||
> "Remember that this project uses Express.js with PostgreSQL and follows REST conventions"
|
||||
|
||||
Start a **new chat**, then:
|
||||
|
||||
> "What's the tech stack for this project?"
|
||||
|
||||
It remembers.
|
||||
|
||||
---
|
||||
|
||||
## Secure API Keys (Optional)
|
||||
|
||||
VS Code supports input variables to avoid hardcoding secrets:
|
||||
|
||||
```json
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"type": "promptString",
|
||||
"id": "vestige-data-dir",
|
||||
"description": "Vestige data directory"
|
||||
}
|
||||
],
|
||||
"servers": {
|
||||
"vestige": {
|
||||
"command": "/usr/local/bin/vestige-mcp",
|
||||
"args": ["--data-dir", "${input:vestige-data-dir}"],
|
||||
"env": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Share Memory Config With Your Team
|
||||
|
||||
Since `.vscode/mcp.json` lives in the project, you can commit it:
|
||||
|
||||
```bash
|
||||
git add .vscode/mcp.json
|
||||
git commit -m "Add Vestige memory server for Copilot"
|
||||
```
|
||||
|
||||
Every team member with Vestige installed will automatically get memory-enabled Copilot.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
<details>
|
||||
<summary>Vestige not showing in Copilot</summary>
|
||||
|
||||
1. Ensure you're using **agent mode** in Copilot Chat (not inline completions).
|
||||
2. Verify VS Code version is 1.99+.
|
||||
3. Check the config file is at `.vscode/mcp.json` (not `.vscode/settings.json`).
|
||||
4. Verify the key is `"servers"` not `"mcpServers"`.
|
||||
5. Test the binary manually:
|
||||
```bash
|
||||
which vestige-mcp && echo "Found" || echo "Not found"
|
||||
```
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## Also Works With
|
||||
|
||||
| IDE | Guide |
|
||||
|-----|-------|
|
||||
| Xcode 26.3 | [Setup](./xcode.md) |
|
||||
| Cursor | [Setup](./cursor.md) |
|
||||
| JetBrains | [Setup](./jetbrains.md) |
|
||||
| Windsurf | [Setup](./windsurf.md) |
|
||||
| Claude Code | [Setup](../CONFIGURATION.md#claude-code-one-liner) |
|
||||
| Claude Desktop | [Setup](../CONFIGURATION.md#claude-desktop-macos) |
|
||||
|
||||
Your AI remembers everything, everywhere.
|
||||
155
docs/integrations/windsurf.md
Normal file
155
docs/integrations/windsurf.md
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
# Windsurf
|
||||
|
||||
> Give Cascade a brain that remembers between sessions.
|
||||
|
||||
Windsurf has native MCP support through its Cascade AI. Add Vestige and Cascade remembers your architecture, preferences, and past decisions across every session.
|
||||
|
||||
---
|
||||
|
||||
## Setup
|
||||
|
||||
### 1. Open the config file
|
||||
|
||||
**Option A — Via UI:**
|
||||
|
||||
1. Open **Windsurf > Settings > Advanced Settings**
|
||||
2. Scroll to the **"Cascade"** section
|
||||
3. Click **"view the raw JSON config file"**
|
||||
|
||||
**Option B — Direct path:**
|
||||
|
||||
| Platform | Path |
|
||||
|----------|------|
|
||||
| macOS / Linux | `~/.codeium/windsurf/mcp_config.json` |
|
||||
| Windows | `%USERPROFILE%\.codeium\windsurf\mcp_config.json` |
|
||||
|
||||
```bash
|
||||
# macOS / Linux
|
||||
open -e ~/.codeium/windsurf/mcp_config.json
|
||||
```
|
||||
|
||||
### 2. Add Vestige
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"vestige": {
|
||||
"command": "/usr/local/bin/vestige-mcp",
|
||||
"args": [],
|
||||
"env": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**With environment variable expansion** (Windsurf-specific feature):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"vestige": {
|
||||
"command": "${env:HOME}/.cargo/bin/vestige-mcp",
|
||||
"args": [],
|
||||
"env": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Windows:**
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"vestige": {
|
||||
"command": "C:\\Users\\you\\.cargo\\bin\\vestige-mcp.exe",
|
||||
"args": [],
|
||||
"env": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Restart Windsurf
|
||||
|
||||
Restart the IDE or refresh the Cascade panel.
|
||||
|
||||
### 4. Verify
|
||||
|
||||
Open Cascade and ask:
|
||||
|
||||
> "What MCP tools do you have?"
|
||||
|
||||
You should see Vestige's tools listed.
|
||||
|
||||
---
|
||||
|
||||
## First Use
|
||||
|
||||
In Cascade:
|
||||
|
||||
> "Remember that this project uses Next.js 15 with the App Router and Drizzle ORM"
|
||||
|
||||
Start a **new Cascade session**, then:
|
||||
|
||||
> "What framework does this project use?"
|
||||
|
||||
It remembers.
|
||||
|
||||
---
|
||||
|
||||
## Project-Specific Memory
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"vestige": {
|
||||
"command": "/usr/local/bin/vestige-mcp",
|
||||
"args": ["--data-dir", "${env:HOME}/projects/my-app/.vestige"],
|
||||
"env": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Important: Tool Limit
|
||||
|
||||
Windsurf has a **hard cap of 100 tools** across all MCP servers. Vestige uses ~19 tools, leaving plenty of room for other servers.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
<details>
|
||||
<summary>Vestige not appearing in Cascade</summary>
|
||||
|
||||
1. Verify the config file is valid JSON:
|
||||
```bash
|
||||
cat ~/.codeium/windsurf/mcp_config.json | python3 -m json.tool
|
||||
```
|
||||
2. Ensure you're using absolute paths (or `${env:HOME}` expansion).
|
||||
3. Check the Cascade panel for error messages.
|
||||
4. Fully restart Windsurf.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Tool limit exceeded</summary>
|
||||
|
||||
If you have many MCP servers and exceed 100 total tools, Cascade will ignore excess servers. Remove unused servers or use Vestige's unified tools (each handles multiple operations).
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## Also Works With
|
||||
|
||||
| IDE | Guide |
|
||||
|-----|-------|
|
||||
| Xcode 26.3 | [Setup](./xcode.md) |
|
||||
| Cursor | [Setup](./cursor.md) |
|
||||
| VS Code (Copilot) | [Setup](./vscode.md) |
|
||||
| JetBrains | [Setup](./jetbrains.md) |
|
||||
| Claude Code | [Setup](../CONFIGURATION.md#claude-code-one-liner) |
|
||||
| Claude Desktop | [Setup](../CONFIGURATION.md#claude-desktop-macos) |
|
||||
|
||||
Your AI remembers everything, everywhere.
|
||||
260
docs/integrations/xcode.md
Normal file
260
docs/integrations/xcode.md
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
# Xcode 26.3
|
||||
|
||||
> Give Apple Intelligence a brain that remembers.
|
||||
|
||||
Xcode 26.3 supports [agentic coding](https://developer.apple.com/documentation/xcode/giving-agentic-coding-tools-access-to-xcode) with full MCP (Model Context Protocol) integration. Vestige plugs directly into Xcode's Claude Agent, giving it persistent memory across every coding session.
|
||||
|
||||
**Vestige is the first cognitive memory server for Xcode.**
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Xcode 26.3** or later (Release Candidate or stable)
|
||||
- **vestige-mcp** binary installed ([Installation guide](../../README.md#quick-start))
|
||||
|
||||
Verify Vestige is installed:
|
||||
|
||||
```bash
|
||||
which vestige-mcp
|
||||
# Should output: /usr/local/bin/vestige-mcp
|
||||
```
|
||||
|
||||
If you installed to a different location, note the **absolute path** — you'll need it below.
|
||||
|
||||
---
|
||||
|
||||
## Setup
|
||||
|
||||
### 1. Open the config file
|
||||
|
||||
Xcode's Claude Agent reads MCP configuration from:
|
||||
|
||||
```
|
||||
~/Library/Developer/Xcode/CodingAssistant/ClaudeAgentConfig/.claude
|
||||
```
|
||||
|
||||
Create or edit this file:
|
||||
|
||||
```bash
|
||||
mkdir -p ~/Library/Developer/Xcode/CodingAssistant/ClaudeAgentConfig
|
||||
open -e ~/Library/Developer/Xcode/CodingAssistant/ClaudeAgentConfig/.claude
|
||||
```
|
||||
|
||||
### 2. Add Vestige
|
||||
|
||||
Paste the following configuration:
|
||||
|
||||
```json
|
||||
{
|
||||
"projects": {
|
||||
"*": {
|
||||
"mcpServers": {
|
||||
"vestige": {
|
||||
"type": "stdio",
|
||||
"command": "/usr/local/bin/vestige-mcp",
|
||||
"args": [],
|
||||
"env": {
|
||||
"PATH": "/usr/local/bin:/usr/bin:/bin"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hasTrustDialogAccepted": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> **Important:** Xcode runs agents in a sandboxed environment that does **not** inherit your shell configuration (`.zshrc`, `.bashrc`, etc.). You **must** use absolute paths for the `command` field and explicitly set `PATH` in the `env` block.
|
||||
|
||||
#### Project-specific memory
|
||||
|
||||
To give each project its own isolated memory, use `--data-dir`:
|
||||
|
||||
```json
|
||||
{
|
||||
"projects": {
|
||||
"/Users/you/Developer/MyApp": {
|
||||
"mcpServers": {
|
||||
"vestige": {
|
||||
"type": "stdio",
|
||||
"command": "/usr/local/bin/vestige-mcp",
|
||||
"args": ["--data-dir", "/Users/you/Developer/MyApp/.vestige"],
|
||||
"env": {
|
||||
"PATH": "/usr/local/bin:/usr/bin:/bin"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hasTrustDialogAccepted": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Restart Xcode
|
||||
|
||||
Quit and reopen Xcode. The Claude Agent will now load Vestige on startup.
|
||||
|
||||
### 4. Verify
|
||||
|
||||
In Xcode's Agent panel, type:
|
||||
|
||||
```
|
||||
/context
|
||||
```
|
||||
|
||||
You should see `vestige` listed as an available MCP server with its tools (search, smart_ingest, memory, etc.).
|
||||
|
||||
---
|
||||
|
||||
## First Use
|
||||
|
||||
Open any project and ask the Claude Agent:
|
||||
|
||||
> "Remember that this project uses SwiftUI with MVVM architecture and targets iOS 18+"
|
||||
|
||||
Start a **new session**, then ask:
|
||||
|
||||
> "What architecture does this project use?"
|
||||
|
||||
It remembers.
|
||||
|
||||
---
|
||||
|
||||
## What Vestige Does for Xcode
|
||||
|
||||
| Without Vestige | With Vestige |
|
||||
|-----------------|--------------|
|
||||
| Every session starts from zero | Agent recalls your architecture, patterns, and preferences |
|
||||
| Re-explain SwiftUI conventions each time | Agent knows your conventions from day one |
|
||||
| Bug fixes are forgotten | Agent remembers past fixes and avoids regressions |
|
||||
| No context between Xcode and other IDEs | Shared memory across Xcode, Cursor, VS Code, and more |
|
||||
|
||||
### Example Workflows
|
||||
|
||||
**Architecture decisions:**
|
||||
> "Remember: we chose Observation framework over Combine for state management because it's simpler and Apple-recommended for iOS 17+."
|
||||
|
||||
**Bug documentation:**
|
||||
> The agent fixes a Core Data migration crash? Vestige automatically stores the fix. Next time it encounters a migration issue, it remembers the solution.
|
||||
|
||||
**Cross-IDE memory:**
|
||||
> Fix a backend bug in VS Code. Open the iOS app in Xcode. The agent already knows about the API change because Vestige shares memory across all your tools.
|
||||
|
||||
---
|
||||
|
||||
## Tips
|
||||
|
||||
### Use a CLAUDE.md for proactive memory
|
||||
|
||||
Place a `CLAUDE.md` in your project root to make the agent use Vestige automatically:
|
||||
|
||||
```markdown
|
||||
## Memory
|
||||
|
||||
At the start of every session:
|
||||
1. Search Vestige for this project's context
|
||||
2. Recall architecture decisions and coding patterns
|
||||
3. Save important decisions and bug fixes without being asked
|
||||
```
|
||||
|
||||
See [CLAUDE.md templates](../CLAUDE-SETUP.md) for a full setup.
|
||||
|
||||
### Embedding model cache
|
||||
|
||||
The first time Vestige runs, it downloads the Nomic embedding model (~130MB). In Xcode's sandboxed environment, the cache location is:
|
||||
|
||||
```
|
||||
~/Library/Caches/com.vestige.core/fastembed
|
||||
```
|
||||
|
||||
If the download fails behind a corporate proxy, pre-download by running `vestige-mcp` once from your terminal before using it in Xcode.
|
||||
|
||||
### Skills integration
|
||||
|
||||
You can add Vestige-related skills to Xcode's skills directory:
|
||||
|
||||
```
|
||||
~/Library/Developer/Xcode/CodingAssistant/ClaudeAgentConfig/skills/
|
||||
```
|
||||
|
||||
Drop a markdown file describing how the agent should use memory for your iOS/macOS projects.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
<details>
|
||||
<summary>"vestige" not showing in /context</summary>
|
||||
|
||||
1. Verify the binary path is correct and absolute:
|
||||
```bash
|
||||
ls -la /usr/local/bin/vestige-mcp
|
||||
```
|
||||
|
||||
2. Check that the config file is valid JSON:
|
||||
```bash
|
||||
cat ~/Library/Developer/Xcode/CodingAssistant/ClaudeAgentConfig/.claude | python3 -m json.tool
|
||||
```
|
||||
|
||||
3. Ensure you fully quit and restarted Xcode (Cmd+Q, not just close window).
|
||||
|
||||
4. Check Xcode's agent logs for errors:
|
||||
```bash
|
||||
log show --predicate 'subsystem == "com.apple.dt.Xcode"' --last 5m | grep -i mcp
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Agent can't find vestige-mcp binary</summary>
|
||||
|
||||
Xcode's sandbox does not inherit your shell PATH. Use the full absolute path:
|
||||
|
||||
```json
|
||||
"command": "/usr/local/bin/vestige-mcp"
|
||||
```
|
||||
|
||||
If you installed via `cargo build`, the binary is likely at:
|
||||
```
|
||||
/Users/you/.cargo/bin/vestige-mcp
|
||||
```
|
||||
|
||||
Or wherever you copied it. Run `which vestige-mcp` in your terminal to find it.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Embedding model fails to download</summary>
|
||||
|
||||
The first run downloads ~130MB. If Xcode's sandbox blocks the download:
|
||||
|
||||
1. Run `vestige-mcp` once from your terminal to cache the model
|
||||
2. The cache at `~/Library/Caches/com.vestige.core/fastembed` will be available to the sandboxed instance
|
||||
|
||||
Behind a proxy:
|
||||
```bash
|
||||
HTTPS_PROXY=your-proxy:port vestige-mcp
|
||||
```
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## Also Works With
|
||||
|
||||
Vestige uses the MCP standard — the same memory works across all your tools:
|
||||
|
||||
| IDE | Guide |
|
||||
|-----|-------|
|
||||
| Claude Code | [Setup](../CONFIGURATION.md#claude-code-one-liner) |
|
||||
| Claude Desktop | [Setup](../CONFIGURATION.md#claude-desktop-macos) |
|
||||
| Cursor | [Setup](./cursor.md) |
|
||||
| VS Code (Copilot) | [Setup](./vscode.md) |
|
||||
| JetBrains | [Setup](./jetbrains.md) |
|
||||
| Windsurf | [Setup](./windsurf.md) |
|
||||
|
||||
Your AI remembers everything, everywhere.
|
||||
|
||||
---
|
||||
|
||||
<p align="center">
|
||||
<a href="../../README.md">Back to README</a>
|
||||
</p>
|
||||
360
packages/vestige-init/bin/init.js
Executable file
360
packages/vestige-init/bin/init.js
Executable file
|
|
@ -0,0 +1,360 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
const HOME = os.homedir();
|
||||
const PLATFORM = os.platform();
|
||||
|
||||
// ─── Branding ───────────────────────────────────────────────────────────────
|
||||
|
||||
const BANNER = `
|
||||
vestige init
|
||||
Give your AI a brain in 10 seconds.
|
||||
`;
|
||||
|
||||
// ─── IDE Definitions ────────────────────────────────────────────────────────
|
||||
|
||||
const IDE_CONFIGS = {
|
||||
'Claude Code': {
|
||||
detect: () => {
|
||||
try {
|
||||
execSync('which claude', { stdio: 'ignore' });
|
||||
return true;
|
||||
} catch { return false; }
|
||||
},
|
||||
configPath: () => path.join(HOME, '.claude', 'settings.json'),
|
||||
format: 'claude-code',
|
||||
inject: (binaryPath) => {
|
||||
try {
|
||||
const result = execSync(`claude mcp add vestige "${binaryPath}" -s user 2>&1`, { encoding: 'utf8' });
|
||||
if (result.includes('already exists')) {
|
||||
console.log(' [skip] Claude Code — already configured');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (err) {
|
||||
const msg = err.stdout || err.stderr || '';
|
||||
if (msg.includes('already exists')) {
|
||||
console.log(' [skip] Claude Code — already configured');
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
'Claude Desktop': {
|
||||
detect: () => {
|
||||
const paths = {
|
||||
darwin: path.join(HOME, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'),
|
||||
win32: path.join(process.env.APPDATA || '', 'Claude', 'claude_desktop_config.json'),
|
||||
linux: path.join(HOME, '.config', 'Claude', 'claude_desktop_config.json'),
|
||||
};
|
||||
return fs.existsSync(paths[PLATFORM] || '');
|
||||
},
|
||||
configPath: () => {
|
||||
const paths = {
|
||||
darwin: path.join(HOME, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'),
|
||||
win32: path.join(process.env.APPDATA || '', 'Claude', 'claude_desktop_config.json'),
|
||||
linux: path.join(HOME, '.config', 'Claude', 'claude_desktop_config.json'),
|
||||
};
|
||||
return paths[PLATFORM];
|
||||
},
|
||||
format: 'mcpServers',
|
||||
key: 'mcpServers',
|
||||
},
|
||||
|
||||
'Cursor': {
|
||||
detect: () => {
|
||||
const configPath = path.join(HOME, '.cursor', 'mcp.json');
|
||||
const appExists = PLATFORM === 'darwin'
|
||||
? fs.existsSync('/Applications/Cursor.app')
|
||||
: fs.existsSync(path.join(HOME, '.cursor'));
|
||||
return appExists || fs.existsSync(configPath);
|
||||
},
|
||||
configPath: () => path.join(HOME, '.cursor', 'mcp.json'),
|
||||
format: 'mcpServers',
|
||||
key: 'mcpServers',
|
||||
},
|
||||
|
||||
'VS Code (Copilot)': {
|
||||
detect: () => {
|
||||
try {
|
||||
execSync('which code', { stdio: 'ignore' });
|
||||
return true;
|
||||
} catch {
|
||||
return PLATFORM === 'darwin' && fs.existsSync('/Applications/Visual Studio Code.app');
|
||||
}
|
||||
},
|
||||
configPath: () => {
|
||||
// User-level MCP config
|
||||
const paths = {
|
||||
darwin: path.join(HOME, 'Library', 'Application Support', 'Code', 'User', 'settings.json'),
|
||||
win32: path.join(process.env.APPDATA || '', 'Code', 'User', 'settings.json'),
|
||||
linux: path.join(HOME, '.config', 'Code', 'User', 'settings.json'),
|
||||
};
|
||||
return paths[PLATFORM];
|
||||
},
|
||||
format: 'vscode',
|
||||
key: 'servers',
|
||||
note: 'Tip: For project-level config, create .vscode/mcp.json with {"servers": {"vestige": ...}}',
|
||||
},
|
||||
|
||||
'Xcode 26.3': {
|
||||
detect: () => {
|
||||
if (PLATFORM !== 'darwin') return false;
|
||||
return fs.existsSync('/Applications/Xcode.app') ||
|
||||
fs.existsSync(path.join(HOME, 'Library', 'Developer', 'Xcode'));
|
||||
},
|
||||
configPath: () => path.join(HOME, 'Library', 'Developer', 'Xcode', 'CodingAssistant', 'ClaudeAgentConfig', '.claude'),
|
||||
format: 'xcode',
|
||||
key: 'projects',
|
||||
},
|
||||
|
||||
'JetBrains (Junie)': {
|
||||
detect: () => {
|
||||
const jetbrainsDir = PLATFORM === 'darwin'
|
||||
? path.join(HOME, 'Library', 'Application Support', 'JetBrains')
|
||||
: path.join(HOME, '.config', 'JetBrains');
|
||||
return fs.existsSync(jetbrainsDir);
|
||||
},
|
||||
configPath: () => path.join(HOME, '.junie', 'mcp', 'mcp.json'),
|
||||
format: 'mcpServers',
|
||||
key: 'mcpServers',
|
||||
},
|
||||
|
||||
'Windsurf': {
|
||||
detect: () => {
|
||||
const configPath = PLATFORM === 'win32'
|
||||
? path.join(HOME, '.codeium', 'windsurf', 'mcp_config.json')
|
||||
: path.join(HOME, '.codeium', 'windsurf', 'mcp_config.json');
|
||||
return fs.existsSync(configPath) ||
|
||||
(PLATFORM === 'darwin' && fs.existsSync('/Applications/Windsurf.app'));
|
||||
},
|
||||
configPath: () => path.join(HOME, '.codeium', 'windsurf', 'mcp_config.json'),
|
||||
format: 'mcpServers',
|
||||
key: 'mcpServers',
|
||||
},
|
||||
};
|
||||
|
||||
// ─── Helpers ────────────────────────────────────────────────────────────────
|
||||
|
||||
function findBinary() {
|
||||
// Check common locations
|
||||
const candidates = [
|
||||
path.join('/usr', 'local', 'bin', 'vestige-mcp'),
|
||||
path.join(HOME, '.cargo', 'bin', 'vestige-mcp'),
|
||||
// npm global install location
|
||||
(() => {
|
||||
try {
|
||||
const npmPrefix = execSync('npm prefix -g', { encoding: 'utf8' }).trim();
|
||||
return path.join(npmPrefix, 'bin', 'vestige-mcp');
|
||||
} catch { return null; }
|
||||
})(),
|
||||
].filter(Boolean);
|
||||
|
||||
// Also try which/where
|
||||
try {
|
||||
const result = execSync(PLATFORM === 'win32' ? 'where vestige-mcp' : 'which vestige-mcp', {
|
||||
encoding: 'utf8',
|
||||
stdio: ['pipe', 'pipe', 'ignore'],
|
||||
}).trim();
|
||||
if (result) candidates.unshift(result);
|
||||
} catch {}
|
||||
|
||||
for (const candidate of candidates) {
|
||||
if (fs.existsSync(candidate)) return candidate;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function readJsonSafe(filePath) {
|
||||
try {
|
||||
const content = fs.readFileSync(filePath, 'utf8');
|
||||
return JSON.parse(content);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function ensureDir(filePath) {
|
||||
const dir = path.dirname(filePath);
|
||||
if (!dir || dir === '.') return;
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
}
|
||||
|
||||
function buildVestigeConfig(binaryPath) {
|
||||
return {
|
||||
command: binaryPath,
|
||||
args: [],
|
||||
env: {},
|
||||
};
|
||||
}
|
||||
|
||||
function buildXcodeConfig(binaryPath) {
|
||||
return {
|
||||
projects: {
|
||||
'*': {
|
||||
mcpServers: {
|
||||
vestige: {
|
||||
type: 'stdio',
|
||||
command: binaryPath,
|
||||
args: [],
|
||||
env: {
|
||||
PATH: '/usr/local/bin:/usr/bin:/bin',
|
||||
},
|
||||
},
|
||||
},
|
||||
hasTrustDialogAccepted: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function injectConfig(ide, ideName, binaryPath) {
|
||||
const configPath = ide.configPath();
|
||||
if (!configPath) return false;
|
||||
|
||||
// Claude Code uses its own CLI
|
||||
if (ide.format === 'claude-code') {
|
||||
return ide.inject(binaryPath);
|
||||
}
|
||||
|
||||
ensureDir(configPath);
|
||||
let config = readJsonSafe(configPath) || {};
|
||||
|
||||
if (ide.format === 'xcode') {
|
||||
// Xcode has a different structure
|
||||
const xcodeConfig = buildXcodeConfig(binaryPath);
|
||||
if (config.projects && config.projects['*'] && config.projects['*'].mcpServers && config.projects['*'].mcpServers.vestige) {
|
||||
console.log(` [skip] ${ideName} — already configured`);
|
||||
return false;
|
||||
}
|
||||
// Merge with existing config
|
||||
if (!config.projects) config.projects = {};
|
||||
if (!config.projects['*']) config.projects['*'] = {};
|
||||
if (!config.projects['*'].mcpServers) config.projects['*'].mcpServers = {};
|
||||
config.projects['*'].mcpServers.vestige = xcodeConfig.projects['*'].mcpServers.vestige;
|
||||
config.projects['*'].hasTrustDialogAccepted = true;
|
||||
} else if (ide.format === 'vscode') {
|
||||
// VS Code uses "mcp" key in settings.json with "servers" subkey
|
||||
if (!config.mcp) config.mcp = {};
|
||||
if (!config.mcp.servers) config.mcp.servers = {};
|
||||
if (config.mcp.servers.vestige) {
|
||||
console.log(` [skip] ${ideName} — already configured`);
|
||||
return false;
|
||||
}
|
||||
config.mcp.servers.vestige = buildVestigeConfig(binaryPath);
|
||||
} else {
|
||||
// Standard mcpServers format (Cursor, Claude Desktop, JetBrains, Windsurf)
|
||||
const key = ide.key || 'mcpServers';
|
||||
if (!config[key]) config[key] = {};
|
||||
if (config[key].vestige) {
|
||||
console.log(` [skip] ${ideName} — already configured`);
|
||||
return false;
|
||||
}
|
||||
config[key].vestige = buildVestigeConfig(binaryPath);
|
||||
}
|
||||
|
||||
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
|
||||
return true;
|
||||
}
|
||||
|
||||
// ─── Main ───────────────────────────────────────────────────────────────────
|
||||
|
||||
function main() {
|
||||
console.log(BANNER);
|
||||
|
||||
// Step 1: Find the binary
|
||||
console.log('Looking for vestige-mcp binary...');
|
||||
const binaryPath = findBinary();
|
||||
|
||||
if (!binaryPath) {
|
||||
console.log('');
|
||||
console.log('vestige-mcp not found. Installing...');
|
||||
console.log('');
|
||||
console.log('Install manually:');
|
||||
console.log('');
|
||||
console.log(' # macOS (Apple Silicon)');
|
||||
console.log(' curl -L https://github.com/samvallad33/vestige/releases/latest/download/vestige-mcp-aarch64-apple-darwin.tar.gz | tar -xz');
|
||||
console.log(' sudo mv vestige-mcp vestige vestige-restore /usr/local/bin/');
|
||||
console.log('');
|
||||
console.log(' # Or via npm');
|
||||
console.log(' npm install -g vestige-mcp-server');
|
||||
console.log('');
|
||||
console.log('Then run: npx @vestige/init');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(` Found: ${binaryPath}`);
|
||||
console.log('');
|
||||
|
||||
// Step 2: Detect IDEs
|
||||
console.log('Scanning for IDEs...');
|
||||
const detected = [];
|
||||
const notFound = [];
|
||||
|
||||
for (const [name, ide] of Object.entries(IDE_CONFIGS)) {
|
||||
if (ide.detect()) {
|
||||
detected.push({ name, ide });
|
||||
console.log(` [found] ${name}`);
|
||||
} else {
|
||||
notFound.push(name);
|
||||
}
|
||||
}
|
||||
|
||||
if (detected.length === 0) {
|
||||
console.log(' No supported IDEs found.');
|
||||
console.log('');
|
||||
console.log('Supported: Claude Code, Claude Desktop, Cursor, VS Code, Xcode, JetBrains, Windsurf');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('');
|
||||
|
||||
// Step 3: Inject configs
|
||||
console.log('Configuring Vestige...');
|
||||
let configured = 0;
|
||||
let skipped = 0;
|
||||
|
||||
for (const { name, ide } of detected) {
|
||||
try {
|
||||
const injected = injectConfig(ide, name, binaryPath);
|
||||
if (injected) {
|
||||
console.log(` [done] ${name}`);
|
||||
configured++;
|
||||
if (ide.note) {
|
||||
console.log(` ${ide.note}`);
|
||||
}
|
||||
} else {
|
||||
skipped++;
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(` [fail] ${name} — ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('');
|
||||
|
||||
// Step 4: Summary
|
||||
if (configured > 0) {
|
||||
console.log(`Vestige configured for ${configured} IDE${configured > 1 ? 's' : ''}.${skipped > 0 ? ` (${skipped} already configured)` : ''}`);
|
||||
console.log('');
|
||||
console.log('Next steps:');
|
||||
console.log(' 1. Restart your IDE(s)');
|
||||
console.log(' 2. Ask your AI: "Remember that I prefer TypeScript over JavaScript"');
|
||||
console.log(' 3. New session: "What are my coding preferences?"');
|
||||
console.log('');
|
||||
console.log('Your AI has a brain now.');
|
||||
} else {
|
||||
console.log('All detected IDEs already have Vestige configured.');
|
||||
}
|
||||
|
||||
console.log('');
|
||||
console.log('Docs: https://github.com/samvallad33/vestige');
|
||||
}
|
||||
|
||||
main();
|
||||
32
packages/vestige-init/package.json
Normal file
32
packages/vestige-init/package.json
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"name": "@vestige/init",
|
||||
"version": "1.0.0",
|
||||
"description": "Give your AI a brain in 10 seconds — zero-config Vestige installer",
|
||||
"bin": {
|
||||
"vestige-init": "bin/init.js"
|
||||
},
|
||||
"keywords": [
|
||||
"vestige",
|
||||
"mcp",
|
||||
"ai",
|
||||
"memory",
|
||||
"claude",
|
||||
"copilot",
|
||||
"cursor",
|
||||
"xcode",
|
||||
"jetbrains",
|
||||
"windsurf",
|
||||
"init",
|
||||
"installer"
|
||||
],
|
||||
"author": "Sam Valladares",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/samvallad33/vestige.git",
|
||||
"directory": "packages/vestige-init"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue