Home › TAS Guard › Windows setup
Set up TAS Guard on Windows with Claude Desktop and Alpaca
Two copy-paste PowerShell scripts put TAS Guard between Claude Desktop and an Alpaca paper account, so Claude can trade within your limits and you approve anything bigger. Tested end to end on Windows with the Microsoft Store version of Claude Desktop on 20 October 2026.
1. Install Node.js and uv
Install Node.js 18 or newer (the LTS installer is fine). Then, in PowerShell:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Close PowerShell, open a new window, and install Alpaca's MCP server once:
uv tool install alpaca-mcp-server alpaca-mcp-server --version
2. Get Alpaca paper API keys
At app.alpaca.markets, switch to your Paper account (top-left), open API Keys and generate a key and secret. Paper keys start with PK.
3. Create the guard config
This asks for the keys without showing them, checks them against Alpaca's paper API, and writes %USERPROFILE%\tas-guard\alpaca.json with starter limits: $500 per order, $1,000 per day, approval over $100, SPY and AAPL only. Paste the whole block:
$ErrorActionPreference = "Stop"
New-Item -ItemType Directory -Force -Path "$HOME\tas-guard" | Out-Null
$k = Read-Host "Alpaca PAPER API key" -AsSecureString
$s = Read-Host "Alpaca PAPER secret" -AsSecureString
$key = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($k)).Trim()
$sec = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($s)).Trim()
try { $a = Invoke-RestMethod "https://paper-api.alpaca.markets/v2/account" -Headers @{ "APCA-API-KEY-ID" = $key; "APCA-API-SECRET-KEY" = $sec }; "Alpaca paper account: $($a.status)" }
catch { throw "Alpaca rejected these keys ($($_.Exception.Message)). Use keys from your PAPER account. Nothing was saved." }
$cfg = [ordered]@{
name = "alpaca-paper"; profile = "alpaca-mcp-server"
upstream = [ordered]@{ command = "alpaca-mcp-server"; args = @(); env = [ordered]@{ ALPACA_API_KEY = $key; ALPACA_SECRET_KEY = $sec; ALPACA_PAPER_TRADE = "true" } }
policy = [ordered]@{ max_order_value = 500; max_daily_value = 1000; approve_over = 100; symbols_allow = @("SPY", "AAPL") }
}
[IO.File]::WriteAllText("$HOME\tas-guard\alpaca.json", ($cfg | ConvertTo-Json -Depth 10), (New-Object Text.UTF8Encoding $false))
Remove-Variable k, s, key, sec, cfg
"Saved $HOME\tas-guard\alpaca.json"
$ErrorActionPreference = "Continue"Change the limits by editing alpaca.json; every option is in the policy reference and on GitHub.
4. Add the guard to Claude Desktop
This quits Claude Desktop, finds its config (Store or standard install), backs it up and adds alpaca-guarded. It doesn't copy your keys there; they stay in the guard file.
$ErrorActionPreference = "Stop"
Get-Process -Name "Claude" -ErrorAction SilentlyContinue | Stop-Process -Force; Start-Sleep 3
$dirs = @(Get-ChildItem "$env:LOCALAPPDATA\Packages\Claude_*\LocalCache\Roaming\Claude" -Directory -ErrorAction SilentlyContinue | ForEach-Object FullName) + @("$env:APPDATA\Claude")
$dir = $dirs | Where-Object { Test-Path $_ } | Select-Object -First 1
if (-not $dir) { throw "Claude Desktop's settings folder wasn't found. Open Claude Desktop once, quit it, and run this again." }
$path = Join-Path $dir "claude_desktop_config.json"
if ((Test-Path $path) -and (Get-Item $path).Length -gt 0) { Copy-Item $path "$path.bak" -Force; $j = Get-Content $path -Raw | ConvertFrom-Json } else { $j = [pscustomobject]@{} }
$srv = [pscustomobject]@{ command = "cmd"; args = @("/c", "npx", "-y", "tas-guard", "run", "--config", "$HOME\tas-guard\alpaca.json") }
if (-not ($j.PSObject.Properties.Name -contains "mcpServers")) { $j | Add-Member -NotePropertyName mcpServers -NotePropertyValue ([pscustomobject]@{}) }
$j.mcpServers | Add-Member -NotePropertyName "alpaca-guarded" -NotePropertyValue $srv -Force
[IO.File]::WriteAllText($path, ($j | ConvertTo-Json -Depth 30), (New-Object Text.UTF8Encoding $false))
"Added alpaca-guarded to $path. Now open Claude Desktop."
$ErrorActionPreference = "Continue"Open Claude Desktop, switch to Chat, start a new chat and check + → Connectors for alpaca-guarded.
5. Test it
| Ask Claude | What should happen |
|---|---|
| Call the tas_guard_status tool. | Shows paper mode, kill switch off and your limits. |
| Buy 1 share of SPY with a limit order at $1. | Goes through. It appears in Alpaca's paper Orders tab and won't fill at $1. |
| Buy 1 share of AAPL at market. | Held for approval, because a market order has no price. Run npx tas-guard approve <id>, then tell Claude to retry. It executes once. |
| Buy 10 SPY at $600. Submit it anyway so we can see the guard decide. | Blocked by the guard: $6,000 is over the $500 per-order limit. |
Run npx tas-guard kill, then: Buy 1 SPY limit $1. | Blocked by the kill switch. Turn it off with npx tas-guard resume. |
| Cancel all my open orders. | Held for approval, because it also cancels stop-losses. Approve it the same way. |
Then check the record: npx tas-guard log --tail 20 lists every decision, and npx tas-guard verify-log confirms nobody edited it.
Your controls
npx tas-guard pending # actions waiting for you npx tas-guard approve <id> # approve one npx tas-guard deny <id> npx tas-guard kill # stop all new orders now npx tas-guard resume npx tas-guard log --tail 20
Troubleshooting
Alpaca returns 401 Unauthorized, but the keys work elsewhere
Claude Desktop keeps its own copy of each server's settings, so it can keep passing old keys. Keep the keys in alpaca.json (as in step 3); keys in the guard file always win. Claude Desktop's server log (Settings → Developer) shows credential ALPACA_API_KEY: ...ABCD (from guard config) with the key's last 4 characters, so you can check which key is in use.
alpaca-guarded doesn't appear in Claude Desktop
Claude Desktop rewrites its config file while it's running, which can undo your edit. Quit it from the system tray first (closing the window isn't enough); the step 4 script does this for you. In Chat, look under + → Connectors; the Code tab uses a different list.
It takes 15 to 25 seconds to appear
That's uvx re-resolving Alpaca's server on every launch. uv tool install alpaca-mcp-server (step 1) installs it once; the guard file then starts it directly.
No approval prompt appears in the app
Claude Desktop doesn't show the in-app prompt (tested October 2026). Approve held actions from PowerShell with npx tas-guard approve <id>; npx tas-guard pending lists them.
Your config file is in an unexpected folder
The Microsoft Store version of Claude Desktop keeps it under %LOCALAPPDATA%\Packages\Claude_*\LocalCache\Roaming\Claude\; the standard installer uses %APPDATA%\Claude\. The step 4 script checks both.