A plugin-based desktop dashboard for macOS. Plugins are Docker containers that serve their own UI, communicate with the host through a REST API, and expose tools to AI assistants via the Model Context Protocol (MCP).
Nexus is a Tauri 2 app with a React frontend and a Rust backend. Plugins are Docker images that get pulled, started, and managed by the host. Each plugin container:
- Serves a web UI on an assigned port (rendered in the Nexus shell)
- Authenticates to the Host API with a per-plugin bearer token
- Declares permissions for what it can access (filesystem, network, processes, etc.)
- Optionally exposes MCP tools that AI assistants like Claude can call
The host runs a native MCP gateway at http://127.0.0.1:9600/mcp (Streamable HTTP transport). AI clients connect directly — no sidecar binary needed. When plugins start or stop, tool availability updates automatically.
Claude Desktop / AI Client
|
| MCP (Streamable HTTP)
v
Nexus Host API (Axum) — :9600/mcp
|
| Docker API
v
Plugin Containers
[hello-world] [permission-tester] [your-plugin]
Frontend: React 19, TypeScript, Tailwind CSS, Zustand Backend: Rust, Tauri 2, Axum, Bollard (Docker) MCP Gateway: Native Streamable HTTP Plugin SDK: Auto-generated TypeScript client from OpenAPI spec
- macOS (Apple Silicon or Intel)
- Docker Desktop running
- Rust (stable)
- Node.js 22+ with pnpm
# Install frontend dependencies
pnpm install
# Run in development mode (starts Vite + Tauri)
cargo tauri devcargo tauri buildThis produces a signed .dmg and .app bundle in src-tauri/target/release/bundle/.
Plugins are Docker containers with a plugin.json manifest. See examples/plugins/hello-world/ for a complete example.
{
"id": "com.yourname.my-plugin",
"name": "My Plugin",
"version": "0.1.0",
"description": "What it does",
"image": "my-plugin:latest",
"ui": { "port": 80, "path": "/" },
"permissions": ["system:info"],
"health": { "endpoint": "/health", "interval_secs": 30 },
"mcp": {
"tools": [
{
"name": "do_something",
"description": "Does something useful",
"permissions": ["system:info"],
"input_schema": { "type": "object", "properties": {} }
}
]
}
}Plugins exchange their secret (NEXUS_PLUGIN_SECRET) for a short-lived access token via POST /api/v1/auth/token, then use it as a Bearer token to call the Host API:
| Endpoint | Description |
|---|---|
GET /api/v1/system/info |
Host OS, hostname, uptime, CPU, memory |
GET /api/v1/fs/read?path=... |
Read a file |
GET /api/v1/fs/list?path=... |
List a directory |
POST /api/v1/fs/write |
Write a file |
GET /api/v1/process/list |
Running processes |
GET /api/v1/docker/containers |
Docker containers |
POST /api/v1/network/proxy |
Proxy an HTTP request |
GET /api/v1/settings |
Plugin-scoped settings |
PUT /api/v1/settings |
Update settings |
Full OpenAPI spec available at GET /api/openapi.json when the app is running.
TypeScript SDK for Nexus plugins — published to GitHub Packages:
npm install @imdanibytes/nexus-sdk --registry=https://npm.pkg.github.comsrc/ React frontend
src-tauri/ Rust backend (Tauri shell, Host API, plugin manager)
packages/nexus-sdk/ TypeScript SDK (generated client + hand-written wrapper)
examples/plugins/ Example plugins (hello-world, permission-tester)
examples/extensions/ Test extension binaries
scripts/ Build & release scripts
docs/ Architecture docs, roadmap, release checklist
Plugins declare required permissions in their manifest. Users approve permissions at install time. Available scopes:
system:info filesystem:read filesystem:write process:list network:proxy docker:read
Runtime approval dialogs appear when a plugin accesses a resource for the first time.
Releases are automated via GitHub Actions. Pushing a v* tag triggers:
- build - Compiles the app for both
aarch64-apple-darwinandx86_64-apple-darwin - build-sdk - Validates the plugin SDK compiles
- publish - Creates a GitHub Release with signed DMGs and publishes the SDK to GitHub Packages
The app includes an auto-updater that checks for new releases on startup.