mcp server
Nexus
Single-user dashboard for net worth, Gmail, calendar and smart home. Go, React, SQLite, passkeys.
Set up
Runs on your computer. Pick your agent and operating system.
This project does not publish an install method we can turn into a config. Follow the README instead.
README
synced Oct 27, 2026Nexus
A private, single-user personal dashboard. Go backend, React/TypeScript
frontend, SQLite, WebAuthn passkey login. It binds to 127.0.0.1 only, is
reached by its owner over a Cloudflare Tunnel, and ships as a single binary with
the frontend embedded.
Tabs
- Landing page: greeting, morning briefing and a summary card per module.
- CONSOLE: a shell in the browser over a PTY;
claudeinside it opens a chat pane,claude -clithe normal TUI. - NET WORTH: holdings valued at live prices, manual cash and liability balances, optional Plaid bank linking, monthly snapshots and a 30-day delta.
- ADVISOR: a personal financial advisor chat (Claude Opus via the Claude Code CLI on your subscription, not the API) that reads your net worth data through its own tools and keeps long-term memory in SQLite.
- EMAIL: a Gmail client with folders, search, a sanitized HTML reading pane, drafts and send.
- CALENDAR: a month grid across Google calendars, with event creation.
- CONTROL: status checks and start/stop for owner-defined processes.
- HOME: smart-home switches through SmartThings, or TP-Link Kasa on the LAN.
- MEMORY: a force-directed graph of long-term memory notes.
- SETTINGS: Google connection and client-side preferences.
Every integration is optional. Without its credentials a tab shows a "not connected" state instead of an error.
Requirements
- Go 1.26+
- Node 20+ and npm
Quick start
This runs a local instance on localhost with a throwaway passkey.
cp .env.example .env
go run ./cmd/nexus genkey # paste the output into NEXUS_MASTER_KEY
go run ./cmd/nexus genkey # paste this one into NEXUS_SETUP_TOKEN
# in .env, for local use:
# NEXUS_RP_ID=localhost
# NEXUS_ORIGIN=http://localhost:8765
npm --prefix web install
npm --prefix web run build # builds web/dist, embedded by go:embed
go run ./cmd/nexus # serves http://127.0.0.1:8765
Open http://localhost:8765 (use localhost, not 127.0.0.1, so it matches
the RP ID), click Enroll passkey, paste the setup token, and save the
recovery code it shows once. Then remove NEXUS_SETUP_TOKEN from .env and
restart. GET /healthz returns {"status":"ok"}.
A passkey is bound to one RP ID, so a localhost enrollment will not work on the
production domain. See docs/setup.md for production enrollment
and each integration.
Configuration
All settings come from the environment, loaded from .env (gitignored). Every
variable is documented in .env.example.
| Variable | Required | Purpose |
|---|---|---|
NEXUS_MASTER_KEY | yes | base64 AES-256 key that encrypts secrets at rest |
NEXUS_RP_ID | yes | WebAuthn RP ID, no default |
NEXUS_ORIGIN | yes | full origin the browser sends |
NEXUS_PORT | no (8765) | loopback port |
NEXUS_DB_PATH | no (nexus.db) | SQLite file |
NEXUS_SETUP_TOKEN | enrollment only | gates the one-time passkey enrollment |
ANTHROPIC_API_KEY | no | assistant and briefing |
GOOGLE_CLIENT_ID / _SECRET | no | Gmail and Calendar |
FINNHUB_API_KEY or TWELVEDATA_API_KEY | no | equity prices (crypto uses CoinGecko) |
PLAID_CLIENT_ID / _SECRET / _ENV | no | bank and brokerage linking |
SMARTTHINGS_CLIENT_ID / _SECRET | no | smart-home control |
NEXUS_CC_BASE_DIR | no | enables the CONSOLE shell, confined to this dir |
NEXUS_MCP_TOKEN | no | mounts the read-only remote MCP endpoint |
Security
- Loopback-only listener; remote access goes through the tunnel.
- One passkey, one Argon2id-hashed recovery code, cookie sessions with CSRF tokens and idle plus absolute expiry.
- OAuth refresh tokens and Plaid access tokens are AES-256-GCM encrypted in SQLite. The audit log records events, never tokens or message content.
- The Content-Security-Policy is
'self'by default, with these exceptions:script-srcadds'wasm-unsafe-eval'(the self-hosted Spline runtime) andhttps://cdn.plaid.com;style-srcallows'unsafe-inline'(xterm.js and React inline styles);img-srcandworker-srcallowblob:;connect-srcandframe-srcallow the Plaid hosts. There is no'unsafe-eval', andframe-ancestorsis'none'. The full header is ininternal/server/server.go.
Adding a module
Tabs and dashboard cards come from a backend registry.
- Create
internal/integrations/<name>/with a type that implementsintegrations.Module:Name()(route prefix/api/<name>),Routes(chi.Router)(mounted behind session auth) andData(ctx)(the card payload). - Register it in
cmd/nexus/main.gowithregistry.Register(<name>.New(...)).
The card then appears in /api/dashboard and the module is queryable over the
MCP endpoint; implementing mcp.Detailer returns richer detail there. internal/integrations/memgraph is a
small read-only example.
Commands
go run ./cmd/nexus # start the server
go run ./cmd/nexus genkey # generate a random base64 key
go run ./cmd/nexus help # usage
go test ./... # Go tests
go build -o nexus ./cmd/nexus
Docs
- docs/setup.md: passkey enrollment, Google, Plaid, home automation, CONSOLE shell
- docs/internals.md: remote MCP endpoint, assistant model routing and memory, net worth math, the ADVISOR tab
License
MIT