Skip to content

Patcherly connectors overview

Connectors are small programs that run on your servers (or inside your WordPress site) and connect your applications to Patcherly. They watch logs and paths you configure, send errors to the platform, upload code context when needed, and—when you approve a fix—apply patches on your environment with a pre-patch snapshot so you can roll back.

This page is the customer-facing overview. For install commands and per-stack steps, continue to Installing a connector and the guides below.

What you get

Language and framework are auto-set on first successful context upload when the target row has no values yet.

  • Same workflow everywhere — whether you use Python, Node.js, PHP, or WordPress, the journey is the same at a high level: errors are collected → you click Analyze with AI (or auto-analysis starts analysis for you) → AI proposes a fix → you approve the fix (or auto-apply does on eligible plans) → the connector applies the patch → Patcherly checks that things still work, and rolls back when something goes wrong. Plan limits still apply.
  • Target backups (your files) — Before changing files, the connector creates a target backup: a snapshot of the relevant files on your system. See Understanding errors (lifecycle) and Rollback for detail.
  • Context for better fixes — Connectors can send file and log context so analysis matches your codebase (subject to path exclusions and your plan). Each context upload is capped per request; if uploads fail with a size error, open Support from the bottom of the dashboard sidebar.
  • Secure fix delivery — Each connector authenticates with its own OAuth token (you set it up once by running patcherly login on the target server), signs every request with a unique secret, and verifies that fix payloads from Patcherly are signed before applying them.

Sending a test event (Test Mode)

You can prove your pipeline works end-to-end without waiting for a real error. Synthetic test events are gated by a per-target Test Mode window in your dashboard — that gate is deliberate: it stops an exposed connector credential, a curious script on your server, or a stray click from spraying fake errors into your real feed and triggering notifications. The window is 30 minutes per target and you control it.

  1. In your Patcherly dashboard, open Targets, click the target, and flip Test Mode ON.
  2. From your connector host, send a sample:
  3. WordPressSettings → Patcherly → Diagnostics → Send Sample Error
  4. Python / Node.js / PHPpatcherly send-test (CLI auto-checks the window first)
  5. The synthetic event appears in Errors, flagged as a sample so it never affects your metrics or notifications.

If Test Mode is off when you try, the connector prints (or shows you) the exact dashboard URL to enable it. The WordPress plugin's Connector Status panel also surfaces the Test Mode: On/Off state at a glance, with a one-click link to the toggle when it's off.

Keeping the connection alive

Once a connector is paired, the connection is designed to stay alive forever without you having to reconnect — even if your site is quiet and has no real errors for weeks. You don't need to do anything to enable this; here's just so you know how it works:

  • WordPress plugin — uses WordPress' built-in scheduled tasks to say "hello" to Patcherly once a day. That tiny check-in is enough to refresh the connection credentials and tell the dashboard your site is still alive.
  • Python / Node.js / PHP CLIs — every command you run already counts as a check-in, so on hosts that detect errors regularly there's nothing to do. For hosts that are paired but might sit idle for weeks, run patcherly heartbeat from a daily cron / systemd timer:
0 6 * * *  /usr/local/bin/patcherly heartbeat

The dashboard shows a small "Connector is healthy" check in the onboarding panel once it's heard from your connector in the last 24 hours. If that check stays unchecked, see Troubleshooting → Connector shows stale or disconnected.

Fail-closed apply contract

All connectors share the same fail-closed apply pipeline. If the fix payload sent to your server is not a valid unified diff, the connector:

  1. Takes a backup before parsing (target files are never touched first).
  2. Refuses to apply anything if parsing fails — no string-replacement fallback, no partial mutation.
  3. Restores the backup it just took and reports the attempt to Patcherly as a failed fix with reason unsupported_patch_format.

You will see this in your fix history as a failed attempt with a parser error message. Re-request the analysis to generate a fresh diff. Manually retrying the same payload won't change the outcome. See Troubleshooting → Fix marked unsupported_patch_format.

After a fix: restarts (Python / Node / PHP targets)

Some stacks need a process reload after files change. If your plan includes it, you can configure App restart automation for Python, Node.js, and PHP targets so approved shell commands run after a successful apply. WordPress targets do not run this automation — the bundled plugin patches files only and never executes arbitrary shell commands. Use Restarting your application and your host's usual procedures there.

Full guide: App restart automation · Post-apply restart safety

Package registries (Node.js, Python, PHP)

Prefer the universal installer? Use that first. When you install from a language package manager instead, use the official registry listing for your stack:

Stack Install command Registry
Node.js npm install @patcherly/nodejs-connector@latest npm — @patcherly/nodejs-connector
Python pip install patcherly-connector PyPI — patcherly-connector
PHP composer global require patcherly/php-connector Packagist — patcherly/php-connector

WordPress uses the WordPress.org plugin directory — not npm/PyPI/Packagist. See WordPress connector.

Pinned release archives (.zip / .tar.gz) remain on GitHub Releases when you need an exact version without a registry.

[!NOTE] Registry @latest: Each connector stack versions independently. npm, PyPI, and Packagist only publish when that connector's source changed in a release — a Node-only fix bumps npm without advancing PyPI or Packagist. Prefer npm install @patcherly/nodejs-connector@latest, unpinned pip/composer installs, or pin the archive for your stack from GitHub Releases.

Capability matrix

The table below summarises what each official connector can do at the target. Plan limits still apply — some rows depend on your subscription tier (e.g. auto-analysis, post-apply tests). Auto-analysis itself is decided by Patcherly based on your plan and the Auto-Analysis target toggle, not by the connector.

Capability Python Node.js PHP (standalone) WordPress
Patch apply (unified diff)
Backup before apply
Manual rollback (dashboard)
Post-apply restart manifest
Post-apply test execution pytest npm test phpunit / pest
HMAC request + response verify
Custom-sanitiser patterns

Post-apply test execution runs the local test framework after a successful patch on plans that include agent testing. Each connector tries its native runner first (pytest for Python, npm test for Node.js, vendor/bin/phpunit or vendor/bin/pest for PHP) and falls back to a synthetic connector_smoke row when no runner is installed in the project. To opt in to PHP automatic runs, install PHPUnit or Pest with Composer (composer require --dev phpunit/phpunit or composer require pestphp/pest --dev).

The post-apply restart manifest is a YAML document configured per-target in the dashboard. Each step is executed by the connector without invoking a shell: the agent rejects &&, ||, |, ;, backticks, $(, >, < in any string command before tokenising it, and uses the language's safe-exec primitive (asyncio.create_subprocess_exec in Python, child_process.execFile in Node, proc_open with an argv array in PHP 7.4+). Per-error_id dedup keeps a single error from triggering more than one restart in the same agent lifetime. See App restart automation for full setup steps.

Why WordPress is file-only. The WordPress plugin runs inside wp-content/plugins/ under the web-server user, and WordPress.org plugin-directory rules forbid bundling shell-out code. Patching files is safe and idempotent; running arbitrary shell commands from a CMS plugin is not. Use a standalone connector if you need post-apply automation on a WordPress host.

Standalone connectors (Python, Node.js, PHP) and log files

Did you know? Python, Node.js, and PHP connectors run outside your application as their own process. They are not affected when your app crashes — unlike the WordPress plugin, they do not need Emergency Rescue. They only detect what actually lands in log files they watch. If errors are missing in Patcherly, the usual causes are: your app is not writing failures to a log file, or the file is not on the target's monitored list. Add or enable logging in your stack, then confirm the path appears under Targets → Log paths (presets cover common locations; add custom paths on Core/Pro). See Custom log paths.

What gets redacted automatically

Every connector runs a built-in sanitiser over log lines and tracebacks before they leave your server. The built-in pattern set covers the highest-signal vendor tokens that commonly leak into stack traces:

  • AWS access key IDsAKIA… and ASIA… (long-term and STS temporary)
  • GitHub tokensghp_, gho_, ghu_, ghs_, ghr_ (PATs, OAuth, app installations)
  • Slack tokensxoxb-, xoxp-, xoxa-, xapp-
  • Stripe API keyssk_live_, sk_test_, rk_live_, rk_test_, pk_live_, pk_test_, whsec_
  • Database / message-bus URIspostgresql://, mysql://, mongodb://, mongodb+srv://, redis(s)://, amqp(s)://, clickhouse(s)://, mssql://, oracle://, jdbc:*:// (username and password normalised to USERNAME_REDACTED:PASSWORD_REDACTED)
  • OpenSSH public-key blobsssh-rsa, ssh-ed25519, ssh-dss, ecdsa-sha2-nistp{256,384,521}
  • PEM private-key blocks — OPENSSH / RSA / DSA / EC / ENCRYPTED and PKCS#8 unencrypted (-----BEGIN PRIVATE KEY----- with no algorithm prefix — what openssl pkcs8 exports for modern Ed25519/RSA/EC keys)
  • JWT, HMAC, SMTP, and generic *_password / *_secret assignments

The built-in list is identical across all four connectors (Python, Node.js, PHP standalone, WordPress) and Patcherly re-runs it on its own side as defence-in-depth. To cover your own custom token shapes (internal API keys, vendor SDKs not on this list, session IDs, etc.), use Custom sanitiser patterns on each target.

Hardening: backup folders and the public web

Applies to: any website/app (target) reachable from the public internet over HTTP/HTTPS — i.e. served by Apache or Nginx. All connectors (Node.js, Python, PHP, WordPress) are affected the same way. If your app is not web-facing (background worker, CLI tool, internal-only service), you can skip this section.

Before each fix, the connector copies the files it's about to change into a local backup directory on your website/app (target) so the change can be rolled back. If that directory ends up under your site's public document root, those backup files could be reachable via a URL like https://yourdomain.com/backups/… — bad. This section explains what's protected by default and what you need to add yourself.

Default protection — what every connector already does

Every connector (Node, Python, PHP, WordPress) automatically writes an .htaccess file and an IIS web.config deny file inside its backup directory (WordPress also protects uploads/patcherly/ storage the same way, and Site Health can warn if a canary URL returns HTTP 200):

# Deny all direct access to backup files
Order Deny,Allow
Deny from all

# Prevent directory listing
Options -Indexes

Apache + AllowOverride All honours .htaccess. IIS honours web.config. Both are silently ignored on Nginx — add the vhost rule below. On WordPress, Site Health / Settings → Diagnostics / an admin notice warn when a canary under uploads/patcherly returns HTTP 200. CLI agents cannot detect Nginx for you.

Coverage matrix

Your web server Backup / storage under webroot? Default protection
Apache + AllowOverride All Yes Protected by the auto-written .htaccess
IIS Yes Protected by the auto-written web.config
Apache + AllowOverride None Yes Not protected — add the vhost rule below
Nginx Yes Not protected.htaccess / web.config ignored; add the vhost rule below
Any (CLI agents) No (e.g. PATCHERLY_BACKUP_ROOT=../backups outside document root) Backups not reachable via HTTP — still add a deny if other files sit under the webroot

WordPress note: Storage stays under wp-content/uploads/patcherly/ (WP.org-compatible). Optional PATCHERLY_BACKUP_ROOT relocates pre-apply backups only. Queue, fix-cache, locks, and emergency.log remain under uploads — on Nginx you still need the vhost deny below for that path.

Tip (CLI agents): Prefer keeping the backup directory outside the webroot via PATCHERLY_BACKUP_ROOT before relying on vhost rules alone.

Nginx — vhost snippet

Add inside your server { ... } block (or save as /etc/nginx/snippets/patcherly-backup-protection.conf and include it):

# Deny access to Patcherly backup and storage directories
location ~ ^/(.*/)?(backups|\.patcherly_backups|patcherly_backups|uploads/patcherly)/ {
    deny all;
    return 403;
}

Apache — vhost snippet

Drop inside a <VirtualHost> or save as /etc/apache2/conf-available/patcherly-backup-protection.conf and a2enconf it. Requires mod_authz_core (loaded by default on Apache 2.4+):

<LocationMatch "^/(.*/)?(backups|\.patcherly_backups|patcherly_backups|uploads/patcherly)/">
    Require all denied
</LocationMatch>

Verifying

After reloading the web server, try fetching a backup path from outside the host:

curl -i https://yourdomain.com/backups/
# Expect: HTTP/1.1 403 Forbidden

If you still see backup files, see Troubleshooting → backup issues.

Where to go next

Goal Article
Install or upgrade Installing a connector
npm / PyPI / Packagist Package registries (above)
WordPress WordPress connector
Node.js Node.js connector
Python Python connector
PHP PHP connector
Ongoing control Connector management
Errors and fixes Understanding errors
Something wrong Troubleshooting

Product boundaries

Patcherly is an error-driven repair workflow, not a replacement for dedicated 24/7 uptime or full-APM products. See Product scope.