{"id":"7e1450b8-6c29-47c5-8af5-8ac0a92ae6cd","slug":"kierank07-nexus","kind":"mcp","name":"Nexus","summary":"Single-user dashboard for net worth, Gmail, calendar and smart home. Go, React, SQLite, passkeys.","owner":"KieranK07","repoUrl":"https://github.com/KieranK07/Nexus","license":"MIT","licenseTier":"permissive","trust":"community","stars":1,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-06-27T21:50:35.000Z","addedAt":"2026-10-21T04:45:00.779Z","logoUrl":"https://avatars.githubusercontent.com/u/101907753?u=99ca99d4a5afdcfda34b6d69ffe630bd3eea253c&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["data-analytics","databases","productivity"],"tags":["go","personal-dashboard","react","self-hosted","webauthn","dashboard","passkeys","sqlite"],"runtime":"go","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-27T00:33:30.794Z","sample":false,"url":"https://conduits.dev/tools/kierank07-nexus","language":"Go","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# Nexus\n\n![Nexus home screen with demo data](docs/img/dashboard.png)\n\nA private, single-user personal dashboard. Go backend, React/TypeScript\nfrontend, SQLite, WebAuthn passkey login. It binds to `127.0.0.1` only, is\nreached by its owner over a Cloudflare Tunnel, and ships as a single binary with\nthe frontend embedded.\n\n## Tabs\n\n- **Landing page**: greeting, morning briefing and a summary card per module.\n- **CONSOLE**: a shell in the browser over a PTY; `claude` inside it opens a\n  chat pane, `claude -cli` the normal TUI.\n- **NET WORTH**: holdings valued at live prices, manual cash and liability\n  balances, optional Plaid bank linking, monthly snapshots and a 30-day delta.\n- **ADVISOR**: a personal financial advisor chat (Claude Opus via the Claude Code\n  CLI on your subscription, not the API) that reads your net worth data through\n  its own tools and keeps long-term memory in SQLite.\n- **EMAIL**: a Gmail client with folders, search, a sanitized HTML reading pane,\n  drafts and send.\n- **CALENDAR**: a month grid across Google calendars, with event creation.\n- **CONTROL**: status checks and start/stop for owner-defined processes.\n- **HOME**: smart-home switches through SmartThings, or TP-Link Kasa on the LAN.\n- **MEMORY**: a force-directed graph of long-term memory notes.\n- **SETTINGS**: Google connection and client-side preferences.\n\nEvery integration is optional. Without its credentials a tab shows a\n\"not connected\" state instead of an error.\n\n## Requirements\n\n- Go 1.26+\n- Node 20+ and npm\n\n## Quick start\n\nThis runs a local instance on `localhost` with a throwaway passkey.\n\n```sh\ncp .env.example .env\ngo run ./cmd/nexus genkey          # paste the output into NEXUS_MASTER_KEY\ngo run ./cmd/nexus genkey          # paste this one into NEXUS_SETUP_TOKEN\n# in .env, for local use:\n#   NEXUS_RP_ID=localhost\n#   NEXUS_ORIGIN=http://localhost:8765\n\nnpm --prefix web install\nnpm --prefix web run build         # builds web/dist, embedded by go:embed\ngo run ./cmd/nexus                 # serves http://127.0.0.1:8765\n```\n\nOpen `http://localhost:8765` (use `localhost`, not `127.0.0.1`, so it matches\nthe RP ID), click **Enroll passkey**, paste the setup token, and save the\nrecovery code it shows once. Then remove `NEXUS_SETUP_TOKEN` from `.env` and\nrestart. `GET /healthz` returns `{\"status\":\"ok\"}`.\n\nA passkey is bound to one RP ID, so a `localhost` enrollment will not work on the\nproduction domain. See [docs/setup.md](docs/setup.md) for production enrollment\nand each integration.\n\n## Configuration\n\nAll settings come from the environment, loaded from `.env` (gitignored). Every\nvariable is documented in [`.env.example`](.env.example).\n\n| Variable | Required | Purpose |\n| --- | --- | --- |\n| `NEXUS_MASTER_KEY` | yes | base64 AES-256 key that encrypts secrets at rest |\n| `NEXUS_RP_ID` | yes | WebAuthn RP ID, no default |\n| `NEXUS_ORIGIN` | yes | full origin the browser sends |\n| `NEXUS_PORT` | no (8765) | loopback port |\n| `NEXUS_DB_PATH` | no (`nexus.db`) | SQLite file |\n| `NEXUS_SETUP_TOKEN` | enrollment only | gates the one-time passkey enrollment |\n| `ANTHROPIC_API_KEY` | no | assistant and briefing |\n| `GOOGLE_CLIENT_ID` / `_SECRET` | no | Gmail and Calendar |\n| `FINNHUB_API_KEY` or `TWELVEDATA_API_KEY` | no | equity prices (crypto uses CoinGecko) |\n| `PLAID_CLIENT_ID` / `_SECRET` / `_ENV` | no | bank and brokerage linking |\n| `SMARTTHINGS_CLIENT_ID` / `_SECRET` | no | smart-home control |\n| `NEXUS_CC_BASE_DIR` | no | enables the CONSOLE shell, confined to this dir |\n| `NEXUS_MCP_TOKEN` | no | mounts the read-only remote MCP endpoint |\n\n## Security\n\n- Loopback-only listener; remote access goes through the tunnel.\n- One passkey, one Argon2id-hashed recovery code, cookie sessions with CSRF\n  tokens and idle plus absolute expiry.\n- OAuth refresh tokens and Plaid access tokens are AES-256-GCM encrypted in\n  SQLite. The audit log records events, never tokens or message content.\n- The Content-Security-Policy is `'self'` by default, with these exceptions:\n  `script-src` adds `'wasm-unsafe-eval'` (the self-hosted Spline runtime) and\n  `https://cdn.plaid.com`; `style-src` allows `'unsafe-inline'` (xterm.js and\n  React inline styles); `img-src` and `worker-src` allow `blob:`; `connect-src`\n  and `frame-src` allow the Plaid hosts. There is no `'unsafe-eval'`, and\n  `frame-ancestors` is `'none'`. The full header is in\n  `internal/server/server.go`.\n\n## Adding a module\n\nTabs and dashboard cards come from a backend registry.\n\n1. Create `internal/integrations/<name>/` with a type that implements\n   `integrations.Module`: `Name()` (route prefix `/api/<name>`), `Routes(chi.Router)`\n   (mounted behind session auth) and `Data(ctx)` (the card payload).\n2. Register it in `cmd/nexus/main.go` with `registry.Register(<name>.New(...))`.\n\nThe card then appears in `/api/dashboard` and the module is queryable over the\nMCP endpoint; implementing `mcp.Detailer` returns richer detail there. `internal/integrations/memgraph` is a\nsmall read-only example.\n\n## Commands\n\n```sh\ngo run ./cmd/nexus           # start the server\ngo run ./cmd/nexus genkey    # generate a random base64 key\ngo run ./cmd/nexus help      # usage\ngo test ./...                # Go tests\ngo build -o nexus ./cmd/nexus\n```\n\n## Docs\n\n- [docs/setup.md](docs/setup.md): passkey enrollment, Google, Plaid, home\n  automation, CONSOLE shell\n- [docs/internals.md](docs/internals.md): remote MCP endpoint, assistant model\n  routing and memory, net worth math, the ADVISOR tab\n\n## License\n\nMIT\n"}