
ConnectWise CPQ
io.github.WYRE-AIPublished by GitHub account WYRE-AIv1.0.6Updated Oct 24, 2026
MCP server for ConnectWise CPQ (Sell) — quotes, line items, customers, terms, and templates.
Overview
MCP server for ConnectWise CPQ (Sell) that lets an assistant search, read, create and edit quotes, line items, customers, terms and templates.
- What you can do
- Search and read quotes, quote versions, line items, customers, tabs, terms, templates, tax codes, recurring revenues and users, plus a connection test.
- Create quotes by copying a template, and update quote headers and quote customers.
- Add and update line items, and add or update quote terms.
- Delete quote items, terms, customers, versions and whole quotes (irreversible).
- Show a read-only quote card with header, status badges, line-item summary and totals where the host supports MCP Apps.
- When to use it
- Useful when an assistant needs to work inside a ConnectWise CPQ (Sell) tenant: looking up quotes and their line items, drafting a quote from a template, adjusting terms or customers, or cleaning up quote records. It is not a full CPQ integration — there are no publish, e-sign, PDF, order-porting or product-catalog endpoints.
- Requirements
- Runs as a local stdio process, or as an HTTP container (GHCR image) for gateway hosting. Needs a ConnectWise CPQ API user on CPQ 2022.2+ and three keys: CPQ_ACCESS_KEY, CPQ_PUBLIC_KEY and CPQ_PRIVATE_KEY, supplied as environment variables or, in gateway mode, as the X-CPQ-Access-Key, X-CPQ-Public-Key and X-CPQ-Private-Key headers. HTTP mode also requires CONDUIT_S2S_SECRET and an X-Gateway-S2S signed header. Building from source needs GitHub Packages auth and a locally built SDK tarball.
Installation
In SourceWeft
- Open ConnectWise CPQ in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
connectwise-cpq-mcp
MCP server for ConnectWise CPQ (Sell) — quotes, line items, customers, terms, tabs, templates, tax codes, recurring revenues, and users.
Built on the MCP 2026-07-28 spec via the split v2 SDK
(@modelcontextprotocol/server / /node / /client ^2.0.0-beta.5) with dual-era
serving: one shared McpServerFactory behind createMcpHandler({ legacy: 'stateless' })
answers both 2025-era initialize-handshake clients (the WYRE gateway today) and modern
2026-07-28 envelope clients — with an identical, deterministic 25-tool surface for every
caller. Ships as a GHCR container only (no MCPB bundle).
Tools (25, flat)
Reads: cpq_test_connection, cpq_search_quotes, cpq_get_quote, cpq_get_quote_versions,
cpq_search_quote_items, cpq_get_quote_item, cpq_list_quote_customers,
cpq_search_quote_tabs, cpq_list_quote_terms, cpq_list_templates, cpq_list_tax_codes,
cpq_list_recurring_revenues, cpq_list_users.
Writes: cpq_create_quote_from_template, cpq_update_quote (⚠ HIGH-IMPACT),
cpq_create_quote_item, cpq_update_quote_item, cpq_update_quote_customer,
cpq_create_quote_term, cpq_update_quote_term, and the ⚠ DESTRUCTIVE — IRREVERSIBLE
deletes: cpq_delete_quote_item, cpq_delete_quote_term, cpq_delete_quote_customer,
cpq_delete_quote_version, cpq_delete_quote.
Quote creation is copy-only (/api/quotes/copyById) — the CPQ API has no create-from-scratch,
publish/e-sign, order-porting, PDF, or product-catalog endpoints (pair with connectwise-psa
for those).
Credentials
CPQ requires an API user and CPQ 2022.2+. Three parts, all required:
In gateway mode a request missing any header is answered 401 (JSON-RPC error -32001)
before the MCP handler runs — it never falls through to env credentials.
Copy .env.example for local configuration. Leave CONDUIT_S2S_SECRET empty in that file.
/health and /healthz stay unauthenticated and do not read credentials. The stdio transport does not use CONDUIT_S2S_SECRET.
HTTP authentication
With MCP_TRANSPORT=http and CONDUIT_S2S_SECRET set, every /mcp request must include X-Gateway-S2S. The check is verifyS2sHeader in src/s2s-verify.ts: the header value is t=<unix seconds>,v1=<hex>, where the hex is HMAC-SHA256 of the literal string t=<unix seconds> keyed with CONDUIT_S2S_SECRET (64 lowercase hex characters). The timestamp must be within 300 seconds of the server clock. A missing or invalid header returns 401 before vendor credentials are read.
In AUTH_MODE=gateway those three X-CPQ-* headers are the only credential source for that request. With AUTH_MODE=env, a signed request uses CPQ_ACCESS_KEY, CPQ_PUBLIC_KEY, and CPQ_PRIVATE_KEY from the environment when the headers are absent.
Running
Local HTTP without a secret is development-only. It binds 127.0.0.1 (a non-loopback MCP_HTTP_HOST is overridden and logged) and logs a warning:
Local-dev note:
@wyre-technology/node-connectwise-cpqis declared at^1.0.0but is not yet published; until the SDK's first release lands,npm cifrom a fresh clone fails. Install the locally built SDK tarball instead:npm install /path/to/wyre-ai-node-connectwise-cpq-0.0.0-semantically-released.tgz(then keeppackage.jsonat^1.0.0).
Docker (linux/amd64 per fleet law):
The image listens on 0.0.0.0 inside the container (MCP_HTTP_HOST) and defaults to AUTH_MODE=gateway. Publish the port on loopback and pass the S2S secret. In gateway mode, CPQ credentials arrive on each request as headers; they are not read from the environment.
Compose refuses to start when CONDUIT_S2S_SECRET is unset, defaults AUTH_MODE to gateway, publishes 127.0.0.1:8080:8080, and does not inject CPQ_ACCESS_KEY, CPQ_PUBLIC_KEY, or CPQ_PRIVATE_KEY:
Single-tenant HTTP (AUTH_MODE=env) still requires the S2S secret, then uses the CPQ_* variables:
MCP Apps quote card
cpq_get_quote advertises a read-only MCP Apps card
(ui://connectwise-cpq/quote-card.html) showing the quote header, status badges, a
line-item summary, and totals. The card is purely additive: hosts without MCP Apps support
get the full QuoteView JSON (the _card field is extra, never a replacement), and any card
build failure leaves the JSON untouched. Rebuild the embedded UI with npm run build:ui
(output committed at src/generated/quote-card-html.ts). Brand at serve time via
MCP_BRAND_* env vars.
Elicitation and destructive-action consent
Where the connected client supports elicitation, the server asks before acting: date range
on unfiltered quote searches, template pick on ambiguous names, tab pick when adding items,
and confirmation before every delete. Elicitation rides the SDK v2 MRTR seam: handlers
return input_required results (embedded elicitation/create requests) that 2026-07-28
clients fulfil and retry, and that the SDK's legacy shim fulfils server-side for 2025-era
stateful connections (stdio). All elicitation is MRTR-safe: no vendor mutation ever fires
before an elicitation point, so a client retry of the original request cannot duplicate a
write.
Callers that never declared the form-elicitation capability — including stateless legacy HTTP requests, which is how the WYRE Conduit gateway connects — cannot be prompted at all. What that means depends on the stakes:
- Optional elicitation degrades gracefully (design.md §4): an unfiltered search falls back to a default 90-day range and says so, and the ambiguous template/tab pickers return an error listing the candidates.
- Destructive tools fail closed. A client that cannot answer has not consented, so the
five
cpq_delete_*tools refuse to run and return an actionable error naming what to do. A non-interactive caller opts in per call with"confirm_destructive_action": true, declared in each destructive tool's input schema so the gate is actually satisfiable. That argument is consulted only when no prompt is possible — it can never skip a confirmation an interactive user would otherwise have seen.
Vendor quirks encoded here
- Missing
Authorizationheader → CPQ answers 500 (not 401); credentials are validated client-side before any request. - The real 401 body carries a vendor typo (
"...has occured during basic auth validation"). Content-Type: application/json; version=1.0on every request (media-type versioning).- List responses are bare JSON arrays — pagination terminates on a short page.
- Condition dates must be date-only and bracketed:
createDate >= [2026-07-01]. - PATCH bodies are RFC 6902 JSON Patch arrays.
License
Apache-2.0 © WYRE Technology
Source: README.md at commit ca2c56a
Tools
0Version history
2- v1.0.6LatestOct 14, 2026
- v1.0.5Sep 16, 2026
Score
50% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts