@verygoodplugins/mcp-freescout 1.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 ADDED
@@ -0,0 +1,477 @@
1
+ # MCP FreeScout Server
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.
4
+
5
+ ## Features
6
+
7
+ - 🎫 **Ticket Management**: Fetch, analyze, and update FreeScout tickets
8
+ - 🔍 **Intelligent Analysis**: Automatically analyze tickets to determine issue type, root cause, and solutions
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
13
+
14
+ ## Installation
15
+
16
+ ### Prerequisites
17
+
18
+ - Node.js 18 or higher
19
+ - FreeScout instance with API access enabled
20
+ - Git (for worktree management features)
21
+
22
+ ## Quick Start (Recommended)
23
+
24
+ The easiest way to use this MCP server is with `npx`:
25
+
26
+ ### With Claude Desktop
27
+
28
+ Add this to your Claude Desktop settings (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
29
+
30
+ ```json
31
+ {
32
+ "mcpServers": {
33
+ "freescout": {
34
+ "command": "npx",
35
+ "args": ["@verygoodplugins/mcp-freescout@latest"],
36
+ "env": {
37
+ "FREESCOUT_URL": "https://your-freescout-domain.com",
38
+ "FREESCOUT_API_KEY": "your-api-key-here"
39
+ }
40
+ }
41
+ }
42
+ }
43
+ ```
44
+
45
+ ### With Cursor IDE
46
+
47
+ Add this to your Cursor settings.json:
48
+
49
+ ```json
50
+ {
51
+ "mcp.servers": {
52
+ "freescout": {
53
+ "command": "npx",
54
+ "args": ["@verygoodplugins/mcp-freescout@latest"],
55
+ "env": {
56
+ "FREESCOUT_URL": "https://your-freescout-domain.com",
57
+ "FREESCOUT_API_KEY": "your-api-key-here"
58
+ }
59
+ }
60
+ }
61
+ }
62
+ ```
63
+
64
+ That's it! The server will automatically use your current workspace directory for Git operations.
65
+
66
+ ## Manual Installation (Alternative)
67
+
68
+ If you prefer to install and run the server locally:
69
+
70
+ 1. Clone this repository:
71
+ ```bash
72
+ git clone https://github.com/verygoodplugins/mcp-freescout.git
73
+ cd mcp-freescout
74
+ ```
75
+
76
+ 2. Install dependencies:
77
+ ```bash
78
+ npm install
79
+ ```
80
+
81
+ 3. Build the TypeScript code:
82
+ ```bash
83
+ npm run build
84
+ ```
85
+
86
+ 4. Configure your MCP client to use the local installation:
87
+
88
+ ```json
89
+ {
90
+ "mcpServers": {
91
+ "freescout": {
92
+ "command": "node",
93
+ "args": ["/path/to/mcp-freescout/dist/index.js"],
94
+ "env": {
95
+ "FREESCOUT_URL": "https://your-freescout-domain.com",
96
+ "FREESCOUT_API_KEY": "your-api-key-here"
97
+ }
98
+ }
99
+ }
100
+ }
101
+ ```
102
+
103
+ ## Usage with Other MCP Clients
104
+
105
+ Run the server directly:
106
+
107
+ ```bash
108
+ npm start
109
+ ```
110
+
111
+ Or in development mode with auto-reload:
112
+
113
+ ```bash
114
+ npm run dev
115
+ ```
116
+
117
+ ## Available Tools
118
+
119
+ ### Core Ticket Operations
120
+
121
+ #### `freescout_get_ticket`
122
+ Fetch a FreeScout ticket with all its details and conversation threads.
123
+
124
+ **Parameters:**
125
+ - `ticket` (required): Ticket ID, number, or FreeScout URL
126
+ - `includeThreads` (optional): Include conversation threads (default: true)
127
+
128
+ **Example:**
129
+ ```javascript
130
+ {
131
+ "ticket": "12345",
132
+ "includeThreads": true
133
+ }
134
+ ```
135
+
136
+ #### `freescout_analyze_ticket`
137
+ Analyze a ticket to determine issue type, root cause, and suggested solutions.
138
+
139
+ **Parameters:**
140
+ - `ticket` (required): Ticket ID, number, or FreeScout URL
141
+
142
+ **Returns:**
143
+ - Customer information
144
+ - Issue description and classification
145
+ - Code snippets and error messages
146
+ - Reproducibility status
147
+ - Root cause analysis
148
+ - Bug vs feature request vs third-party issue determination
149
+
150
+ #### `freescout_add_note`
151
+ Add an internal note to a ticket for team communication.
152
+
153
+ **Parameters:**
154
+ - `ticket` (required): Ticket ID, number, or FreeScout URL
155
+ - `note` (required): The note content
156
+ - `userId` (optional): User ID for the note (defaults to env setting)
157
+
158
+ #### `freescout_update_ticket`
159
+ Update ticket status and/or assignment.
160
+
161
+ **Parameters:**
162
+ - `ticket` (required): Ticket ID, number, or FreeScout URL
163
+ - `status` (optional): New status ('active', 'pending', 'closed', 'spam')
164
+ - `assignTo` (optional): User ID to assign the ticket to
165
+
166
+ #### `freescout_draft_reply`
167
+ Generate a customer reply based on ticket analysis and fix description.
168
+
169
+ **Parameters:**
170
+ - `ticket` (required): Ticket ID, number, or FreeScout URL
171
+ - `fixDescription` (optional): Description of the implemented fix
172
+ - `isExplanatory` (optional): Whether this is an explanatory reply (no code changes)
173
+
174
+ #### `freescout_search_tickets`
175
+ Search for tickets across your FreeScout instance.
176
+
177
+ **Parameters:**
178
+ - `query` (required): Search query
179
+ - `status` (optional): Filter by status ('active', 'pending', 'closed', 'spam', 'all')
180
+
181
+ ### Git Workflow Tools
182
+
183
+ #### `git_create_worktree`
184
+ Create a Git worktree for isolated ticket implementation.
185
+
186
+ **Parameters:**
187
+ - `ticketId` (required): Ticket ID for the worktree
188
+ - `branchName` (optional): Custom branch name (default: fix/freescout-{ticketId})
189
+ - `baseBranch` (optional): Base branch to create from (default: master)
190
+
191
+ #### `git_remove_worktree`
192
+ Remove a Git worktree after work is complete.
193
+
194
+ **Parameters:**
195
+ - `ticketId` (required): Ticket ID of the worktree to remove
196
+
197
+ #### `github_create_pr`
198
+ Create a GitHub pull request for the current branch. Automatically detects the repository from git remote.
199
+
200
+ **Parameters:**
201
+ - `title` (required): PR title
202
+ - `body` (required): PR description/body
203
+ - `ticketId` (optional): FreeScout ticket ID for reference (adds link to PR body)
204
+ - `branch` (optional): Branch name (defaults to current branch)
205
+ - `baseBranch` (optional): Base branch (default: master)
206
+ - `draft` (optional): Create as draft PR (default: false)
207
+
208
+ **Features:**
209
+ - Auto-detects GitHub repository from git remote (no configuration needed!)
210
+ - Adds FreeScout ticket link to PR body when ticketId is provided
211
+ - Supports draft PRs for work in progress
212
+ - Uses GitHub CLI (gh) for authentication
213
+
214
+ ### Workflow Automation
215
+
216
+ #### `freescout_implement_ticket`
217
+ Complete workflow automation: analyze ticket, create worktree, and prepare implementation plan.
218
+
219
+ **Parameters:**
220
+ - `ticket` (required): Ticket ID, number, or FreeScout URL
221
+ - `additionalContext` (optional): Additional context or implementation suggestions
222
+ - `autoCreateWorktree` (optional): Automatically create Git worktree (default: true)
223
+
224
+ **Returns:**
225
+ - Complete ticket analysis
226
+ - Customer information
227
+ - Issue classification (bug/feature/third-party)
228
+ - Implementation plan
229
+ - Git worktree details
230
+ - Next steps guidance
231
+
232
+ ## Workflow Examples
233
+
234
+ ### Basic Ticket Analysis
235
+ ```javascript
236
+ // Analyze a ticket to understand the issue
237
+ await mcp.callTool('freescout_analyze_ticket', {
238
+ ticket: '12345'
239
+ });
240
+ ```
241
+
242
+ ### Complete Implementation Workflow
243
+ ```javascript
244
+ // 1. Start the implementation workflow
245
+ const plan = await mcp.callTool('freescout_implement_ticket', {
246
+ ticket: 'https://support.example.com/conversation/12345',
247
+ additionalContext: 'Consider backward compatibility'
248
+ });
249
+
250
+ // 2. After implementing the fix, create a GitHub PR
251
+ await mcp.callTool('github_create_pr', {
252
+ title: 'Fix: Validation error in checkout (FreeScout #12345)',
253
+ body: `## Summary
254
+ Fixes the validation error reported in the checkout process.
255
+
256
+ ## Changes
257
+ - Fixed validation logic in checkout.js
258
+ - Added error handling for edge cases
259
+
260
+ ## Testing
261
+ - Tested with various input combinations
262
+ - All existing tests pass`,
263
+ ticketId: '12345' // Automatically adds FreeScout link to PR
264
+ });
265
+
266
+ // 3. Draft a customer reply
267
+ const reply = await mcp.callTool('freescout_draft_reply', {
268
+ ticket: '12345',
269
+ fixDescription: 'Fixed the validation error in the checkout process'
270
+ });
271
+
272
+ // 4. Add the draft as an internal note for review
273
+ await mcp.callTool('freescout_add_note', {
274
+ ticket: '12345',
275
+ note: `Draft reply for customer:\n\n${reply}`
276
+ });
277
+
278
+ // 5. Update ticket status and assignment
279
+ await mcp.callTool('freescout_update_ticket', {
280
+ ticket: '12345',
281
+ status: 'active',
282
+ assignTo: 1
283
+ });
284
+
285
+ // 6. Clean up the worktree after PR is created
286
+ await mcp.callTool('git_remove_worktree', {
287
+ ticketId: '12345'
288
+ });
289
+ ```
290
+
291
+ ### Handling Non-Bug Issues
292
+ ```javascript
293
+ // For third-party issues or feature requests
294
+ const reply = await mcp.callTool('freescout_draft_reply', {
295
+ ticket: '12345',
296
+ fixDescription: 'This is a limitation of the Elementor plugin that we cannot override.',
297
+ isExplanatory: true
298
+ });
299
+ ```
300
+
301
+ ## Architecture
302
+
303
+ ### Components
304
+
305
+ 1. **FreeScout API Client** (`freescout-api.ts`)
306
+ - Handles all API communication with FreeScout
307
+ - Manages authentication and request formatting
308
+ - Provides ticket parsing utilities
309
+
310
+ 2. **Ticket Analyzer** (`ticket-analyzer.ts`)
311
+ - Intelligent ticket content analysis
312
+ - Issue classification (bug vs feature vs configuration)
313
+ - Code snippet and error extraction
314
+ - Root cause determination
315
+
316
+ 3. **MCP Server** (`index.ts`)
317
+ - Tool registration and request handling
318
+ - Integration with Git for worktree management
319
+ - Response formatting and error handling
320
+
321
+ ### Data Flow
322
+
323
+ ```
324
+ User Request → MCP Server → FreeScout API → Ticket Analyzer
325
+ ↓ ↓
326
+ Git Operations Analysis Results
327
+ ↓ ↓
328
+ Worktree Management Customer Reply
329
+ ↓ ↓
330
+ Response → User
331
+ ```
332
+
333
+ ## Development
334
+
335
+ ### Running in Development Mode
336
+ ```bash
337
+ npm run dev
338
+ ```
339
+
340
+ ### Running Tests
341
+ ```bash
342
+ npm test
343
+ ```
344
+
345
+ ### Linting
346
+ ```bash
347
+ npm run lint
348
+ ```
349
+
350
+ ### Building for Production
351
+ ```bash
352
+ npm run build
353
+ ```
354
+
355
+ ## Configuration
356
+
357
+ ### Required Environment Variables
358
+
359
+ | Variable | Description | Example |
360
+ |----------|-------------|---------|
361
+ | `FREESCOUT_URL` | Your FreeScout instance URL | `https://support.example.com` |
362
+ | `FREESCOUT_API_KEY` | FreeScout API key | `your-api-key-here` |
363
+
364
+ ### Optional Environment Variables
365
+
366
+ | Variable | Description | Default |
367
+ |----------|-------------|---------|
368
+ | `FREESCOUT_DEFAULT_USER_ID` | Default user ID for assignments | `1` |
369
+ | `WORKING_DIRECTORY` | Base directory for Git operations | Current working directory¹ |
370
+ | `GITHUB_TOKEN` | GitHub token for PR creation | - |
371
+ | `GITHUB_REPO` | GitHub repository (owner/repo) | Auto-detected from git remote² |
372
+
373
+ ¹ **Note**: Automatically uses the current project/workspace directory. Only set this if you need to work on a different directory.
374
+
375
+ ² **Note**: The server automatically detects the GitHub repository from your git remote. Only set `GITHUB_REPO` if you need to override the auto-detection or if your project doesn't have a GitHub remote configured.
376
+
377
+ ### Advanced Configuration Example
378
+
379
+ For more control, you can specify additional environment variables:
380
+
381
+ ```json
382
+ {
383
+ "mcpServers": {
384
+ "freescout": {
385
+ "command": "npx",
386
+ "args": ["@verygoodplugins/mcp-freescout@latest"],
387
+ "env": {
388
+ "FREESCOUT_URL": "https://support.example.com",
389
+ "FREESCOUT_API_KEY": "your-api-key",
390
+ "FREESCOUT_DEFAULT_USER_ID": "2",
391
+ "WORKING_DIRECTORY": "/path/to/specific/project",
392
+ "GITHUB_TOKEN": "ghp_yourtoken",
393
+ "GITHUB_REPO": "owner/repo"
394
+ }
395
+ }
396
+ }
397
+ }
398
+ ```
399
+
400
+ ### FreeScout API Setup
401
+
402
+ 1. Log into your FreeScout instance as an administrator
403
+ 2. Navigate to Manage → API Keys
404
+ 3. Create a new API key with appropriate permissions:
405
+ - View conversations
406
+ - Update conversations
407
+ - Create threads (for notes)
408
+
409
+ ## Best Practices
410
+
411
+ ### Ticket Analysis
412
+ - Always analyze tickets before implementing fixes
413
+ - Check for third-party limitations before attempting fixes
414
+ - Verify reproducibility with team notes
415
+
416
+ ### Git Workflow
417
+ - Use worktrees for parallel development
418
+ - Clean up worktrees after PR creation
419
+ - Keep branch names descriptive
420
+
421
+ ### Customer Communication
422
+ - Generate draft replies for review
423
+ - Include fix descriptions in customer communications
424
+ - Use explanatory replies for non-bug issues
425
+
426
+ ## Troubleshooting
427
+
428
+ ### Common Issues
429
+
430
+ #### API Connection Errors
431
+ - Verify your FreeScout URL includes the protocol (https://)
432
+ - Check API key permissions in FreeScout
433
+ - Ensure your FreeScout instance has API access enabled
434
+
435
+ #### Git Worktree Errors
436
+ - Ensure Git is installed and accessible
437
+ - Verify the working directory is a Git repository (defaults to current directory)
438
+ - Check that the base branch exists
439
+ - If needed, explicitly set WORKING_DIRECTORY to your Git repository path
440
+
441
+ #### Ticket Parsing Issues
442
+ - The server accepts ticket IDs, numbers, and full URLs
443
+ - URLs are automatically parsed to extract ticket IDs
444
+ - Numeric inputs are treated as ticket IDs
445
+
446
+ ## Contributing
447
+
448
+ Contributions are welcome! Please:
449
+
450
+ 1. Fork the repository
451
+ 2. Create a feature branch
452
+ 3. Make your changes with tests
453
+ 4. Submit a pull request
454
+
455
+ ## License
456
+
457
+ GPL-3.0 License - see LICENSE file for details
458
+
459
+ ## Support
460
+
461
+ For issues, questions, or suggestions:
462
+ - [Open an issue on GitHub](https://github.com/verygoodplugins/mcp-freescout/issues)
463
+ - [Contact the maintainers](https://verygoodplugins.com/contact)
464
+ - Check the documentation
465
+
466
+ ## Roadmap
467
+
468
+ - [ ] Batch ticket operations
469
+ - [ ] Webhook support for real-time updates
470
+ - [ ] Template system for common replies
471
+ - [ ] Integration with CI/CD pipelines
472
+ - [ ] Advanced search filters
473
+ - [ ] Ticket metrics and analytics
474
+ - [ ] Multi-language support for customer replies
475
+ - [ ] Attachment handling
476
+ - [ ] Custom field support
477
+ - [ ] Automated testing integration
@@ -0,0 +1,18 @@
1
+ import type { FreeScoutConversation, FreeScoutApiResponse, FreeScoutThread } from './types.js';
2
+ export declare class FreeScoutAPI {
3
+ private baseUrl;
4
+ private apiKey;
5
+ constructor(baseUrl: string, apiKey: string);
6
+ private request;
7
+ getConversation(ticketId: string, includeThreads?: boolean): Promise<FreeScoutConversation>;
8
+ addThread(ticketId: string, type: 'note' | 'message' | 'customer', text: string, userId?: number): Promise<FreeScoutThread>;
9
+ updateConversation(ticketId: string, updates: {
10
+ status?: 'active' | 'pending' | 'closed' | 'spam';
11
+ assignTo?: number;
12
+ byUser?: number;
13
+ }): Promise<FreeScoutConversation>;
14
+ searchConversations(query: string, status?: string): Promise<FreeScoutApiResponse<FreeScoutConversation>>;
15
+ extractTicketIdFromUrl(url: string): string | null;
16
+ parseTicketInput(input: string): string;
17
+ }
18
+ //# sourceMappingURL=freescout-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"freescout-api.d.ts","sourceRoot":"","sources":["../src/freescout-api.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;YAK7B,OAAO;IA6Bf,eAAe,CACnB,QAAQ,EAAE,MAAM,EAChB,cAAc,GAAE,OAAc,GAC7B,OAAO,CAAC,qBAAqB,CAAC;IAO3B,SAAS,CACb,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,EACrC,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,eAAe,CAAC;IAiBrB,kBAAkB,CACtB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE;QACP,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;QAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GACA,OAAO,CAAC,qBAAqB,CAAC;IAQ3B,mBAAmB,CACvB,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,oBAAoB,CAAC,qBAAqB,CAAC,CAAC;IAUvD,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAQlD,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;CAoBxC"}
@@ -0,0 +1,79 @@
1
+ import fetch from 'node-fetch';
2
+ export class FreeScoutAPI {
3
+ baseUrl;
4
+ apiKey;
5
+ constructor(baseUrl, apiKey) {
6
+ this.baseUrl = baseUrl.replace(/\/$/, ''); // Remove trailing slash
7
+ this.apiKey = apiKey;
8
+ }
9
+ async request(path, method = 'GET', body) {
10
+ const url = `${this.baseUrl}/api${path}`;
11
+ const headers = {
12
+ 'X-FreeScout-API-Key': this.apiKey,
13
+ };
14
+ if (body) {
15
+ headers['Content-Type'] = 'application/json';
16
+ }
17
+ const response = await fetch(url, {
18
+ method,
19
+ headers,
20
+ body: body ? JSON.stringify(body) : undefined,
21
+ });
22
+ if (!response.ok) {
23
+ const errorText = await response.text();
24
+ throw new Error(`FreeScout API error: ${response.status} - ${errorText}`);
25
+ }
26
+ return response.json();
27
+ }
28
+ async getConversation(ticketId, includeThreads = true) {
29
+ const embed = includeThreads ? '?embed=threads' : '';
30
+ return this.request(`/conversations/${ticketId}${embed}`);
31
+ }
32
+ async addThread(ticketId, type, text, userId) {
33
+ const body = {
34
+ type,
35
+ text,
36
+ };
37
+ if (userId) {
38
+ body.user = userId;
39
+ }
40
+ return this.request(`/conversations/${ticketId}/threads`, 'POST', body);
41
+ }
42
+ async updateConversation(ticketId, updates) {
43
+ return this.request(`/conversations/${ticketId}`, 'PUT', updates);
44
+ }
45
+ async searchConversations(query, status) {
46
+ const params = new URLSearchParams();
47
+ if (query)
48
+ params.append('query', query);
49
+ if (status)
50
+ params.append('status', status);
51
+ return this.request(`/conversations?${params.toString()}`);
52
+ }
53
+ extractTicketIdFromUrl(url) {
54
+ // Match patterns like:
55
+ // https://domain.com/conversation/12345
56
+ // https://domain.com/conversations/12345
57
+ const match = url.match(/conversations?\/(\d+)/);
58
+ return match ? match[1] : null;
59
+ }
60
+ parseTicketInput(input) {
61
+ // Check if input is a URL
62
+ if (input.includes('http')) {
63
+ const ticketId = this.extractTicketIdFromUrl(input);
64
+ if (ticketId)
65
+ return ticketId;
66
+ }
67
+ // Check if input is numeric (ticket ID)
68
+ if (/^\d+$/.test(input.trim())) {
69
+ return input.trim();
70
+ }
71
+ // Try to extract ticket ID from text like "ticket #12345"
72
+ const match = input.match(/#?(\d+)/);
73
+ if (match) {
74
+ return match[1];
75
+ }
76
+ throw new Error(`Could not extract ticket ID from input: ${input}`);
77
+ }
78
+ }
79
+ //# sourceMappingURL=freescout-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"freescout-api.js","sourceRoot":"","sources":["../src/freescout-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}