Skip to content

feat(3cx): add 3CX PBX plugin — native MCP server skills, commands - #225

Merged
asachs01 merged 1 commit into
mainfrom
feat/3cx-plugin
Aug 21, 2026
Merged

feat(3cx): add 3CX PBX plugin — native MCP server skills, commands#225
asachs01 merged 1 commit into
mainfrom
feat/3cx-plugin

Conversation

@asachs01

@asachs01 asachs01 commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a plugin for 3CX's native PBX MCP server, introduced in 3CX V20 Update 10 (announced July 30, 2026 as an Alpha release — 3CX's own release notes describe it as "intended for testing and evaluation only"). This is a first-party server built into the PBX itself, distinct from the older third-party SSIG-IT/3cx-mcp-server community project on GitHub — the two are not conflated anywhere in this plugin, and no claim from the community project (including its "Enterprise/Enterprise Plus license required" note) is carried over, since it isn't confirmed for 3CX's native offering.

Why this is a plugin now, and why it looks different from other plugins here: every 3CX PBX exposes its own MCP endpoint at its own FQDN (https://yourpbx.3cx.eu/mcp pattern) with its own OAuth authorization server — there's no shared mcp.3cx.com. That means it doesn't fit Conduit's single-shared-endpoint vendor catalog (src/credentials/vendor-config.ts has no 3cx entry, and structurally can't in the normal sense). So this plugin documents two real connection paths instead of shipping a .mcp.json:

  1. Direct, standaloneclaude mcp add --transport http straight at a PBX's own URL, OAuth done directly against that PBX.
  2. Through Conduit's BYO MCP feature (/connect/byo) — generic, vendor-agnostic code (src/byo/*) that auto-discovers the PBX's OAuth flow (RFC 9728 → RFC 8414 → RFC 7591 DCR, RFC 9207 issuer validation) and auto-classifies each tool's permission tier from its name/description (src/byo/byo-tool-classifier.ts), since there's no hand-curated VENDOR_TOOL_CONFIG entry to read from.

GOVERNANCE.md works through what that BYO classifier heuristic actually does to 3CX's documented tool groups (verified directly against the real source in wyre-technology/conduit, not assumed) — including a genuine, non-obvious gap: the Query tool is enforced SELECT-only inside the PBX regardless of role, but Conduit's classifier tiers on the tool's name. If that name doesn't lead with a recognized read verb, it tiers write despite the PBX-side restriction — a usability gap, not a safety one, but worth knowing before assuming a read-tier grant reaches it.

3CX has not published exact MCP tool-name strings anywhere I could access — only human-readable capability labels in its own "MCP Tools and Permissions Reference." Every skill here describes tools by capability rather than inventing snake_case identifiers, and points at calling tools/list against the live PBX as the authoritative source.

What was added

Category: productivity — no telephony/UC/voip category exists in this repo's taxonomy (checked: accounting, bcdr, crm, documentation, email-security, incident-management, infrastructure, knowledge, legal, marketplace, monitoring, network, psa, psa-rmm, rmm, sales, security, workflow-pack). network is specifically network-device monitoring (Auvik/Domotz/Meraki), not a fit for a phone system. productivity already houses Slack — another communications/collaboration platform — so 3CX mirrors that placement rather than forcing a new category.

Directory: msp-claude-plugins/3cx/3cx/

  • skills/api-patterns — connection setup (direct + Conduit BYO), the inherited permission model, and how to discover the live tool surface
  • skills/directory — contact/extension lookups (email, exact extension, phonebook, CRM-synced)
  • skills/calls-queues — active calls, recordings, voicemail, queue/department/profile visibility, plus the write actions that change live routing (with explicit caution language)
  • skills/pbx-admin — system diagnostics, PBX inventory/database, the read-only Query tool, call flow apps, and blocklist/blacklist/DID write actions (with explicit caution language)
  • commands/find-contact.md, commands/pbx-health-check.md, commands/queue-status.md
  • GOVERNANCE.md, README.md

No subagent — checked the closest analogues in this repo (vendors running their own hosted/native MCP server rather than a WYRE-built one: pax8, rootly, runzero; connectwise-cpq is WYRE-built, not a vendor-hosted analogue, so it wasn't used as a pattern source). None of those three ship a populated agents/ directory — matching that precedent, this plugin ships skills + commands only.

No .env.example and no .mcp.json — every connection is OAuth against a PBX-specific URL with no static token or shared endpoint to template, matching the wyre-gateway plugin's precedent (pure OAuth, no headers/secrets) rather than the API-key .env.example pattern used by token-based vendors.

plugin.json starts at 0.1.0, matching the actual starting-version convention of the three most recently added vendor-hosted-MCP plugins (axcient, rootly, runzero all shipped 0.1.0 initially, not 1.0.0).

Also touched: docs/scripts/generate-plugins.ts (added a 3cx3CX display-name mapping so the docs site doesn't title-case it as "3cx"), docs/src/data/plugins.ts (regenerated), scripts/unanchored-docs.json (one new inventoried entry — see verification below).

Verification

All commands run from the repo root in a clean worktree off origin/main, after committing.

1. Docs-site regen + build (docs/, using --ignore-scripts locally because sharp's native build fails on this machine regardless of Node version 22/26 — pre-existing, unrelated to this change, and self-heals via the deploy-docs.yml workflow's npm ci on Node 20):

$ npx tsx scripts/generate-plugins.ts
Generated .../docs/src/data/plugins.ts with 81 plugins
Categories: accounting, bcdr, crm, documentation, email-security, incident-management, infrastructure, legal, marketplace, monitoring, network, productivity, psa, rmm, sales, security, workflow-pack
Generated .../docs/src/data/sharedSkills.ts with 5 shared skills

Plugin count moved 80 → 81 in the generated data (confirmed by diffing against git show HEAD~1). The new entry:

id: '3cx', name: '3CX', vendor: '3CX', category: 'productivity', maturity: 'beta'
skills: [calls-queues, directory, pbx-admin, api-patterns]  (4)
agents: []  (0)
commands: [/find-contact, /pbx-health-check, /queue-status]  (3)

Full npx astro build + npx pagefind --site dist (site build + search index, the parts of npm run build that don't need sharp) also completed clean: 159 pages including /plugins/3cx/, homepage hero shows "81 Plugins" / "365 skills" (was 80/361 before).

2. Marketplace drift + bump gate:

$ node scripts/check-marketplace-drift.mjs --base origin/main
bump gate: compared HEAD against merge base 9a557b25d135 (14 changed files, 1 plugins touched)
✔ marketplace drift check passed (82 entries)

3. Doc-reference resolution:

$ node scripts/check-doc-references.mjs --verbose
inventory: 82 plugins, 1302 resolvable ids, 212 skill slugs, 165 plugin aliases
scanned 1283 files, 1537 skill-shaped references
✔ reference check passed (1537 skill-shaped references across 1283 files resolve against 1302 ids from 82 plugins)

(Caught and fixed one real issue along the way: an early draft backtick-referenced `3cx-mcp-server` inside an Anti-triggers bullet, which this check correctly flagged as a dangling skill-id-shaped reference. Reworded to italics since it's naming an external GitHub project, not a sibling skill.)

4. Tool anchoring:

$ node scripts/check-tool-anchoring.mjs
✔ tool-anchoring check passed (835 skills/agents/commands; 158 un-anchored, all inventoried)

One new unit is in the inventory: 3cx:skills/api-patterns, flagged for the claude mcp add --scope project --transport http ... setup command (a real CLI invocation, not a 3CX API operation — there's no MCP tool to anchor it to). This is the same class of exception the script's own design accounts for (see pax8:commands/search-products.md, already inventoried for the same reason — hyphenated tool names the script's snake_case regex can't see). Added via node scripts/check-tool-anchoring.mjs --update, which produced a clean, purely-additive one-line diff to scripts/unanchored-docs.json.

5. Plugin validation:

$ claude plugin validate .
Validating marketplace manifest: .../marketplace.json
✔ Validation passed

$ claude plugin validate msp-claude-plugins/3cx/3cx
Validating plugin manifest: .../3cx/3cx/.claude-plugin/plugin.json
✔ Validation passed

Also ran claude plugin validate across all 82 registered plugins (mirroring the CI loop in validate.yml) to confirm the generate-plugins.ts display-name edit didn't regress anything else: 0 failed out of 82.

6. Sanity checks:

  • No .mcp.json anywhere under msp-claude-plugins/3cx/ (confirmed via find).
  • No triggers: field in any SKILL.md frontmatter (confirmed via grep).
  • No version field on the new marketplace entry (only plugin.json carries version).

Not merging — leaving this for review.


View with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is enabled.

3CX shipped a native MCP server built into the PBX in V20 Update 10
(Alpha, July 30 2026). Every PBX exposes its own OAuth-protected endpoint
at its own FQDN, so it doesn't fit Conduit's single-shared-endpoint vendor
catalog — this plugin documents both the direct standalone connection and
Conduit's generic BYO MCP path (/connect/byo) instead of shipping a
.mcp.json.

Adds 4 skills (api-patterns, directory, calls-queues, pbx-admin), 3
commands (find-contact, pbx-health-check, queue-status), and a GOVERNANCE.md
grounded in the real BYO tool-tiering heuristic (src/byo/byo-tool-classifier.ts)
rather than the standard VENDOR_TOOL_CONFIG story, since 3CX has no catalog
entry. Registers under the "productivity" category (no telephony/UC
category exists; mirrors Slack's placement).
@asachs01
asachs01 merged commit b0139ac into main Aug 21, 2026
3 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in MSP Claude Plugins Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant