Config
pinchtab config is the CLI entry point for creating, inspecting, validating, and editing PinchTab’s config file.
For security posture, token usage, sensitive endpoint policy, and IDPI guidance, see Security.
Commands
pinchtab config
Opens the interactive config overview/editor.
It currently exposes these high-signal settings directly:
multiInstance.strategymultiInstance.allocationPolicyinstanceDefaults.stealthLevelinstanceDefaults.tabEvictionPolicyinstanceDefaults.tabPolicy.lifecycle
It also shows:
- the active config file path
- the dashboard URL when the server is running
- the masked server token
- a
Copy tokenaction
pinchtab configpinchtab config pinchtab config init
Creates a default config file at the current config path.
pinchtab config initpinchtab config init config init respects PINCHTAB_CONFIG. If that environment variable is set, the file is created there.
Generated config files include a $schema URL for IDE completion and validation.
pinchtab config schema
Prints the JSON Schema URL for this PinchTab build. Source builds, development
builds, and versions without a published schema use the main schema URL.
When a matching release schema is known, PinchTab uses that release tag; when a
newer matching schema is known, PinchTab uses the closest newer tag.
pinchtab config schemapinchtab config schema Print the bundled schema JSON:
pinchtab config schema --printpinchtab config schema --print pinchtab config show
Shows the effective runtime configuration.
pinchtab config showpinchtab config show Secret values such as server.token remain masked in this output.
The Security section also includes security.trustLoopbackProxy as Trust Loopback Proxy so proxy trust posture is explicit.
pinchtab config token
Copies the configured server.token to the system clipboard without printing it
to stdout.
pinchtab config tokenpinchtab config token If clipboard access is unavailable, the command reports that safely and still does not print the token.
pinchtab config path
Prints the config file path PinchTab will read.
pinchtab config pathpinchtab config path pinchtab config validate
Validates the current config file.
pinchtab config validatepinchtab config validate pinchtab config get
Reads a single dotted-path value from the file config.
pinchtab config get server.portpinchtab config get instanceDefaults.modepinchtab config get security.attach.allowHosts
pinchtab config get server.portpinchtab config get instanceDefaults.modepinchtab config get security.attach.allowHosts
pinchtab config set
Sets a single dotted-path value in the file config.
pinchtab config set server.port 8080pinchtab config set instanceDefaults.mode headedpinchtab config set multiInstance.strategy explicit
pinchtab config set server.port 8080pinchtab config set instanceDefaults.mode headedpinchtab config set multiInstance.strategy explicit
pinchtab config patch
Merges a JSON object into the config file.
pinchtab config patch '{"server":{"port":"8080"}}'pinchtab config patch '{"instanceDefaults":{"mode":"headed","maxTabs":50}}'pinchtab config patch '{"observability":{"activity":{"retentionDays":14}}}'
pinchtab config patch '{"server":{"port":"8080"}}'pinchtab config patch '{"instanceDefaults":{"mode":"headed","maxTabs":50}}'pinchtab config patch '{"observability":{"activity":{"retentionDays":14}}}'
Load Order
PinchTab applies configuration in this order:
- built-in defaults
- the config file selected by
PINCHTAB_CONFIGor the default path PINCHTAB_TOKEN, if set, overridingserver.tokenat runtime
Supported environment variables:
PINCHTAB_CONFIG: choose the config file pathPINCHTAB_TOKEN: override the API token at runtimePINCHTAB_RATE_LIMIT_MAX: per-client request cap per 10-second window (default 3000, sized for agent-driven snapshot/action bursts). Lower it (e.g. to 300) when exposing the port beyond localhost. Child instances inherit it from the orchestrator’s environment.
For remote CLI targeting, use the root --server flag instead of config.
Config File Location
Default location by OS:
- macOS:
~/.pinchtab/config.json - Linux:
~/.pinchtab/config.json - Windows:
%APPDATA%\pinchtab\config.json
On macOS and Linux, PinchTab defaults to ~/.pinchtab so the CLI, npm-managed binary, and config file all use the same base directory.
If you are upgrading from an older macOS setup and still have a config at ~/Library/Application Support/pinchtab/config.json, treat that as a legacy location and move or merge it into ~/.pinchtab/config.json.
Override the config path with:
export PINCHTAB_CONFIG=/path/to/config.jsonexport PINCHTAB_CONFIG=/path/to/config.json Config Shape
Current nested file-config shape:
{
"$schema": "https://raw.githubusercontent.com/pinchtab/pinchtab/main/schema/config.json",
"configVersion": "0.8.0",
"server": {
"port": "9867",
"bind": "127.0.0.1",
"token": "your-secret-token",
"stateDir": "/path/to/state",
"networkBufferSize": 100,
"retainNetworkBodies": false,
"retainNetworkBodyMaxBytes": 262144,
"trustProxyHeaders": false,
"cookieSecure": null
},
"browser": {
"version": "144.0.7559.133",
"binary": "/path/to/chrome",
"remoteDebuggingPort": null,
"extraFlags": "--disable-gpu",
"cloak": {
"fingerprintSeed": "42069",
"platform": "windows",
"locale": "en-GB",
"timezone": "Europe/London",
"webrtcIP": "auto",
"fontsDir": "/path/to/fonts",
"storageQuotaMB": 2048,
"disableDefaultStealthArgs": true
},
"extensionPaths": ["/path/to/pinchtab/extensions"]
},
"instanceDefaults": {
"mode": "headless",
"noRestore": false,
"timezone": "Europe/Rome",
"blockImages": false,
"blockMedia": false,
"blockAds": false,
"maxTabs": 20,
"maxParallelTabs": 0,
"userAgent": "",
"noAnimations": false,
"humanize": false,
"stealthLevel": "light",
"tabEvictionPolicy": "close_lru",
"tabPolicy": {
"lifecycle": "keep",
"closeDelaySec": 300,
"restore": false
},
"dialogAutoAccept": false
},
"security": {
"allowEvaluate": false,
"allowMacro": false,
"allowScreencast": false,
"allowDownload": false,
"allowCookies": false,
"allowFileScheme": false,
"allowedDomains": ["127.0.0.1", "localhost", "::1"],
"downloadAllowedDomains": [],
"downloadMaxBytes": 20971520,
"allowUpload": false,
"allowClipboard": false,
"uploadMaxRequestBytes": 10485760,
"uploadMaxFiles": 8,
"uploadMaxFileBytes": 5242880,
"uploadMaxTotalBytes": 10485760,
"maxRedirects": -1,
"trustedProxyCIDRs": [],
"trustedResolveCIDRs": [],
"attach": {
"enabled": false,
"allowHosts": ["127.0.0.1", "localhost", "::1"],
"allowSchemes": ["ws", "wss", "http", "https"],
"forwardProxyAuth": false
},
"idpi": {
"enabled": true,
"strictMode": true,
"scanContent": true,
"wrapContent": true,
"customPatterns": [],
"scanTimeoutSec": 5,
"shieldThreshold": 30
}
},
"profiles": {
"baseDir": "/path/to/profiles",
"defaultProfile": "default"
},
"multiInstance": {
"strategy": "always-on",
"allocationPolicy": "fcfs",
"instancePortStart": 9868,
"instancePortEnd": 9968,
"restart": {
"maxRestarts": 20,
"initBackoffSec": 2,
"maxBackoffSec": 60,
"stableAfterSec": 300
}
},
"timeouts": {
"actionSec": 30,
"navigateSec": 60,
"shutdownSec": 10,
"waitNavMs": 1000
},
"autoSolver": {
"enabled": false,
"autoTrigger": true,
"triggerOnNavigate": true,
"triggerOnAction": true,
"maxAttempts": 8,
"solverTimeoutSec": 30,
"retryBaseDelayMs": 500,
"retryMaxDelayMs": 10000,
"solvers": ["cloudflare", "semantic"],
"llmProvider": "",
"llmFallback": false,
"external": {
"capsolverKey": "",
"twoCaptchaKey": ""
}
},
"scheduler": {
"enabled": false,
"strategy": "fair-fifo",
"maxQueueSize": 1000,
"maxPerAgent": 100,
"maxInflight": 20,
"maxPerAgentInflight": 10,
"resultTTLSec": 300,
"workerCount": 4
},
"observability": {
"activity": {
"enabled": true,
"sessionIdleSec": 1800,
"retentionDays": 1,
"events": {
"dashboard": false,
"server": false,
"bridge": false,
"orchestrator": false,
"scheduler": false,
"mcp": false,
"other": false
}
}
}
}
autoSolver.external is config-file-only. Capsolver and 2Captcha credentials
are stored there.
Semantic Flow Credentials
The semantic-first autosolver flow injects credential values into recognised
login/signup/form fields. Configure them under autoSolver.credentials in
the config file:
{
"autoSolver": {
"credentials": {
"login": { "user": "you@example.com", "password": "..." },
"signup": { "name": "Jane Doe", "email": "you@example.com", "password": "..." },
"form": { "field1": "...", "field2": "...", "email": "you@example.com" }
}
}
}
Notes:
- Edit credentials by writing the config file directly. The dashboard config API redacts them on read (GET returns blanks) and preserves on-disk values when a PUT comes in with empty fields, so secrets never round-trip through the UI.
- The form solver step 2 falls back to
form.emailwhenform.field2is empty. - Steps without a configured value fall through to a click-only flow (e.g. a login attempt with no password becomes a “click submit” attempt).
The dashboard Settings page exposes the non-secret AutoSolver settings and shows the active config file path. Provider keys remain managed directly in the config file.
Browser Selection
The CLI uses --browser <name> to select a browser. In the config file the
equivalent field is browsers.default:
{
"browsers": { "default": "cloak" }
}
browsers.default explicitly selects the local browser backend:
chromeuses the normal Chrome/Chromium launch path.ghost-chromeserves static-friendly reads from a lightweight fetcher and escalates to Chrome when a page needs rendering.cloakuses a discovered or configured local CloakBrowser Chromium binary.
When browsers.default is omitted, PinchTab prefers a discovered local
CloakBrowser installation and otherwise falls back to Chrome. Newly generated
config files make the same choice, while existing configs that explicitly set
browsers.default to chrome continue to use Chrome.
browsers.available optionally restricts which browsers requests may select.
For multiple named configurations of the same provider (different binaries,
proxies, or fingerprints), use browser.targets with browser.defaultTarget
and browser.fallbackOrder — see Terminology.
The legacy browser.provider field is no longer supported and is rejected at
validation time.
When the selected browser is cloak, PinchTab uses browser.binary when set
or searches its normal local CloakBrowser paths. A named CloakBrowser target
must set that target’s binary explicitly. PinchTab does not download, bundle,
or redistribute the CloakBrowser binary.
On macOS, prefer a dedicated automation browser over your daily Google
Chrome. Launching /Applications/Google Chrome.app headless makes macOS treat
Chrome as already running, so opening your normal Chrome from the Dock just
activates the windowless automation process and no window appears (issue #583).
PinchTab’s discovery now prefers Google Chrome for Testing, Chromium, then Chrome
Canary, and only falls back to your primary Chrome as a last resort. If only your
daily Chrome is installed, install Google Chrome for
Testing or set
browser.binary to a separate Chrome/Chromium build. pinchtab doctor browsers
warns when automation would use your primary Chrome.
browser.cloak maps supported CloakBrowser fingerprint settings to native launch
flags:
fingerprintSeed->--fingerprintplatform->--fingerprint-platformlocale->--fingerprint-localetimezone->--fingerprint-timezonewebrtcIP->--fingerprint-webrtc-ipfontsDir->--fingerprint-fonts-dirstorageQuotaMB->--fingerprint-storage-quota
disableDefaultStealthArgs defaults to true for CloakBrowser targets. When set,
PinchTab keeps its process, profile, tab, extension, and action-control behavior,
but does not add its own JS stealth overlays or automation-hiding launch flags.
Set it to false only when you intentionally want PinchTab’s legacy stealth layer
on top of CloakBrowser’s native patches.
Advanced CloakBrowser flags can still go through browser.extraFlags when they
are not PinchTab-owned lifecycle flags.
browser.proxy.geo is a CloakBrowser fingerprint-alignment hint. When a proxy
server and geo block are configured for a CloakBrowser target, PinchTab maps the
geo values into native CloakBrowser fingerprint flags unless the target already
sets the corresponding browser.cloak field. The stock chrome browser does
not derive --lang, TZ, or WebRTC launch settings from proxy geo data.
Browser Extra Flags
browser.extraFlags is validated and sanitized. It is only for user-safe Chrome flags that do not weaken browser security and do not override PinchTab-owned launch behavior.
Rejected examples include:
--no-sandbox--disable-web-security--ignore-certificate-errors--user-agent=...--enable-automation=...--disable-blink-features=...
Use the dedicated config fields instead:
instanceDefaults.userAgentfor UA overridesinstanceDefaults.modefor headed/headlessinstanceDefaults.timezonefor timezonebrowser.extensionPathsfor extension loadingbrowser.remoteDebuggingPortfor the remote debugging port
For Linux container compatibility, use the runtime-managed path instead of browser.extraFlags. PinchTab enables --no-sandbox automatically when needed.
By default, PinchTab looks for unpacked Chrome extensions in <server.stateDir>/extensions. On a normal local install that means the OS-specific PinchTab config directory plus extensions/, for example:
- macOS:
~/.pinchtab/extensions - Linux:
~/.pinchtab/extensions - Windows:
%APPDATA%\\pinchtab\\extensions
You can change or clear that default with browser.extensionPaths.
Tab Policy
instanceDefaults.tabPolicy groups tab lifecycle behavior:
{
"instanceDefaults": {
"tabPolicy": {
"eviction": "close_lru",
"lifecycle": "keep",
"closeDelaySec": 300,
"restore": false
}
}
}
evictioncontrols what happens whenmaxTabsis reached:close_lru,close_oldest, orreject.lifecyclecontrols idle lifecycle behavior:keepdisables lifecycle auto-close and is the default;close_idleauto-closes a tab after it handles an authorized/text,/snapshot, or/actionrequest.closeDelaySecis the idle delay forclose_idle. The default is300seconds when auto-close is enabled.restorecontrols whether session tabs are restored on startup. The default isfalse.
instanceDefaults.tabEvictionPolicy is still accepted for compatibility. New configs should use instanceDefaults.tabPolicy.eviction.
Humanized Input
instanceDefaults.humanize controls whether click and typing actions use the slower humanized path by default. The default is false, which keeps automation fast and deterministic by using raw CDP input.
Callers can override the instance default per action with the JSON field humanize:
{"kind":"click","selector":"#submit","humanize":true}opts a single action into bezier mouse movement and human-like delays.{"kind":"type","selector":"#name","text":"Ada","humanize":true}opts a single type action into the slower per-character path.
Rationale: humanized input is useful for compatibility with pages that react poorly to raw input, but it adds sleeps and multi-step pointer movement. Keeping it opt-in prevents accidental seconds of overhead in default E2E and agent runs.
Sections
| Section | Purpose |
|---|---|
server | HTTP server settings, engine selection, proxy trust, and network buffer defaults |
browser | Chrome executable, version pin, extra flags, and extension paths |
instanceDefaults | Default behavior for managed instances |
security | Sensitive feature gates, transfer limits, attach policy, and IDPI |
profiles | Profile storage defaults |
multiInstance | Orchestrator strategy, allocation, port range, and restart policy |
timeouts | Action, navigation, shutdown, and navigation wait delays |
scheduler | Optional task queue |
observability | Activity logging, source selection, and retention |
config get And config set Support
pinchtab config get and pinchtab config set only support these top-level sections:
serverbrowserinstanceDefaultssecurityprofilesmultiInstancetimeoutsobservability
They do not expose every field in those sections, and they do not support scheduler.*.
Use pinchtab config patch or edit config.json directly for fields such as:
server.networkBufferSizebrowser.extensionPathsinstanceDefaults.dialogAutoAcceptinstanceDefaults.tabPolicy.*security.allowClipboardsecurity.idpi.scanTimeoutSecsecurity.idpi.shieldThresholdscheduler.*observability.activity.events.*
Common Examples
Headed Mode
{
"instanceDefaults": {
"mode": "headed"
}
}
Network Bind With Token
pinchtab config set server.bind 0.0.0.0pinchtab config set server.token secretpinchtab server
pinchtab config set server.bind 0.0.0.0pinchtab config set server.token secretpinchtab server
Changing server.bind away from loopback is a documented, non-default, security-reducing deployment change. Use it only when remote reachability is intentional, keep a token set, and review the outer network boundary explicitly.
If the dashboard is served over plain HTTP on a non-loopback bind, PinchTab shows an in-product warning because session cookies are no longer transport encrypted. Prefer HTTPS or localhost when possible.
Dashboard Cookie Transport
server.cookieSecure controls whether the dashboard session cookie must use the
Secure flag:
null/ unset /auto: default behavior. Session cookies areSecureon HTTPS and non-Secureon plain HTTP.true: always requireSecure. Dashboard login works only over HTTPS.false: always omitSecure, even on HTTPS. Use only for operator-managed edge cases.
Examples:
pinchtab config set server.cookieSecure truepinchtab config set server.cookieSecure falsepinchtab config set server.cookieSecure auto
pinchtab config set server.cookieSecure truepinchtab config set server.cookieSecure falsepinchtab config set server.cookieSecure auto
When server.cookieSecure = true, plain-HTTP dashboard login fails explicitly
with an HTTPS-required error instead of appearing to succeed and looping.
If TLS terminates in front of PinchTab, also set server.trustProxyHeaders=true
only when the proxy is trusted and rewrites Forwarded / X-Forwarded-*
headers correctly.
Custom Instance Port Range
{
"multiInstance": {
"instancePortStart": 8100,
"instancePortEnd": 8200
}
}
Attach Policy
{
"security": {
"attach": {
"enabled": true,
"allowHosts": ["127.0.0.1", "localhost", "chrome.internal"],
"allowSchemes": ["ws", "wss", "http", "https"],
"forwardProxyAuth": false
}
}
}
security.attach.allowHosts is an allowlist. If you set it to ["*"], PinchTab accepts any reachable attach host with an allowed scheme. That is a documented, non-default, security-reducing override: it removes host allowlisting entirely and should only be used on isolated, operator-controlled networks.
security.attach.forwardProxyAuth controls whether PinchTab may send configured proxy authentication credentials over remote CDP attach. It defaults to false; enable it only when the attached browser process and CDP transport are trusted.
Activity Retention
{
"observability": {
"activity": {
"retentionDays": 14,
"sessionIdleSec": 1800
}
}
}
server.trustProxyHeaders should stay false unless PinchTab is behind a trusted reverse proxy that overwrites Forwarded and X-Forwarded-* headers. Do not enable it on direct-exposure deployments or behind proxies that pass client-supplied forwarding headers through unchanged.
Legacy Flat Format
Older flat config is still accepted for backward compatibility:
{
"port": "9867",
"headless": true,
"maxTabs": 20,
"allowEvaluate": false,
"timeoutSec": 30,
"navigateSec": 60
}
Use pinchtab config init to create the current nested format.
Validation
pinchtab config validate checks, among other things:
- valid
instanceDefaults.mode - valid
instanceDefaults.stealthLevel - valid
instanceDefaults.tabEvictionPolicy - valid
instanceDefaults.tabPolicy.eviction - valid
instanceDefaults.tabPolicy.lifecycle - non-negative
instanceDefaults.tabPolicy.closeDelaySec instanceDefaults.maxTabs >= 1instanceDefaults.maxParallelTabs >= 0- valid
multiInstance.strategy - valid
multiInstance.allocationPolicy - valid
multiInstance.restart.*values - valid
security.attach.allowSchemes multiInstance.instancePortStart <= multiInstance.instancePortEndmultiInstance.restart.initBackoffSec <= multiInstance.restart.maxBackoffSec- non-negative timeout values
- non-negative
server.networkBufferSize - non-negative
security.idpi.scanTimeoutSec - positive
observability.activity.sessionIdleSecandretentionDays
Valid enum values:
| Field | Values |
|---|---|
instanceDefaults.mode | headless, headed |
instanceDefaults.stealthLevel | light, medium, full |
instanceDefaults.tabEvictionPolicy | reject, close_oldest, close_lru |
instanceDefaults.tabPolicy.eviction | reject, close_oldest, close_lru |
instanceDefaults.tabPolicy.lifecycle | keep, close_idle |
multiInstance.strategy | simple, explicit, simple-autorestart, always-on, no-instance |
multiInstance.allocationPolicy | fcfs, round_robin, random |
security.attach.allowSchemes | ws, wss, http, https |
security.attach.forwardProxyAuth | true, false |
Notes
config showreports effective runtime values, not just raw file contents.config get,set, andpatchoperate on the file config model, not transient runtime overrides.- the dashboard config API treats
server.tokenas write-only; use the CLI or file editing to manage it.