Jetpack CRM REST API Improved releases
A complete, standards-compliant WordPress REST API for Jetpack CRM (a.k.a. `zero-bs-crm`), plus an embedded MCP (Model Context Protocol) server that lets AI agents work with your CRM through native tools.
by Иван Никитин · github.com/ivannin/jetpack-crm-rest-api-improved · website
Install
The author publishes release zips, so WP-CLI can install straight from GitHub:
wp plugin install https://github.com/ivannin/jetpack-crm-rest-api-improved/releases/download/v0.9.0/jetpack-crm-rest-api-improved.zipA complete, standards-compliant WordPress REST API for Jetpack CRM (a.k.a.
zero-bs-crm), plus an embedded MCP (Model Context Protocol) server that lets
AI agents work with your CRM through native tools.
The plugin replaces the incomplete and non-standard Jetpack CRM API with a single, consistent REST layer that covers every major CRM entity, uses real WordPress authentication, returns correct HTTP status codes, and ships with auto-generated OpenAPI documentation and an MCP endpoint.
- REST namespace:
jpcrm-improved/v1 - Base URL:
https://<your-site>/wp-json/jpcrm-improved/v1 - MCP endpoint:
https://<your-site>/wp-json/jpcrm-improved/v1/mcp - License: MIT
Table of contents
- Why this plugin exists
- Features
- Requirements
- Installation
- Configuration
- Authentication
- Quick start
- REST API overview
- MCP server overview
- Architecture
- Extending the plugin
- Security notes
- Development and testing
- Documentation
- Changelog
- Credits
- License
Why this plugin exists
The REST API bundled with Jetpack CRM has several long-standing problems that make it unsuitable for modern integrations:
- Custom route (
/zbs_api/) instead of the WordPress standard/wp-json/. - Credentials in query strings, which leak secrets into server logs, proxies, browser history and referrers.
- A single global key/secret with no per-user scoping, roles or revocation.
- Broken semantics: many endpoints require a trailing slash, return
405, or time out; some "read" operations usePOST. - Errors returned as HTTP 200 with
{ "error": 100 }, so clients cannot tell success from failure. - Missing operations: no
DELETE, no standaloneUPDATE, noGETby ID for most entities, and no access to tasks, logs, forms, segments, tags, custom fields, meta, line items, templates or emails. - No pagination headers, schemas, validation or batch operations.
Jetpack CRM REST API Improved implements the whole surface as a normal WordPress
REST API. See docs/REST-API.md for the full reference.
Features
- Full CRUD (
GET,POST,PUT,PATCH,DELETE) for: contacts, companies, invoices, quotes, transactions, tasks, task reminders, logs, forms, segments, quote templates, line items, tags, emails, email threads and email templates. - Standard WordPress authentication using Application Passwords (HTTP Basic)
or the logged-in cookie plus
X-WP-Nonce. - Capability-based authorization mapped to Jetpack CRM permissions
(
admin_zerobs_*). - Consistent responses: JSON objects for single items, arrays for collections,
201 Createdon create, correct400/401/403/404/405/422/500errors. - Pagination with
X-WP-TotalandX-WP-TotalPagesheaders. - Sub-resources for every CRM entity: tags, meta, custom fields, external sources and object links.
- Batch endpoint for running multiple operations in one request.
- Auto-generated OpenAPI 3.0.3 document at
/openapi.json. - Embedded MCP server (Streamable HTTP) with generic CRUD tools, discovery, resources, prompts and safety modes.
- Extensible through WordPress filters and actions.
Requirements
| Requirement | Version |
|---|---|
| WordPress | 6.0 or newer |
| PHP | 7.4 or newer |
Jetpack CRM (zero-bs-crm) |
Active and configured |
The plugin activates only when Jetpack CRM is active; otherwise the REST routes are simply not registered.
Installation
From the latest release (recommended)
Download the packaged plugin ZIP from the latest GitHub release:
https://github.com/ivannin/jetpack-crm-rest-api-improved/releases
- Open the releases page and download the latest
jetpack-crm-rest-api-improved.zipasset. - In WordPress, go to Plugins → Add New → Upload Plugin, choose the ZIP file, then click Install Now and Activate.
- Make sure Jetpack CRM is installed and active.
Alternatively, unzip the archive and upload the jetpack-crm-rest-api-improved
folder to wp-content/plugins/ (for example via SFTP).
From source (development)
Clone the repository and, optionally, install the Composer development tools:
git clone https://github.com/ivannin/jetpack-crm-rest-api-improved.git
The plugin ships with a PSR-4 fallback autoloader, so it works without running Composer. To use the optimized Composer autoloader or the development tools (PHPUnit, PHPCS, WPCS), run inside the plugin folder:
composer install --no-dev # production
composer install # development
Via Composer
composer require ivannikitin/jetpack-crm-rest-api-improved
Updating
Download the newest release ZIP from https://github.com/ivannin/jetpack-crm-rest-api-improved/releases and replace the plugin, or update it from the WordPress plugin screen. Your settings are preserved: they are stored as WordPress options and kept across updates.
Configuration
Open Jetpack CRM → REST API / MCP in the WordPress admin. The page is available
to users with the admin_zerobs_manage_options capability.
| Setting | Option name | Default | Description |
|---|---|---|---|
| MCP server | jpcrm_improved_mcp_enabled |
false |
Registers the /mcp endpoint. When off, only the REST API is exposed. |
crm_raw |
jpcrm_improved_mcp_raw_enabled |
false |
Exposes the crm_raw tool, which can call any REST route in the namespace. Intended for debugging; not recommended in production. |
| Read-only mode | jpcrm_improved_mcp_readonly |
false |
Hides and blocks all write tools. The agent can still read and search. |
| Confirmation | jpcrm_improved_mcp_confirm |
false |
Requires an explicit confirm=true argument for crm_delete, crm_batch and crm_raw. |
| Logging | jpcrm_improved_mcp_logging |
false |
Logs MCP method and tool names (never secrets) to debug.log when WP_DEBUG is enabled. |
The settings page also displays the exact MCP endpoint URL and the expected
Authorization: Basic ... header.
Authentication
The plugin does not invent its own authentication. It uses the standard WordPress mechanisms, so any client that can authenticate against WordPress can use the API.
Application Passwords (recommended)
-
Edit your WordPress user profile and scroll to Application Passwords.
-
Enter a name (for example,
crm-integration) and click Add New Application Password. -
Copy the generated password and send it as HTTP Basic auth using the format
base64(login:application_password):curl -u "admin:xxxx xxxx xxxx xxxx xxxx xxxx" \ https://example.com/wp-json/jpcrm-improved/v1/status
Application Passwords require HTTPS. For local development over HTTP the plugin
automatically enables them when WordPress runs with
WP_ENVIRONMENT_TYPE=local.
Create passwords in the WordPress admin, not via WP-CLI. With a persistent object cache enabled (for example W3TC + Redis), a password created with
--all`, which permanently wipes working integrations.wp user application-password createis invisible to web requests until the_application_passwordsusermeta cache is refreshed from a web context.wp cache flushfrom CLI does not invalidate it, so the REST API answers401 jpcrm_rest_unauthorized. A password created in Profile → Application Passwords works immediately. Avoid `wp user application-password deleteUse
GET /statusto diagnose: itsdiagnosticsblock reportsobject_cache,object_cache_dropinandapplication_passwords_countfor the current user.
Cookie authentication
Requests made from a logged-in browser session must include a valid REST nonce in
the X-WP-Nonce header.
Permissions
Each operation checks a Jetpack CRM capability for the current user. The mapping is
documented in docs/REST-API.md. A user without
the required capability receives 403 jpcrm_rest_forbidden.
Quick start
List the five most recent contacts:
curl -u "admin:APP_PASSWORD" \
"https://example.com/wp-json/jpcrm-improved/v1/contacts?per_page=5&orderby=id&order=desc"
Create a contact:
curl -u "admin:APP_PASSWORD" \
-H "Content-Type: application/json" \
-X POST "https://example.com/wp-json/jpcrm-improved/v1/contacts" \
-d '{
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Doe",
"status": "Lead",
"tags": ["web"]
}'
Update a contact (partial update):
curl -u "admin:APP_PASSWORD" \
-H "Content-Type: application/json" \
-X PATCH "https://example.com/wp-json/jpcrm-improved/v1/contacts/123" \
-d '{ "status": "Customer" }'
Delete a contact:
curl -u "admin:APP_PASSWORD" \
-X DELETE "https://example.com/wp-json/jpcrm-improved/v1/contacts/123"
Inspect your own permissions:
curl -u "admin:APP_PASSWORD" \
"https://example.com/wp-json/jpcrm-improved/v1/me"
Discover the API:
curl -u "admin:APP_PASSWORD" \
"https://example.com/wp-json/jpcrm-improved/v1/openapi.json"
REST API overview
All routes live under /wp-json/jpcrm-improved/v1.
| Resource | Path | Operations |
|---|---|---|
| Contacts | /contacts |
list, get, create, update, delete |
| Companies | /companies |
list, get, create, update, delete |
| Invoices | /invoices |
list, get, create, update, delete |
| Quotes | /quotes |
list, get, create, update, delete, accept |
| Transactions | /transactions |
list, get, create, update, delete |
| Tasks | /tasks |
list, get, create, update, delete |
| Task reminders | /task-reminders |
list, get, create, update, delete |
| Logs | /logs |
list, get, create, update, delete |
| Forms | /forms |
list, get, create, update, delete |
| Segments | /segments |
list, get, create, update, delete, compile |
| Quote templates | /quote-templates |
list, get, create, update, delete |
| Line items | /line-items |
list, get, create, update, delete |
| Tags | /tags |
list, get, create, update, delete |
| Emails | /emails |
list, get, send, delete |
| Email threads | /email-threads |
list, get, delete, star, read, reply |
| Email templates | /email-templates |
list, get, create, update, delete |
| System | /status, /me |
read |
| Batch | /batch |
run multiple operations |
| OpenAPI | /openapi.json |
read |
Collections support page, per_page, offset, orderby, order, search
(alias s), plus entity-specific filters. Collection responses include
X-WP-Total and X-WP-TotalPages headers.
See the full REST API reference for parameters, fields, sub-resources, error codes and examples.
MCP server overview
When enabled, the plugin exposes a Model Context Protocol server over Streamable HTTP. AI agents (Claude Desktop, Cursor, opencode, Hermes Agent, custom clients) connect with their own WordPress user and Application Password and get a native toolkit for the CRM.
- Endpoint:
POST /wp-json/jpcrm-improved/v1/mcp - Transport: Streamable HTTP (JSON-RPC 2.0, single requests and batches)
- Server name:
jetpack-crm-mcp - Protocol versions:
2025-03-26,2025-06-18(default),2026-07-28 - Tools: 21 built-in tools are registered, of which 20 are listed by
tools/listby default —crm_rawonly appears whenjpcrm_improved_mcp_raw_enabledis on, and write tools are hidden in read-only mode. Includes a generic CRUD facade (crm_search,crm_get,crm_create,crm_update,crm_delete,crm_batch,crm_raw), discovery (crm_entities,crm_me,crm_status), email tools, sub-resource tools and action tools. - Resources:
jpcrm://entities,jpcrm://me,jpcrm://status,jpcrm://openapiviaresources/list; the templatejpcrm://{entity}/{id}is advertised separately viaresources/templates/list. - Prompts:
summarize_contact,contact_timeline,pipeline_review,draft_email.
Every MCP tool dispatches internally through the plugin's own REST controllers via
rest_do_request(), so permissions, validation and response shapes are identical
to the REST API. There is no network hop and no second source of truth.
See the full MCP server documentation.
Architecture
AI agent ──(MCP / Streamable HTTP, Basic Application Password)──► WordPress
│
REST controllers ──► DAL3 ──► wp_zbs_* tables
│
Jetpack CRM core
classes/Rest/— REST controllers, field mapping, permissions, OpenAPI.classes/Rest/Controllers/— one controller per resource.classes/Mcp/— JSON-RPC server, HTTP endpoint, tool registry, tools.classes/Admin/SettingsPage.php— the admin settings page.classes/Plugin.php— bootstrap, hooks and CRM extension registration.
The REST layer talks to Jetpack CRM's data layer (DAL3). Emails and email
templates, which do not have DAL support in the CRM core, are handled through the
Rest\MailAdapter.
Extending the plugin
Filters
| Filter | Default | Purpose |
|---|---|---|
jpcrm_improved_rest_controllers |
controller list | Add or remove REST controllers. |
jpcrm_improved_rest_max_per_page |
1000 |
Maximum per_page value. Use 0 or less to disable the cap. |
jpcrm_improved_rest_batch_max_requests |
25 |
Maximum number of sub-requests in POST /batch. |
jpcrm_improved_openapi_public |
false |
Make /openapi.json publicly readable. |
jpcrm_improved_mcp_batch_max_requests |
25 |
Maximum number of operations in the crm_batch tool. |
jpcrm_improved_mcp_raw_enabled |
option value | Programmatically gate the crm_raw tool. |
Actions
| Action | Purpose |
|---|---|
jpcrm_improved_mcp_register_tools |
Receives the ToolRegistry; call ->add() to register custom MCP tools. |
Example — make the OpenAPI document public:
add_filter( 'jpcrm_improved_openapi_public', '__return_true' );
Example — register a custom MCP tool:
add_action( 'jpcrm_improved_mcp_register_tools', function ( $registry ) {
$registry->add( array(
'name' => 'my_tool',
'description' => 'Does something useful.',
'inputSchema' => array(
'type' => 'object',
'properties' => array( 'id' => array( 'type' => 'integer' ) ),
'required' => array( 'id' ),
),
'capability' => array( 'contacts', 'read' ),
'annotations' => array(
'readOnlyHint' => true,
'destructiveHint' => false,
'idempotentHint' => true,
'openWorldHint' => false,
),
'handler' => 'my_tool_handler',
) );
} );
Security notes
- Authentication is delegated entirely to WordPress; the plugin stores no API keys of its own.
- Always use HTTPS. Application Passwords are transmitted with every request and must not be sent over plain HTTP.
- Use a dedicated WordPress user for integrations and grant only the CRM capabilities it needs.
- For AI agents, consider enabling Read-only mode and requiring confirmation for destructive operations.
- Keep
crm_rawdisabled unless you are actively debugging. - Never commit Application Passwords, database credentials or other secrets to
version control. The bundled
.gitignoreexcludes.env, logs, dependencies and build artifacts.
Development and testing
The plugin depends on Jetpack CRM, so the recommended development setup is a
WordPress install (often Docker) with the plugin mounted at
wp-content/plugins/jetpack-crm-rest-api-improved.
Useful commands inside the plugin directory:
composer install # install development dependencies
vendor/bin/phpcs # WordPress Coding Standards
vendor/bin/phpunit # run the unit/integration suite (when present)
Complementary end-to-end checks used during development include HTTP contract runs
(run.ps1 against a running site) and an MCP coverage check that verifies every
registered route is reachable through an MCP tool. Those scripts live in the
development workspace outside the distributable plugin folder.
Documentation
| Document | Description |
|---|---|
docs/REST-API.md |
Complete REST API reference: authentication, parameters, resources, fields, sub-resources, errors, batch and OpenAPI. |
docs/MCP-SERVER.md |
Complete MCP server reference: transport, JSON-RPC methods, tool catalog, resources, prompts, entity registry and safety modes. |
The living, machine-readable specification is always available at
GET /wp-json/jpcrm-improved/v1/openapi.json.
Changelog
0.9.0
- Fixed: the
logscollection is no longer empty; listing supportsobject_type+object_id,type,search,pinned,owner, sorting and pagination (#1). - Fixed:
DELETE /logs/{id}now deletes the record instead of returning a false404(#6). - Fixed:
X-WP-Total/X-WP-TotalPages(and the MCPcrm_searchtotal) now respectsearch,status,ownerand other filters; 0 matches →0(#2). - Fixed: emails no longer return
date_sent: -1; the response exposes a booleansentand a real ISO-8601date_sent(ornull) (#3). - Fixed:
crm_entitiesreportsrequired_on_create: []for contacts (email is recommended, not required) and documentsidentity_fields(#5). - Docs: clarified
resources/templates/list, the conditional tool count, the WP-CLI Application Password/object-cache pitfall, and added adiagnosticsblock toGET /status(#4).
0.8.0
- REST API for all Jetpack CRM entities: contacts, companies, invoices, quotes, transactions, tasks, task reminders, logs, forms, segments, quote templates, line items, tags, emails, email threads and email templates.
- Sub-resource routes for tags, meta, custom fields, external sources and links.
- Batch endpoint and OpenAPI 3.0.3 generation.
- Embedded MCP server with generic CRUD, discovery, resources, prompts and safety
modes (read-only, confirmation,
crm_raw, logging). - Admin settings page under Jetpack CRM → REST API / MCP.
Credits
- Author: Ivan Nikitin — https://ivannikitin.com
- Requires: Jetpack CRM (
zero-bs-crm)
License
This plugin is released under the MIT License. See the LICENSE
file for the full text.
Releases
2 releases. Each count is every asset in that release; expand a row for the breakdown.