Shoddy · Picker

Quick Start

The tools level in two steps: install pick, then register it. At the end, an assistant can read your database through the query gate.

This page sets up the tools level, the first of pick's three levels. At this level pick has a connection to one server, checks every query at its gate, and needs you to declare nothing else. The other two levels, guardrails and screenings, come after, and you turn each one on by adding one section to a file.

Before you start, you need two things. The first is the archive for your computer from the latest release, where an archive is one file that holds others, like a zip file. The second is a SQL Server you can reach, with a database in it. If you have no server, the next section makes one on a Windows machine.

Before you start: a server

If you can already reach a SQL Server, skip this section and keep its connection string to hand. A connection string is the text that says which server to reach and how to sign in to it. If you have no server, start LocalDB, the small SQL Server that comes with the Windows development tools:

sqllocaldb start MSSQLLocalDB

If your system says that sqllocaldb is not a command, install SQL Server Express LocalDB and run the line again. Then make a small database with one table in it, so you have something to read:

sqlcmd -S "(localdb)\MSSQLLocalDB" -E -Q "CREATE DATABASE Sales;"
sqlcmd -S "(localdb)\MSSQLLocalDB" -E -d Sales -Q "CREATE TABLE dbo.Customers(id int PRIMARY KEY, name nvarchar(80)); INSERT dbo.Customers VALUES (1, N'Iris Sutcliffe'), (2, N'Harold Wilson');"

1. Install it

pick is a single file, and it needs no .NET runtime and no installer. In the commands below, put the version you downloaded in place of X.Y.Z.

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

Open a new terminal, because the one you just used still has the old PATH. That is the list of folders where your system looks for commands. Then check that pick runs:

pick version

You should see the word pick followed by the version number you downloaded.

If you see not recognised or command not found, open a new terminal and try again. Nothing later on this page will work until this line does. Putting it on PATH has the details.

2. Register it

To register pick is to tell it which server to use, and to tell the assistant where pick is. You write two short files and set one value, and you do it by hand, because pick has no setup command.

The configuration file

In your project folder, make a file called .picker.json with this line in it:

{"tools":{"servers":{"main":{"connect":"env:MAIN_SQL"}}}}

This file has only a tools section, so it sets up the tools level and nothing more. It names one server, main, and says its connection string is in an environment variable called MAIN_SQL. An environment variable is a named value your system keeps outside any file, so no password sits in the project.

The connection

Set MAIN_SQL to your connection string. The Windows line below is for LocalDB, and if you use another server, put its connection string in place of this one.

Windows · PowerShell
[Environment]::SetEnvironmentVariable('MAIN_SQL', 'Server=(localdb)\MSSQLLocalDB;Integrated Security=true;TrustServerCertificate=true', 'User')
macOS and Linux
echo 'export MAIN_SQL="Server=myhost;User Id=reader;Password=...;TrustServerCertificate=true"' >> ~/.profile

Open a new terminal again, so that it sees the new value. Then ask pick what it can see:

pick catalogs

You should see the three level lines first, and then the server you named:

levels
  tools       on, always; settings from C:\github\app\.picker.json
  guardrails  off
  screenings  off

main  (connect: env:MAIN_SQL)
  every database this login can reach; guardrails are off, so none is declared
source: C:\github\app\.picker.json

Notice the line under main, which says the server is open. Every database the login can enter is there, apart from the four system databases that every SQL Server has. The catalogs verb opens no connection, so it works even when the server is down. To test the connection itself, run pick doctor.

The entry for the assistant

For Claude Code, add one entry to the file .mcp.json in your project folder. If the file does not exist yet, make it and put exactly this in it:

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

Other clients take the same command and arguments in a file of their own, and Registering, per client lists each one.

Then restart the assistant, because a client reads its list of servers only when it starts. Ask it to call catalogs, and it should show the same lines you saw above. When you change .picker.json later, you need no restart, because pick reads the file again before every call.

Try the gate

Run one query that works and one describe, which shows a table's columns. Then try the commands in the table below, each of which the gate refuses:

pick select "SELECT TOP 5 * FROM Sales.dbo.Customers"
pick describe Sales.dbo.Customers
CommandExitWhy it is refused
pick select "DELETE FROM Sales.dbo.Customers"8It is not a SELECT, and pick has no way to change data.
pick select "SELECT 1; SELECT 2"8One call may carry only one statement.
pick select "SELECT name FROM sys.tables"8The system catalog is closed, so use describe instead.
pick select "SELECT * FROM master.dbo.spt_values"3master is a system database, so pick says it is not there.

An exit code is the number a command hands back when it ends, so that a script can tell what happened. The reference lists every exit code and what it means.

Turning on more