Intranet
Lightweight local HTTP file server with plugin support.
- Rating
- 4.2 (170 reviews)
- Downloads
- 17,627 downloads
- Version
- 1.0.0
Overview
Lightweight local HTTP file server with plugin support.
Complete Documentation
View Source →
Intranet
Lightweight local HTTP file server — no Apache/nginx needed, no root required. Serves static files, mounts plugin directories, and runs index.py entry points as CGI.
Entry point: {baseDir}/scripts/intranet.py
Setup
See SETUP.md for prerequisites and setup instructions.
Commands
python3 {baseDir}/scripts/intranet.py start # Start on default port 8080
python3 {baseDir}/scripts/intranet.py start --port 9000 # Custom port
python3 {baseDir}/scripts/intranet.py start --host 0.0.0.0 # LAN access (requires token + allowed_hosts)
python3 {baseDir}/scripts/intranet.py start --token SECRET # Enable bearer token auth
python3 {baseDir}/scripts/intranet.py status # Check if running
python3 {baseDir}/scripts/intranet.py stop # Stop server
Directory Layout
{workspace}/intranet/
├── config.json # Server config (NOT served)
└── www/ # Webroot (served files go here)
├── index.html
└── ...
Config lives in {workspace}/intranet/config.json, webroot is {workspace}/intranet/www/. The config file is never exposed to HTTP.
Plugins
Plugins mount external directories at URL prefixes. Configure in config.json:
{
"plugins": {
"banker": "{workspace}/skills/banker/web",
"deliveries": "{workspace}/skills/deliveries/web"
}
}
Plugin config supports simple (static only) or extended (with CGI hash) format:
{
"plugins": {
"static-only": "/path/to/dir",
"with-cgi": {
"dir": "/path/to/dir",
"hash": "sha256:abc123..."
}
}
}
- Plugin paths must be inside the workspace
- If CGI is enabled and a plugin has a
hash,index.pyat the plugin root handles all sub-paths — but only if its SHA-256 matches - Plugins without a
hashare static-only (CGI blocked even when globally enabled) - Generate a hash:
shasum -a 256 /path/to/index.py
CGI Execution
Off by default. Enable in config.json:
{
"cgi": true
}
When enabled, only files named index.py can execute as CGI:
- Webroot:
index.pyin any subdirectory handles that directory's requests - Plugins:
index.pyat the plugin root handles all plugin sub-paths - All other
.pyfiles → 403 Forbidden (never served, never executed) - Scripts must have the executable bit set (
chmod +x)
Security
- Webroot isolation — config.json is outside the webroot (
www/), never served - CGI off by default — must be explicitly enabled via
"cgi": truein config.json - Path containment — all resolved paths must stay within their base directory. Symlinks are followed but the resolved target is checked for containment.
- Plugin allowlist — only directories explicitly registered in
config.jsonare served; must be inside workspace - CGI restricted to
index.py— no arbitrary script execution; plugin CGI requires SHA-256 hash in config.json. Webroot CGI does not require a hash (webroot files are under your direct control) - All
.pyfiles blocked exceptindex.pyentry points (not served as text, not executed) - Host allowlist — optional
allowed_hostsrestricts whichHostheaders are accepted - Token auth — optional bearer token via
--tokenflag orconfig.json. Browser clients visit?token=SECRETonce → session cookie set → all subsequent navigation works. API clients useAuthorization: Bearerheader. - Path traversal protection — all paths resolved and validated before serving
- Default bind:
127.0.0.1(loopback only). LAN access via--host 0.0.0.0requires both token auth andallowed_hostsin config.json.
Workspace Detection
The server auto-detects the workspace by walking up from $PWD (or the script location) looking for a skills/ directory. The detected path is printed on startup so you can verify it.
To skip autodiscovery, set INTRANET_WORKSPACE to the workspace root:
INTRANET_WORKSPACE=/path/to/workspace python3 scripts/intranet.py start
Notes
- All state files are inside the workspace:
- Config:
{workspace}/intranet/config.json - PID:
{workspace}/intranet/.pid - Runtime:
{workspace}/intranet/.conf - Webroot:
{workspace}/intranet/www/ - No files are written outside the workspace
- 30-second timeout on CGI execution (when enabled)
Installation
openclaw install intranet
💻Code Examples
└── ...
Config lives in `{workspace}/intranet/config.json`, webroot is `{workspace}/intranet/www/`. The config file is never exposed to HTTP.
## Plugins
Plugins mount external directories at URL prefixes. Configure in `config.json`:}
- Plugin paths must be inside the workspace
- If CGI is enabled and a plugin has a `hash`, `index.py` at the plugin root handles all sub-paths — but only if its SHA-256 matches
- Plugins without a `hash` are static-only (CGI blocked even when globally enabled)
- Generate a hash: `shasum -a 256 /path/to/index.py`
## CGI Execution
**Off by default.** Enable in `config.json`:}
When enabled, only files named `index.py` can execute as CGI:
- **Webroot**: `index.py` in any subdirectory handles that directory's requests
- **Plugins**: `index.py` at the plugin root handles all plugin sub-paths
- **All other `.py` files** → 403 Forbidden (never served, never executed)
- Scripts must have the executable bit set (`chmod +x`)
## Security
- **Webroot isolation** — config.json is outside the webroot (`www/`), never served
- **CGI off by default** — must be explicitly enabled via `"cgi": true` in config.json
- **Path containment** — all resolved paths must stay within their base directory. Symlinks are followed but the resolved target is checked for containment.
- **Plugin allowlist** — only directories explicitly registered in `config.json` are served; must be inside workspace
- **CGI restricted to `index.py`** — no arbitrary script execution; plugin CGI requires SHA-256 hash in config.json. Webroot CGI does not require a hash (webroot files are under your direct control)
- **All `.py` files blocked** except `index.py` entry points (not served as text, not executed)
- **Host allowlist** — optional `allowed_hosts` restricts which `Host` headers are accepted
- **Token auth** — optional bearer token via `--token` flag or `config.json`. Browser clients visit `?token=SECRET` once → session cookie set → all subsequent navigation works. API clients use `Authorization: Bearer <token>` header.
- **Path traversal protection** — all paths resolved and validated before serving
- **Default bind: `127.0.0.1`** (loopback only). LAN access via `--host 0.0.0.0` requires both token auth and `allowed_hosts` in config.json.
## Workspace Detection
The server auto-detects the workspace by walking up from `$PWD` (or the script location) looking for a `skills/` directory. The detected path is printed on startup so you can verify it.
To skip autodiscovery, set `INTRANET_WORKSPACE` to the workspace root:python3 {baseDir}/scripts/intranet.py start # Start on default port 8080
python3 {baseDir}/scripts/intranet.py start --port 9000 # Custom port
python3 {baseDir}/scripts/intranet.py start --host 0.0.0.0 # LAN access (requires token + allowed_hosts)
python3 {baseDir}/scripts/intranet.py start --token SECRET # Enable bearer token auth
python3 {baseDir}/scripts/intranet.py status # Check if running
python3 {baseDir}/scripts/intranet.py stop # Stop server{workspace}/intranet/
├── config.json # Server config (NOT served)
└── www/ # Webroot (served files go here)
├── index.html
└── ...{
"plugins": {
"banker": "{workspace}/skills/banker/web",
"deliveries": "{workspace}/skills/deliveries/web"
}
}{
"plugins": {
"static-only": "/path/to/dir",
"with-cgi": {
"dir": "/path/to/dir",
"hash": "sha256:abc123..."
}
}
}{
"cgi": true
}Tags
Quick Info
Ready to Install?
Get started with this skill in seconds
Related Skills
4claw
4claw — a moderated imageboard for AI agents.
Aap Passport
Agent Attestation Protocol - The Reverse Turing Test.
Acestep Lyrics Transcription
Transcribe audio to timestamped lyrics using OpenAI Whisper or ElevenLabs Scribe API.
Adaptive Suite
A continuously adaptive skill suite that empowers Clawdbot.