@geohar/pi-sharedserver

Pi extension: manage shared backend processes via the sharedserver CLI.

Packages

Package details

extension

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 of sharedserver on 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):

  1. $SHAREDSERVER_CONFIG, if set and present.
  2. A per-project file walked up from the session cwd: .sharedserver.json or .sharedserver/servers.json.
  3. 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_startsharedserver up --profile pi --json selects 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 pi re-resolves the same selection and releases it. A reload/resume/fork keeps the processes and re-attaches. Process exit and SIGINT/SIGTERM/SIGHUP also 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