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.strategy
  • multiInstance.allocationPolicy
  • instanceDefaults.stealthLevel
  • instanceDefaults.tabEvictionPolicy

It also shows:

  • the active config file path
  • the dashboard URL when the server is running
  • the masked server token
  • a Copy token action
terminal
pinchtab config
pinchtab config

pinchtab config init

Creates a default config file at the current config path.

terminal
pinchtab config init
pinchtab config init

config init respects PINCHTAB_CONFIG. If that environment variable is set, the file is created there.

pinchtab config show

Shows the effective runtime configuration.

terminal
pinchtab config show
pinchtab config show

Secret values such as server.token remain masked in this output.

pinchtab config token

Copies the configured server.token to the system clipboard without printing it to stdout.

terminal
pinchtab config token
pinchtab 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.

terminal
pinchtab config path
pinchtab config path

pinchtab config validate

Validates the current config file.

terminal
pinchtab config validate
pinchtab config validate

pinchtab config get

Reads a single dotted-path value from the file config.

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

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

terminal
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:

  1. built-in defaults
  2. the config file selected by PINCHTAB_CONFIG or the default path
  3. PINCHTAB_TOKEN, if set, overriding server.token at runtime

Supported environment variables:

  • PINCHTAB_CONFIG: choose the config file path
  • PINCHTAB_TOKEN: override the API token at runtime

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.

Override the config path with:

terminal
export PINCHTAB_CONFIG=/path/to/config.json
export PINCHTAB_CONFIG=/path/to/config.json

Config Shape

Current nested file-config shape:

{
  "configVersion": "0.8.0",
  "server": {
    "port": "9867",
    "bind": "127.0.0.1",
    "token": "your-secret-token",
    "stateDir": "/path/to/state",
    "engine": "chrome",
    "networkBufferSize": 100,
    "trustProxyHeaders": false,
    "cookieSecure": null
  },
  "browser": {
    "version": "144.0.7559.133",
    "binary": "/path/to/chrome",
    "extraFlags": "--disable-gpu",
    "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,
    "stealthLevel": "light",
    "tabEvictionPolicy": "close_lru",
    "dialogAutoAccept": false
  },
  "security": {
    "allowEvaluate": false,
    "allowMacro": false,
    "allowScreencast": false,
    "allowDownload": 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"]
    },
    "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,
    "maxAttempts": 8,
    "solvers": ["cloudflare", "semantic", "capsolver", "twocaptcha"],
    "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.

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.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.userAgent for UA overrides
  • instanceDefaults.mode for headed/headless
  • instanceDefaults.timezone for timezone
  • browser.extensionPaths for extension loading
  • browser.remoteDebuggingPort for 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.

Sections

SectionPurpose
serverHTTP server settings, engine selection, proxy trust, and network buffer defaults
browserChrome executable, version pin, extra flags, and extension paths
instanceDefaultsDefault behavior for managed instances
securitySensitive feature gates, transfer limits, attach policy, and IDPI
profilesProfile storage defaults
multiInstanceOrchestrator strategy, allocation, port range, and restart policy
timeoutsAction, navigation, shutdown, and navigation wait delays
schedulerOptional task queue
observabilityActivity logging, source selection, and retention

config get And config set Support

pinchtab config get and pinchtab config set only support these top-level sections:

  • server
  • browser
  • instanceDefaults
  • security
  • profiles
  • multiInstance
  • timeouts
  • observability

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.engine
  • server.networkBufferSize
  • browser.extensionPaths
  • instanceDefaults.dialogAutoAccept
  • security.allowClipboard
  • security.idpi.scanTimeoutSec
  • security.idpi.shieldThreshold
  • scheduler.*
  • observability.activity.events.*

Common Examples

Headed Mode

{
  "instanceDefaults": {
    "mode": "headed"
  }
}

Network Bind With Token

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

server.cookieSecure controls whether the dashboard session cookie must use the Secure flag:

  • null / unset / auto: default behavior. Session cookies are Secure on HTTPS and non-Secure on plain HTTP.
  • true: always require Secure. Dashboard login works only over HTTPS.
  • false: always omit Secure, even on HTTPS. Use only for operator-managed edge cases.

Examples:

terminal
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"]
    }
  }
}

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.

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
  • instanceDefaults.maxTabs >= 1
  • instanceDefaults.maxParallelTabs >= 0
  • valid multiInstance.strategy
  • valid multiInstance.allocationPolicy
  • valid multiInstance.restart.* values
  • valid security.attach.allowSchemes
  • multiInstance.instancePortStart <= multiInstance.instancePortEnd
  • multiInstance.restart.initBackoffSec <= multiInstance.restart.maxBackoffSec
  • non-negative timeout values
  • non-negative server.networkBufferSize
  • non-negative security.idpi.scanTimeoutSec
  • positive observability.activity.sessionIdleSec and retentionDays

Valid enum values:

FieldValues
instanceDefaults.modeheadless, headed
instanceDefaults.stealthLevellight, medium, full
instanceDefaults.tabEvictionPolicyreject, close_oldest, close_lru
multiInstance.strategysimple, explicit, simple-autorestart, always-on, no-instance
multiInstance.allocationPolicyfcfs, round_robin, random
security.attach.allowSchemesws, wss, http, https

Notes

  • config show reports effective runtime values, not just raw file contents.
  • config get, set, and patch operate on the file config model, not transient runtime overrides.
  • the dashboard config API treats server.token as write-only; use the CLI or file editing to manage it.