Shoddy · Picker

Installing It

The download, getting it on PATH, registering it with each client, the local file, and doctor. Read this once per machine.

This is the long version of the quick start. It covers the same two steps, install and register, with all of the details. Come here when a step did not work, or when you use a client other than Claude Code.

Most of this page belongs to the tools level, which is the level that is always on. The one exception is the section on burler, a helper program that only the screenings level needs. Where it matters, each section says which level it serves.

The download

Each release has one archive for each operating system, where an archive is one file that holds others, like a zip file. Inside is a single program that needs no .NET runtime on your machine.

PlatformArchive
Windowspick-X.Y.Z-win-x64.zip
macOS, Apple siliconpick-X.Y.Z-osx-arm64.tar.gz
macOS, Intelpick-X.Y.Z-osx-x64.tar.gz
Linuxpick-X.Y.Z-linux-x64.tar.gz

The macOS and Linux archives are tar files, because only a tar file keeps the mark that lets a program run. Each archive also holds the notice and license files. Two Microsoft libraries are built into the program, and both use the MIT license. ScriptDom reads T-SQL, the SQL that SQL Server speaks, and the query gate is built on it. SqlClient carries the connection to the server.

ScriptDom and SqlClient are in pick and in no other program here. In the same way, PdfPig is only in fettle, and ONNX Runtime is only in burler, because no program here uses another's code. The full list of libraries is in THIRD-PARTY-NOTICES.md.

Putting it on PATH

PATH is the list of folders where your system looks for the commands you type. The commands below unpack pick into a folder of its own and add that folder to the list.

Windows · PowerShell
$dir = "$env:LOCALAPPDATA\Programs\pick"
New-Item -ItemType Directory -Force $dir | Out-Null
Expand-Archive pick-X.Y.Z-win-x64.zip -DestinationPath $dir -Force
Get-ChildItem $dir -Recurse | Unblock-File
$user = [Environment]::GetEnvironmentVariable('Path', 'User')
if ($user -notlike "*$dir*") {
    [Environment]::SetEnvironmentVariable('Path', "$user;$dir", 'User')
}
macOS and Linux
mkdir -p ~/.local/bin
tar -xzf pick-X.Y.Z-osx-arm64.tar.gz -C ~/.local/bin
xattr -d com.apple.quarantine ~/.local/bin/pick   # macOS only

Then open a new terminal and check that pick runs:

pick version

Three problems give no error message of their own. If the check fails, look at each of them in turn.

From source

You can also build pick yourself from this repository. No other project here has to be built first, because pick uses none of them:

./scripts/fettler-build.ps1 publish X.Y.Z    # makes the fettle, burler and pick archives

The archives land in the artifacts/publish/ folder. To build only pick, and only for this machine, run this instead:

dotnet publish pick -c Release -r win-x64 --self-contained `
    -p:PublishSingleFile=true -o $env:LOCALAPPDATA\Programs\pick

The same code on every platform

pick moves its network traffic the same way on Windows, macOS and Linux. Older SQL Server drivers used a network part that only Windows has. pick turns that part off twice: once in its settings file, and once in the first line of code it runs. No archive carries a Windows-only network library, so pick has no behaviour that only Windows shows.

Registering it, per client

To register pick is to add one entry to a file that your AI client reads, where a client is the program the assistant runs in. pick has no setup command, so you write the entry by hand. The entry holds the same command and arguments in every client, and only the file and the name of the outer key change.

ClientFileKey
Claude Code, this project.mcp.json in the project foldermcpServers
Claude Code, every project~/.claude.jsonmcpServers
Claude Desktopclaude_desktop_config.json in the Claude folder under your app datamcpServers
VS Code with Copilot Chat.vscode/mcp.json in the project folderservers

For Claude Code, the entry in .mcp.json is the one below, and the Claude Code extension for VS Code reads the same file.

{
  "mcpServers": {
    "picker": { "command": "pick", "args": ["serve"] }
  }
}

For VS Code with Copilot Chat, the entry in .vscode/mcp.json is this:

{
  "servers": {
    "picker": { "command": "pick", "args": ["serve"] }
  }
}

Claude Desktop has no project folder, so it starts pick in a folder of its own, where pick finds no .picker.json. Name the file yourself with --config and its full path:

{
  "mcpServers": {
    "picker": { "command": "pick", "args": ["serve", "--config", "C:\\github\\app\\.picker.json"] }
  }
}

No deny list goes with any of these entries. A deny list is a client setting that blocks some of the client's own built-in tools. The clients have no built-in tool for SQL, so pick adds a route to the data without opening any other.

The local file

The local file, .picker.local.json, sits beside .picker.json, and you keep it out of source control. It holds what is different on each machine and what must never be checked in. It may supply two things and nothing else:

{
  "tools": { "servers": { "main": { "connect": "Server=(localdb)\\MSSQLLocalDB;Integrated Security=true;TrustServerCertificate=true" } } },
  "screenings": { "models": "C:\\screening-models" }
}

If the local file names a server that .picker.json does not declare, pick refuses to load. The same happens if it declares databases, a guardrails section or a screen, because the local file cannot widen what the reviewed file allows. pick also refuses a password in .picker.json itself, because that file goes into source control.

Checking it with doctor

The doctor verb checks the setup and prints one line for each check. It opens with the three level lines, so that you see first which levels are on. Then it checks the configuration file and makes a short test connection to each server.

pick 2.1.0
  ok tools: on, always; settings from C:\github\app\.picker.json
  ok guardrails: off
  ok screenings: off
  ok configuration: C:\github\app\.picker.json
  ok server main: connects (guardrails off: every database the login can reach)

A check that failed starts with !! in place of ok. A level that is off gets one line, and doctor runs none of that level's checks. So the models and burler lines appear only when screenings are on. It never prints a connection string or a password.

burler, for screenings

Skip this section unless you turn on screenings. The first tier of the screen runs inside pick with nothing else installed. Three categories, clinical, legal and scientific, need models, and the models run in burler, a helper program. The fettle program uses the same helper, so one download serves both of them.

The MCP front end

The command pick serve starts pick as an MCP server. MCP is the protocol (a set of rules for messages) that AI clients use to call outside tools. The client starts the server, and you do not. If you run it by hand, it waits for input and looks stuck, which is normal.

The tools are named mcp__picker__VERB, such as mcp__picker__catalogs. Each answer is the same one that the command line gives when you add --json.

pick VERBpick serve
Started byyou, or a scriptthe client, from the entry above
Reads its settings fromthe nearest .picker.json at or above the current folder, or --config PATHthe .picker.json where the client started it, or --config PATH. It reads the file again before every call.
Answers withtext, or JSON with --jsonMCP results, the same as --json

No tool takes a connection string, a server name or a database name, so the assistant cannot point pick anywhere new. You edit the two files, and pick refuses to write them. The instructions that pick sends the client at startup say which levels are on.

To check that the server is running, ask the assistant to call catalogs. If the tool is missing, the server did not start, and the usual cause is that pick is not on PATH.

Updating and removing