Skip to content

⚙️ Configuration

Two JSON files. proxy config path and proxy settings path print exactly which ones are in use.

OSDirectory
macOS~/Library/Application Support/tspm/
Linux~/.config/tspm/ (respects XDG_CONFIG_HOME)

config.json

  1. --config-file <PATH>
  2. TSPM_CONFIG
  3. config_path in settings.json — a relative value is resolved against the directory holding settings.json, not your working directory
  4. The OS config directory above

settings.json

  1. --settings-file <PATH>
  2. TSPM_SETTINGS
  3. The OS config directory above
  4. ./settings.json in the working directory

The working-directory entry is last on purpose. settings.json is a common filename, and letting any directory you happen to be in outrank your own configuration would make the tool behave differently depending on where it was run from.

Both files are created with defaults on first run. A file that exists but contains invalid JSON is reported on stderr and left untouched — it is never overwritten, so a typo cannot cost you your profiles.


settings.json
{
"config_path": null,
"lang": "ru"
}
FieldTypeDescription
config_pathstring or nullPath to a custom config.json. ~ is expanded. null uses the OS config directory.
langstringInterface language: "ru" or "en". Defaults to "ru".

Edit it with proxy settings set --config-path ~/proxies.json or proxy lang en.


config.json
{
"active_profile": "work",
"profiles": {
"work": {
"name": "Work SOCKS",
"host": "127.0.0.1",
"port": 1080,
"protocol": "socks5"
},
"lab": {
"name": "Lab HTTP",
"host": "127.0.0.1",
"port": 8080,
"protocol": "http"
}
},
"ping_targets": [
{ "name": "Google", "url": "https://www.google.com" },
{ "name": "GitHub", "url": "https://github.com" },
{ "name": "OpenAI", "url": "https://status.openai.com/api/v2/status.json" },
{ "name": "Anthropic", "url": "https://www.anthropic.com" },
{ "name": "Cloudflare", "url": "https://1.1.1.1" }
],
"diagnose_endpoints": [
{ "name": "GitHub API", "url": "https://api.github.com" }
],
"geo_apis": [
"https://ifconfig.co/json",
"http://ip-api.com/json"
],
"ipv4_api": "https://api4.ipify.org",
"ipv6_api": "https://api6.ipify.org",
"health_check_url": "https://www.gstatic.com/generate_204",
"speedtest_url": "https://speed.cloudflare.com/__down?bytes=2097152"
}

A complete, current example ships as configs/config.default.json.

FieldTypeUsed byDescription
active_profilestringeverythingKey of the active entry in profiles
profilesmapeverythingProfile key → profile object
ping_targetsarrayping, benchmark, best, monitor, dashEndpoints probed for latency
diagnose_endpointsarraydiagnoseEndpoints checked for reachability
geo_apisarraystatus, dashJSON IP/geolocation APIs, tried in order until one answers
ipv4_apistringstatusPlain-text endpoint returning your external IPv4
ipv6_apistringstatusPlain-text endpoint returning your external IPv6
health_check_urlstringmonitorProbed to decide whether the proxy still works. Use something that answers 204.
speedtest_urlstringspeedtestDownloaded to measure throughput

Every field is optional. A config missing any of them — including one written by an older version — loads with the built-in default for whatever is absent.

FieldTypeDescription
namestringDisplay name
hoststringHostname or IP. Letters, digits, ., -, _, :, [, ] only.
portnumber1–65535
protocolstringhttp, https, socks4, socks4a, socks5, socks5h. Defaults to socks5.

Profiles are validated whenever they are written, whether by profile set or by import. An invalid profile is rejected rather than saved, because the values end up in a proxy URL and in shell statements.

Note for users upgrading from 2.1.x: the unused top-level enabled field was removed. Existing files keep working; the field is simply ignored.

Diagram

Drag to move. Pinch or scroll to zoom. Keyboard: arrows, +, −, 0.