oci ghcr.io/wyre-ai/connectwise-cpq-mcp:v1.0.5stdioApache-2.0updated 8d ago
MCP server for ConnectWise CPQ (Sell) โ quotes, line items, customers, terms, tabs, templates, tax codes, recurring revenues, and users.
What can you do with ConnectWise CPQ?
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:
| Env var (env mode) | Gateway header (AUTH_MODE=gateway) |
Where to find it |
|---|---|---|
CPQ_ACCESS_KEY |
X-CPQ-Access-Key |
Sell URL: ...home?accesskey=<this> |
CPQ_PUBLIC_KEY |
X-CPQ-Public-Key |
Settings โ Organization Settings โ API Keys |
CPQ_PRIVATE_KEY |
X-CPQ-Private-Key |
Shown once at key creation |
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.
Running
export NODE_AUTH_TOKEN=$(gh auth token) # GitHub Packages auth for @wyre-ai/*
npm install
npm run build
node dist/index.js # stdio (default)
MCP_TRANSPORT=http node dist/index.js # HTTP on :8080 (/mcp, /health)
node scripts/smoke-dual-era.mjs # proves both protocol eras serve the same tools
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):
docker build --platform linux/amd64 --build-arg GITHUB_TOKEN=$(gh auth token) \
-t connectwise-cpq-mcp .
docker run -p 8080:8080 -e CPQ_ACCESS_KEY=... -e CPQ_PUBLIC_KEY=... -e CPQ_PRIVATE_KEY=... \
connectwise-cpq-mcp
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
Install
Add ConnectWise CPQ to your client. Pick the one you use.
claude mcp add ghcr-io-wyre-ai-connectwise-cpq-mcp-v1-0 -- docker run -i --rm ghcr.io/wyre-ai/connectwise-cpq-mcp:v1.0.5codex mcp add ghcr-io-wyre-ai-connectwise-cpq-mcp-v1-0 -- docker run -i --rm ghcr.io/wyre-ai/connectwise-cpq-mcp:v1.0.5amp mcp add ghcr-io-wyre-ai-connectwise-cpq-mcp-v1-0 -- docker run -i --rm ghcr.io/wyre-ai/connectwise-cpq-mcp:v1.0.5{
"mcpServers": {
"ghcr-io-wyre-ai-connectwise-cpq-mcp-v1-0": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/wyre-ai/connectwise-cpq-mcp:v1.0.5"
]
}
}
}Add to `claude_desktop_config.json`, then restart Claude Desktop.
{
"mcpServers": {
"ghcr-io-wyre-ai-connectwise-cpq-mcp-v1-0": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/wyre-ai/connectwise-cpq-mcp:v1.0.5"
]
}
}
}Add to `~/.cursor/mcp.json`, or `.cursor/mcp.json` for a single project.
code --add-mcp '{"name":"ghcr-io-wyre-ai-connectwise-cpq-mcp-v1-0","command":"docker","args":["run","-i","--rm","ghcr.io/wyre-ai/connectwise-cpq-mcp:v1.0.5"]}'Or add the block manually to `.vscode/mcp.json` under `servers`.
{
"mcpServers": {
"ghcr-io-wyre-ai-connectwise-cpq-mcp-v1-0": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/wyre-ai/connectwise-cpq-mcp:v1.0.5"
]
}
}
}Add to `~/.codeium/windsurf/mcp_config.json`.
{
"mcpServers": {
"ghcr-io-wyre-ai-connectwise-cpq-mcp-v1-0": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/wyre-ai/connectwise-cpq-mcp:v1.0.5"
]
}
}
}Add to `cline_mcp_settings.json` via the MCP Servers panel.
{
"mcpServers": {
"ghcr-io-wyre-ai-connectwise-cpq-mcp-v1-0": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/wyre-ai/connectwise-cpq-mcp:v1.0.5"
]
}
}
}Add to `~/.gemini/settings.json`.
{
"mcpServers": {
"ghcr-io-wyre-ai-connectwise-cpq-mcp-v1-0": {
"type": "local",
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/wyre-ai/connectwise-cpq-mcp:v1.0.5"
],
"tools": [
"*"
]
}
}
}Add to `~/.copilot/mcp-config.json`, or run `/mcp add` inside the CLI.
{
"context_servers": {
"ghcr-io-wyre-ai-connectwise-cpq-mcp-v1-0": {
"command": {
"path": "docker",
"args": [
"run",
"-i",
"--rm",
"ghcr.io/wyre-ai/connectwise-cpq-mcp:v1.0.5"
]
}
}
}
}Add to your Zed `settings.json`.
docker run -i --rm ghcr.io/wyre-ai/connectwise-cpq-mcp:v1.0.5Run `goose configure`, choose **Add Extension โ Command-line Extension**, and paste this command.
Score
39 / 100
Incomplete
- Documentation25/25
- Maintenance19/25
- Trust16/20
- Capability0/15
- Install experience12/15
- Documents what it does and how to connect
- Has a resolvable package or endpoint
- Exposes at least one tool, prompt or resource
- README has substantive content
- Includes a code example
- Documents its configuration
- Mentions credentials or security posture
- Last commit 1 days ago
- Has a release history
- Repository is not archived
- Licensed Apache-2.0
- Namespace verified in the official MCP registry
- Claimed by its owner
- Published under an organisation
- 0 tool(s) documented
- Provides prompt templates
- Provides resources
- 12 documented install method(s)
- Published to a package registry
- Offers a hosted endpoint โ no local install
Version history
| Versions | Published |
|---|---|
| 1.0.5Latest | Aug 26, 2026 |