@helmdesk/mcp 0.5.0 → 0.7.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.
package/README.md CHANGED
@@ -68,8 +68,19 @@ HELMDESK_API_KEY=sk_live_xxx npx @helmdesk/mcp
68
68
  | `write_log` | Ship log events to the project (sandbox events are quota-exempt) |
69
69
  | `query_logs` | Query raw application log events (filter by level, search, fingerprint) |
70
70
  | `list_log_issues` | List grouped error issues — "did anything break?" |
71
-
72
- 15 tools in total — `tickets:write` is required for ticket mutations and `add_ticket_tag`/`remove_ticket_tag`, `emails:send` for `send_email`/`send_email_batch` (batch also needs the Pro plan or higher), `articles:write` for `create_article`, `logs:read` for `query_logs`/`list_log_issues`. A key with empty scopes has full access.
71
+ | `list_feedback_conversations` | List feedback conversations (filter by status, rating, source, customer, search, date range) |
72
+ | `get_feedback_conversation` | Get a feedback conversation with its full message thread |
73
+ | `reply_to_feedback` | Post a staff reply to a feedback conversation (emailed to the customer) |
74
+ | `close_feedback_conversation` | Close a handled conversation (or reopen it via `status: "open"`) |
75
+ | `list_feedback_requests` | List outgoing feedback requests with funnel status (sent/opened/responded) |
76
+ | `request_feedback` | Create a feedback request and email the customer a branded respond link |
77
+ | `list_customers` | List/search the customer directory (filter by email/name/company text or your app's `externalId`) |
78
+ | `get_customer` | Get a customer with their full interaction history (tickets + feedback) — "who is this person?" |
79
+ | `create_customer` | Create or pre-load a customer (set `externalId` to your own app's user id) |
80
+ | `update_customer` | Update a customer's profile — incl. the staff-only `internalNote` for CRM-style context |
81
+ | `delete_customer` | Remove a customer (their tickets/feedback are untouched) |
82
+
83
+ 36 tools in total — `tickets:write` is required for ticket mutations and `add_ticket_tag`/`remove_ticket_tag`, `emails:send` for `send_email`/`send_email_batch` (batch also needs the Pro plan or higher), `articles:write` for `create_article`, `logs:read` for `query_logs`/`list_log_issues`, `feedback:read` for the feedback list/get tools and `feedback:write` for `reply_to_feedback`/`close_feedback_conversation`/`request_feedback`, `customers:read` for `list_customers`/`get_customer` and `customers:write` for `create_customer`/`update_customer`/`delete_customer`. A key with empty scopes has full access.
73
84
 
74
85
  ## Available Resources
75
86
 
@@ -91,6 +102,10 @@ Once connected, you can ask your AI agent:
91
102
  - "Check my pending tickets and draft replies for any waiting more than 24 hours"
92
103
  - "List unassigned billing tickets, tag the urgent ones `needs-engineering`, and assign them to me"
93
104
  - "We keep getting the same SSO question — write a published KB article answering it, then reply to ticket #88 linking it"
105
+ - "Show me open feedback conversations rated 3 or below and draft replies"
106
+ - "Send a feedback request to jane@example.com asking how onboarding went"
107
+ - "Who is jane@example.com? Show me everything she's asked us and any feedback she's given"
108
+ - "Add an internal note to that customer: churn risk, complained about pricing twice"
94
109
 
95
110
  ## Testing
96
111
 
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAWnE,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,kBAAkB,GAAG,SAAS,CA0B9E"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAanE,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,kBAAkB,GAAG,SAAS,CA4B9E"}
package/dist/server.js CHANGED
@@ -4,6 +4,8 @@ import { registerTicketTools } from './tools/tickets.js';
4
4
  import { registerEmailTools } from './tools/emails.js';
5
5
  import { registerArticleTools } from './tools/articles.js';
6
6
  import { registerLogTools } from './tools/logs.js';
7
+ import { registerFeedbackTools } from './tools/feedback.js';
8
+ import { registerCustomerTools } from './tools/customers.js';
7
9
  import { registerTeamTools } from './tools/team.js';
8
10
  import { registerWebhookTools } from './tools/webhooks.js';
9
11
  import { registerTicketResources } from './resources/tickets.js';
@@ -23,6 +25,8 @@ export function createHelmdeskMcpServer(options) {
23
25
  registerEmailTools(server, getClient);
24
26
  registerArticleTools(server, getClient);
25
27
  registerLogTools(server, getClient);
28
+ registerFeedbackTools(server, getClient);
29
+ registerCustomerTools(server, getClient);
26
30
  registerTeamTools(server, getClient);
27
31
  registerWebhookTools(server, getClient);
28
32
  // Register all resources
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAOlE,MAAM,UAAU,uBAAuB,CAAC,OAA2B;IACjE,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC;QAChC,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC,CAAA;IAEF,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,MAAM,CAAA;IAE9B,qBAAqB;IACrB,mBAAmB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACtC,kBAAkB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACrC,oBAAoB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACvC,gBAAgB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACnC,iBAAiB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACpC,oBAAoB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAEvC,yBAAyB;IACzB,uBAAuB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAC1C,wBAAwB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAE3C,OAAO,MAAM,CAAA;AACf,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAOlE,MAAM,UAAU,uBAAuB,CAAC,OAA2B;IACjE,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC;QAChC,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC,CAAA;IAEF,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,MAAM,CAAA;IAE9B,qBAAqB;IACrB,mBAAmB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACtC,kBAAkB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACrC,oBAAoB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACvC,gBAAgB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACnC,qBAAqB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACxC,qBAAqB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACxC,iBAAiB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACpC,oBAAoB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAEvC,yBAAyB;IACzB,uBAAuB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAC1C,wBAAwB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAE3C,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { HelmdeskClient } from '@helmdesk/sdk';
3
+ export declare function registerCustomerTools(server: McpServer, getClient: () => HelmdeskClient): void;
4
+ //# sourceMappingURL=customers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"customers.d.ts","sourceRoot":"","sources":["../../src/tools/customers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAEnD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,QAgIvF"}
@@ -0,0 +1,102 @@
1
+ import { z } from 'zod';
2
+ export function registerCustomerTools(server, getClient) {
3
+ server.tool('list_customers', 'List the project\'s customers, most recently seen first (requires the customers:read scope). The directory builds itself from tickets and feedback, so this is everyone who has ever interacted with the project. Use search to match email/name/company, or externalId to resolve one of YOUR app\'s user ids to its Helmdesk customer.', {
4
+ search: z.string().optional().describe('Substring match on email, name, or company'),
5
+ externalId: z.string().optional()
6
+ .describe('Exact match on the customer\'s id in the installer\'s own app (their user id)'),
7
+ page: z.number().optional().describe('Page number (default: 1)'),
8
+ limit: z.number().optional().describe('Results per page (default: 25, max: 100)'),
9
+ }, async (params) => {
10
+ const client = getClient();
11
+ const result = await client.customers.list({
12
+ search: params.search,
13
+ externalId: params.externalId,
14
+ page: params.page,
15
+ limit: params.limit,
16
+ });
17
+ return {
18
+ content: [{
19
+ type: 'text',
20
+ text: JSON.stringify(result, null, 2),
21
+ }],
22
+ };
23
+ });
24
+ server.tool('get_customer', 'Get a customer including their full interaction history — their tickets and feedback conversations, joined by email, recent-first, capped at 50 each (requires the customers:read scope). This is the best "who is this person?" tool: one call gives you their profile (name, company, externalId, staff-only internalNote, metadata) plus everything they ever asked or said.', {
25
+ customerId: z.string().describe('The customer ID (UUID). Find it via list_customers.'),
26
+ }, async ({ customerId }) => {
27
+ const client = getClient();
28
+ const result = await client.customers.get(customerId);
29
+ return {
30
+ content: [{
31
+ type: 'text',
32
+ text: JSON.stringify(result, null, 2),
33
+ }],
34
+ };
35
+ });
36
+ server.tool('create_customer', 'Create a customer explicitly (requires the customers:write scope). Customers are also created automatically when someone opens a ticket or gives feedback — use this to pre-load or enrich the directory, e.g. syncing your own user base with externalId set to your app\'s user id. Fails with a 409 conflict if the email already exists in this environment.', {
37
+ email: z.string().email().describe('Customer email — unique per project + environment, immutable after creation'),
38
+ name: z.string().optional().describe('Display name (max 200 characters)'),
39
+ company: z.string().optional().describe('Company name (max 200 characters)'),
40
+ externalId: z.string().optional()
41
+ .describe('The customer\'s id in the installer\'s own app, e.g. their user id (max 200 characters)'),
42
+ internalNote: z.string().optional()
43
+ .describe('Staff-only note, never shown to the customer (max 5000 characters)'),
44
+ metadata: z.record(z.unknown()).optional()
45
+ .describe('Arbitrary JSON metadata (at most 8 KB serialized)'),
46
+ }, async (params) => {
47
+ const client = getClient();
48
+ const result = await client.customers.create({
49
+ email: params.email,
50
+ name: params.name,
51
+ company: params.company,
52
+ externalId: params.externalId,
53
+ internalNote: params.internalNote,
54
+ metadata: params.metadata,
55
+ });
56
+ return {
57
+ content: [{
58
+ type: 'text',
59
+ text: JSON.stringify(result, null, 2),
60
+ }],
61
+ };
62
+ });
63
+ server.tool('update_customer', 'Update a customer\'s profile (requires the customers:write scope). Email is immutable — it is the join key back to tickets and feedback. internalNote is a staff-only, CRM-style note the customer never sees: use it to record context like "churn risk, complained about pricing in March" so the next agent (human or AI) has the backstory. Pass null to clear a field.', {
64
+ customerId: z.string().describe('The customer ID (UUID)'),
65
+ name: z.string().nullable().optional().describe('Display name (null clears)'),
66
+ company: z.string().nullable().optional().describe('Company name (null clears)'),
67
+ externalId: z.string().nullable().optional()
68
+ .describe('The customer\'s id in the installer\'s own app (null clears)'),
69
+ internalNote: z.string().nullable().optional()
70
+ .describe('Staff-only CRM-style note, never shown to the customer (null clears, max 5000 characters)'),
71
+ metadata: z.record(z.unknown()).nullable().optional()
72
+ .describe('Arbitrary JSON metadata, at most 8 KB serialized (null clears)'),
73
+ }, async ({ customerId, ...patch }) => {
74
+ const client = getClient();
75
+ const result = await client.customers.update(customerId, {
76
+ name: patch.name,
77
+ company: patch.company,
78
+ externalId: patch.externalId,
79
+ internalNote: patch.internalNote,
80
+ metadata: patch.metadata,
81
+ });
82
+ return {
83
+ content: [{
84
+ type: 'text',
85
+ text: JSON.stringify(result, null, 2),
86
+ }],
87
+ };
88
+ });
89
+ server.tool('delete_customer', 'Delete a customer from the directory (requires the customers:write scope). Their tickets and feedback conversations are untouched — linkage is by email, not foreign key — and any new interaction from the same email simply re-creates the customer.', {
90
+ customerId: z.string().describe('The customer ID (UUID)'),
91
+ }, async ({ customerId }) => {
92
+ const client = getClient();
93
+ const result = await client.customers.delete(customerId);
94
+ return {
95
+ content: [{
96
+ type: 'text',
97
+ text: JSON.stringify(result, null, 2),
98
+ }],
99
+ };
100
+ });
101
+ }
102
+ //# sourceMappingURL=customers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"customers.js","sourceRoot":"","sources":["../../src/tools/customers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { HelmdeskClient } from '@helmdesk/sdk';
3
+ export declare function registerFeedbackTools(server: McpServer, getClient: () => HelmdeskClient): void;
4
+ //# sourceMappingURL=feedback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../../src/tools/feedback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAEnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAOnD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,QA6KvF"}
@@ -0,0 +1,137 @@
1
+ import { z } from 'zod';
2
+ // The SDK does not expose a feedback resource yet, so these tools call the
3
+ // v1 feedback endpoints through the client's public `request()` method — the
4
+ // same primitive every SDK resource class is built on. Swap to
5
+ // `client.feedback.*` once the SDK grows a feedback resource.
6
+ export function registerFeedbackTools(server, getClient) {
7
+ server.tool('list_feedback_conversations', 'List feedback conversations (customer feedback threads) with optional filters, newest first (requires the feedback:read scope). Each conversation has a title, status (open/closed), optional 1-5 rating, source (request/api/widget/dashboard), and customer info. Use customerEmail to see everything one customer said, or search to match title/customer text.', {
8
+ status: z.enum(['open', 'closed']).optional().describe('Filter by conversation status'),
9
+ rating: z.number().int().min(1).max(5).optional().describe('Filter by exact customer rating (1-5)'),
10
+ source: z.enum(['request', 'api', 'widget', 'dashboard']).optional()
11
+ .describe('Filter by how the conversation started (e.g. "request" = replies to a feedback request email)'),
12
+ customerEmail: z.string().optional().describe('Filter by the customer\'s email address'),
13
+ search: z.string().optional().describe('Substring match on title or customer email/name'),
14
+ dateFrom: z.string().optional().describe('ISO date lower bound, e.g. "2026-07-01"'),
15
+ dateTo: z.string().optional().describe('ISO date upper bound (inclusive day)'),
16
+ page: z.number().optional().describe('Page number (default: 1)'),
17
+ limit: z.number().optional().describe('Results per page (default: 25, max: 100)'),
18
+ }, async (params) => {
19
+ const client = getClient();
20
+ const result = await client.request('GET', '/feedback/conversations', {
21
+ params: {
22
+ status: params.status,
23
+ rating: params.rating !== undefined ? String(params.rating) : undefined,
24
+ source: params.source,
25
+ customerEmail: params.customerEmail,
26
+ search: params.search,
27
+ dateFrom: params.dateFrom,
28
+ dateTo: params.dateTo,
29
+ page: params.page !== undefined ? String(params.page) : undefined,
30
+ limit: params.limit !== undefined ? String(params.limit) : undefined,
31
+ },
32
+ });
33
+ return {
34
+ content: [{
35
+ type: 'text',
36
+ text: JSON.stringify(result, null, 2),
37
+ }],
38
+ };
39
+ });
40
+ server.tool('get_feedback_conversation', 'Get a feedback conversation\'s full detail including the complete message thread (customer + staff messages, with any attachments), rating, and status (requires the feedback:read scope). Use this to read the whole exchange before replying with reply_to_feedback.', {
41
+ conversationId: z.string().describe('The feedback conversation ID (UUID)'),
42
+ }, async ({ conversationId }) => {
43
+ const client = getClient();
44
+ const result = await client.request('GET', `/feedback/conversations/${conversationId}`);
45
+ return {
46
+ content: [{
47
+ type: 'text',
48
+ text: JSON.stringify(result, null, 2),
49
+ }],
50
+ };
51
+ });
52
+ server.tool('reply_to_feedback', 'Post a staff reply to a feedback conversation (requires the feedback:write scope). The reply is recorded on the thread and the customer is emailed the message with a link back to the conversation — so only send text you intend the customer to read.', {
53
+ conversationId: z.string().describe('The feedback conversation ID to reply to'),
54
+ body: z.string().describe('Reply message body (plain text, max 10000 characters)'),
55
+ }, async ({ conversationId, body }) => {
56
+ const client = getClient();
57
+ const result = await client.request('POST', `/feedback/conversations/${conversationId}/messages`, { body: { body } });
58
+ return {
59
+ content: [{
60
+ type: 'text',
61
+ text: JSON.stringify(result, null, 2),
62
+ }],
63
+ };
64
+ });
65
+ server.tool('close_feedback_conversation', 'Close a feedback conversation once it has been handled (requires the feedback:write scope). Pass status "open" instead to reopen a previously closed conversation. Closing does not notify the customer.', {
66
+ conversationId: z.string().describe('The feedback conversation ID'),
67
+ status: z.enum(['open', 'closed']).optional()
68
+ .describe('Target status (default: "closed"; pass "open" to reopen)'),
69
+ }, async ({ conversationId, status }) => {
70
+ const client = getClient();
71
+ const result = await client.request('PATCH', `/feedback/conversations/${conversationId}`, { body: { status: status ?? 'closed' } });
72
+ return {
73
+ content: [{
74
+ type: 'text',
75
+ text: JSON.stringify(result, null, 2),
76
+ }],
77
+ };
78
+ });
79
+ server.tool('list_feedback_requests', 'List outgoing feedback requests ("tickles") with their funnel status, newest first (requires the feedback:read scope). Status tracks the funnel: "created" (link-only request, not yet opened), "sent" (emailed), "opened" (customer opened the respond page), "responded" (customer answered — a feedback conversation now exists). Link-channel rows include their respondUrl. Use this to see who has not responded yet before nudging again.', {
80
+ status: z.enum(['created', 'sent', 'opened', 'responded']).optional()
81
+ .describe('Filter by funnel status'),
82
+ customerEmail: z.string().optional().describe('Filter by the customer\'s email address'),
83
+ search: z.string().optional().describe('Substring match on title or customer email/name'),
84
+ dateFrom: z.string().optional().describe('ISO date lower bound, e.g. "2026-07-01"'),
85
+ dateTo: z.string().optional().describe('ISO date upper bound (inclusive day)'),
86
+ page: z.number().optional().describe('Page number (default: 1)'),
87
+ limit: z.number().optional().describe('Results per page (default: 25, max: 100)'),
88
+ }, async (params) => {
89
+ const client = getClient();
90
+ const result = await client.request('GET', '/feedback/requests', {
91
+ params: {
92
+ status: params.status,
93
+ customerEmail: params.customerEmail,
94
+ search: params.search,
95
+ dateFrom: params.dateFrom,
96
+ dateTo: params.dateTo,
97
+ page: params.page !== undefined ? String(params.page) : undefined,
98
+ limit: params.limit !== undefined ? String(params.limit) : undefined,
99
+ },
100
+ });
101
+ return {
102
+ content: [{
103
+ type: 'text',
104
+ text: JSON.stringify(result, null, 2),
105
+ }],
106
+ };
107
+ });
108
+ server.tool('request_feedback', 'Ask a customer for feedback (requires the feedback:write scope). With the default channel "email" this creates a feedback request AND immediately emails the customer a branded message with your prompt and a respond link (with a sandbox key the email is captured, not delivered). With channel "link" NO email is sent — the response returns respondUrl, the public respond link, for you to embed in your own email/coupon/message; the funnel still tracks opened/responded either way. When the customer answers, a feedback conversation is created and the request\'s status becomes "responded".', {
109
+ title: z.string().describe('Short internal title for the request, e.g. "Post-onboarding check-in" (max 300 characters)'),
110
+ message: z.string().describe('The message/question the customer receives in the email — or sees on the respond page for channel "link" (max 10000 characters)'),
111
+ customerEmail: z.string().email().describe('Customer email address to send the request to'),
112
+ customerName: z.string().optional().describe('Customer display name (used in the email greeting)'),
113
+ channel: z.enum(['email', 'link']).optional()
114
+ .describe('"email" (default): Helmdesk sends the branded email. "link": no email — returns respondUrl to embed in your own email/coupon.'),
115
+ internalNote: z.string().optional()
116
+ .describe('Staff-only note, never shown to the customer, e.g. "Sent $50 coupon WELCOME50" (max 2000 characters)'),
117
+ }, async (params) => {
118
+ const client = getClient();
119
+ const result = await client.request('POST', '/feedback/requests', {
120
+ body: {
121
+ title: params.title,
122
+ message: params.message,
123
+ customerEmail: params.customerEmail,
124
+ customerName: params.customerName,
125
+ channel: params.channel,
126
+ internalNote: params.internalNote,
127
+ },
128
+ });
129
+ return {
130
+ content: [{
131
+ type: 'text',
132
+ text: JSON.stringify(result, null, 2),
133
+ }],
134
+ };
135
+ });
136
+ }
137
+ //# sourceMappingURL=feedback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback.js","sourceRoot":"","sources":["../../src/tools/feedback.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@helmdesk/mcp",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "MCP server for Helmdesk — let AI agents manage tickets, send emails, and search your knowledge base",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -22,7 +22,7 @@
22
22
  "dependencies": {
23
23
  "@modelcontextprotocol/sdk": "^1.12.1",
24
24
  "zod": "^3.25.23",
25
- "@helmdesk/sdk": "0.7.0"
25
+ "@helmdesk/sdk": "0.9.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/node": "^20",