README.md
Rama main · réplica de lectura del repositorio original.
# MynetworK - Multi-Source Network Dashboard
<div align="center">
<img src="src/icons/logo_mynetwork.svg" alt="MynetworK" width="96" height="96" />


[](https://github.com/Erreur32/MynetworK/pkgs/container/mynetwork)



[](https://scorecard.dev/viewer/?uri=github.com/Erreur32/MynetworK)
[](https://github.com/Erreur32/MynetworK/security/code-scanning)
[](https://sonarcloud.io/summary/overall?id=Erreur32_MynetworK)

<h1 align="center">MynetworK</h1>
<p align="center">
Unified Freebox + UniFi management + Network Scanner.
</p>
**📖 [Read in French (Lire en français)](README.fr.md)**
<p align="center">
<sub>Powered by</sub><br/>
<img src="img-capture/free-sas.png" alt="Freebox" height="32" />
<img src="img-capture/ubiquiti-networks.svg" alt="Ubiquiti Unifi" height="32" />
</p>
**A multi-source network dashboard to manage Freebox, UniFi and Network Scanner**
[Installation](#installation) | [Features](#features) | [Configuration](#configuration) | [MCP](#mcp-model-context-protocol) | [Home Assistant](#home-assistant)
</div>
---
## Overview
**MynetworK** is a unified dashboard to manage and monitor multiple local network data sources:

- **Freebox** - Full management of your Freebox (Ultra, Delta, Pop)
- **UniFi Controller** - Monitor and manage your UniFi infrastructure
- **Network Scan** - Device discovery and analysis with automatic vendor detection
## Features
- 🔐 **User authentication** - JWT system with role management (admin, user, viewer)
- 🔌 **Plugin system** - Modular architecture to easily add new data sources
- 📊 **Unified dashboard** - Centralized view of all plugin data
- 📝 **Full logging** - Traceability of all actions with advanced filters
- 👥 **User management** - Administration interface to manage access
- 🐳 **Docker ready** - Simplified deployment with Docker Compose
- 🌐 **Internationalization (i18n)** - English (default) and French; language switcher in header. See [Docs/INTERNATIONALIZATION.md](Docs/INTERNATIONALIZATION.md).
- 🤖 **MCP server** - Native [Model Context Protocol](https://modelcontextprotocol.io) server for Freebox, UniFi and the network scanner, LAN-only. See [MCP](#mcp-model-context-protocol) below.
> [!TIP]
>
> <details>
> <summary> 🖼️ Click to view other screenshots</summary>
>
> 
>
> 
>
> 
>
> 
>
> </details>
> [!NOTE]
> A dedicated and **fully functional** version for **Home Assistant** is available here: [https://github.com/Erreur32/HA_mynetwork](https://github.com/Erreur32/HA_mynetwork)
>
## Installation
### Prerequisites
- Docker and Docker Compose
- Local network access to Freebox/UniFi
### docker-compose.yml
```yaml
services:
mynetwork:
image: ghcr.io/erreur32/mynetwork:latest
restart: unless-stopped
ports:
# Dashboard external port (default: 7505)
- "${DASHBOARD_PORT:-7505}:3000"
environment:
# Required secret (no fallback in production)
JWT_SECRET: ${JWT_SECRET}
# Configuration
CONFIG_FILE_PATH: ${CONFIG_FILE_PATH:-/app/config/mynetwork.conf}
FREEBOX_HOST: ${FREEBOX_HOST:-mafreebox.freebox.fr}
FREEBOX_TOKEN_FILE: /app/data/freebox_token.json
# Host metrics access
HOST_ROOT_PATH: ${HOST_ROOT_PATH:-/host}
# PUBLIC_URL (optional, only with reverse proxy)
# PUBLIC_URL: https://dashboard.example.com
volumes:
# Persistent data (Freebox token, local DB, etc.)
- ./data:/app/data
# Host metrics (read-only) — CPU, RAM, network, ARP table, hostname
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /etc/hostname:/host/etc/hostname:ro
- /etc/hosts:/host/etc/hosts:ro
# Network capabilities for scan (ping / ARP)
cap_add:
- NET_RAW
- NET_ADMIN
- SETUID
- SETGID
cap_drop:
- ALL
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3000/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
```
> [!IMPORTANT]
> **v0.7.80 Breaking Change:** Docker volumes have changed. `/:/host:ro` and `docker.sock` mounts removed for security. See [CHANGELOG](CHANGELOG.md#0780---2026-04-15) for migration instructions.
**Launch:**
```bash
# Start with Docker Compose
docker-compose up -d
# View logs
docker-compose logs -f
# Stop
docker-compose down
# Update image
docker-compose pull
docker-compose up -d
```
**Recommendation:** Use the **[.env file](#secure-jwt_secret-configuration)** (`.env` at project root); Docker Compose reads it automatically and injects `JWT_SECRET` into the container.
> For more details, see the [Secure JWT_SECRET configuration](#secure-jwt_secret-configuration) section for all configuration methods, security best practices and verification.
The dashboard will be available at:
- **http://localhost:7505** - from the host machine
- **http://SERVER_IP:7505** - from another device on the network
<details>
<summary><strong>Advanced configuration</strong></summary>
### Optional: External configuration file (`.conf`)
You can use an external `.conf` file for configuration:
1. **Create the config file:**
```bash
cp config/mynetwork.conf.example config/mynetwork.conf
# Edit config/mynetwork.conf to your needs
```
2. **Mount the file in Docker:**
Uncomment the line in `docker-compose.yml`:
```yaml
volumes:
- mynetwork_data:/app/data
- ./config/mynetwork.conf:/app/config/mynetwork.conf:ro
```
3. **Automatic sync:**
- On startup, if the `.conf` file exists → import into the database
- If the file does not exist → export current configuration
4. **API endpoints:**
- `GET /api/config/export` - Export current configuration
- `POST /api/config/import` - Import from file
- `GET /api/config/file` - Check file status
- `POST /api/config/sync` - Manual sync
#### Nginx (reverse proxy)
If you use **nginx** as a reverse proxy in front of MynetworK, set `PUBLIC_URL` to the public URL (via nginx), not the Docker container URL.
**Case 1: Without nginx (direct access)**
No `PUBLIC_URL` needed. The app works on the mapped port (e.g. `http://YOUR_IP:7505`).
**Case 2: With nginx (reverse proxy)**
1. **Nginx config:** See `Docs/nginx.example.conf` for a full example.
2. **docker-compose.yml:**
```yaml
environment:
- PUBLIC_URL=http://mynetwork.example.com
# Or with HTTPS:
# - PUBLIC_URL=https://mynetwork.example.com
```
3. **Minimal nginx example:**
```nginx
server {
listen 80;
server_name mynetwork.example.com;
location / {
proxy_pass http://192.168.1.150:7505;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}
```
4. **Benefits of nginx:** SSL/HTTPS (e.g. Let's Encrypt), multiple services on one server, caching, clean URLs.
See `Docs/nginx.example.conf` for a complete HTTP/HTTPS setup.
</details>
<details id="secure-jwt_secret-configuration">
<summary><strong>Secure JWT_SECRET configuration</strong></summary>
**Critical – Security:** The default JWT secret (`change-me-in-production-please-use-strong-secret`) is for **development only**. In production you **must** set the `JWT_SECRET` environment variable to a unique, strong value.
#### Why it matters
`JWT_SECRET` is used to sign and verify JWT authentication tokens. A weak or default secret allows an attacker to:
- Forge valid JWTs and impersonate any user
- Access the system without authentication (full admin access)
- Compromise all users and their data
- Change permissions and access restricted features
#### Where it is used
`JWT_SECRET` is loaded at server startup in `server/services/authService.ts` from `process.env.JWT_SECRET`. If unset, the default value is used and a warning is logged. The secret is used to sign tokens on login and verify them on authenticated requests.
## Dependencies & supply-chain
MynetworK runs entirely on your machine and only talks to the network equipment you configure (Freebox / UniFi / your LAN). It never phones home. The full list of npm packages it ships is in [`package.json`](./package.json); below is what's important to know.
### Runtime — backend (Node / Express)
| Package | Used for | Notes |
| --- | --- | --- |
| `express` | HTTP server | Stable, widely audited |
| `helmet` | Security headers (CSP, HSTS, X-Frame-Options…) | Defense-in-depth |
| `express-rate-limit` | API and write-route throttling, IPv6-aware | |
| `compression` | gzip responses | |
| `cors` | CORS rules | Tight defaults |
| `bcrypt` | Password hashing | |
| `jsonwebtoken` | Issue / verify JWTs | See `JWT_SECRET` above |
| `better-sqlite3` | Local DB (data, sessions, scans, topology snapshots, manual placements) | Database file lives in the mounted `./data` volume — back it up like any DB |
| `node-cron` | Daily topology refresh + scheduled scans | Local only, no internet |
| `ws` | WebSockets for live UI updates | Listens on the same port as the HTTP server |
### Runtime — frontend (React / Vite)
| Package | Used for | Notes |
| --- | --- | --- |
| `react` / `react-dom` | UI framework | |
| `react-router-dom` | Client-side routing | |
| `zustand` | State management | |
| `i18next` / `react-i18next` | English / French translations | |
| `recharts` | Bar / line charts on the dashboard | Brings `d3-shape`, `d3-scale`, `d3-array`, etc. as transitive deps |
| `@xyflow/react` (React Flow) | Interactive topology graph (`/topology`) | Brings `d3-zoom`, `d3-drag`, `d3-selection`, `d3-interpolate` |
| `dagre` | Tree / hierarchical layout for the topology | |
| `html-to-image` | PNG / SVG export of the topology | Runs entirely in the browser, no upload |
| `jspdf` | PDF export of the topology (A4, raster) | Browser-only |
| `lucide-react` | Icon set | |
| `react-markdown` + `remark-gfm` | Render the in-app changelog | Sanitised |
| `leaflet` + `leaflet.markercluster` | Map view | |
| `sonner` | Toast notifications | |
### Security considerations
- **No telemetry.** None of these packages call out to a third-party server when the app runs. The Docker container does not need outbound internet to function — it only reaches the LAN equipment you configure.
- **Export libraries (`html-to-image`, `jspdf`)** are 100 % client-side. Generated PNG / PDF / SVG files stay in your browser; nothing is uploaded.
- **Topology stack (`@xyflow/react`, `dagre`)** runs in the browser and on a SQLite-backed snapshot. The snapshot only contains data your active plugins already have access to (Freebox / UniFi devices on your LAN).
- **Charts stack (`recharts`)** renders local data only.
- **Supply chain.** Dependabot is enabled on this repo and proposes weekly updates. Snyk runs on every push (`Snyk Security` in CI). SonarCloud runs on every push to flag suspicious changes.
- **Reproducible builds.** `package-lock.json` is committed. The published Docker image is built from a tagged commit by GitHub Actions (`Build & Push Docker Image` workflow) and pushed to GHCR, so you can verify what's running.
- **Updating.** Pull the new image from GHCR (`docker compose pull && docker compose up -d`). The version that's running is shown in the UI footer and at startup in the container logs.
If you spot a security issue, please open a private GitHub security advisory rather than a public issue.
## Configuration
#### Configuration methods (recommended order)
##### 1. **`.env` file (recommended for production)**
Docker Compose automatically reads `.env` at project root.
1. **Generate a strong secret** (at least 32 characters):
```bash
# Linux/macOS:
openssl rand -base64 32
# Windows PowerShell:
[Convert]::ToBase64String((1..32 | ForEach-Object { Get-Random -Maximum 256 }))
```
2. **Create a `.env` file** at project root:
```bash
# .env
JWT_SECRET=your_generated_secret_here_minimum_32_chars
DASHBOARD_PORT=7505
FREEBOX_HOST=mafreebox.freebox.fr
PUBLIC_URL=https://mynetwork.example.com
```
3. **Restrict permissions:**
```bash
chmod 600 .env
```
4. **Start with Docker Compose:**
```bash
docker-compose up -d
```
##### 2. **`.env` with `--env-file`**
```bash
echo "JWT_SECRET=$(openssl rand -base64 32)" > .env.production
docker-compose --env-file .env.production up -d
```
#### Verification
After startup, check that a custom secret is in use:
```bash
docker-compose logs | grep -i "jwt\|secret"
```
If you see a warning like: *"Using default JWT secret. Please set JWT_SECRET..."*, then `JWT_SECRET` was not set correctly.
**In the web UI:** Administration → Security → JWT configuration section shows whether the default secret is used.
#### Security best practices
1. **Length:** At least **32 characters** (64 recommended)
2. **Random:** Use random data, not predictable passwords
3. **Unique:** Each production instance should have its own secret
4. **Storage:** Restrict `.env` permissions (`chmod 600`), add `.env` to `.gitignore`, use a secrets manager for critical deployments
5. **Rotation:** Change the secret periodically (e.g. every 6–12 months) or if compromise is suspected
6. **Dev vs prod:** Use different secrets for development and production
#### JWT secret rotation
1. Generate a new secret: `openssl rand -base64 32`
2. Update `.env`: `JWT_SECRET=new_secret`
3. Restart: `docker-compose restart`
4. All users will need to log in again (existing tokens are invalidated).
#### Example `.env`
```bash
# .env – Production
JWT_SECRET=your_openssl_generated_secret_here
DASHBOARD_PORT=7505
FREEBOX_HOST=mafreebox.freebox.fr
PUBLIC_URL=https://mynetwork.example.com
```
</details>
## First login
1. Open the dashboard (http://localhost:7505 or your server IP).
2. Log in with default credentials:
- **Username:** `admin`
- **Password:** `admin123`
3. **Change the password immediately after first login.**
4. Configure your plugins in the **Plugins** page.
<details>
<summary><strong>Features</strong></summary>
### Main dashboard
- **Multi-source statistics** - Unified view of all plugin data
- **Real-time charts** - Throughput, connections, stats
- **Network overview** - Global state of your infrastructure
### Plugin management
- **Centralized configuration** - UI to configure each plugin
- **Enable/disable** - Fine-grained control of each data source
- **Connection status** - Check each plugin’s state
### Freebox (plugin)
- **Full dashboard** - All Freebox features (WiFi, LAN, Downloads, VMs, TV, Phone)
- **Compatibility** - Ultra, Delta, Pop
- **Native API** - Official Freebox OS API
### UniFi Controller (plugin)
- **Network monitoring** - AP stats, clients, traffic
- **Multi-site** - Multiple UniFi sites
- **Real-time data** - Automatic stats updates
- **Dual API** - Local Controller (node-unifi) and Site Manager API (cloud)
- **Stats badges** - System stats in header (throughput, uptime, devices)
### Network Scan (plugin)
- **Auto discovery** - Full local network scan (IPs, MAC, hostnames)
- **Vendor detection** - Automatic manufacturer identification (Wireshark DB, Freebox/UniFi, or external API)
- **Scheduled scans** - Periodic full scan and refresh
- **History** - Device evolution over time with charts
- **Wireshark vendor DB** - Full integration with Wireshark `manuf` and auto-update
- **Priority system** - Hostname/vendor detection order (Freebox, UniFi, Scanner)
- **Modern UI** - Interactive table with sort, filters, search and inline hostname editing
### User management (admin)
- **Full CRUD** - Create, edit, delete users
- **Roles** - Permissions (admin, user, viewer)
- **Security** - Passwords hashed with bcrypt
### Activity logs (admin)
- **Full traceability** - All actions logged
- **Advanced filters** - By user, plugin, action, level, period
- **Export** - Log export (planned)
</details>
<details>
<summary><strong>Architecture</strong></summary>
MynetworK uses a modular architecture:
- **React frontend** (TypeScript) - Modern UI
- **Express backend** (TypeScript) - REST API and WebSocket
- **SQLite database** - Configuration and data storage
- **Plugin system** - Extensible architecture for new data sources
See [DEV/ARCHITECTURE_PLUGINS.md](DEV/ARCHITECTURE_PLUGINS.md) for details.
</details>
<details>
<summary><strong>Documentation</strong></summary>
### For users
- **[CHANGELOG.md](CHANGELOG.md)** - Change log and new features
### For developers
See **[DEV/README-DEV.md](DEV/README-DEV.md)** for development documentation.
**Main docs:**
- **[DEV/DOCUMENTATION.md](DEV/DOCUMENTATION.md)** - Documentation index
- **[DEV/GUIDE_DEVELOPPEMENT.md](DEV/GUIDE_DEVELOPPEMENT.md)** - Developer guide
- **[DEV/ARCHITECTURE_PLUGINS.md](DEV/ARCHITECTURE_PLUGINS.md)** - Plugin architecture
**Docs folder ([Docs/](Docs/)):** Setup and production guides (UniFi, Freebox, env vars, Nginx, troubleshooting, reset). Key docs have **English** and **French** versions (see [Docs/README.md](Docs/README.md)).
</details>
## Home Assistant
> [!IMPORTANT]
> A dedicated **fully functional** version for **Home Assistant** is available:
> [](https://github.com/Erreur32/HA_mynetwork)
>
> - **HACS integration** ready
> - **Add-on** support
> - **Optimized** for HA Supervisor/Docker
> - **Auto-discovery** of Freebox/UniFi networks
See [HA Repo](https://github.com/Erreur32/HA_mynetwork) for installation.
## MCP (Model Context Protocol)
MynetworK ships a native [MCP](https://modelcontextprotocol.io) server, so an MCP client (e.g. Claude Desktop, Claude Code) can query and control your Freebox, UniFi controller and network scanner directly, no need to go through the web UI.
- **LAN-only** - not exposed through the reverse proxy; gated by an IP allowlist (RFC1918 + loopback + Tailscale 100.64.0.0/10) in addition to a dedicated bearer token
- **Behind a reverse proxy** - the allowlist checks the TCP peer address and ignores `X-Forwarded-For` by default. If a proxy is the only path to the app and you want the real client checked, list it in `MCP_TRUSTED_PROXIES` (IPv4/CIDR, comma-separated); the same setting covers API tokens and the Prometheus export
- **Named, multi-token auth** - separate from the JWT web session; create as many named tokens as you need (one per client/device), each with its own optional expiry, from the admin panel
- **Managed from the admin UI** - the "MCP" tab lets you create tokens (shown once), revoke them individually, and shows whether MCP is enabled, the endpoint, active sessions and each token's status/last-used time
### 1. Generate an access token
From the admin panel: Settings > MCP > General tab > "New token". Name it, pick a duration (or unlimited), and copy the token shown: it is never displayed again.
A CLI fallback also exists, for when the admin panel is unreachable (see [Docs/MCP_DEV_SETUP.md](Docs/MCP_DEV_SETUP.md) for the full explanation):
```bash
# Docker (production, default deployment, container name is "mynetwork")
docker exec -it -u node mynetwork node_modules/.bin/tsx scripts/mcp-token.ts
# Local / dev (bare npm run dev, no container)
npm run mcp:token
```
Each CLI run creates a new token named "CLI" with no expiry, without touching tokens created from the admin UI.
### 2. Connect a client
The server speaks the standard MCP **Streamable HTTP** transport at `http://<LAN-IP>:<PORT>/api/mcp`: swap in the LAN IP and port printed above, and the token, for any client below.
**Claude Code (CLI)**
```bash
claude mcp add --transport http mynetwork http://<LAN-IP>:<PORT>/api/mcp \
--header "Authorization: Bearer <token>"
```
Or add it to a project's `.mcp.json`:
```json
{
"mcpServers": {
"mynetwork": {
"type": "http",
"url": "http://<LAN-IP>:<PORT>/api/mcp",
"headers": { "Authorization": "Bearer <token>" }
}
}
}
```
**Claude Desktop**
Paid plans (Pro/Max/Team/Enterprise) can add it directly under Settings → Connectors, which speaks Streamable HTTP natively. On the free plan, or for any stdio-only client, bridge it with [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) in `claude_desktop_config.json`:
```json
{
"mcpServers": {
"mynetwork": {
"command": "npx",
"args": [
"mcp-remote@latest",
"http://<LAN-IP>:<PORT>/api/mcp",
"--header",
"Authorization: Bearer <token>"
]
}
}
}
```
**Other agents / clients**
Any MCP client with Streamable HTTP support (Cursor, Continue, custom agents built on the MCP SDK, ...) only needs the URL and the bearer header above. For a stdio-only client, the same `mcp-remote` bridge shown for Claude Desktop applies.
### Available tools
| Source | Read | Write |
|---|---|---|
| **Freebox** | system info, connection status, WiFi status/stations, LAN hosts, DHCP config/leases, switch ports, call log, contacts | reboot, toggle WiFi/BSS, add a DHCP static lease |
| **UniFi** | devices, clients, WLANs, network config, port forwarding rules, bandwidth report, system info, sites | block/unblock a client, enable/disable a WLAN, restart a device |
| **Network scanner** | stats, devices, device by IP, blacklist | trigger/rescan a scan, add a manual IP, rename a host, blacklist add/remove |
Write actions are limited to non-destructive operations (nothing deletes data), though some are disruptive by nature (a reboot or a device restart briefly interrupts connectivity — tool descriptions flag this explicitly).
### Examples
What a tool call looks like from an MCP client, and the kind of response it gets back (values below are illustrative, not real data).
**Freebox — read: which devices are currently on WiFi**
```
> freebox_get_wifi_stations
```
```json
{
"success": true,
"result": [
{
"mac": "AA:BB:CC:11:22:33",
"hostname": "laptop-julien",
"ip": "192.168.1.42",
"band": "5G",
"rssi": -52,
"connected_since": 3841
},
{
"mac": "AA:BB:CC:44:55:66",
"hostname": "iphone-julien",
"ip": "192.168.1.57",
"band": "2G4",
"rssi": -67,
"connected_since": 120
}
]
}
```
**UniFi — write: block a client from the network**
```
> unifi_block_client { "mac": "AA:BB:CC:77:88:99" }
```
```json
{
"success": true,
"result": {
"mac": "AA:BB:CC:77:88:99",
"blocked": true
}
}
```
## Security
- **JWT authentication** - Secure tokens with expiration
- **Password hashing** - bcrypt with salt rounds
- **Auth middleware** - Protection of sensitive routes
- **Action logging** - Full traceability
- **Role-based access** - Granular permissions
## Contributing
Contributions are welcome.
### Guidelines
- Follow existing code style (4 spaces, camelCase, comments in English)
- Add TypeScript types for new code
- Test changes before submitting
- Document new features
- Follow project rule files
## License
This project is licensed under the MIT License. See [LICENSE](LICENSE) for details.
## Acknowledgments
### Original project
This project is heavily inspired by **Freebox OS Ultra Dashboard** by [HGHugo](https://github.com/HGHugo/FreeboxOS-Ultra-Dashboard). Many thanks to the original author for the work that served as a base for MynetworK.
**Original project:** [FreeboxOS-Ultra-Dashboard](https://github.com/HGHugo/FreeboxOS-Ultra-Dashboard)
### Others
- [Free](https://www.free.fr) for the Freebox and its open API
- [Freebox SDK](https://dev.freebox.fr) for API documentation
- [Ubiquiti](https://www.ui.com) for UniFi
- The open-source community for the libraries used
---
<div align="center">
**Made with ❤️ for multi-source network management**
**MynetworK - Multi-Source Network Dashboard**
</div>