@geohar/pi-sharedserver
Pi extension: manage shared backend processes via the sharedserver CLI.
Package details
Install @geohar/pi-sharedserver from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@geohar/pi-sharedserver- Package
@geohar/pi-sharedserver- Version
0.8.2- Published
- Aug 19, 2026
- Downloads
- 518/mo · 518/wk
- Author
- georgeharker
- License
- MIT
- Types
- extension
- Size
- 81.7 KB
- Dependencies
- 0 dependencies · 0 peers
Pi manifest JSON
{
"extensions": [
"./src/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-sharedserver
A Pi extension that manages shared backend processes through the
sharedserver CLI.
When a Pi session starts, the extension brings up this host's profile with
sharedserver up --profile pi; when the session quits it releases it with
sharedserver down. The sharedserver binary reads the config, expands ${VAR},
and selects the profile's servers itself. Because sharedserver is reference-counted,
multiple Pi instances — or other tools using the same name — share a single backend
process. The server survives Pi restarts inside its grace period and shuts down
automatically when the last client leaves.
It is the Pi counterpart of sharedserver's Claude Code and OpenCode plugins and reads
the same servers.json, so one config drives every client.
About sharedserver
sharedserver
(crates.io) is a small Rust CLI that runs a
long-lived process on behalf of several clients with reference counting, a configurable
grace period after the last client detaches, and a watcher that reaps dead clients. It
exposes a tiny verb surface — use, unuse, up, down, list, info, check
(up/down bring a whole profile up or down) — and stores
per-server state in lockfiles under $XDG_RUNTIME_DIR/sharedserver/ (or
/tmp/sharedserver/). This extension only ever speaks to that CLI.
You do not need to install it. On first use the extension fetches a matching
sharedserver from GitHub releases if one isn't already present — prebuilt, so no Rust
toolchain is involved. Any sharedserver already on PATH (or in ~/.cargo/bin,
~/.local/bin, /opt/homebrew/bin, /usr/local/bin) is used as-is, and an explicit
$SHAREDSERVER_BIN is always honoured. The version fetched matches this extension's own
version, so the pair stay in lockstep (identical to the Claude Code and OpenCode
plugins, with which it shares an install lock).
Requirements
- pi coding agent (
@earendil-works/pi-coding-agent) curl, for the one-time fetch ofsharedserveron first use — nothing else.- Node.js 18+
Install
pi install npm:@geohar/pi-sharedserver
Or from the repo (git-install shim resolves plugins/pi):
pi install git:github.com/georgeharker/sharedserver
Configuration
The extension reads a servers.json via the shared discovery chain (first hit wins; a
per-project file replaces the global rather than merging):
$SHAREDSERVER_CONFIG, if set and present.- A per-project file walked up from the session cwd:
.sharedserver.jsonor.sharedserver/servers.json. - The global
~/.config/sharedserver/servers.json.
{
"servers": {
"my-vector-db": {
"command": "qdrant",
"args": ["--config-path", "${HOME}/.config/qdrant/config.yaml"],
"gracePeriod": "1h",
"logFile": "${HOME}/.local/state/sharedserver/qdrant.log"
}
}
}
${VAR} references are expanded from the environment, matching the Claude hook's
envsubst pass, so one file behaves identically in every client.
Per-server fields
| Field | Meaning |
|---|---|
command |
Binary to run (required unless lazy). |
args |
Arguments passed to command. |
env |
Extra env vars forwarded via --env KEY=VALUE. |
gracePeriod |
Grace period after the last client detaches, e.g. 30m, 1h, 2h30m. |
logFile |
Capture the managed server's stdout/stderr to this path. |
metadata |
Optional metadata string forwarded to sharedserver. |
lazy |
Only attach if already running; never start it. |
skipIfEnv |
Env var name; when set (non-empty) this server is skipped entirely (another host already launched it). |
Environment overrides
| Variable | Purpose |
|---|---|
SHAREDSERVER_BIN |
Explicit path to the sharedserver binary. |
SHAREDSERVER_LOCKDIR |
Override SHAREDSERVER_LOCKDIR for child invocations. |
SHAREDSERVER_CONFIG |
Explicit path to a servers.json, overriding discovery. |
PI_SHAREDSERVER_NOTIFY |
Set to false to silence TUI notifications. |
PI_SHAREDSERVER_PROFILE |
Profile this session brings up. Default pi. |
Profiles
The extension brings up the pi profile (override with $PI_SHAREDSERVER_PROFILE).
Add an optional top-level profiles map to servers.json to give each host its own
slice:
{
"servers": { "chroma": { "command": "chroma" }, "watchman": { "lazy": true } },
"profiles": { "pi": ["chroma"] }
}
A server named by no profile (watchman above) is universal and comes up for every
host. A config with no profiles brings up every server, exactly as before — nothing you
already have needs to change.
Lifecycle
session_start→sharedserver up --profile pi --jsonselects and starts this host's servers (refcounted; shared across clients). A 2.5s health check then verifies each server the report said started/attached is still alive.session_shutdown(reason === "quit") →sharedserver down --profile pire-resolves the same selection and releases it. A reload/resume/fork keeps the processes and re-attaches. Process exit andSIGINT/SIGTERM/SIGHUPalso drain cleanly.
No servers configured is a normal, quiet state — an unconfigured install starts cleanly.
Commands
The extension registers a /sharedserver slash command for on-demand control and
introspection beyond the automatic host-profile lifecycle:
| Command | Does |
|---|---|
/sharedserver status |
Show running servers |
/sharedserver up <profile> |
Bring up a (task) profile on demand |
/sharedserver down <profile> |
Release it |
/sharedserver config show |
Print the whole config |
/sharedserver config lookup <name> |
One server's def + the profiles it's in |
Verbs and the config sub-verbs autocomplete. Config mutations
(register/unregister) are intentionally not exposed as slash commands — those
are install-time edits, not in-session actions.
License
MIT