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. With Repo Pull Requests, a site can open a GitHub PR instead of (or as well as) applying live.
This page is the customer-facing overview. For install commands and per-stack steps, continue to Installing a connector and the guides below. Marketing download links: patcherly.com/connectors.
What you get¶
Language and framework are set from the connector on context upload (overwriting the site row when the detected values change). While a connector is paired, those fields stay locked in Sites → Edit; disconnect to change them manually.
- 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. With Repo Pull Requests, a site can open a GitHub PR instead of (or as well as) applying live.
- Site backups (your files) - Before changing files, the connector creates a site 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 loginon the site 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-site 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 site and you control it.
- In your Patcherly dashboard, open Sites, click the site, and flip Test Mode ON.
- From your connector host, send a sample:
- WordPress - enable Test Mode on Sites, then use your connector’s test flow from the dashboard (or wait for a real error). The plugin Home status bar can turn Test Mode off when it is open.
- Python / Node.js / PHP -
patcherly send-test(CLI auto-checks the window first) - 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, it stays connected as long as it can reach Patcherly and refreshes its credentials. Normal traffic (sending errors, applying fixes, status checks) does that automatically. If the host sits idle too long with no check-in, credentials expire and you will need to pair again.
- WordPress plugin - schedules a small daily "hello" via WordPress' built-in tasks so quiet sites keep credentials fresh and the dashboard sees the site as alive. Keep WordPress cron working (or a real system cron hitting
wp-cron.php). - Python / Node.js / PHP CLIs - every connector command already counts as a check-in. On quiet hosts, run
patcherly heartbeatfrom a daily cron /systemdtimer:
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.
What the Sites status means¶
The colored dot next to each site name is the agent status (healthy / stale / offline, or a tip when the connector reported deactivate or uninstall). Full table: Agent status on Sites.
Unpair vs uninstall¶
| Command | What it does | Sites tip |
|---|---|---|
patcherly logout | Unpairs only. Keeps the install, queues, and backups. | Offline |
patcherly uninstall | Stops the agent if it can, unpairs, clears local credentials / queues / cache, and asks about backups. Leaves the install folder for you to delete. | Connector reported uninstalled |
WordPress uses Deactivate / Delete in Plugins instead. See WordPress connector.
When a fix cannot be applied safely¶
All connectors follow the same safe apply path on your server:
- They check the approved fix before touching any site files (no backup yet).
- If the fix cannot be read or cannot match the live files, nothing is written and no backup is created.
- On the dashboard, that error shows as Failed (unreadable fix) or returns to Analyzed with an orange Stale patch badge (the file on the site changed since the fix was prepared). Your files stay as they were.
A site backup is created only when the connector is about to write files for a fix that passed those checks.
After a fix: restarts (Python / Node / PHP sites)¶
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 sites so approved shell commands run after a successful apply. WordPress sites do not run this automation - the bundled plugin patches files only and never executes arbitrary shell commands. Use Restart after a fix 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.
Release archives (always the latest build for each stack):
Full steps: Installing a connector.
[!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. Prefernpm install @patcherly/nodejs-connector@latest, unpinned pip/composer installs, pin a version on your registry, or download the archive for your stack above.
Capability matrix¶
The table below summarises what each official connector can do at the site. 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 site toggle, not by the connector.
| Capability | Python | Node.js | PHP (standalone) | WordPress |
|---|---|---|---|---|
| Patch apply | ✓ | ✓ | ✓ | ✓ |
| 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 (
pytestfor Python,npm testfor Node.js,vendor/bin/phpunitorvendor/bin/pestfor PHP) and falls back to a syntheticconnector_smokerow 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/phpunitorcomposer require pestphp/pest --dev). On Node.js,npm testruns from your app directory (not the connector package) with a hard wall-clock timeout (default 60s, overridePATCHERLY_NPM_TEST_TIMEOUT_MS). A hanging or failingscripts.testreports test failure and can leave the error short of Fixed / Verifying until tests finish or time out - keep smoke suites short and non-interactive.
The post-apply restart manifest is a YAML document configured per-site in the dashboard. String-form run commands are tokenised and checked for shell metacharacters before launch; array-form run (YAML list) skips that string scan but argv[0] must be on the binary allowlist. Connectors use safe-exec primitives (asyncio.create_subprocess_exec, child_process.execFile, proc_open with an argv array). Child processes inherit the agent environment with Patcherly OAuth/credential env keys stripped (app secrets such as DATABASE_URL remain). 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 site's monitored list. Add or enable logging in your stack, then confirm the path under Sites → expand the site → Monitored Logs → Customize (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 IDs -
AKIA…andASIA…(long-term and STS temporary) - GitHub tokens -
ghp_,gho_,ghu_,ghs_,ghr_(PATs, OAuth, app installations) - Slack tokens -
xoxb-,xoxp-,xoxa-,xapp- - Stripe API keys -
sk_live_,sk_test_,rk_live_,rk_test_,pk_live_,pk_test_,whsec_ - Database / message-bus URIs -
postgresql://,mysql://,mongodb://,mongodb+srv://,redis(s)://,amqp(s)://,clickhouse(s)://,mssql://,oracle://,jdbc:*://(username and password normalised toUSERNAME_REDACTED:PASSWORD_REDACTED) - OpenSSH public-key blobs -
ssh-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 - whatopenssl pkcs8exports for modern Ed25519/RSA/EC keys) - JWT, HMAC, SMTP, and generic
*_password/*_secretassignments
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 site.
Hardening: backup folders and the public web¶
Applies to: any site or app 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 site or app 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, Tools → Site Health and Settings → Diagnostics explain when a canary under uploads/patcherly returns HTTP 200 and how to add optional vhost hardening. 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 (prefer PATCHERLY_BACKUP_ROOT outside the document root; default is .patcherly_backups) | 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). OptionalPATCHERLY_BACKUP_ROOTrelocates pre-apply backups only. Queue, fix-cache, locks, andemergency.logremain 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_ROOTbefore 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:
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.