About MCP
MCP is an MCP server published by asmit557 in the Other category.
The repository has 14 stars and 0 forks, with the last commit 3 months ago. Recent commit activity is the strongest signal that reported issues will get attention.
Install
git clone https://github.com/asmit557/MCPThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Ask AI
Ask AI about MCP
Powered by Claude · Grounded in docs
Security checks
Static checks derived from the repository 2 days ago. Heuristics on the source, not an audit.
- ✓README presentThe repository ships documentation.
- ✓License declaredUsable under a stated license.
- ✓Tests presentA test suite exists in the repository.
- !Dependencies pinnedNo lockfile. Installs can pull different code over time.
- ✓No dynamic code executionSource scan found no eval, dynamic Function, or shell execution.
1 check has not been run yet.
README
Nexus
A local MCP server that gives Claude a persistent memory, a private search index for your files and chats, encrypted secret storage, cost visibility across every LLM you use, and a bridge to every other MCP server on your machine.
Claude Desktop is powerful, but on its own it forgets everything between chats, can't see your files, can't hold API keys safely, can't tell you what you've spent this month, and only talks to one MCP server at a time. Nexus fixes all of that from a single local process.
Status: 1.0 — 342 tests green. All features are opt-in; existing users can enable them one at a time.
60-second tour
Without Nexus:
You: "Can you review the auth middleware in my project?" Claude: "Sure — please paste the code." [You paste 400 lines.] Claude: "I see a race condition in the token refresh… want me to explain?" You: "Yes." [Answers.]
— next day, new chat —
You: "What did we decide about that auth issue yesterday?" Claude: "I don't have access to previous conversations."
With Nexus:
You: "Register
~/code/my-appas workspaceapp." Claude: [workspace_register→ indexed 340 files in 4s]You: "Review the auth middleware in workspace
app." Claude: [workspace_search→workspace_read_file src/auth/middleware.ts→ returns the actual code and reviews it]— next day, new chat —
You: "Recall what we decided about the auth issue." Claude: [
recall query="auth middleware review"→ surfaces yesterday's chat] "We agreed to add a mutex around token refresh…"
That's the whole product in three exchanges. Everything else is variations on the same theme: make Claude aware of the stuff you already have.
Who is this for
- Solo developers who use Claude Desktop daily and are tired of pasting code.
- AI/ML engineers running local Ollama alongside cloud APIs and wanting one unified interface.
- Privacy-conscious users who don't want secrets or notes leaving their machine.
- Anyone paying multiple LLM bills and wanting one number for monthly spend.
- MCP power users who want to compose multiple upstream MCP servers under one roof.
It is not for:
- Teams that need multi-tenant SaaS features (auth, RBAC, sharing).
- Enterprises that need SOC-2 / GDPR audit tooling out of the box.
- Anyone who doesn't already use Claude Desktop (Nexus is an MCP server — Claude Desktop is its primary client).
The problem
Anyone who uses Claude Desktop seriously runs into the same wall:
- No cross-conversation memory. "What did we decide about the migration last Tuesday?" — Claude has no idea.
- Every prompt starts from zero. You paste the same code, the same doc, the same context, chat after chat.
- Secrets end up in chat. An API key pasted once for a quick test now lives in your Claude history, in your exports, in your logs.
- No spend visibility. Claude Pro on one bill, Anthropic API on another, OpenAI API on a third — no single view of what you're actually spending on LLMs each month.
- One MCP server at a time. Gmail MCP, Calendar MCP, browser MCP — each ships as its own subprocess, each competes for the "Nexus" slot.
- Screenshots and clipboards are dark data. You have the answer somewhere, you just can't find it.
Nexus is one local process that solves all six.
What ships in 1.0
Core routing (from the original spec)
- Universal gateway across Ollama, LM Studio, OpenAI, Anthropic, Groq, Together, Fireworks, DeepSeek, Gemini, OpenRouter, Mistral, Cohere.
- Rules-based router with fallback chains, cost + privacy constraints, and per-task-type overrides.
- Speculative cascade — try a cheap tier first, escalate only when confidence is low.
- Two-layer cache (exact hash + optional semantic similarity) with configurable TTL.
- Guardrails pipeline — PII detection (Presidio), prompt-injection filters, constitutional AI critique-revise.
- Memory — long-term facts with time-decay retrieval + episodic session store.
- RAG — hybrid BM25 + dense retrieval over PDFs, code, CSVs, images.
- Sandboxed code executor, web research, knowledge graph, personas, firewall for outbound content control.
- Full observability dashboard at
http://127.0.0.1:8765with per-trace inputs, outputs, costs, and Prometheus metrics.
Personal-productivity subsystems (Phase 1–4 additions)
Each one is a self-contained opt-in subsystem. Enable it in ~/.nexus/config/nexus.yaml, restart Claude Desktop, done.
| Subsystem | What it does | Problem it solves |
|---|---|---|
| Workspaces | Watches a folder, indexes every file, exposes workspace_search + workspace_read_file |
Kills the "paste code every message" tax |
| Inbox | One place to save URLs, PDFs, text snippets, images; auto-OCR'd screenshots + clipboard captures | Unifies dark data across bookmarks / downloads / notes |
| Chat recall | Indexes your Claude Desktop + ChatGPT exports; recall(query, days) retrieves relevant snippets |
Solves "what did we discuss last week?" |
| Vault | Encrypted secret storage via OS keyring; {{vault.NAME}} templating; auto-redaction from every log and trace |
Keeps API keys out of chat history |
| Reminders | remind("in 30 min", "check deploy") → OS notification |
Never lose a follow-up mid-conversation |
| Voice | nexus voice CLI records mic → local faster-whisper → transcript on stdout |
Free, private, offline speech-to-text |
| Cost ledger | Imports Anthropic / OpenAI / Claude Pro spend + joins with internal calls | One monthly LLM burn number |
| MCP bridges | Spawns other MCP servers as subprocesses, proxies their tools as bridge_<name>_<tool> |
Talk to Gmail, Calendar, Playwright — all through Nexus |
How each subsystem works
1. Workspaces
Register a folder → Nexus walks the tree respecting ignore_patterns (.git/, node_modules/, __pycache__/, size caps), skips binary files via null-byte detection, and hands each file to the RAG parser dispatcher (PDF via PyMuPDF, code via tree-sitter, everything else via plain-text chunker). A watchdog observer debounces edits and re-indexes changed files in the background.
MCP surface: workspace_register, workspace_list, workspace_search, workspace_read_file, workspace_reindex, workspace_unregister.
Safety: workspace_read_file rejects .. traversal, absolute paths, and any symlink escape. Only files under the registered root can be read.
2. Inbox
One reserved RAG collection (_inbox) with a metadata table (inbox_items). Every save is content-hash-deduplicated so re-saving the same URL or PDF is a cheap no-op.
- URLs: fetched via
PageFetcher, main content extracted viareadability-lxml(with a naïve tag-strip fallback if not installed), chunked into RAG. - PDFs: dispatched through the existing RAG parser (fitz → pdfplumber fallback).
- Text snippets: direct RAG insert with a caller-supplied source tag.
- Images: routed through the existing OCR service (Tesseract → vision-LLM fallback).
Watchers (optional):
ScreenshotWatcher—watchdogobserver on~/Downloads,~/Pictures/Screenshots, and per-platform defaults. New image → OCR → save.ClipboardWatcher— asyncio polling loop overpyperclip. Content changes trigger a save; short (< 8 char) or duplicate content is skipped.
MCP surface: inbox_save_url, inbox_save_text, inbox_save_file, inbox_search, inbox_list_recent, screenshot_search, clipboard_search, clipboard_history.
3. Chat recall
Claude Desktop and ChatGPT both let you export your conversations as JSON. Drop those exports into ~/.nexus/chatlog-imports/ (or a configured directory). Nexus parses both formats (Claude's chat_messages array + ChatGPT's mapping DAG), joins each message with its role tag, and indexes the whole conversation as one document in the _claude_chats RAG collection.
State is tracked per conversation in the chat_index_state table so re-imports only touch what changed. The recall(query, days=30, k=10) tool queries the collection and post-filters by the original conversation's created_at.
Why not scrape IndexedDB directly? Claude Desktop stores chats in a LevelDB-backed IndexedDB whose schema is undocumented and changes between releases. The export path is stable, ships today, works for ChatGPT too.
MCP surface: recall, chatlog_import, chatlog_stats.
4. Vault
Two backends:
- Keyring (default): raw values live in the OS credential store — Windows Credential Manager, macOS Keychain, Linux Secret Service / kwallet. Never on disk.
- File: Fernet-encrypted blob under
<data_dir>/vault.enc. Key derived from a per-install passphrase via PBKDF2-HMAC-SHA256 (200k iterations). Atomic writes.
Metadata (name, backend, timestamps) lives in the SQLite secrets table so listing doesn't touch the keyring. Names are validated to env-var style (^[A-Z][A-Z0-9_]{0,63}$).
Redaction hook: on startup, every stored secret's raw value is registered with the structlog redaction processor. Any log line or trace input/output containing the value is rewritten to ***REDACTED*** before it lands on disk. New secrets registered live via a change listener.
Template resolution: any string field passing through the router pipeline may reference {{vault.NAME}}. Unknown names raise a clear error instead of silently forwarding the placeholder to the provider.
MCP surface: vault_set, vault_list_names, vault_delete. There is deliberately no vault_get tool — reads only happen in-process.
5. Reminders
A thin adapter over the existing persistent scheduler. Registers a notification job kind at startup. remind("in 30 minutes", "check deploy") parses the time via dateparser (with ISO-8601 fallback), enqueues a schedule_once job. When the job fires, the handler dispatches via one of three channels:
- Desktop —
plyer.notification.notify(Windows toast, macOS notification centre, Linux libnotify). - Log — structured log entry. Useful in headless deploys.
- Webhook — POSTs
{title, message, timestamp}to a configured URL.
Because reminders are just scheduler jobs, they survive restarts, show up in scheduler_list, and can be cancelled with scheduler_cancel.
MCP surface: remind.
6. Voice (local Whisper)
nexus voice CLI records N seconds from the default microphone via sounddevice, wraps the float32 PCM into a WAV buffer, and runs faster-whisper (CTranslate2 backend) in-process. Model is lazy-loaded once per process; subsequent runs skip the load. Transcript goes to stdout so it pipes cleanly:
nexus voice -s 8 -q | Set-Clipboard # Windows PowerShell
nexus voice -s 8 -q | pbcopy # macOS
nexus voice -s 8 -q | wl-copy # Linux (Wayland)
The MCP transcribe_audio tool also accepts model="faster-whisper/base" (or small, medium, large-v3, distil-large-v3) — same in-process engine, same cache, callable from inside Claude for file-based transcription.
No cloud, no API key, no cost. First run downloads the model (~145 MB for base, ~3 GB for large-v3).
7. Cost ledger
Three import paths land data in the external_usage table with a synthetic unique_key for dedup:
- CSV — the "download report" button on every provider dashboard. Parsers ship for Anthropic, OpenAI, Claude Pro, plus a generic fallback.
- Anthropic API —
GET /v1/organizations/usage_report/messagesusing an admin key. - OpenAI API —
GET /v1/organization/usage/completionsusing an admin key.
Both API imports read the admin key from the vault (never from an env var directly), so the "one place for secrets" invariant holds.
cost_summary(period) joins external imports with Nexus-internal backend_calls and returns a single rollup. cost_by_backend(period) breaks it down per model. Periods: day / week / month / year / all.
MCP surface: cost_summary, cost_by_backend, cost_import.
8. MCP bridges
The mcp Python package supports both server and client roles. Nexus uses the client side to spawn each configured upstream MCP server as a stdio subprocess, performs the initialize() handshake, calls list_tools(), and — for every tool T on server X — registers a proxy tool named bridge_<X>_<T> on the local FastMCP.
Signature synthesis: FastMCP infers each tool's input schema from the registered function's Python signature. A bare **kwargs doesn't work. Nexus walks the upstream tool's inputSchema.properties and builds an async function with matching keyword-only parameters, so Claude sees the same shape end-to-end.
Firewall gate: every proxied call runs through check_arbitrary first. Denied calls return {"error": "blocked by firewall", "rule": ...} without touching the upstream.
Lifecycle: subprocesses start on server boot, run under an asyncio task each, and shut down cleanly on NexusApp.shutdown. bridge_reload reconciles against config without restarting Nexus; bridge_disable tears down one.
MCP surface: bridge_list, bridge_reload, bridge_disable, plus the dynamic bridge_<X>_<T> proxies.
Example end-to-end workflows
Real multi-step scenarios that only work because subsystems compose.
"I just joined a codebase — help me understand it"
You: Register C:\code\legacy-api as workspace "legacy".
Then read src/orders/processor.py and explain what it does.
You: Search the "legacy" workspace for "webhook signature".
You: Save https://legacy-api.internal/docs/webhooks to my inbox.
You: Ask again — this time using inbox_search + workspace_search
together: how does webhook verification work here?
You: Remind me tomorrow 10am: "review Alice's PR on webhook auth".
One workspace + one saved URL + one reminder — Claude now has the code, the docs, and a follow-up. Nothing left your laptop.
"I use three LLM providers and have no idea what I'm spending"
You: vault_set name="ANTHROPIC_ADMIN_KEY" value="sk-admin-..."
You: vault_set name="OPENAI_ADMIN_KEY" value="sk-admin-..."
You: cost_import source="anthropic" days=30
You: cost_import source="openai" days=30
You: cost_import source="claude_pro_csv" path="C:\downloads\pro-jul.csv"
You: cost_summary period="month"
→ total_cost_usd: 47.30
by_source: { "anthropic": 22.10, "openai": 15.20, "claude_pro": 10.00 }
internal_cost_usd: 0.00 (nothing routed through local Nexus this month)
Three APIs, one number. Admin keys stayed in the OS keyring the whole time.
"Bring back everything I've ever discussed with Claude about React hooks"
[Export past chats from Claude Desktop UI, drop into ~/.nexus/chatlog-imports/]
You: chatlog_import
→ files_scanned: 47, conversations_indexed: 47
You: recall query="React hooks useEffect dependency array" days=180 k=8
→ 8 snippets from 5 past conversations, each with title + created_at.
Nine months of context, one query.
"I want to research a topic across the web without leaving Claude"
Requires the fetch MCP bridge:
bridges:
enabled: true
upstream_servers:
- name: fetch
command: python
args: ["-m", "mcp_server_fetch"]
Then:
You: bridge_fetch_fetch url="https://news.ycombinator.com/item?id=..."
inbox_save_url url="https://news.ycombinator.com/item?id=..."
You: recall query="hacker news discussion I saved about rust async"
→ surfaces the saved page from the inbox.
Bridged fetch + inbox + recall — three subsystems, one workflow.
How the whole thing connects
When you launch Claude Desktop:
- Claude reads
claude_desktop_config.json, sees thenexusMCP entry, spawnsnexus serve --transport stdioas a subprocess. - Nexus's
NexusApp.startup()runs in order:- Configure logging → open the SQLite database → migrate schema to v14.
- Register backends (Ollama, OpenAI, Anthropic, …).
- Build the router pipeline + guardrails + cache.
- Boot the personal subsystems that have
enabled: trueinnexus.yaml. - Start the dashboard as a background asyncio task on
127.0.0.1:8765. - Register every MCP tool on
FastMCP.
- Claude Desktop calls
initialize()over stdin/stdout, thenlist_tools(). It now knows about ~126 tools including the personal ones. - Every user message that ends with a tool call flows Claude → stdio → Nexus → subsystem → storage → response → stdio → Claude.
- Every tool call is traced. The dashboard reads the same SQLite database and renders
/traces,/subsystems,/metricslive. - When you quit Claude Desktop, its subprocess dies →
NexusApp.shutdown()fires → watchers stop → dashboard closes → DB commits are flushed.
One process. One database. One dashboard. Every tool traced. Every secret redacted.
Install
Prerequisites
- Python 3.11 or newer
- Claude Desktop (Windows / macOS)
- Optional: Ollama or another local LLM runtime if you want offline routing
Install Nexus
git clone https://github.com/asmit557/nexus
cd nexus
# Core install
pip install -e .
# With personal-productivity extras (vault, watchers, whisper, dateparser, etc.)
pip install -e ".[personal]"
# Everything (also enables vectors, guardrails, RAG parsers, agents, multimodal, graph)
pip install -e ".[all]"
Verify
nexus doctor --show-skips
Every check should be PASS except any optional extras you didn't install (they show as SKIP).
First-time setup
# Creates ~/.nexus/config/nexus.yaml and ~/.nexus/.env from templates,
# migrates the SQLite database, and wires Nexus into Claude Desktop's config.
nexus init
nexus init finds Claude Desktop's config file automatically — including the Windows Store (MSIX) install path at %LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\claude_desktop_config.json.
Start
There's nothing to start manually. Once wired, Claude Desktop launches Nexus as a subprocess when it starts. Just launch Claude Desktop and open a new chat.
# Only run this if you want a dashboard-only instance (not required for Claude Desktop use):
nexus serve
Verify integration
Open any Claude Desktop chat and try:
Use the ping tool from nexus.
You should see {"pong": true, "server": "nexus", "version": "1.0.0"}. If not, quit Claude Desktop from the system tray and reopen — that forces the subprocess to restart.
Open http://127.0.0.1:8765/subsystems in a browser to see the live dashboard.
Configuration
All flags live in ~/.nexus/config/nexus.yaml. Personal-productivity subsystems default to enabled: false so an install is a no-op until you opt in.
Minimal example — everything enabled
server:
transport: stdio # what Claude Desktop uses
observability:
dashboard:
enabled: true
port: 8765
# --- Personal-productivity subsystems ---
workspaces:
enabled: true
watch: true # incremental re-index on file save
max_file_size_kb: 512
# ignore_patterns has sensible defaults; override to add your own
inbox:
enabled: true
watch_screenshots: true # OCR new images in screenshot_dirs
watch_clipboard: true
clipboard_poll_seconds: 2.0
# screenshot_dirs: [] # empty → auto-detect Downloads / Pictures
chatlog:
enabled: true
# claude_data_path: null # null → ~/.nexus/chatlog-imports/
poll_interval_minutes: 15
retention_days: 365
vault:
enabled: true
backend: keyring # or "file" for a Fernet blob under data_dir
redact_from_traces: true
notifications:
enabled: true
channel: desktop # or "log" / "webhook"
webhook_url: null
costs:
enabled: true
anthropic_api_key_env: ANTHROPIC_ADMIN_KEY # vault name
openai_api_key_env: OPENAI_ADMIN_KEY
refresh_cron: "0 3 * * *" # 3 AM daily auto-refresh (via scheduler)
bridges:
enabled: false # flip on when you have upstream servers
upstream_servers:
- name: fetch
command: python
args: ["-m", "mcp_server_fetch"]
env: {}
Environment variables
Any config field can be overridden with an env var following the NEXUS_<SECTION>__<FIELD> convention:
export NEXUS_WORKSPACES__ENABLED=true
export NEXUS_VAULT__BACKEND=file
Backend API keys
Cloud-provider keys are only loaded from env vars, never from YAML. Each backend declares an api_key_env (e.g. OPENAI_API_KEY). Store them in ~/.nexus/.env:
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
GROQ_API_KEY=gsk_...
Testing the setup
After enabling a subsystem, restart Claude Desktop and try these prompts:
Workspaces:
Register the folder C:\path\to\my-project as a workspace called "myproj" using workspace_register.
Search the "myproj" workspace for "database migration".
Read src/main.py from the "myproj" workspace.
Inbox:
Save https://en.wikipedia.org/wiki/Model_Context_Protocol to my inbox.
Search my inbox for "protocol servers".
Chat recall (after dropping exported JSONs into ~/.nexus/chatlog-imports/):
Run chatlog_import.
Recall query="database migration decision" days=30.
Vault:
vault_set name="TEST_KEY" value="fake-value-for-testing"
vault_list_names
vault_delete "TEST_KEY"
Reminders:
remind when="in 60 seconds" message="test notification"
Voice (in your terminal, not Claude):
nexus voice -s 5 -m base
Cost ledger:
cost_import source="claude_pro_csv" path="C:\path\to\claude-billing.csv"
cost_summary period="month"
Bridges (after installing mcp-server-fetch):
bridge_list
bridge_fetch_fetch url="https://example.com"
The dashboard at http://127.0.0.1:8765/subsystems will show every enabled subsystem with a wired badge and live counts.
Privacy & data handling
Nexus is local-first by design. Here's exactly what stays on your machine vs. what leaves it.
Always local (never leaves your machine)
- Workspaces — file contents, embeddings, chunk indexes. Only ever read through
workspace_read_file. - Inbox — URL fetches happen from your machine; extracted text + embeddings stay in your local SQLite.
- Chat recall — imported chat JSONs, embeddings, per-conversation state.
- Vault — secret bytes live in the OS keyring (Credential Manager / Keychain / Secret Service) OR a Fernet-encrypted file. Never plaintext on disk.
- Reminders — jobs in your local scheduler table.
- Voice transcription —
faster-whisperruns in-process; audio never leaves. - Cost ledger — CSV imports read from disk; the rollup stays in SQLite.
- All observability — traces, metrics, logs live under
~/.nexus/.
Leaves your machine only when you explicitly invoke it
- LLM calls to cloud backends (OpenAI, Anthropic, Groq, …) go directly from Nexus → the provider you asked to route to.
- Web fetches (
inbox_save_url,web_research) contact the site you specified. - Cost API imports (
cost_import source="anthropic") hit the provider's admin usage endpoint. - MCP bridges may spawn processes that themselves make network calls (a Gmail bridge does, obviously; a fetch bridge does when you invoke it).
Redaction
- Every value stored in the vault is registered with the log redaction processor. Any log line, trace input, or trace output containing that value is rewritten to
***REDACTED***before hitting disk. - Well-known secret shapes (Bearer tokens,
sk-...,sk-ant-..., AWS access keys, JWTs, SHA-1 signatures) are always redacted, even without registering them. - Field-name substring matching redacts keys named
api_key,token,password,authorization, and friends — but preservestokens_in/tokens_outand similar accounting fields.
Where the data lives on disk
~/.nexus/
├── config/
│ └── nexus.yaml ← your config
├── nexus.db ← SQLite: traces, workspaces, inbox, secrets metadata, cost rows, …
├── logs/
│ └── nexus.log ← structured logs (redacted)
├── vectors/ ← LanceDB embeddings when enabled
├── sandboxes/ ← code executor workdirs
├── chatlog-imports/ ← drop exported chat JSONs here
├── training/ ← reserved for future use
└── vault.enc, vault.key ← only present when vault.backend=file
You can back up the whole ~/.nexus/ directory as one unit. nexus backup does exactly this using VACUUM INTO for the database.
Frequently asked questions
Q: Do I have to install everything at once?
No. Every subsystem is opt-in. The default nexus init gives you routing + memory + RAG + dashboard, nothing else. Enable subsystems one at a time in nexus.yaml.
Q: Do I need Ollama to use Nexus? No. Nexus works with cloud providers alone (OpenAI, Anthropic, Groq, …). It also works with Ollama alone. Or any combination.
Q: Does Nexus store my chats with Claude Desktop?
Not automatically. Chats live in Claude Desktop's own storage. The chat-recall subsystem only sees conversations you manually export from Claude Desktop's UI and drop into ~/.nexus/chatlog-imports/.
Q: Where do vault secrets actually live on Windows?
In the Windows Credential Manager under the service name nexus. Open Control Panel → User Accounts → Credential Manager → Web Credentials to see them. On macOS: Keychain Access, service nexus. On Linux: whatever your libsecret daemon uses (usually GNOME Keyring or KWallet).
Q: What happens if I delete ~/.nexus/vault.key?
The file-backend vault becomes unreadable — this is by design. Rotate by re-setting every secret with vault_set. Keyring-backed secrets are unaffected.
Q: Can multiple users share a Nexus install? Not intended. Nexus is per-user, per-machine. The SQLite database, keyring entries, and dashboard are all single-tenant.
Q: How much disk does it use?
Baseline: ~20 MB for the code + a few MB of SQLite. RAG collections grow linearly with content indexed (~1-2× the raw text size once embedded). Whisper models: 145 MB (base) to 3 GB (large-v3). Everything is under ~/.nexus/.
Q: How much CPU/RAM does it use? Idle: negligible (one Python process, some background asyncio tasks). During indexing / embedding / transcription: whatever those workloads normally cost.
Q: Does the dashboard need to be open for anything to work? No. The dashboard is read-only. Nexus works exactly the same with or without a browser tab open on it.
Q: What happens when Claude Desktop updates?
Nothing — Nexus is a separate subprocess. Only the config file location matters, and nexus init handles that.
Q: Can I run Nexus without Claude Desktop, just for the dashboard?
Yes. nexus serve in a terminal boots everything. You lose the MCP surface (nobody's calling the tools) but the dashboard, doctor, backup, and CLI voice all work standalone.
Q: How do I upgrade?
git pull
pip install -e ".[personal]"
The SQLite schema migration runs automatically on next start. All migrations are additive (new tables only, no destructive ALTERs).
Q: Is there a hosted version? No. Nexus is deliberately local-only.
Troubleshooting
"Could not attach mcp server nexus" in Claude Desktop
Claude spawned Nexus but the subprocess died before completing the MCP handshake. Common causes:
- Port 8765 already in use. A previous Nexus or unrelated service is bound to it. Nexus pre-flights the port and skips the dashboard gracefully — but if you see repeated
dashboard.port_in_usewarnings, kill the offending process:netstat -ano | findstr :8765 taskkill /F /PID <pid> - You're running
nexus servemanually AND letting Claude spawn its own. Only one instance should own the port. Ctrl+C the manual one. - A broken subsystem is crashing startup. Check
~/.nexus/logs/nexus.logfor<name>.startup_failed. Setenabled: falsefor that subsystem and restart.
"pip install fails: WinError 32 nexus.exe is being used"
Claude Desktop's Nexus subprocess is holding the executable open:
- Quit Claude Desktop from the system tray (not just close the window).
taskkill /F /IM nexus.exe- Re-run pip install.
nexus doctor shows a FAIL row
Match the check name against these fixes:
config— YAML syntax error. Runnexus config checkfor a detailed line/column.database— corrupt SQLite. Restore withnexus restore <backup>.backends— API key env var missing. Add to~/.nexus/.envor set the env var directly.claude_desktop— config not registered. Runnexus init --force.
The dashboard is unreachable
- Confirm the port:
netstat -ano | findstr :8765. - Confirm
observability.dashboard.enabled: truein your config. - Confirm you're browsing to
http://127.0.0.1:8765(notlocalhost:8765— some corporate DNS blocks that).
Watchers aren't firing (screenshots / clipboard / workspaces)
- Install the extras:
pip install "nexus-mcp[personal]"(addswatchdog,pyperclip). - Restart Claude Desktop to reboot the subsystem — hot reload is not supported for watchers.
- Check
~/.nexus/logs/nexus.logforwatchdog_missingorpyperclip_missingmessages.
"vault secret not found: XYZ"
The {{vault.XYZ}} placeholder was resolved against an empty vault. Options:
- Set the secret:
vault_set name="XYZ" value="...". - Use
vault_list_namesto confirm what's stored. - If you're the caller: verify the exact name (case-sensitive after upper-casing).
Whisper transcription fails on first run
The faster-whisper model has to download from Hugging Face (~145 MB for base). Requires internet on first use per model. Subsequent runs use the cached weights.
Architecture (in one screen)
+------------------------------------------------------------+
| Claude Desktop ─stdio→ NexusApp |
+------------------------------------------------------------+
│
▼
+-----------------------------------------------------+
| MCP tool surface (~126 tools, all traced) |
+-----------------------------------------------------+
| Router pipeline: rules → cache → backend |
+-----------------------------------------------------+
| Subsystems (each opt-in, each an attr on NexusApp) |
| |
| memory · sessions · rag · sql · sandbox · delegate |
| · scheduler · research · vision · transcription |
| · ocr · imagegen · kg · personas · firewall |
| |
| + workspaces · inbox · chatlog · vault |
| + notifications · costs · bridges |
+-----------------------------------------------------+
│
▼
+-----------------------------------------------------+
| Storage: SQLite (aiosqlite, WAL, schema v14) |
| + OS keyring / vault.enc + LanceDB (optional) |
+-----------------------------------------------------+
│
▼
+-----------------------------------------------------+
| Dashboard @ 127.0.0.1:8765 |
| /healthz /readyz /metrics /traces /subsystems |
+-----------------------------------------------------+
- Every subsystem lives on a package under
src/nexus/<name>/and hangs offNexusAppas an attribute. - Every MCP tool guards for a disabled subsystem and returns
{"error": "<name> disabled"}rather than raising. - Every startup block is wrapped in
try/except— a broken subsystem logs<name>.startup_failedand continues. - The dashboard runs in a background asyncio task alongside the MCP stdio loop; a busy port is detected before uvicorn is invoked so it never cascades into MCP.
Rolling back a subsystem
Set its enabled flag to false in nexus.yaml and restart Claude Desktop. On-disk data (workspaces table, inbox items, secrets, imported cost rows) is preserved — the subsystem simply becomes invisible until re-enabled. Nothing is destructive.
Non-goals
Nexus is deliberately opinionated about what it doesn't do:
- No federation. Peer-to-peer multi-instance sync isn't a solo-user problem.
- No learned routing (bandit / semantic). These need traffic volume solo users don't produce; rules are enough.
- No training loop. Fine-tuning is a separate tool.
- No marketplace. A shareable-artifact store needs users first.
- No HITL approval subsystem. Claude Desktop is already interactive.
These were previously in scope and were cut in the 1.0 trim to keep the surface honest.
Development
# Full test suite (342 tests)
pytest tests/unit tests/integration tests/e2e -q
# Just the fast unit tests
pytest tests/unit -q
# One subsystem
pytest tests/integration/test_workspaces_service.py -v
Docs, tool inventory, config reference, and event catalog can be regenerated:
nexus docs generate --output docs/
Directory layout at a glance:
src/nexus/
├── server.py ← NexusApp: bootstraps + wires every subsystem
├── config/ ← Pydantic schemas + YAML/env loader
├── backends/ ← One adapter per LLM provider
├── router/ ← Rules router + cascade + estimator
├── cache/ ← Exact + semantic cache
├── rag/ ← Hybrid retrieval, parsers, vectorstores
├── memory/ ← Long-term + session store
├── agents/ ← Delegate, sandbox, SQL, web research
├── multimodal/ ← Vision, transcription (cloud + local), OCR, image gen
├── kg/ ← Knowledge graph service
├── personas/ ← Versioned prompt library
├── firewall/ ← Rule engine + audit log
├── observability/ ← Traces DB, tracing, redaction, conventions
├── scheduler/ ← Persistent async scheduler
├── dashboard/ ← FastAPI routes + Jinja templates
├── tools/ ← MCP tool registrations, one file per category
│
├── workspaces/ ← Phase 1: folder-scoped RAG collections
├── inbox/ ← Phase 1: URLs / PDFs / snippets + watchers
├── chatlog/ ← Phase 1: cross-conversation recall
├── vault/ ← Phase 2: encrypted secrets + redaction hook
├── notifications/ ← Phase 2: OS reminders on the scheduler
├── costs/ ← Phase 4: unified cost ledger
└── bridges/ ← Phase 4: upstream MCP-server proxying
Contributions welcome — the codebase is deliberately small and every subsystem follows the same pattern (service + tools + tests + dashboard card).
Glossary
Non-obvious terms in this README, in the order you'd meet them:
- MCP (Model Context Protocol) — Anthropic's open protocol for connecting Claude (and other LLMs) to external tools and data. Every MCP server exposes named tools with JSON schemas; the client (Claude Desktop) discovers and calls them.
- stdio transport — one of the two MCP transports. The client spawns the server as a subprocess and talks to it via stdin/stdout. Nexus uses this.
- FastMCP — the Python framework Nexus uses to register MCP tools. Provides the
@mcp.tool()decorator that turns a Python function into a callable MCP tool. - RAG (Retrieval-Augmented Generation) — indexing documents so an LLM can search + read them at query time instead of stuffing everything into the prompt.
- BM25 — a classical keyword-ranking algorithm. Cheap, no embeddings needed. Strong when the question uses vocabulary from the source.
- Dense retrieval — semantic search via embedding similarity. Strong on paraphrases + concept drift.
- RRF (Reciprocal Rank Fusion) — the scoring formula Nexus uses to combine BM25 and dense rankings without calibration.
- Embedding — a fixed-length vector representation of text. Similar meanings → nearby vectors.
- Trace — the record of one tool call: input, output, backend used, cost, latency, guardrail decisions. Persisted to SQLite.
- Subsystem — one self-contained package under
src/nexus/<name>/that hangs offNexusAppas an attribute. - Guardrails — input/output filters over a tool call: PII scrubbing, prompt-injection detection, refusal consistency.
- Firewall — a rule engine over outbound URLs, domains, and content patterns. Same idea as a network firewall, applied to LLM tool calls.
- Scheduler — the persistent job queue backing reminders and any future cron work. Restart-safe.
- Vault — encrypted secret storage. Backends: OS keyring or Fernet-encrypted file.
- Fernet — a symmetric-encryption format from the
cryptographypackage. AES-128-CBC + HMAC-SHA256 in one authenticated envelope. - PBKDF2-HMAC-SHA256 — the key-derivation function used to turn the vault passphrase into an AES key. 200k iterations by default.
- Watchdog — a Python library that watches filesystem events (created, modified, deleted). Nexus uses it for workspace incremental reindex and screenshot capture.
- Whisper / faster-whisper — OpenAI's open-weights speech-to-text model.
faster-whisperis a CTranslate2 port that runs 4× faster with the same accuracy. plyer— cross-platform library that Nexus uses to fire OS notifications (Windows toast, macOS notification centre, Linux libnotify).pyperclip— cross-platform clipboard access.dateparser— natural-language date parser ("tomorrow 9am", "in 2 hours").- CTranslate2 — the C++ inference runtime under
faster-whisper.
Contributing
Contributions are welcome. A few conventions to preserve:
- New subsystems are opt-in. Add a config section with
enabled: bool = False. Existing users must see zero behaviour change until they flip a flag. - Startup is fault-tolerant. Wrap subsystem init in
try/except; log<name>.startup_failedand null out the attribute rather than aborting. - Tools are defensive. Every MCP tool checks
app.<subsystem> is Noneand returns{"error": "<name> disabled"}. - Schema is additive. New tables only. No destructive
ALTER TABLEmigrations. - Redaction is baked in. Any log line, trace input, or trace output flows through the redaction processor before hitting disk.
- Tests come with the code. New subsystem = new
tests/unit/test_<name>_*.py+tests/integration/test_<name>_service.py.
Every subsystem in this codebase follows the same shape — service class + MCP tools + tests + dashboard card. Copy an existing one (workspaces is a good template) and adapt.
Support & questions
- Issues: https://github.com/asmit557/nexus/issues
- Logs:
~/.nexus/logs/nexus.log— always check here first; the structured events tell you what happened. - Doctor:
nexus doctor --show-skips --json— a single command that reports every runtime + config + integration check. - Traces:
http://127.0.0.1:8765/traces— every tool call is inspectable.
License
Apache 2.0. See LICENSE.
README fetched from the repository 2 days ago. The original is authoritative.