@verygoodplugins/mcp-freescout 1.4.0 β†’ 2.0.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
@@ -1,15 +1,34 @@
1
1
  # FreeScout MCP Server
2
2
 
3
- An MCP (Model Context Protocol) server for FreeScout helpdesk ticket management and workflow automation. This server provides tools to interact with FreeScout tickets, analyze issues, manage responses, and integrate with Git workflows.
3
+ An MCP (Model Context Protocol) server for FreeScout helpdesk ticket management. This server provides tools to interact with FreeScout tickets, analyze issues, and manage customer responses.
4
4
 
5
5
  ## Features
6
6
 
7
7
  - 🎫 **Ticket Management**: Fetch, analyze, and update FreeScout tickets
8
8
  - πŸ” **Intelligent Analysis**: Automatically analyze tickets to determine issue type, root cause, and solutions
9
9
  - πŸ’¬ **Draft Responses**: Generate customer replies based on ticket analysis
10
- - 🌳 **Git Integration**: Create and manage Git worktrees for ticket implementations
11
- - πŸ”„ **Full Workflow Support**: Complete ticket-to-PR workflow automation
12
- - πŸ“Š **Search Capabilities**: Search and filter tickets across your FreeScout instance with mailbox filtering support
10
+ - πŸ“Š **Advanced Search**: First-class filter parameters with relative time support ("7d", "24h")
11
+ - πŸ”’ **Type Safety**: Full Zod schema validation with structured outputs
12
+ - πŸ” **Reliability**: Automatic retry logic with exponential backoff for transient failures
13
+ - ⚑ **Modern SDK**: Built on MCP SDK 1.25+ with `McpServer` and `registerTool()` patterns
14
+
15
+ ## What's New in v2.0
16
+
17
+ **Breaking Changes:**
18
+
19
+ - Search API redesigned with explicit filter parameters instead of query-string syntax
20
+ - Migrated to modern `McpServer` class with structured outputs
21
+ - Removed Git/GitHub tools (use dedicated Git MCP servers for workflow automation)
22
+
23
+ **New Features:**
24
+
25
+ - Explicit search filters: `assignee`, `updatedSince`, `createdSince`, `page`, `pageSize`
26
+ - Relative time support: Use "7d", "24h", "30m" in date filters
27
+ - Exponential backoff retry logic for network errors and rate limits
28
+ - Structured content responses for better type safety
29
+ - Full Zod schema validation throughout
30
+
31
+ See [CHANGELOG.md](CHANGELOG.md) for migration guide.
13
32
 
14
33
  ## Installation
15
34
 
@@ -17,8 +36,6 @@ An MCP (Model Context Protocol) server for FreeScout helpdesk ticket management
17
36
 
18
37
  - Node.js 18 or higher
19
38
  - FreeScout instance with API access enabled
20
- - Git (for worktree management features)
21
- - GitHub CLI (`gh`) for GitHub integration (install from https://cli.github.com/)
22
39
 
23
40
  ## Quick Start (Recommended)
24
41
 
@@ -32,7 +49,8 @@ Add this to your Claude Desktop settings (`~/Library/Application Support/Claude/
32
49
  {
33
50
  "mcpServers": {
34
51
  "freescout": {
35
- "command": "npx @verygoodplugins/mcp-freescout@latest",
52
+ "command": "npx",
53
+ "args": ["@verygoodplugins/mcp-freescout@latest"],
36
54
  "env": {
37
55
  "FREESCOUT_URL": "https://your-freescout-domain.com",
38
56
  "FREESCOUT_API_KEY": "your-api-key-here"
@@ -47,8 +65,9 @@ Add this to your Claude Desktop settings (`~/Library/Application Support/Claude/
47
65
  Add this to your Cursor MCP settings:
48
66
 
49
67
  **Method 1: Via Cursor Settings UI**
68
+
50
69
  1. Open Cursor Settings (Cmd/Ctrl + ,)
51
- 2. Search for "MCP"
70
+ 2. Search for "MCP"
52
71
  3. Click "Edit in settings.json"
53
72
  4. Add the MCP server configuration
54
73
 
@@ -64,8 +83,7 @@ Add this to your Cursor settings.json or create `~/.cursor/mcp.json`:
64
83
  "args": ["@verygoodplugins/mcp-freescout@latest"],
65
84
  "env": {
66
85
  "FREESCOUT_URL": "https://your-freescout-domain.com",
67
- "FREESCOUT_API_KEY": "your-api-key-here",
68
- "WORKING_DIRECTORY": "${workspaceFolder}"
86
+ "FREESCOUT_API_KEY": "your-api-key-here"
69
87
  }
70
88
  }
71
89
  }
@@ -80,17 +98,20 @@ That's it! The server will automatically use your current workspace directory fo
80
98
  If you prefer to install and run the server locally:
81
99
 
82
100
  1. Clone this repository:
101
+
83
102
  ```bash
84
103
  git clone https://github.com/verygoodplugins/mcp-freescout.git
85
104
  cd mcp-freescout
86
105
  ```
87
106
 
88
107
  2. Install dependencies:
108
+
89
109
  ```bash
90
110
  npm install
91
111
  ```
92
112
 
93
113
  3. Build the TypeScript code:
114
+
94
115
  ```bash
95
116
  npm run build
96
117
  ```
@@ -105,8 +126,7 @@ npm run build
105
126
  "args": ["/path/to/mcp-freescout/dist/index.js"],
106
127
  "env": {
107
128
  "FREESCOUT_URL": "https://your-freescout-domain.com",
108
- "FREESCOUT_API_KEY": "your-api-key-here",
109
- "WORKING_DIRECTORY": "/path/to/your/project"
129
+ "FREESCOUT_API_KEY": "your-api-key-here"
110
130
  }
111
131
  }
112
132
  }
@@ -132,13 +152,16 @@ npm run dev
132
152
  ### Core Ticket Operations
133
153
 
134
154
  #### `freescout_get_ticket`
155
+
135
156
  Fetch a FreeScout ticket with all its details and conversation threads.
136
157
 
137
158
  **Parameters:**
159
+
138
160
  - `ticket` (required): Ticket ID, number, or FreeScout URL
139
161
  - `includeThreads` (optional): Include conversation threads (default: true)
140
162
 
141
163
  **Natural Language Examples:**
164
+
142
165
  - "Show me ticket #12345"
143
166
  - "Get the details for FreeScout ticket 34811"
144
167
  - "Fetch ticket https://support.example.com/conversation/12345"
@@ -146,6 +169,7 @@ Fetch a FreeScout ticket with all its details and conversation threads.
146
169
  - "Pull up the conversation for ticket #34811"
147
170
 
148
171
  **Example:**
172
+
149
173
  ```javascript
150
174
  {
151
175
  "ticket": "12345",
@@ -157,14 +181,16 @@ Fetch a FreeScout ticket with all its details and conversation threads.
157
181
 
158
182
  ![FreeScout ticket details and conversation threads displayed in Cursor chat interface](https://github.com/user-attachments/assets/0144056d-f6d6-4275-9f55-dade0be3ba8c)
159
183
 
160
-
161
184
  #### `freescout_analyze_ticket`
185
+
162
186
  Analyze a ticket to determine issue type, root cause, and suggested solutions.
163
187
 
164
188
  **Parameters:**
189
+
165
190
  - `ticket` (required): Ticket ID, number, or FreeScout URL
166
191
 
167
192
  **Natural Language Examples:**
193
+
168
194
  - "Analyze ticket #12345"
169
195
  - "What kind of issue is ticket 34811?"
170
196
  - "Can you analyze this ticket and tell me if it's a bug?"
@@ -172,6 +198,7 @@ Analyze a ticket to determine issue type, root cause, and suggested solutions.
172
198
  - "Is this ticket a bug or feature request?"
173
199
 
174
200
  **Returns:**
201
+
175
202
  - Customer information
176
203
  - Issue description and classification
177
204
  - Code snippets and error messages
@@ -184,14 +211,17 @@ Analyze a ticket to determine issue type, root cause, and suggested solutions.
184
211
  ![Ticket analysis showing issue type, root cause, and implementation recommendations](https://github.com/user-attachments/assets/19080021-1f29-45a4-8601-556b55d379c3)
185
212
 
186
213
  #### `freescout_add_note`
214
+
187
215
  Add an internal note to a ticket for team communication.
188
216
 
189
217
  **Parameters:**
218
+
190
219
  - `ticket` (required): Ticket ID, number, or FreeScout URL
191
220
  - `note` (required): The note content
192
221
  - `userId` (optional): User ID for the note (defaults to env setting)
193
222
 
194
223
  **Natural Language Examples:**
224
+
195
225
  - "Add a note to ticket #12345 saying 'Reproduced on staging'"
196
226
  - "Leave an internal note on this ticket"
197
227
  - "Add a team note: 'Customer confirmed fix works'"
@@ -199,14 +229,17 @@ Add an internal note to a ticket for team communication.
199
229
  - "Add internal documentation to this ticket"
200
230
 
201
231
  #### `freescout_update_ticket`
232
+
202
233
  Update ticket status and/or assignment.
203
234
 
204
235
  **Parameters:**
236
+
205
237
  - `ticket` (required): Ticket ID, number, or FreeScout URL
206
238
  - `status` (optional): New status ('active', 'pending', 'closed', 'spam')
207
239
  - `assignTo` (optional): User ID to assign the ticket to
208
240
 
209
241
  **Natural Language Examples:**
242
+
210
243
  - "Close ticket #12345"
211
244
  - "Mark ticket 34811 as pending"
212
245
  - "Assign this ticket to user ID 2"
@@ -214,14 +247,17 @@ Update ticket status and/or assignment.
214
247
  - "Update ticket #12345 status to closed and assign to user 1"
215
248
 
216
249
  #### `freescout_create_draft_reply`
250
+
217
251
  Create a draft reply in FreeScout that can be edited before sending. This tool lets the LLM generate the reply content and saves it directly to FreeScout as a draft. **Automatically converts Markdown formatting to HTML** for proper display in FreeScout.
218
252
 
219
253
  **Parameters:**
254
+
220
255
  - `ticket` (required): Ticket ID, number, or FreeScout URL
221
256
  - `replyText` (required): The draft reply content (generated by the LLM, supports Markdown formatting)
222
257
  - `userId` (optional): User ID creating the draft (defaults to env setting)
223
258
 
224
259
  **Natural Language Examples:**
260
+
225
261
  - "Create a draft reply for ticket #12345"
226
262
  - "Draft a customer response for this ticket"
227
263
  - "Generate and save a draft reply explaining the fix"
@@ -229,14 +265,16 @@ Create a draft reply in FreeScout that can be edited before sending. This tool l
229
265
  - "Create a draft reply thanking the customer and explaining the solution"
230
266
 
231
267
  **Markdown Support:**
268
+
232
269
  - **Bold text**: `**text**` or `__text__` β†’ **text**
233
- - *Italic text*: `*text*` or `_text_` β†’ *text*
270
+ - _Italic text_: `*text*` or `_text_` β†’ _text_
234
271
  - `Code`: `` `code` `` β†’ `code`
235
272
  - Numbered lists: `1. item` β†’ proper ordered lists
236
273
  - Bullet lists: `- item` or `* item` β†’ proper unordered lists
237
274
  - Line breaks: Double newlines create paragraphs, single newlines create line breaks
238
275
 
239
276
  **Workflow:**
277
+
240
278
  1. Use `freescout_get_ticket_context` to get customer info and ticket details
241
279
  2. Let the LLM craft a personalized reply using Markdown formatting
242
280
  3. Use `freescout_create_draft_reply` to save the draft in FreeScout (Markdown automatically converted to HTML)
@@ -249,12 +287,15 @@ Create a draft reply in FreeScout that can be edited before sending. This tool l
249
287
  ![Draft reply automatically saved to FreeScout](https://github.com/user-attachments/assets/689bd675-cb34-414e-b18f-d50d4424ace6)
250
288
 
251
289
  #### `freescout_get_ticket_context`
290
+
252
291
  Get ticket context and customer information to help craft personalized replies.
253
292
 
254
293
  **Parameters:**
294
+
255
295
  - `ticket` (required): Ticket ID, number, or FreeScout URL
256
296
 
257
297
  **Natural Language Examples:**
298
+
258
299
  - "Get context for ticket #12345 to write a reply"
259
300
  - "I need customer info and ticket details for drafting a response"
260
301
  - "Gather context for this ticket so I can write a personalized reply"
@@ -262,6 +303,7 @@ Get ticket context and customer information to help craft personalized replies.
262
303
  - "Get ticket context to help craft a customer response"
263
304
 
264
305
  **Returns:**
306
+
265
307
  - Customer name and email
266
308
  - Ticket subject and status
267
309
  - Issue description and analysis
@@ -269,14 +311,17 @@ Get ticket context and customer information to help craft personalized replies.
269
311
  - Analysis results (bug vs feature vs third-party issue)
270
312
 
271
313
  #### `freescout_search_tickets`
314
+
272
315
  Search for tickets across your FreeScout instance.
273
316
 
274
317
  **Parameters:**
318
+
275
319
  - `query` (required): Search query
276
320
  - `status` (optional): Filter by status ('active', 'pending', 'closed', 'spam', 'all')
277
321
  - `mailboxId` (optional): Filter by specific mailbox ID (searches all mailboxes if not specified)
278
322
 
279
323
  **Natural Language Examples:**
324
+
280
325
  - "Search for tickets containing 'OAuth error'"
281
326
  - "Find all pending tickets with 'HighLevel' in them"
282
327
  - "Search for closed tickets about 'plugin conflicts'"
@@ -285,178 +330,106 @@ Search for tickets across your FreeScout instance.
285
330
  - "Search for tickets in mailbox 1 containing 'bug report'"
286
331
  - "Find tickets in mailbox 2 with status pending"
287
332
 
333
+ **Search Parameters (v2.0+):**
334
+
335
+ - `textSearch` (optional): Plain text search in ticket content/subject
336
+ - `assignee` (optional): 'unassigned' | 'any' | user_id (number)
337
+ - `status` (optional): 'active' | 'pending' | 'closed' | 'spam' | 'all'
338
+ - `state` (optional): 'published' | 'deleted'
339
+ - `mailboxId` (optional): Filter by specific mailbox ID
340
+ - `updatedSince` (optional): ISO date or relative time like "7d", "24h", "30m"
341
+ - `createdSince` (optional): ISO date or relative time
342
+ - `page` (optional): Page number for pagination (min: 1)
343
+ - `pageSize` (optional): Results per page (min: 1, max: 100)
344
+
345
+ **Search Tips for AI Agents:**
346
+
347
+ - For **unassigned tickets**: Use `assignee: "unassigned"` with `status: "active"`
348
+ - For **recent tickets**: Use `updatedSince: "7d"` for last 7 days
349
+ - For **specific user**: Use `assignee: 123` (user ID number)
350
+ - **Status "active"** = open/active tickets (NOT "open" - that's invalid)
351
+ - Use **freescout_get_mailboxes** first if filtering by mailbox
352
+ - Combine filters: `{ textSearch: "error", assignee: "unassigned", updatedSince: "24h" }`
353
+
288
354
  #### `freescout_get_mailboxes`
355
+
289
356
  Get a list of all available mailboxes in your FreeScout instance.
290
357
 
291
358
  **Parameters:**
292
359
  None
293
360
 
294
361
  **Natural Language Examples:**
362
+
295
363
  - "Show me all available mailboxes"
296
364
  - "List the mailboxes in FreeScout"
297
365
  - "What mailboxes are configured?"
298
366
  - "Get mailbox information"
299
367
 
300
- ### Git Workflow Tools
301
-
302
- #### `git_create_worktree`
303
- Create a Git worktree for isolated ticket implementation.
304
-
305
- **Parameters:**
306
- - `ticketId` (required): Ticket ID for the worktree
307
- - `branchName` (optional): Custom branch name (default: fix/freescout-{ticketId})
308
- - `baseBranch` (optional): Base branch to create from (default: master)
309
-
310
- **Natural Language Examples:**
311
- - "Create a worktree for ticket #12345"
312
- - "Set up a Git worktree to work on this ticket"
313
- - "Create a new branch and worktree for ticket 34811"
314
- - "Make a worktree for fixing this issue"
315
- - "Set up isolated workspace for this ticket"
316
-
317
- #### `git_remove_worktree`
318
- Remove a Git worktree after work is complete.
319
-
320
- **Parameters:**
321
- - `ticketId` (required): Ticket ID of the worktree to remove
322
-
323
- **Natural Language Examples:**
324
- - "Remove the worktree for ticket #12345"
325
- - "Clean up the worktree for this ticket"
326
- - "Delete worktree for ticket 34811"
327
- - "Remove the Git worktree after finishing the implementation"
328
- - "Clean up workspace for this ticket"
329
-
330
- #### `github_create_pr`
331
- Create a GitHub pull request for the current branch. Automatically detects the repository from git remote.
332
-
333
- **Parameters:**
334
- - `title` (required): PR title
335
- - `body` (required): PR description/body
336
- - `ticketId` (optional): FreeScout ticket ID for reference (adds link to PR body)
337
- - `branch` (optional): Branch name (defaults to current branch)
338
- - `baseBranch` (optional): Base branch (default: master)
339
- - `draft` (optional): Create as draft PR (default: false)
340
-
341
- **Natural Language Examples:**
342
- - "Create a PR for this fix"
343
- - "Make a pull request with title 'Fix OAuth validation error'"
344
- - "Create a GitHub PR for ticket #12345"
345
- - "Submit a pull request for this feature"
346
- - "Create a draft PR for the current branch"
347
-
348
- **Features:**
349
- - Auto-detects GitHub repository using GitHub CLI (no configuration needed!)
350
- - Adds FreeScout ticket link to PR body when ticketId is provided
351
- - Supports draft PRs for work in progress
352
- - Uses GitHub CLI (`gh`) for authentication - no tokens required!
353
- - Requires: `gh` installed and authenticated (`gh auth login`)
354
-
355
- ### Workflow Automation
356
-
357
- #### `freescout_implement_ticket`
358
- workflow automation: analyze ticket, create worktree, and prepare implementation plan.
359
-
360
- **Parameters:**
361
- - `ticket` (required): Ticket ID, number, or FreeScout URL
362
- - `additionalContext` (optional): Additional context or implementation suggestions
363
- - `autoCreateWorktree` (optional): Automatically create Git worktree (default: true)
364
-
365
- **Natural Language Examples:**
366
- - "Start the full implementation workflow for ticket #12345"
367
- - "Please implement a solution to this ticket"
368
- - "Analyze and prepare implementation for this ticket"
369
- - "Run the complete implementation workflow"
370
- - "Prepare this ticket for development with analysis and worktree setup"
371
-
372
- **Returns:**
373
- - Complete ticket analysis
374
- - Customer information
375
- - Issue classification (bug/feature/third-party)
376
- - Implementation plan
377
- - Git worktree details
378
- - Next steps guidance
379
-
380
368
  ## Workflow Examples
381
369
 
382
370
  ### Basic Ticket Analysis
371
+
383
372
  ```javascript
384
373
  // Analyze a ticket to understand the issue
385
374
  await mcp.callTool('freescout_analyze_ticket', {
386
- ticket: '12345'
375
+ ticket: '12345',
387
376
  });
388
377
  ```
389
378
 
390
- ### Complete Implementation Workflow
391
- ```javascript
392
- // 1. Start the implementation workflow
393
- const plan = await mcp.callTool('freescout_implement_ticket', {
394
- ticket: 'https://support.example.com/conversation/12345',
395
- additionalContext: 'Consider backward compatibility'
396
- });
397
-
398
- // 2. After implementing the fix, create a GitHub PR
399
- await mcp.callTool('github_create_pr', {
400
- title: 'Fix: Validation error in checkout (FreeScout #12345)',
401
- body: `## Summary
402
- Fixes the validation error reported in the checkout process.
403
-
404
- ## Changes
405
- - Fixed validation logic in checkout.js
406
- - Added error handling for edge cases
379
+ ### Complete Ticket Response Workflow
407
380
 
408
- ## Testing
409
- - Tested with various input combinations
410
- - All existing tests pass`,
411
- ticketId: '12345' // Automatically adds FreeScout link to PR
381
+ ```javascript
382
+ // 1. Analyze the ticket to understand the issue
383
+ const analysis = await mcp.callTool('freescout_analyze_ticket', {
384
+ ticket: '12345',
412
385
  });
413
386
 
414
- // 3. Get ticket context to craft a personalized reply
387
+ // 2. Get ticket context for personalized reply
415
388
  const context = await mcp.callTool('freescout_get_ticket_context', {
416
- ticket: '12345'
389
+ ticket: '12345',
417
390
  });
418
391
 
419
- // 4. Create a draft reply directly in FreeScout (LLM generates the content with Markdown)
392
+ // 3. Create a draft reply directly in FreeScout
420
393
  await mcp.callTool('freescout_create_draft_reply', {
421
394
  ticket: '12345',
422
395
  replyText: `Hi ${context.customer.name},
423
396
 
424
- Thank you for working through that validation issue with us! Your detailed report was really helpful.
425
-
426
- I've just implemented a fix that addresses the checkout validation error you experienced. The fix includes:
397
+ Thank you for reaching out! Based on my analysis, I can see that ${analysis.issueDescription}.
427
398
 
428
- 1. **Improved validation logic** in the checkout process
429
- 2. **Better error handling** for edge cases
430
- 3. **Additional safeguards** to prevent similar issues
399
+ Here's what I found:
431
400
 
432
- The fix has been submitted for review and will be included in the next plugin update. You'll receive the update through WordPress's automatic update system.
401
+ 1. **Issue Type**: ${analysis.isBug ? 'Bug' : 'Configuration/Feature Request'}
402
+ 2. **Root Cause**: ${analysis.rootCause || 'Under investigation'}
433
403
 
434
- Thanks again for your patience and for helping us improve the plugin!
404
+ I'll look into this and get back to you shortly with a solution.
435
405
 
436
406
  Best regards,
437
- [Your name]`
407
+ [Your name]`,
438
408
  });
439
409
 
440
- // 5. Update ticket status and assignment
410
+ // 4. Update ticket status and assignment
441
411
  await mcp.callTool('freescout_update_ticket', {
442
412
  ticket: '12345',
443
413
  status: 'active',
444
- assignTo: 1
414
+ assignTo: 1,
445
415
  });
446
416
 
447
- // 6. Clean up the worktree after PR is created
448
- await mcp.callTool('git_remove_worktree', {
449
- ticketId: '12345'
417
+ // 5. Add an internal note with findings
418
+ await mcp.callTool('freescout_add_note', {
419
+ ticket: '12345',
420
+ note: `Analysis complete:
421
+ - Is Bug: ${analysis.isBug}
422
+ - Third-party Issue: ${analysis.isThirdPartyIssue}
423
+ - Root Cause: ${analysis.rootCause}`,
450
424
  });
451
425
  ```
452
- ![Complete implementation workflow](https://github.com/user-attachments/assets/dd003100-acfe-420b-b9a8-4253d07545d4)
453
-
454
426
 
455
427
  ### Draft Reply Workflow
428
+
456
429
  ```javascript
457
430
  // 1. Get ticket context for personalized reply
458
431
  const context = await mcp.callTool('freescout_get_ticket_context', {
459
- ticket: '34811'
432
+ ticket: '34811',
460
433
  });
461
434
 
462
435
  // 2. Create draft reply in FreeScout (LLM crafts the content)
@@ -478,19 +451,20 @@ This should prevent the confusion you experienced and help other users avoid sim
478
451
  The update should be available within the next few weeks. Thanks for your patience and for helping us improve the plugin!
479
452
 
480
453
  Best regards,
481
- Jack`
454
+ Jack`,
482
455
  });
483
456
 
484
457
  // The draft is now saved in FreeScout and can be reviewed/edited before sending
485
458
  ```
486
459
 
487
460
  ### Handling Non-Bug Issues
461
+
488
462
  ```javascript
489
463
  // For third-party issues or feature requests
490
464
  const reply = await mcp.callTool('freescout_draft_reply', {
491
465
  ticket: '12345',
492
466
  fixDescription: 'This is a limitation of the Elementor plugin that we cannot override.',
493
- isExplanatory: true
467
+ isExplanatory: true,
494
468
  });
495
469
  ```
496
470
 
@@ -529,21 +503,25 @@ User Request β†’ MCP Server β†’ FreeScout API β†’ Ticket Analyzer
529
503
  ## Development
530
504
 
531
505
  ### Running in Development Mode
506
+
532
507
  ```bash
533
508
  npm run dev
534
509
  ```
535
510
 
536
511
  ### Running Tests
512
+
537
513
  ```bash
538
514
  npm test
539
515
  ```
540
516
 
541
517
  ### Linting
518
+
542
519
  ```bash
543
520
  npm run lint
544
521
  ```
545
522
 
546
523
  ### Building for Production
524
+
547
525
  ```bash
548
526
  npm run build
549
527
  ```
@@ -552,22 +530,16 @@ npm run build
552
530
 
553
531
  ### Required Environment Variables
554
532
 
555
- | Variable | Description | Example |
556
- |----------|-------------|---------|
557
- | `FREESCOUT_URL` | Your FreeScout instance URL | `https://support.example.com` |
558
- | `FREESCOUT_API_KEY` | FreeScout API key | `your-api-key-here` |
533
+ | Variable | Description | Example |
534
+ | ------------------- | --------------------------- | ----------------------------- |
535
+ | `FREESCOUT_URL` | Your FreeScout instance URL | `https://support.example.com` |
536
+ | `FREESCOUT_API_KEY` | FreeScout API key | `your-api-key-here` |
559
537
 
560
538
  ### Optional Environment Variables
561
539
 
562
- | Variable | Description | Default |
563
- |----------|-------------|---------|
564
- | `FREESCOUT_DEFAULT_USER_ID` | Default user ID for assignments | `1` |
565
- | `WORKING_DIRECTORY` | Base directory for Git operations | Current working directoryΒΉ |
566
- | `GITHUB_REPO` | GitHub repository (owner/repo) | Auto-detected using `gh`Β² |
567
-
568
- ΒΉ **Note**: Automatically uses the current project/workspace directory. Only set this if you need to work on a different directory.
569
-
570
- Β² **Note**: The server automatically detects the GitHub repository using GitHub CLI (`gh`). Requires `gh` to be installed and authenticated (`gh auth login`). Only set `GITHUB_REPO` if you need to override the auto-detection.
540
+ | Variable | Description | Default |
541
+ | --------------------------- | ------------------------------- | ------- |
542
+ | `FREESCOUT_DEFAULT_USER_ID` | Default user ID for assignments | `1` |
571
543
 
572
544
  ### Advanced Configuration Example
573
545
 
@@ -577,13 +549,12 @@ For more control, you can specify additional environment variables:
577
549
  {
578
550
  "mcpServers": {
579
551
  "freescout": {
580
- "command": "npx @verygoodplugins/mcp-freescout@latest",
552
+ "command": "npx",
553
+ "args": ["@verygoodplugins/mcp-freescout@latest"],
581
554
  "env": {
582
555
  "FREESCOUT_URL": "https://support.example.com",
583
556
  "FREESCOUT_API_KEY": "your-api-key",
584
- "FREESCOUT_DEFAULT_USER_ID": "2",
585
- "WORKING_DIRECTORY": "/path/to/specific/project",
586
- "GITHUB_REPO": "owner/repo"
557
+ "FREESCOUT_DEFAULT_USER_ID": "2"
587
558
  }
588
559
  }
589
560
  }
@@ -602,40 +573,84 @@ For more control, you can specify additional environment variables:
602
573
  ## Best Practices
603
574
 
604
575
  ### Ticket Analysis
576
+
605
577
  - Always analyze tickets before implementing fixes
606
578
  - Check for third-party limitations before attempting fixes
607
579
  - Verify reproducibility with team notes
608
580
 
609
- ### Git Workflow
610
- - Use worktrees for parallel development
611
- - Clean up worktrees after PR creation
612
- - Keep branch names descriptive
613
-
614
581
  ### Customer Communication
582
+
615
583
  - Generate draft replies for review
616
584
  - Include fix descriptions in customer communications
617
585
  - Use explanatory replies for non-bug issues
618
586
 
587
+ ## Migration from v1.x to v2.0
588
+
589
+ ### Breaking Changes
590
+
591
+ The `freescout_search_tickets` tool has been redesigned with explicit filter parameters. The old query-string syntax is no longer supported.
592
+
593
+ **Before (v1.x):**
594
+
595
+ ```json
596
+ {
597
+ "query": "assignee:null",
598
+ "status": "active"
599
+ }
600
+ ```
601
+
602
+ **After (v2.0):**
603
+
604
+ ```json
605
+ {
606
+ "assignee": "unassigned",
607
+ "status": "active"
608
+ }
609
+ ```
610
+
611
+ **For text search:**
612
+
613
+ ```json
614
+ {
615
+ "textSearch": "authentication error",
616
+ "assignee": "unassigned",
617
+ "updatedSince": "7d"
618
+ }
619
+ ```
620
+
621
+ ### New Features to Adopt
622
+
623
+ 1. **Relative time filters**: Use `"7d"`, `"24h"`, `"30m"` instead of calculating ISO dates
624
+ 2. **Pagination**: Add `page` and `pageSize` parameters for large result sets
625
+ 3. **Structured outputs**: All tools now return typed `structuredContent` for better integration
626
+
627
+ ### Automatic Retries
628
+
629
+ The server now automatically retries failed requests with exponential backoff. No configuration needed - it just works more reliably.
630
+
619
631
  ## Troubleshooting
620
632
 
621
633
  ### Common Issues
622
634
 
623
635
  #### API Connection Errors
636
+
624
637
  - Verify your FreeScout URL includes the protocol (https://)
625
638
  - Check API key permissions in FreeScout
626
639
  - Ensure your FreeScout instance has API access enabled
627
-
628
- #### Git Worktree Errors
629
- - Ensure Git is installed and accessible
630
- - Verify the working directory is a Git repository (defaults to current directory)
631
- - Check that the base branch exists
632
- - If needed, explicitly set WORKING_DIRECTORY to your Git repository path
640
+ - **New in v2.0**: The server will automatically retry transient connection errors
633
641
 
634
642
  #### Ticket Parsing Issues
643
+
635
644
  - The server accepts ticket IDs, numbers, and full URLs
636
645
  - URLs are automatically parsed to extract ticket IDs
637
646
  - Numeric inputs are treated as ticket IDs
638
647
 
648
+ #### Rate Limiting (429 Errors)
649
+
650
+ - **New in v2.0**: The server automatically detects rate limits and backs off
651
+ - Retry logic includes exponential backoff with jitter
652
+ - No manual intervention needed
653
+
639
654
  ## Contributing
640
655
 
641
656
  Contributions are welcome! Please:
@@ -652,8 +667,9 @@ GPL-3.0 License - see LICENSE file for details
652
667
  ## Support
653
668
 
654
669
  For issues, questions, or suggestions:
670
+
655
671
  - [Open an issue on GitHub](https://github.com/verygoodplugins/mcp-freescout/issues)
656
- - [Contact the maintainers](https://verygoodplugins.com/contact)
672
+ - [Contact the maintainers](https://verygoodplugins.com/contact?utm_source=github)
657
673
  - Check the documentation
658
674
 
659
675
  ## Roadmap