nanocore
v1.0.60
Published
CLI to orchestrate Volted-compatible NodeServers
Readme
NanoCore
CLI to orchestrate NanoServers — AI microservices with built-in asset management, real-time discovery, and system telemetry.
Quick Start
npx nanocore@latest startTo use a custom config file for storage paths:
npx nanocore@latest start --paths ./nanocore.config.jsonTo register a NanoServer:
npx nanocore@latest register ./path/to/serverInstall
npm install -g nanocoreCLI
nanocore start [--paths <config>] # Start all servers + asset server + WebSocket
nanocore register [path] # Register a NanoServer (reads nanoserver.json)
nanocore add <user/repo> # Clone from GitHub, register, install deps
nanocore install [path] # Install dependencies for a server
nanocore list # List registered servers
nanocore env <server> <key> <val> # Set env variable (by name or package id)
nanocore unregister [path] # Remove a serverArchitecture
nanocore start boots three services:
| Service | Port | Role | |---------|------|------| | Asset Server (HTTP) | 3001 | File uploads, downloads, presigned URLs, dependency management | | WebSocket | 50052 | Real-time push: server status, assets, telemetry, resources | | Orchestrator | — | Spawns/manages child processes, hot-reload, graceful shutdown |
NanoServers signal readiness by printing [NANOSERVER_READY] to stdout.
Configuration
NanoServer manifest (nanoserver.json)
Each NanoServer needs this in its root:
{
"serverDisplayName": "My Server",
"serverPackageId": "my-server",
"language": "javascript"
}Optional field: dependencies (array of model/asset dependencies with hash, type, and providers).
Supported languages: javascript, python. Python servers use a venv and run server.py.
Storage paths (nanocore.config.json)
Located in CWD (or override with --paths). Paths are relative to $HOME unless absolute.
{
"paths": {
"temp": "nanocore/temp",
"nodeservers": "nanocore/nodeservers",
"image": "nanocore/media/image",
"video": "nanocore/media/video",
"script": "nanocore/media/script",
"mesh": "nanocore/media/mesh",
"file": "nanocore/media/file",
"tensor": "nanocore/media/tensor",
"checkpoint": "nanocore/models/checkpoint",
"lora": "nanocore/models/lora",
"vae": "nanocore/models/vae",
"embedding": "nanocore/models/embedding",
"controlnet": "nanocore/models/controlnet",
"upscale": "nanocore/models/upscale"
},
"ephemeral": {
"ttl_hours": 8,
"gc": true
}
}Server registry (nodeservers.json)
Stored automatically at:
- Linux/macOS:
~/.config/nanocore/nodeservers.json - Windows:
%APPDATA%\nanocore\nodeservers.json - Override:
NANOCORE_CONFIGenv variable
Environment variables
| Variable | Default | Description |
|----------|---------|-------------|
| ASSET_HTTP_PORT | 3001 | Asset server port |
| ASSET_API_TOKEN | changeme | Bearer token for API auth |
| ASSET_HOST | localhost | Hostname used in NANOCORE_HTTP_ENDPOINT URL injected into NanoServers |
| PRESIGNED_SECRET | random | JWT secret for presigned URLs |
| NANOCORE_LOG_LEVEL | info | Log level (error, warn, info, debug, verbose, silent). LOG_LEVEL also accepted as fallback |
| NANOCORE_CONFIG | — | Override path for nodeservers.json |
NanoCore injects these into every child NanoServer: PORT, SERVER_UID, NANOCORE_HTTP_ENDPOINT, NANOCORE_TOKEN, PYTHON_ENV, PYTHONUNBUFFERED, FORCE_COLOR.
API
All endpoints require Authorization: Bearer <ASSET_API_TOKEN>.
Assets
| Method | Path | Description |
|--------|------|-------------|
| POST | /assets | Upload file (multipart: file, type, meta, ephemeral) |
| GET | /assets | List assets (query: type, hash) |
| GET | /assets/:hash/meta | Get asset metadata |
| GET | /assets/:hash/presigned | Get presigned download URL (1h window) |
| GET | /assets/:hash/download | Download (via presigned token or Bearer). Also: /assets/:hash/download/:filename |
| DELETE | /assets/:hash | Delete asset |
| POST | /assets/:hash/promote | Promote ephemeral asset to persistent storage |
Uploads are ephemeral by default (set ephemeral=false for persistent). Ephemeral assets expire after ttl_hours and are cleaned by GC every 15 minutes. All assets are deduplicated by SHA-256 hash.
Dependencies
| Method | Path | Description |
|--------|------|-------------|
| GET | /nodeservers/:serverUid/dependencies | List dependencies (with installed status) |
| POST | /nodeservers/:serverUid/dependencies | Download a dependency (filename or hash) |
| DELETE | /nodeservers/:serverUid/dependencies | Remove installed dependency |
Dependencies are declared in nanoserver.json and downloaded via IPFS or HTTP with hash verification.
Other
| Method | Path | Description |
|--------|------|-------------|
| POST | /nodeservers | Add server from GitHub ({ "repository": "user/repo" }) |
| POST | /resources | Report resource allocation/free (from NanoServers) |
| GET | /system/info | System overview (CPU, RAM, GPU, runtime) |
| GET | /jobs | List active/queued download jobs |
| GET | /jobs/:jobId | Get job status |
WebSocket (port 50052)
Clients receive a full state snapshot on connect, then real-time events:
| Message type | Trigger |
|---|---|
| init | Connection (servers + assets + resources) |
| update | Server added/removed |
| asset_update | Asset added/removed |
| resource_update | Model loaded/freed in VRAM |
| dependency_progress | Download progress |
| telemetry | System stats (CPU, RAM, GPU, processes) |
Development
npm run build # Compile TypeScript
npm run dev # Run via ts-nodeLicense
MIT
