dealdesk-plugin 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/.agents/plugins/marketplace.json +24 -0
  2. package/.claude-plugin/marketplace.json +29 -0
  3. package/.claude-plugin/plugin.json +18 -0
  4. package/.codex-plugin/plugin.json +30 -0
  5. package/.cursor-plugin/marketplace.json +29 -0
  6. package/.cursor-plugin/mcp.json +11 -0
  7. package/.cursor-plugin/plugin.json +18 -0
  8. package/.mcp.json +8 -0
  9. package/AGENTS.md +13 -0
  10. package/LICENSE +21 -0
  11. package/README.md +124 -3
  12. package/assets/logo-animated.svg +50 -0
  13. package/assets/logo.svg +8 -0
  14. package/bin/dealdesk-plugin.js +717 -0
  15. package/commands/dealdesk-craft-quote.md +15 -0
  16. package/commands/dealdesk-create-card.md +14 -0
  17. package/commands/dealdesk-directory-activity.md +12 -0
  18. package/commands/dealdesk-evaluate-configuration.md +10 -0
  19. package/commands/dealdesk-export-analysis.md +10 -0
  20. package/commands/dealdesk-find-or-create-customer.md +12 -0
  21. package/commands/dealdesk-help.md +62 -0
  22. package/commands/dealdesk-log-card-activity.md +13 -0
  23. package/commands/dealdesk-publish-portfolio.md +13 -0
  24. package/commands/dealdesk-quote-from-portfolio.md +12 -0
  25. package/commands/dealdesk-share-quote.md +13 -0
  26. package/mcp.json +9 -0
  27. package/package.json +59 -6
  28. package/plugin.json +36 -0
  29. package/scripts/bump-version.js +56 -0
  30. package/scripts/package-plugin-zip.js +130 -0
  31. package/scripts/test-project-scope.js +29 -0
  32. package/scripts/validate-npm-release.js +23 -0
  33. package/scripts/validate-skills.js +56 -0
  34. package/scripts/version-files.js +10 -0
  35. package/scripts/zip-archive.js +139 -0
  36. package/skills/README.md +30 -0
  37. package/skills/dealdesk-craft-quote/SKILL.md +21 -0
  38. package/skills/dealdesk-create-card/SKILL.md +59 -0
  39. package/skills/dealdesk-directory-activity/SKILL.md +14 -0
  40. package/skills/dealdesk-evaluate-configuration/SKILL.md +10 -0
  41. package/skills/dealdesk-export-analysis/SKILL.md +11 -0
  42. package/skills/dealdesk-find-or-create-customer/SKILL.md +14 -0
  43. package/skills/dealdesk-help/SKILL.md +63 -0
  44. package/skills/dealdesk-log-card-activity/SKILL.md +36 -0
  45. package/skills/dealdesk-manage-cases/SKILL.md +29 -0
  46. package/skills/dealdesk-manage-orders/SKILL.md +12 -0
  47. package/skills/dealdesk-portfolio-browse/SKILL.md +12 -0
  48. package/skills/dealdesk-publish-portfolio/SKILL.md +16 -0
  49. package/skills/dealdesk-quote-from-portfolio/SKILL.md +15 -0
  50. package/skills/dealdesk-share-quote/SKILL.md +16 -0
@@ -0,0 +1,139 @@
1
+ 'use strict';
2
+
3
+ const zlib = require('zlib');
4
+
5
+ const CRC_TABLE = (() => {
6
+ const table = new Uint32Array(256);
7
+ for (let n = 0; n < 256; n += 1) {
8
+ let c = n;
9
+ for (let k = 0; k < 8; k += 1) {
10
+ c = (c & 1) ? (0xedb88320 ^ (c >>> 1)) : (c >>> 1);
11
+ }
12
+ table[n] = c >>> 0;
13
+ }
14
+ return table;
15
+ })();
16
+
17
+ function crc32(buf) {
18
+ let c = 0xffffffff;
19
+ for (let i = 0; i < buf.length; i += 1) {
20
+ c = CRC_TABLE[(c ^ buf[i]) & 0xff] ^ (c >>> 8);
21
+ }
22
+ return (c ^ 0xffffffff) >>> 0;
23
+ }
24
+
25
+ function dosDateTime(date) {
26
+ const time =
27
+ (date.getUTCHours() << 11) |
28
+ (date.getUTCMinutes() << 5) |
29
+ Math.floor(date.getUTCSeconds() / 2);
30
+ const day =
31
+ ((date.getUTCFullYear() - 1980) << 9) |
32
+ ((date.getUTCMonth() + 1) << 5) |
33
+ date.getUTCDate();
34
+ return { time, day };
35
+ }
36
+
37
+ function createZip(files, date = new Date()) {
38
+ const { time, day } = dosDateTime(date);
39
+ const locals = [];
40
+ const centrals = [];
41
+ let offset = 0;
42
+
43
+ for (const file of files) {
44
+ if (!file.name || /\\|\.\.|^\/|^\s|\s$/.test(file.name)) {
45
+ throw new Error(`Unsafe zip path: ${file.name}`);
46
+ }
47
+ const name = Buffer.from(file.name, 'utf8');
48
+ const data = Buffer.isBuffer(file.data) ? file.data : Buffer.from(file.data);
49
+ const compressed = zlib.deflateRawSync(data);
50
+ const crc = crc32(data);
51
+
52
+ const local = Buffer.alloc(30);
53
+ local.writeUInt32LE(0x04034b50, 0);
54
+ local.writeUInt16LE(20, 4);
55
+ local.writeUInt16LE(0, 6);
56
+ local.writeUInt16LE(8, 8);
57
+ local.writeUInt16LE(time, 10);
58
+ local.writeUInt16LE(day, 12);
59
+ local.writeUInt32LE(crc, 14);
60
+ local.writeUInt32LE(compressed.length, 18);
61
+ local.writeUInt32LE(data.length, 22);
62
+ local.writeUInt16LE(name.length, 26);
63
+ local.writeUInt16LE(0, 28);
64
+
65
+ const central = Buffer.alloc(46);
66
+ central.writeUInt32LE(0x02014b50, 0);
67
+ central.writeUInt16LE(20, 4);
68
+ central.writeUInt16LE(20, 6);
69
+ central.writeUInt16LE(0, 8);
70
+ central.writeUInt16LE(8, 10);
71
+ central.writeUInt16LE(time, 12);
72
+ central.writeUInt16LE(day, 14);
73
+ central.writeUInt32LE(crc, 16);
74
+ central.writeUInt32LE(compressed.length, 20);
75
+ central.writeUInt32LE(data.length, 24);
76
+ central.writeUInt16LE(name.length, 28);
77
+ central.writeUInt16LE(0, 30);
78
+ central.writeUInt16LE(0, 32);
79
+ central.writeUInt16LE(0, 34);
80
+ central.writeUInt16LE(0, 36);
81
+ central.writeUInt32LE(0, 38);
82
+ central.writeUInt32LE(offset, 42);
83
+
84
+ locals.push(Buffer.concat([local, name, compressed]));
85
+ centrals.push(Buffer.concat([central, name]));
86
+ offset += local.length + name.length + compressed.length;
87
+ }
88
+
89
+ const centralDir = Buffer.concat(centrals);
90
+ const eocd = Buffer.alloc(22);
91
+ eocd.writeUInt32LE(0x06054b50, 0);
92
+ eocd.writeUInt16LE(0, 4);
93
+ eocd.writeUInt16LE(0, 6);
94
+ eocd.writeUInt16LE(files.length, 8);
95
+ eocd.writeUInt16LE(files.length, 10);
96
+ eocd.writeUInt32LE(centralDir.length, 12);
97
+ eocd.writeUInt32LE(offset, 16);
98
+ eocd.writeUInt16LE(0, 20);
99
+
100
+ return Buffer.concat([...locals, centralDir, eocd]);
101
+ }
102
+
103
+ function readZip(buffer) {
104
+ let eocd = -1;
105
+ const start = Math.max(0, buffer.length - 22 - 0xffff);
106
+ for (let i = buffer.length - 22; i >= start; i -= 1) {
107
+ if (buffer.readUInt32LE(i) === 0x06054b50) {
108
+ eocd = i;
109
+ break;
110
+ }
111
+ }
112
+ if (eocd < 0) throw new Error('ZIP is missing an end-of-central-directory record');
113
+
114
+ const count = buffer.readUInt16LE(eocd + 10);
115
+ let ptr = buffer.readUInt32LE(eocd + 16);
116
+ const entries = [];
117
+ for (let n = 0; n < count; n += 1) {
118
+ if (buffer.readUInt32LE(ptr) !== 0x02014b50) {
119
+ throw new Error('ZIP central directory is truncated');
120
+ }
121
+ const method = buffer.readUInt16LE(ptr + 10);
122
+ const compressedSize = buffer.readUInt32LE(ptr + 20);
123
+ const nameLen = buffer.readUInt16LE(ptr + 28);
124
+ const extraLen = buffer.readUInt16LE(ptr + 30);
125
+ const commentLen = buffer.readUInt16LE(ptr + 32);
126
+ const localOffset = buffer.readUInt32LE(ptr + 42);
127
+ const name = buffer.toString('utf8', ptr + 46, ptr + 46 + nameLen);
128
+ const localNameLen = buffer.readUInt16LE(localOffset + 26);
129
+ const localExtraLen = buffer.readUInt16LE(localOffset + 28);
130
+ const dataStart = localOffset + 30 + localNameLen + localExtraLen;
131
+ const compressed = buffer.subarray(dataStart, dataStart + compressedSize);
132
+ const data = method === 0 ? Buffer.from(compressed) : zlib.inflateRawSync(compressed);
133
+ entries.push({ name, data });
134
+ ptr += 46 + nameLen + extraLen + commentLen;
135
+ }
136
+ return entries;
137
+ }
138
+
139
+ module.exports = { createZip, readZip };
@@ -0,0 +1,30 @@
1
+ # DealDesk skills
2
+
3
+ These notes describe common workflows the DealDesk MCP connector supports. Hosts load each workflow from `skills/<name>/SKILL.md`. Slash commands in `commands/` start the same workflows. Your AI host may also load live skill descriptions from the agenthouse DealDesk server (`dealdesk.list_skills`).
4
+
5
+ ## Guidelines
6
+
7
+ - Prefer update and soft-close over delete. Delete is not offered through MCP.
8
+ - Prefer the export skill for analysis instead of paging through large lists endlessly.
9
+ - For portfolio publish, always review the preview and confirm before publishing.
10
+ - Skill-gated tools need `dealdesk.discover` with the matching domain first. The server remembers that unlock for the API key or OAuth user.
11
+ - **Notes vs email:** use `dealdesk.add_card_note` for internal notes. Log inbound/outbound email with `dealdesk.log_email` (status-update touchpoint). Never store emails as card notes.
12
+
13
+ ## Shipped skills
14
+
15
+ | Skill | Slash command | Purpose |
16
+ | --- | --- | --- |
17
+ | [dealdesk-help](./dealdesk-help/SKILL.md) | `/dealdesk-help` | Overview of capabilities; agent calls `list_skills` / `discover` |
18
+ | [dealdesk-create-card](./dealdesk-create-card/SKILL.md) | `/dealdesk-create-card` | Create or update a desk card |
19
+ | [dealdesk-log-card-activity](./dealdesk-log-card-activity/SKILL.md) | `/dealdesk-log-card-activity` | Notes, comments, tasks, and email touchpoints |
20
+ | [dealdesk-craft-quote](./dealdesk-craft-quote/SKILL.md) | `/dealdesk-craft-quote` | Craft or refine a classic quote |
21
+ | [dealdesk-quote-from-portfolio](./dealdesk-quote-from-portfolio/SKILL.md) | `/dealdesk-quote-from-portfolio` | Evaluate and create a quote from the published portfolio |
22
+ | [dealdesk-evaluate-configuration](./dealdesk-evaluate-configuration/SKILL.md) | `/dealdesk-evaluate-configuration` | Side-effect free CPQ evaluation |
23
+ | [dealdesk-directory-activity](./dealdesk-directory-activity/SKILL.md) | `/dealdesk-directory-activity` | Company/contact notes and commercial summary |
24
+ | [dealdesk-find-or-create-customer](./dealdesk-find-or-create-customer/SKILL.md) | `/dealdesk-find-or-create-customer` | Directory company/contact lookup and create |
25
+ | [dealdesk-share-quote](./dealdesk-share-quote/SKILL.md) | `/dealdesk-share-quote` | Quote status and customer share links (classic + rich) |
26
+ | [dealdesk-manage-cases](./dealdesk-manage-cases/SKILL.md) | — | Local DealDesk cases |
27
+ | [dealdesk-manage-orders](./dealdesk-manage-orders/SKILL.md) | — | Orders (discover `orders`) |
28
+ | [dealdesk-portfolio-browse](./dealdesk-portfolio-browse/SKILL.md) | — | Portfolio articles/revisions (discover `portfolio`) |
29
+ | [dealdesk-export-analysis](./dealdesk-export-analysis/SKILL.md) | `/dealdesk-export-analysis` | Bounded Deal Intelligence export |
30
+ | [dealdesk-publish-portfolio](./dealdesk-publish-portfolio/SKILL.md) | `/dealdesk-publish-portfolio` | Preview then confirm portfolio publish |
@@ -0,0 +1,21 @@
1
+ ---
2
+ name: dealdesk-craft-quote
3
+ description: Guide the user to craft an excellent classic DealDesk quote. Use when they want a new classic quote draft, to clone a past quote, or to refine line items — not only portfolio-evaluated pricing.
4
+ ---
5
+
6
+ # Craft an excellent classic quote
7
+
8
+ Tools: `dealdesk.list_companies`, `dealdesk.get_company`, `dealdesk.create_company`, `dealdesk.list_contacts`, `dealdesk.get_contact`, `dealdesk.create_contact`, `dealdesk.list_quotes`, `dealdesk.get_quote`, `dealdesk.get_quote_summary`, `dealdesk.create_quote`, `dealdesk.clone_quote`, `dealdesk.replace_quote_items`, `dealdesk.patch_quote`, `dealdesk.portfolio_summary`, `dealdesk.portfolio_evaluate`, `dealdesk.discover`, `dealdesk.list_portfolio_articles`, `dealdesk.get_portfolio_article`, `dealdesk.create_quote_from_configuration`, `dealdesk.update_quote_from_configuration`, `dealdesk.create_quote_share`, `dealdesk.render_quote_pdf`
9
+
10
+ ## Conversation (classic-first)
11
+
12
+ 1. Confirm **company** and **contact** (search/create in the Customer Directory).
13
+ 2. Ask what the quote is **about** (title / intent).
14
+ 3. Always ask: scan past quotes and suggest a clone, copy a quote they like, or **create fresh**?
15
+ 4. Consult the **published portfolio** for recommended articles; confirm what belongs in the quote.
16
+ 5. Ask whether positions should be in **groups**, and propose how to separate them (family, category, or custom). Confirm single vs multi selection, included vs optional, and `quantityEditable` where useful.
17
+ 6. Create with `create_quote` or `clone_quote`. Refine with `replace_quote_items` (add/edit/remove positions, regroup).
18
+ 7. Use CPQ `create_quote_from_configuration` / `update_quote_from_configuration` only when the user wants portfolio-evaluated pricing. Pass `quoteLayout` for presentation.
19
+ 8. Offer share link / PDF when ready. Never delete through MCP.
20
+
21
+ Do not invent prices for CPQ lines client-side. Classic/open positions may carry explicit `unitPrice`.
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: dealdesk-create-card
3
+ description: Create or update a DealDesk desk card (title, stage, description, owner, priority, company/contact, deal estimates, quote value override). Use when the user wants a new card, a stage/owner change, estimates, or directory links. Never delete a card.
4
+ ---
5
+
6
+ # Create or update a desk card
7
+
8
+ Tools: `dealdesk.create_card`, `dealdesk.patch_card`, `dealdesk.get_card`, `dealdesk.list_cards`, `dealdesk.list_desk_stages`, `dealdesk.list_desk_users`, `dealdesk.list_card_activity`
9
+
10
+ Create a card or update title, stage, description, owner, priority, Customer Directory links, deal estimates, and quote deal-value override. Soft-close by setting stage `closed` rather than deleting.
11
+
12
+ Use `description` for the main card body. Use `deskDescription` for a local desk-only description. Use `dealdesk.add_card_note` only for structured notes, not as a substitute for the card description.
13
+
14
+ ## Stages (discrete column ids)
15
+
16
+ `stage` is a **board column id**, not a UI label. Call `dealdesk.list_desk_stages` and use a returned `columnId`. Never slugify a German/English label into a stage string (e.g. do **not** send `anfrage-in-bearbeitung`). That creates a ghost column and the card vanishes from the board.
17
+
18
+ Default board (when the project has not customized columns):
19
+
20
+ | columnId | EN | DE |
21
+ | --- | --- | --- |
22
+ | `request` | Open request | Offene Anfrage |
23
+ | `request-in-progress` | Request in progress | Anfrage in Bearbeitung |
24
+ | `quote-preparation` | Quote in preparation | Angebot in Bearbeitung |
25
+ | `quote-sent` | Quote sent | Angebot gesendet |
26
+ | `quote-accepted` | Quote accepted | Angebot angenommen |
27
+ | `order-processing` | Order processing | Auftrag in Vorbereitung |
28
+ | `order-completed` | Order completed | Auftrag abgeschlossen |
29
+ | `closed` | Closed | Geschlossen |
30
+
31
+ Tenants may add column ids — only use ids from `list_desk_stages`.
32
+
33
+ ## Owner and priority
34
+
35
+ Resolve assignees with `dealdesk.list_desk_users`, then set `ownerUserId` on create/patch. Pass `null` on `patch_card` to clear. Filter with `list_cards` + `ownerUserId`. `priority` is free text (default `normal`).
36
+
37
+ ## Deal value, period, and win chance
38
+
39
+ Set on the card with `create_card` / `patch_card`:
40
+
41
+ - `estimatedValue`, `estimatedValueCurrency`, `estimatedValuePeriod` (`one_time` | `month` | `year`), `probabilityPercent`
42
+
43
+ Use `year` for per-year / ARR. Do not invent synonyms (`annual`, `yearly`, `monthly`).
44
+
45
+ When the card has a linked local case, the server updates that case (UI parity) and returns `caseId` when present. Do **not** call `create_case` just to set estimates — that creates a second desk item.
46
+
47
+ ## Quote deal-value override
48
+
49
+ On an unaccepted quote card, `dealValueOverride` + `dealValueOverrideNet` replace quote net on the board/overview (same as the UI). Ignored after accept, decline, or when an order exists. Clear with `dealValueOverrideNet=null`.
50
+
51
+ ## Company / contact
52
+
53
+ `patch_card` with `companyId` / `contactId` (or `null` to clear). Clearing company also clears contact. Company/contact changes also sync a linked local case and quote customer link.
54
+
55
+ ## History
56
+
57
+ `dealdesk.list_card_activity` returns stage/owner/account/note/quote/order/share milestones (not the comment/email timeline — that is status updates).
58
+
59
+ Do **not** use notes to log customer email. Use `dealdesk-log-card-activity` (`dealdesk.log_email`).
@@ -0,0 +1,14 @@
1
+ ---
2
+ name: dealdesk-directory-activity
3
+ description: Read commercial summaries and add or patch notes on a DealDesk company or contact. Use for pipeline context on a customer, not for email logs.
4
+ ---
5
+
6
+ # Directory notes and commercial summary
7
+
8
+ Tools: `dealdesk.get_company`, `dealdesk.get_company_commercial_summary`, `dealdesk.add_company_note`, `dealdesk.patch_company_note`, `dealdesk.get_contact`, `dealdesk.get_contact_commercial_summary`, `dealdesk.add_contact_note`, `dealdesk.patch_contact_note`
9
+
10
+ 1. Resolve the company or contact with `get_company` / `get_contact` when needed.
11
+ 2. Read `get_company_commercial_summary` or `get_contact_commercial_summary` before advising on pipeline.
12
+ 3. Add or patch structured notes with title and body (`add_*_note` / `patch_*_note`).
13
+
14
+ Never store email logs as directory notes. Never delete notes through MCP. For desk-card email, use `dealdesk.log_email` instead.
@@ -0,0 +1,10 @@
1
+ ---
2
+ name: dealdesk-evaluate-configuration
3
+ description: Run a side-effect free DealDesk CPQ evaluation against the portfolio. Use when the user wants totals, blockers, or a rule trace without creating a quote.
4
+ ---
5
+
6
+ # Evaluate a configuration
7
+
8
+ Tools: `dealdesk.portfolio_evaluate`
9
+
10
+ Run a side-effect free CPQ evaluation against the Portfolio. Use this before creating a quote when you need blockers, totals, or a rule trace without persisting a quote.
@@ -0,0 +1,11 @@
1
+ ---
2
+ name: dealdesk-export-analysis
3
+ description: Export DealDesk data for offline analysis with the bounded Deal Intelligence export. Use instead of paging through large card or quote lists.
4
+ ---
5
+
6
+ # Export for analysis
7
+
8
+ Tools: `dealdesk.export_intelligence`
9
+
10
+ Use `dealdesk.export_intelligence` for a bounded workbook. The result contains `filename` and `relativePath` under `applications/dealdesk/exports`. It does not return a server filesystem path or the file bytes. Do not page `list_cards` or `list_quotes` to build a workbook by hand.
11
+
@@ -0,0 +1,14 @@
1
+ ---
2
+ name: dealdesk-find-or-create-customer
3
+ description: Search the DealDesk customer directory and create a company or contact only when no match exists. Use for company or contact lookup.
4
+ ---
5
+
6
+ # Find or create a company / contact
7
+
8
+ Tools: `dealdesk.list_companies`, `dealdesk.get_company`, `dealdesk.create_company`, `dealdesk.patch_company`, `dealdesk.list_contacts`, `dealdesk.get_contact`, `dealdesk.create_contact`, `dealdesk.patch_contact`
9
+
10
+ Search the customer directory first. Create only when no suitable match exists. Update with `dealdesk.patch_company` / `dealdesk.patch_contact` using `expectedRevision` from get.
11
+
12
+ Companies: send `legalName` or `name` (maps to `legalName`). `externalId` is optional and auto-generated as `local-company-<uuid>` when omitted.
13
+
14
+ Contacts: send `displayName` or `name` (or first/last name). `externalId` is optional and auto-generated as `local-contact-<uuid>` when omitted.
@@ -0,0 +1,63 @@
1
+ ---
2
+ name: dealdesk-help
3
+ description: Explain DealDesk capabilities, slash commands, and hard limits. Use when the user asks for help or what they can do with the plugin. Call dealdesk.list_skills before answering when MCP is available.
4
+ ---
5
+
6
+ # DealDesk help
7
+
8
+ Help the user use DealDesk. Prefer live discovery over memory.
9
+
10
+ ## First steps
11
+
12
+ 1. Call `dealdesk.list_projects` and tell the user which `authorizedProjectIds` the token covers. Do not assume the singular `projectId` when more than one id is listed.
13
+ 2. Call `dealdesk.list_skills` and summarize the returned skills in plain language.
14
+ 3. If important tools are missing from the current tool list, call `dealdesk.discover` (omit `domain` for the domain list, or pass a domain such as `desk`, `quotes`, `portfolio`, `directory`, `export`, or `portfolio-authoring`).
15
+ 4. Then answer with the command map below and the live skill list.
16
+
17
+ If MCP is not connected yet, still explain the command map and say which auth path to use.
18
+
19
+ ## Slash commands
20
+
21
+ | Command | What it does |
22
+ | --- | --- |
23
+ | `/dealdesk-help` | This overview |
24
+ | `/dealdesk-create-card` | Create or update a desk card (including company/contact link) |
25
+ | `/dealdesk-log-card-activity` | Log inbound or outbound email on a card timeline |
26
+ | `/dealdesk-craft-quote` | Craft or refine a classic quote (clone or fresh draft) |
27
+ | `/dealdesk-quote-from-portfolio` | Evaluate a configuration and create a quote from the portfolio |
28
+ | `/dealdesk-evaluate-configuration` | Evaluate a configuration without creating a quote |
29
+ | `/dealdesk-directory-activity` | Company/contact commercial summary and notes |
30
+ | `/dealdesk-find-or-create-customer` | Find or create a company or contact |
31
+ | `/dealdesk-share-quote` | Quote status and customer share links (classic + rich) |
32
+ | `/dealdesk-export-analysis` | Bounded Deal Intelligence export |
33
+ | `/dealdesk-publish-portfolio` | Preview then confirm portfolio publish |
34
+
35
+ Hosts may prefix commands with the plugin name (for example `/dealdesk:dealdesk-help`).
36
+
37
+ ## Status updates and email
38
+
39
+ - Email: use `dealdesk.log_email` (or `/dealdesk-log-card-activity`). Never put email in `add_card_note`.
40
+ - Other timeline work: use `dealdesk.create_status_update` for `comment`, `task`, and touchpoints (`phone_call`, `meeting`, `email_incoming`, `email_outgoing`, `misc`).
41
+ - Read the timeline with `dealdesk.list_status_updates`. Update with `dealdesk.patch_status_update`.
42
+ - Structured desk notes: `dealdesk.add_card_note` / `dealdesk.patch_card_note`.
43
+
44
+ ## Quotes and shares
45
+
46
+ - Status and acceptance: `dealdesk.get_quote` (also returns existing shares).
47
+ - Line items without enrichment: `dealdesk.get_quote_summary`.
48
+ - Customer links: `create_quote_share` → `classicUrl` (standard) and `experienceUrl` (rich experience). Soft-close with `patch_quote_share` `isOpen=false`.
49
+
50
+ ## Hard limits
51
+
52
+ - Delete is not available through MCP. Soft-close cards by changing stage; soft-close shares with `isOpen=false`.
53
+ - Portfolio publish needs preview, then `portfolio_publish` with `confirm=true`.
54
+ - Do not invent prices. Prefer portfolio evaluation and published revision ids.
55
+ - Prefer `/dealdesk-export-analysis` over paging through large lists forever.
56
+ - Skill-gated tools need `dealdesk.discover` with the matching domain first (for example `orders`, `portfolio`, `portfolio-authoring`).
57
+ - Remind the user that DealDesk tool results may disclose customer data to the AI host and other tools in the conversation, and that they remain responsible for that data.
58
+
59
+ ## Auth
60
+
61
+ - Sign-in is OAuth. The user signs in on the agenthouse page, chooses one or more projects, and grants DealDesk access. When several projects are authorized, pass `projectId` on scoped tools.
62
+ - Remote URL: `https://api.agenthouse.org/mcp/dealdesk` (ChatGPT, Claude, Codex, Cursor).
63
+ - The Cursor plugin and the local connector open that same page. An API key is only for automation that cannot open a browser (`AGENTHOUSE_API_KEY`, and `AGENTHOUSE_PROJECT_ID` when the account has more than one project).
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: dealdesk-log-card-activity
3
+ description: Add internal notes or log email and other status updates on a DealDesk card timeline. Use for inbound or outbound email, comments, tasks, calls, and meetings. Never store email as a card note.
4
+ ---
5
+
6
+ # Add notes and log email / status updates on a card
7
+
8
+ Tools: `dealdesk.get_card`, `dealdesk.add_card_note`, `dealdesk.patch_card_note`, `dealdesk.list_status_updates`, `dealdesk.create_status_update`, `dealdesk.patch_status_update`, `dealdesk.log_email`
9
+
10
+ ## Notes
11
+
12
+ Use `dealdesk.add_card_note` for internal structured notes (title + body) on a desk card. Edit with `dealdesk.patch_card_note`. Delete is not available through MCP.
13
+
14
+ ## Email (required path)
15
+
16
+ Log inbound or outbound email with `dealdesk.log_email`:
17
+
18
+ - `direction`: `incoming` or `outgoing`
19
+ - `from` / `to` / `subject` / `text`
20
+ - `cardId` of the desk card
21
+
22
+ This creates a status-update **touchpoint** (`email_incoming` / `email_outgoing`) on the card timeline — the same surface the DealDesk UI uses. The server persists structured `from` and `to` fields (and a compatible `participants` string `from → to`). Prefer `dealdesk.log_email` over a generic touchpoint so those fields are set correctly.
23
+
24
+ **Never** put email logs into `add_card_note`.
25
+
26
+ ## Other status updates
27
+
28
+ Use `dealdesk.create_status_update` for:
29
+
30
+ - `type: comment` — timeline comment (`body` required)
31
+ - `type: task` — task (`title` required; optional due date / assignee)
32
+ - `type: touchpoint` — `phone_call`, `meeting`, `email_incoming`, `email_outgoing`, or `misc` (for email, prefer `dealdesk.log_email` so `from` / `to` are persisted)
33
+
34
+ List existing timeline entries with `dealdesk.list_status_updates` (`entityType: desk-card` + `cardId` / `entityId`).
35
+
36
+ Update an existing entry with `dealdesk.patch_status_update` (comment body, task status/fields, or touchpoint fields including `from` / `to`). Prefer listing first for `statusUpdateId` and `updatedAt`.
@@ -0,0 +1,29 @@
1
+ ---
2
+ name: dealdesk-manage-cases
3
+ description: List, create, and update DealDesk cases. Use for local sales/request cases. Not Salesforce Opportunity search. Do not use create_case to set estimates on an existing desk card — use patch_card instead.
4
+ ---
5
+
6
+ # Manage DealDesk cases
7
+
8
+ Tools: `dealdesk.list_cases`, `dealdesk.get_case`, `dealdesk.create_case`, `dealdesk.patch_case`, `dealdesk.list_desk_stages`, `dealdesk.list_desk_users`
9
+
10
+ Create or update local DealDesk cases (title, stage, description, company/contact/quote links, estimates, ownerUserId). Resolve stages with `dealdesk.list_desk_stages` and owners with `dealdesk.list_desk_users`. Soft-close via stage when appropriate. Do not call disconnected Salesforce Opportunity search endpoints.
11
+
12
+ ## Stages (discrete column ids)
13
+
14
+ Same board column ids as desk cards. Call `dealdesk.list_desk_stages` and pass a returned `columnId`. Never slugify UI labels into stage strings.
15
+
16
+ ## Estimates on cases
17
+
18
+ `create_case` / `patch_case` accept:
19
+
20
+ - `estimatedValue`
21
+ - `estimatedValueCurrency` (ISO 4217, e.g. `EUR`)
22
+ - `estimatedValuePeriod` — `one_time` | `month` | `year` (labels the amount; does not convert it)
23
+ - `probabilityPercent` (0–100)
24
+
25
+ These round-trip on get/list. Use `year` for per-year / ARR. Do not invent synonyms (`annual`, `yearly`, `monthly`).
26
+
27
+ ## Desk cards vs cases
28
+
29
+ Creating a case also creates a desk card. If the opportunity already appears as a desk card, set value/chance/period with `dealdesk.patch_card` on that card. Do **not** use `create_case` as a substitute for updating a card’s estimates — that duplicates the opportunity on the desk.
@@ -0,0 +1,12 @@
1
+ ---
2
+ name: dealdesk-manage-orders
3
+ description: Work with DealDesk orders. Discover domain orders first, then list/get/create from quote/patch. Never delete orders through MCP.
4
+ ---
5
+
6
+ # Manage orders
7
+
8
+ Tools: `dealdesk.discover`, `dealdesk.list_orders`, `dealdesk.get_order`, `dealdesk.create_order_from_quote`, `dealdesk.patch_order`
9
+
10
+ 1. Call `dealdesk.discover` with domain `orders` if order tools are not listed.
11
+ 2. Create from a quote with `create_order_from_quote`.
12
+ 3. Patch metadata only. Delete is not available through MCP.
@@ -0,0 +1,12 @@
1
+ ---
2
+ name: dealdesk-portfolio-browse
3
+ description: Browse portfolio articles and revisions. Discover domain portfolio first.
4
+ ---
5
+
6
+ # Browse portfolio
7
+
8
+ Tools: `dealdesk.discover`, `dealdesk.portfolio_summary`, `dealdesk.list_portfolio_articles`, `dealdesk.get_portfolio_article`, `dealdesk.list_portfolio_revisions`, `dealdesk.portfolio_evaluate`
9
+
10
+ 1. Call `dealdesk.discover` with domain `portfolio`.
11
+ 2. List or get articles; list revisions when comparing published content.
12
+ 3. Evaluate configurations with `portfolio_evaluate` (side-effect free).
@@ -0,0 +1,16 @@
1
+ ---
2
+ name: dealdesk-publish-portfolio
3
+ description: Preview a DealDesk portfolio publish and confirm only when blockers are clear. Use when the user asks to publish the portfolio. Never publish without confirm=true.
4
+ ---
5
+
6
+ # Publish portfolio (preview + confirm)
7
+
8
+ Tools: `dealdesk.discover`, `dealdesk.initialize_portfolio_draft`, `dealdesk.portfolio_publish_preview`, `dealdesk.portfolio_publish`
9
+
10
+ 1. Unlock portfolio-authoring tools with `dealdesk.discover` and domain `portfolio-authoring` if needed.
11
+ 2. Call `initialize_portfolio_draft` only when no draft exists.
12
+ 3. Call `portfolio_publish_preview` and review blockers.
13
+ 4. Call `portfolio_publish` only with `confirm=true` when blockers are clear.
14
+
15
+
16
+ Never publish without the explicit confirm flag. Confirm must work from a plain tools/call (no widget required).
@@ -0,0 +1,15 @@
1
+ ---
2
+ name: dealdesk-quote-from-portfolio
3
+ description: Evaluate a configuration and create a DealDesk quote from the published portfolio. Use when the user wants a quote, not a price invented in chat.
4
+ ---
5
+
6
+ # Quote from published portfolio
7
+
8
+ Tools: `dealdesk.portfolio_summary`, `dealdesk.portfolio_evaluate`, `dealdesk.create_quote_from_configuration`, `dealdesk.update_quote_from_configuration`
9
+
10
+ 1. Optionally call `portfolio_summary` to confirm a published revision exists.
11
+ 2. Call `portfolio_evaluate` with the configuration (side-effect free).
12
+ 3. Call `create_quote_from_configuration` or `update_quote_from_configuration` with the published `portfolioRevisionId`, `priceBookRevisionId`, and the same configuration.
13
+
14
+ Do not invent prices client-side. Prefer the published revision ids returned by the API.
15
+
@@ -0,0 +1,16 @@
1
+ ---
2
+ name: dealdesk-share-quote
3
+ description: Inspect DealDesk quote status and create or update customer share links. Use when the user asks for a quote link, share URL, rich experience link, or quote acceptance status.
4
+ ---
5
+
6
+ # Quote status and share links
7
+
8
+ Tools: `dealdesk.list_quotes`, `dealdesk.get_quote`, `dealdesk.get_quote_summary`, `dealdesk.list_quote_shares`, `dealdesk.create_quote_share`, `dealdesk.patch_quote_share`
9
+
10
+ 1. Resolve the quote with `list_quotes` / `get_quote`.
11
+ 2. `get_quote` returns `status`, `acceptanceSummary`, `analytics`, and current `shares`.
12
+ 3. Create a link with `create_quote_share`. Use:
13
+ - `classicUrl` / `classicPath` for the standard customer share
14
+ - `experienceUrl` / `experiencePath` for the rich experience Desk
15
+ 4. Soft-close a link with `patch_quote_share` and `isOpen=false`. Do not delete shares through MCP.
16
+ 5. Prefer `get_quote_summary` when you need stored line items without enrichment.