From b3448031088447d76d80ac6b2bfa08320973a2d9 Mon Sep 17 00:00:00 2001 From: Igor Soarez Date: Thu, 29 Oct 2026 21:40:43 +0000 Subject: pi: generate mcp.json from ~/.config/pi/mcp.d fragments pi reads user-level MCP servers from one file, and a private layer linked that file to the same copy on every host -- so every host got a server only one machine could run. Build it the way models.json is built, from fragments another layer or one machine drops in mcp.d; this repo ships none, and with none the file is left absent. pi-models.py becomes pi-merge.py, which takes the key to merge and an optional base file, and serves both. --- link/pi.sh | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'link/pi.sh') diff --git a/link/pi.sh b/link/pi.sh index 5aec48f..727ed2f 100755 --- a/link/pi.sh +++ b/link/pi.sh @@ -1,6 +1,7 @@ #!/bin/bash -# pi's extensions directory, and its settings.json and models.json, generated. +# pi's extensions directory, and its settings.json, models.json and mcp.json, +# generated. # Dry run by default; pass `yes` to apply. set -euo pipefail @@ -98,7 +99,8 @@ esac # never writes it, keeping its runtime state in the sibling models-store.json -- # so what lands is whatever the repo and the fragments say. A hand-edit of # ~/.pi/agent/models.json does not survive a relink; put it in a fragment. -pi_models_out="$(DRY_RUN="$is_dry_run" python3 "$dotfiles_dir/link/pi-models.py" \ +pi_models_out="$(DRY_RUN="$is_dry_run" python3 "$dotfiles_dir/link/pi-merge.py" \ + providers \ "$config_dir/pi/models.json" \ "$xdg_config_dir/pi/models.d" \ "$pi_dir/models.json")" @@ -113,3 +115,27 @@ do error) red "pi models: ${line#*:}" ;; esac done <<< "$pi_models_out" + +# pi's mcp.json, the same way: pi reads user-level MCP servers from this one +# file only, and the servers are another layer's or one machine's business -- +# a browser on one host, a server behind a credential -- so this repo ships +# none. It is built from every ~/.config/pi/mcp.d/*.json alone, and left +# absent where there are none. It used to be a private layer's link to one +# file for every host, which gave each of them a server only one could run. +# `pi mcp add` writes here and does not survive a relink; add a fragment. +pi_mcp_out="$(DRY_RUN="$is_dry_run" python3 "$dotfiles_dir/link/pi-merge.py" \ + mcpServers \ + - \ + "$xdg_config_dir/pi/mcp.d" \ + "$pi_dir/mcp.json")" + +while IFS= read -r line +do + case "${line%%:*}" in + note) yellow "pi mcp: ${line#*:}" ;; + wrote) green "pi mcp: ${line#*:}" ;; + unchanged) green "pi mcp: unchanged" ;; + would-write) yellow "pi mcp will be generated: ${line#*:}" ;; + error) red "pi mcp: ${line#*:}" ;; + esac +done <<< "$pi_mcp_out" -- cgit v1.2.3