Saddle turns your WordPress site into a Model Context Protocol (MCP) server. AI apps you already use — Claude, Cursor, VS Code, and others — connect to your site and help with real work: reading and writing posts and pages, managing media, and designing pages with your theme’s own styles.
Everything runs on your own site. There is no account to create and no cloud service in the middle: your content, your credentials and every tool call stay in your WordPress. Agents sign in with WordPress core’s Application Passwords, and you decide how much they are allowed to do.
Saddle is built around three rules:
All tools are served from one authenticated endpoint on your site (/wp-json/saddle/v1/mcp). Each tool declares the access level it needs, so a read-only connection can only ever read.
Site management (separate opt-in level) — read and change common Settings screen options (site title, permalinks, reading and discussion settings), activate/deactivate plugins, switch themes, flush the cache.
Note: everything here runs through WordPress’s own functions. Saddle contains no shell commands, no eval(), and no arbitrary code execution — anywhere. Values are validated before saving, and sensitive settings (site URL, security keys, user roles, admin email) can never be touched.
.md playbook files that teach your AI how you like things done), and let each new session start knowing what changed on the site recently, from Saddle’s own activity log.Go to Saddle Connections, name a connection, and approve it. WordPress core issues an Application Password for it, and you paste the shown settings into your AI app. Revoking a connection invalidates its credential immediately.
Note: a Saddle-issued credential only works on Saddle’s own endpoint. It cannot be used against the rest of the REST API or XML-RPC.
A few apps — ChatGPT’s custom connectors among them — give you nowhere to paste a sign-in key. For those, Saddle can run a standard OAuth 2.1 sign-in on your own site: the app sends you to an approval screen in your WordPress admin, you see who is asking and what they want, and you decide.
This is off until you turn it on, on the Settings screen. It runs entirely inside your WordPress — there is no PlugPress server involved at any point, exactly as with Application Passwords. Only administrators can approve a connection, and an approval can never grant more than your chosen access level: if the site is set to read-only, an approved app gets read-only. You can see and revoke approved apps from the Connections screen at any time.
Turning it on publishes the small set of addresses the OAuth standard requires so apps can find and complete the sign-in. With it off — the default — none of them exist.
Saddle speaks MCP itself. It ships no third-party library, and every function, class, option and hook it defines is prefixed saddle / Saddle_ / SADDLE_.
If the separate MCP Adapter plugin happens to be active on the same site, Saddle detects it and uses it instead. That is optional and nothing depends on it — the endpoint, the tools and the safety model are identical either way.
The admin screen is a React app. Its full human-readable source ships inside this plugin in admin/src/; the compiled bundle in admin/build/ is produced from it with the official @wordpress/scripts toolchain.
Saddle Pro is a separate, optional add-on that adds page-builder-native editing (Divi first). This free plugin is complete on its own — nothing in it is locked, limited, or nagging you to upgrade.
Saddle sends no analytics, telemetry, or usage data anywhere, and no content or credentials ever leave your site. Its MCP endpoint is inbound — agents call your site, not the other way round.
The version on WordPress.org makes no outbound request at all. If you installed Saddle from plugpress.co instead, that copy checks for its own updates: it sends the plugin name and the version number you have, to one fixed address, at most once every six hours, and only when WordPress runs an update check. No site address, no content, no account, nothing about you. It is the same thing WordPress does for every plugin you install from WordPress.org, pointed at us instead.
Apart from that, four things make an outbound request, and each one is started by you:
/.well-known/ discovery address — to confirm those endpoints are reachable. Nothing leaves your server.Unsplash (optional, off until you add a key). If you enter your own Unsplash API key on the Integrations screen, the unsplash-search and unsplash-import tools call the Unsplash API (api.unsplash.com, images.unsplash.com) directly from your site, sending only your search keywords or a photo id. With no key saved, no request is ever made. Unsplash API Guidelines: https://help.unsplash.com/en/articles/2511245-unsplash-api-guidelines — API Terms: https://unsplash.com/api-terms — privacy policy: https://unsplash.com/privacy
Attribution: a photo imported this way is saved with a caption crediting the photographer, containing links to their Unsplash profile and to unsplash.com. The Unsplash API Terms require this credit, so it is written for you. Because it is the image’s caption, it is visible wherever your theme displays captions — including on the public side of your site. It is an ordinary caption: edit or clear it in the Media library whenever you like, or pass your own caption when importing. No other external link is ever added to your site, and nothing links back to the plugin author.
Checking an app’s identity (optional, off unless you turn on OAuth sign-in). ChatGPT can’t be given a sign-in key by hand, so Saddle can let apps sign in through an approval screen instead. Some apps identify themselves with a web address that serves a small description of the app. If one does, Saddle fetches that address — and only that address, chosen by the app, never by us — to confirm it vouches for the app, so the approval screen can tell you whether the app was verified or merely self-described. Nothing about your site is sent; it is a plain read. The request is HTTPS-only, follows no redirects, times out in five seconds, is capped at 64 KB, and the answer is cached. With OAuth sign-in off — the default — this never happens.