Release status
The current release is 0.4.0-preview.2, a preview. Its binaries are not code-signed or notarized, so Windows SmartScreen and macOS Gatekeeper will warn before running them. The supervised-run and tool-gateway code is covered by the connector's own test suites; installing it as a service, and its behaviour across reboots and sleep, have not yet been acceptance-tested on every operating system, so treat those paths as preview.
Install and pair
Download the archive for your platform from the download page, extract it, and put toolcaise-connect on your PATH. Then pair it with your workspace:
toolcaise-connect pairPairing prints a code and a link. Open the link in a browser signed in to your workspace and approve this computer; it then appears under Devices, where it can be revoked. Connect only ever makes outbound requests; nothing listens for Toolcaise.
State lives in your user configuration directory under Toolcaise/connect (override with TOOLCAISE_CONNECT_HOME or --home). Files are private to your user, and credentials never appear in status output.
Run it as a service
toolcaise-connect service install
toolcaise-connect service uninstallThis installs a user-level service: a scheduled task at logon on Windows, a LaunchAgent on macOS, a systemd user unit on Linux. It runs while your user session is available; unattended Linux hosts also need user lingering enabled by an administrator. It needs the binary at a stable path. The service is the daemon that uploads what the adapters, supervised runs and the MCP gateway record. Runs and the gateway enforce their limits without it; their reports wait in a durable local queue until it runs.
Supervised runs
run starts your command behind a local gateway, points its OpenAI and Anthropic SDK base URLs at it, measures every model call itself, and stops the command when a limit is reached. Enforcement is local, so it holds with no network path to Toolcaise.
toolcaise-connect run --agent "Nightly research" --max-runtime 45m --max-total-tokens 2000000 -- python agent.py
toolcaise-connect run --agent "Refactor bot" --policy policy.json --max-cost-usd 5 -- node bot.js
toolcaise-connect run --agent "Batch job" --gateway -- python job.py # measure only, no limits| Flag | What it does |
|---|---|
--agent NAME | The agent to report the run against. |
--max-runtime 45m | Wall-clock limit for the whole command. |
--max-total-tokens, --max-input-tokens, --max-output-tokens | Token limits, from the provider's own usage fields. |
--max-model-calls | An exact limit on model calls. |
--max-cost-usd | A spend limit, computed only from prices you supply in a policy file. A model with no price is refused rather than assumed free. |
--allow-model PATTERN | Only models matching these patterns (repeatable; * is a wildcard). |
--on-limit stop|block | stop (the default) ends the command and everything it started; block only refuses further model calls. |
--stop-grace 10s | How long to wait after a polite terminate before killing. |
--policy FILE | Limits, prices and extra upstreams in one JSON file. |
--gateway | Measure model calls without any limit. |
--output FILE | Report whether the file exists and is not empty. Its contents are never read. |
--remote-control | Let the dashboard pause, stop and set limits for this run (below). |
A run stopped by a limit exits with 124, as timeout(1) does, and is recorded as canceled with the limit as its error code. Limits are checked when a response finishes, so calls already in flight complete; a call-count limit is exact.
{
"maxRuntime": "45m",
"maxCostUsd": 5,
"maxTotalTokens": 2000000,
"allowModels": ["claude-*", "gpt-4o*"],
"prices": {
"gpt-4o": { "inputPerMTok": 2.5, "outputPerMTok": 10 },
"claude-*": { "inputPerMTok": 3, "outputPerMTok": 15, "cachedInputPerMTok": 0.3, "cacheWritePerMTok": 3.75 }
},
"upstreams": { "local": { "url": "http://localhost:11434", "kind": "openai" } }
}What the gateway covers. Calls made through an OpenAI-compatible (/chat/completions, /completions, /responses, /embeddings) or Anthropic (/v1/messages) API via OPENAI_BASE_URL, OPENAI_API_BASE or ANTHROPIC_BASE_URL, which the official SDKs and most frameworks honour. An agent that hardcodes a provider endpoint or speaks another protocol bypasses the token, cost and model limits; the runtime limit and process termination still apply. If one of those variables is already set (Azure, LiteLLM, OpenRouter, an internal gateway), that endpoint stays the upstream. Provider keys pass straight through and are never stored. Unknown policy fields are rejected, so a typo cannot silently switch a limit off.
Each call is reported as a model span and a usage sample. Because they come from a credential Connect enrolled for the run, Toolcaise labels them measured by Toolcaise Connect rather than agent-reported. Connect vouches for them; they are not tamper-proof, since the agent runs on the same machine.
Remote control and limits
toolcaise-connect run --agent "Nightly research" --remote-control -- python agent.py- Opt-in, per run. Without the flag the run makes no control requests. With it, instructions reach only the command this process started.
- Pause holds the run's new model calls at the gateway until you resume; a call already being answered finishes. A held call is answered 503 with Retry-After after five minutes, which SDKs retry.
- Stop ends the command and everything it started. The run exits with 125 and is recorded canceled with error code
remote_cancel. Only a stop addressed to this run counts. - Limits set in the dashboard are merged with the machine's and the stricter value wins, so the dashboard can tighten a run but never loosen it: the smaller positive number, both model allowlists, stop over block. Upstreams, and so where provider keys go, can only be set on the machine.
- Never in the way. Local limits hold whether or not Toolcaise can be reached. It polls every ten seconds; after failures it backs off to at most two minutes, so a stop can arrive that late.
Tool gateway (MCP)
mcp puts the same kind of gateway in front of an MCP server. In your MCP client's configuration, replace the server's command with this one and pass the original after --:
toolcaise-connect mcp --name "Filesystem tools" --deny-tools 'shell__*' -- npx -y @modelcontextprotocol/server-filesystem /srv
toolcaise-connect mcp --policy ./policy.json -- ./my-mcp-server| Flag | What it does |
|---|---|
--name NAME | Report the session as a run of this agent, with a span per tool call. Without it, calls are gated locally and nothing is reported. |
--allow-tools PATTERNS | Only these tools (repeatable or comma-separated). |
--deny-tools PATTERNS | Refuse these tools. Deny outranks allow. |
--max-tool-calls N | A budget for the whole session, across every tool. |
--policy FILE | The tools section of a policy file. Flags add to it rather than replace it. |
--remote-control | Let the dashboard pause and stop the session, set its tool rules and approve held calls. Needs --name. Connect 0.3 or later. |
--require-approval PATTERNS | Hold calls to these tools until a person approves them in the dashboard. Needs --remote-control; without it such a call is refused. |
--approval-timeout DURATION | How long a held call waits before it is refused. Ten minutes by default. |
A refused call never reaches the server and is answered the way a tool reports its own failure, so the model can read the reason and try something else. A refused tool is also removed from the tool list. Everything else passes through unchanged.
toolcaise-connect mcp --name "GitHub tools" --remote-control --require-approval 'github__merge_*' -- npx -y @modelcontextprotocol/server-githubWith --remote-control, tool rules set in the dashboard are merged with the machine's and the stricter side wins. A held call waits in Approvals while other calls keep flowing, and the approval is bound to that exact call: the tool and its arguments, hashed. The arguments never leave the machine, so the approver sees the tool name. Approvals need the session's run to have reached Toolcaise, which happens through the background service (service install).
The gateway does not gate by argument: a permitted tool is permitted whatever its arguments, which is what an approval hold is for.
Claude Code and Codex adapters
toolcaise-connect discover --json
toolcaise-connect adapters enable claude
toolcaise-connect adapters enable codex
toolcaise-connect adapters disable claudeDiscovery changes nothing. Enabling an adapter configures that tool's own telemetry to report to Connect's local collector (restart the tool afterwards), and refuses if it already has OpenTelemetry settings. Disabling restores the original file if it has not been edited since; otherwise it keeps your edits and names the private backup. The adapters report allow-listed usage events and metrics, not prompts or tool arguments; they observe the tool and cannot pause or stop it.
Command reference
| Command | What it does |
|---|---|
pair [--server URL] | Pair this computer with a workspace through browser approval. |
service install | uninstall | Install or remove the user-level service. |
status --json | Pairing, queue depth, dropped events, last sync and adapter coverage. |
discover --json | Supported tools found on this machine, without changing anything. |
adapters enable | disable claude | codex | Turn a tool adapter on or off. |
collection pause | resume | Pause or resume uploads from this device. |
run [limits] -- COMMAND | A supervised run. |
mcp [rules] -- SERVER | A gated MCP server. |
version | The connector's version. |
What leaves the machine
Run and span metadata, model names, token counts, costs computed from your prices, limit decisions and allow-listed tool events, sent to your workspace with the agent's own credential. Never prompts, completions, tool arguments or results, headers or provider keys. When the daemon is offline, reports wait in a durable local queue (at most 10,000 events, about 64 MiB) and are delivered at least once; a full queue refuses new events and counts them as lost. No control operation is ever queued.