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.

Paper money only. Run everything here against a paper account until you trust your setup. Not financial advice.

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 ClaudeWhat 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.

Next

Tested with TAS Guard 0.1.1, alpaca-mcp-server 2.4.0, Claude Desktop (Microsoft Store) on Windows, 20 October 2026. TAS Guard is our own open-source tool.

Get the weekly AI-trading stack update

New MCP servers, broker and data API changes, and safety notes. One email a week, unsubscribe anytime.

No spam. Unsubscribe anytime. Privacy