nexup-mcp-server 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 +41 -0
- package/dist/client/auth.d.ts +6 -0
- package/dist/client/auth.d.ts.map +1 -0
- package/dist/client/auth.js +14 -0
- package/dist/client/auth.js.map +1 -0
- package/dist/client/http-client.d.ts +33 -0
- package/dist/client/http-client.d.ts.map +1 -0
- package/dist/client/http-client.js +149 -0
- package/dist/client/http-client.js.map +1 -0
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +19 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +108 -0
- package/dist/index.js.map +1 -0
- package/dist/resources/crm-resources.d.ts +8 -0
- package/dist/resources/crm-resources.d.ts.map +1 -0
- package/dist/resources/crm-resources.js +501 -0
- package/dist/resources/crm-resources.js.map +1 -0
- package/dist/resources/index.d.ts +2 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +2 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/tools/customers.d.ts +221 -0
- package/dist/tools/customers.d.ts.map +1 -0
- package/dist/tools/customers.js +207 -0
- package/dist/tools/customers.js.map +1 -0
- package/dist/tools/index.d.ts +883 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +38 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/notifications.d.ts +16 -0
- package/dist/tools/notifications.d.ts.map +1 -0
- package/dist/tools/notifications.js +47 -0
- package/dist/tools/notifications.js.map +1 -0
- package/dist/tools/prospects.d.ts +478 -0
- package/dist/tools/prospects.d.ts.map +1 -0
- package/dist/tools/prospects.js +336 -0
- package/dist/tools/prospects.js.map +1 -0
- package/dist/tools/tickets.d.ts +83 -0
- package/dist/tools/tickets.d.ts.map +1 -0
- package/dist/tools/tickets.js +171 -0
- package/dist/tools/tickets.js.map +1 -0
- package/dist/tools/transcripts.d.ts +97 -0
- package/dist/tools/transcripts.d.ts.map +1 -0
- package/dist/tools/transcripts.js +188 -0
- package/dist/tools/transcripts.js.map +1 -0
- package/dist/utils/errors.d.ts +9 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +28 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/formatters.d.ts +5 -0
- package/dist/utils/formatters.d.ts.map +1 -0
- package/dist/utils/formatters.js +21 -0
- package/dist/utils/formatters.js.map +1 -0
- package/dist/utils/logger.d.ts +4 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +43 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/validation/schemas.d.ts +424 -0
- package/dist/validation/schemas.d.ts.map +1 -0
- package/dist/validation/schemas.js +114 -0
- package/dist/validation/schemas.js.map +1 -0
- package/package.json +34 -0
package/README.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# MCP Server for NexUp CRM
|
|
2
|
+
|
|
3
|
+
Model Context Protocol server that enables Claude to operate as a first-class CRM user.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
1. Install dependencies:
|
|
8
|
+
```bash
|
|
9
|
+
cd mcp-server
|
|
10
|
+
npm install
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
2. Build the server:
|
|
14
|
+
```bash
|
|
15
|
+
npm run build
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
3. Configure Claude Desktop (see `/docs/MCP_SETUP.md` for details)
|
|
19
|
+
|
|
20
|
+
## Development
|
|
21
|
+
|
|
22
|
+
Run in development mode with auto-reload:
|
|
23
|
+
```bash
|
|
24
|
+
npm run dev
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Environment Variables
|
|
28
|
+
|
|
29
|
+
Required environment variables (set in Claude Desktop config):
|
|
30
|
+
- `MCP_API_URL` - Next.js API URL (e.g., http://localhost:3000 or https://nexup-crm.vercel.app)
|
|
31
|
+
- `MCP_API_KEY` - Your MCP API key from Settings → MCP Setup
|
|
32
|
+
- `MCP_LOG_LEVEL` - (Optional) Logging level (debug|info|warn|error, default: info)
|
|
33
|
+
|
|
34
|
+
## Architecture
|
|
35
|
+
|
|
36
|
+
- **stdio transport** - Communicates with Claude Desktop via stdin/stdout
|
|
37
|
+
- **HTTP client** - Calls Next.js API with Clerk authentication
|
|
38
|
+
- **Per-user isolation** - Each user runs their own MCP server instance
|
|
39
|
+
- **Full audit trail** - All operations logged with user attribution
|
|
40
|
+
|
|
41
|
+
See `/docs/MCP_TOOLS_REFERENCE.md` for complete tool documentation.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/client/auth.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAQnC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { config } from '../config.js';
|
|
2
|
+
/**
|
|
3
|
+
* Auth helper to verify Clerk session token is valid
|
|
4
|
+
* This is a simple check - actual auth is handled by the API
|
|
5
|
+
*/
|
|
6
|
+
export function validateAuth() {
|
|
7
|
+
if (!config.clerkSessionToken) {
|
|
8
|
+
throw new Error('Clerk session token is required');
|
|
9
|
+
}
|
|
10
|
+
if (!config.userEmail) {
|
|
11
|
+
throw new Error('User email is required for audit logging');
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/client/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC;;;GAGG;AACH,MAAM,UAAU,YAAY;IAC1B,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare class HttpClient {
|
|
2
|
+
private client;
|
|
3
|
+
private retryAttempts;
|
|
4
|
+
private retryDelay;
|
|
5
|
+
constructor();
|
|
6
|
+
/**
|
|
7
|
+
* Make a GET request with retry logic
|
|
8
|
+
*/
|
|
9
|
+
get<T = any>(endpoint: string, params?: Record<string, any>): Promise<T>;
|
|
10
|
+
/**
|
|
11
|
+
* Make a POST request with retry logic
|
|
12
|
+
*/
|
|
13
|
+
post<T = any>(endpoint: string, data: any, toolName?: string): Promise<T>;
|
|
14
|
+
/**
|
|
15
|
+
* Make a PATCH request with retry logic
|
|
16
|
+
*/
|
|
17
|
+
patch<T = any>(endpoint: string, data: any, toolName?: string): Promise<T>;
|
|
18
|
+
/**
|
|
19
|
+
* Make a DELETE request with retry logic
|
|
20
|
+
*/
|
|
21
|
+
delete<T = any>(endpoint: string, toolName?: string): Promise<T>;
|
|
22
|
+
/**
|
|
23
|
+
* Request with exponential backoff retry logic
|
|
24
|
+
*/
|
|
25
|
+
private requestWithRetry;
|
|
26
|
+
/**
|
|
27
|
+
* Handle and format errors
|
|
28
|
+
*/
|
|
29
|
+
private handleError;
|
|
30
|
+
private sleep;
|
|
31
|
+
}
|
|
32
|
+
export declare const httpClient: HttpClient;
|
|
33
|
+
//# sourceMappingURL=http-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../src/client/http-client.ts"],"names":[],"mappings":"AAOA,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,UAAU,CAAQ;;IAe1B;;OAEG;IACG,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAI9E;;OAEG;IACG,IAAI,CAAC,CAAC,GAAG,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAQ/E;;OAEG;IACG,KAAK,CAAC,CAAC,GAAG,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAQhF;;OAEG;IACG,MAAM,CAAC,CAAC,GAAG,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAQtE;;OAEG;YACW,gBAAgB;IAoD9B;;OAEG;IACH,OAAO,CAAC,WAAW;IAkFnB,OAAO,CAAC,KAAK;CAGd;AAGD,eAAO,MAAM,UAAU,YAAmB,CAAC"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { config } from '../config.js';
|
|
3
|
+
import { McpError } from '../utils/errors.js';
|
|
4
|
+
import { logger } from '../utils/logger.js';
|
|
5
|
+
const MCP_VERSION = '1.0.0';
|
|
6
|
+
export class HttpClient {
|
|
7
|
+
client;
|
|
8
|
+
retryAttempts = 3;
|
|
9
|
+
retryDelay = 1000; // ms
|
|
10
|
+
constructor() {
|
|
11
|
+
this.client = axios.create({
|
|
12
|
+
baseURL: config.apiUrl,
|
|
13
|
+
headers: {
|
|
14
|
+
'Content-Type': 'application/json',
|
|
15
|
+
'Authorization': `Bearer ${config.apiKey}`,
|
|
16
|
+
'X-MCP-Client': 'true',
|
|
17
|
+
'X-MCP-Version': MCP_VERSION,
|
|
18
|
+
},
|
|
19
|
+
timeout: 30000, // 30 seconds
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Make a GET request with retry logic
|
|
24
|
+
*/
|
|
25
|
+
async get(endpoint, params) {
|
|
26
|
+
return this.requestWithRetry('GET', endpoint, undefined, params);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Make a POST request with retry logic
|
|
30
|
+
*/
|
|
31
|
+
async post(endpoint, data, toolName) {
|
|
32
|
+
const headers = {};
|
|
33
|
+
if (toolName) {
|
|
34
|
+
headers['X-MCP-Tool'] = toolName;
|
|
35
|
+
}
|
|
36
|
+
return this.requestWithRetry('POST', endpoint, data, undefined, headers);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Make a PATCH request with retry logic
|
|
40
|
+
*/
|
|
41
|
+
async patch(endpoint, data, toolName) {
|
|
42
|
+
const headers = {};
|
|
43
|
+
if (toolName) {
|
|
44
|
+
headers['X-MCP-Tool'] = toolName;
|
|
45
|
+
}
|
|
46
|
+
return this.requestWithRetry('PATCH', endpoint, data, undefined, headers);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Make a DELETE request with retry logic
|
|
50
|
+
*/
|
|
51
|
+
async delete(endpoint, toolName) {
|
|
52
|
+
const headers = {};
|
|
53
|
+
if (toolName) {
|
|
54
|
+
headers['X-MCP-Tool'] = toolName;
|
|
55
|
+
}
|
|
56
|
+
return this.requestWithRetry('DELETE', endpoint, undefined, undefined, headers);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Request with exponential backoff retry logic
|
|
60
|
+
*/
|
|
61
|
+
async requestWithRetry(method, endpoint, data, params, additionalHeaders) {
|
|
62
|
+
let lastError;
|
|
63
|
+
for (let attempt = 1; attempt <= this.retryAttempts; attempt++) {
|
|
64
|
+
try {
|
|
65
|
+
const response = await this.client.request({
|
|
66
|
+
method,
|
|
67
|
+
url: endpoint,
|
|
68
|
+
data,
|
|
69
|
+
params,
|
|
70
|
+
headers: additionalHeaders,
|
|
71
|
+
});
|
|
72
|
+
return response.data;
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
lastError = error;
|
|
76
|
+
if (axios.isAxiosError(error)) {
|
|
77
|
+
const axiosError = error;
|
|
78
|
+
// Don't retry on client errors (4xx) except for 429 (rate limit)
|
|
79
|
+
if (axiosError.response?.status && axiosError.response.status < 500 && axiosError.response.status !== 429) {
|
|
80
|
+
throw this.handleError(axiosError);
|
|
81
|
+
}
|
|
82
|
+
// Log retry attempt
|
|
83
|
+
if (attempt < this.retryAttempts) {
|
|
84
|
+
const delay = this.retryDelay * Math.pow(2, attempt - 1);
|
|
85
|
+
logger.warn(`Request failed, retrying in ${delay}ms (attempt ${attempt}/${this.retryAttempts})`, {
|
|
86
|
+
endpoint,
|
|
87
|
+
method,
|
|
88
|
+
error: axiosError.message,
|
|
89
|
+
});
|
|
90
|
+
await this.sleep(delay);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
// Non-Axios error, don't retry
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// All retries exhausted
|
|
100
|
+
throw this.handleError(lastError);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Handle and format errors
|
|
104
|
+
*/
|
|
105
|
+
handleError(error) {
|
|
106
|
+
if (axios.isAxiosError(error)) {
|
|
107
|
+
const status = error.response?.status;
|
|
108
|
+
const data = error.response?.data;
|
|
109
|
+
// Auth errors
|
|
110
|
+
if (status === 401) {
|
|
111
|
+
return new McpError('Authentication failed. Your MCP API key may be invalid or revoked. Please check your API key in Settings → MCP Setup.', 'AUTH_ERROR', 401);
|
|
112
|
+
}
|
|
113
|
+
if (status === 403) {
|
|
114
|
+
return new McpError(data?.error || 'You do not have permission to perform this action.', 'PERMISSION_DENIED', 403);
|
|
115
|
+
}
|
|
116
|
+
// Validation errors
|
|
117
|
+
if (status === 400) {
|
|
118
|
+
return new McpError(data?.error || 'Invalid request data.', 'VALIDATION_ERROR', 400, data);
|
|
119
|
+
}
|
|
120
|
+
// Not found
|
|
121
|
+
if (status === 404) {
|
|
122
|
+
return new McpError(data?.error || 'Resource not found.', 'NOT_FOUND', 404);
|
|
123
|
+
}
|
|
124
|
+
// Conflict (duplicate)
|
|
125
|
+
if (status === 409) {
|
|
126
|
+
return new McpError(data?.error || 'Resource already exists.', 'CONFLICT', 409);
|
|
127
|
+
}
|
|
128
|
+
// Server errors
|
|
129
|
+
if (status && status >= 500) {
|
|
130
|
+
return new McpError('The CRM API is experiencing issues. Please try again later.', 'SERVER_ERROR', status);
|
|
131
|
+
}
|
|
132
|
+
// Network/timeout errors
|
|
133
|
+
if (error.code === 'ECONNREFUSED') {
|
|
134
|
+
return new McpError(`Cannot connect to CRM API at ${config.apiUrl}. Make sure the Next.js dev server is running.`, 'CONNECTION_ERROR');
|
|
135
|
+
}
|
|
136
|
+
if (error.code === 'ETIMEDOUT' || error.code === 'ECONNABORTED') {
|
|
137
|
+
return new McpError('Request timed out. The API is taking too long to respond.', 'TIMEOUT_ERROR');
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// Generic error
|
|
141
|
+
return new McpError(error.message || 'An unexpected error occurred.', 'UNKNOWN_ERROR');
|
|
142
|
+
}
|
|
143
|
+
sleep(ms) {
|
|
144
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Singleton instance
|
|
148
|
+
export const httpClient = new HttpClient();
|
|
149
|
+
//# sourceMappingURL=http-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-client.js","sourceRoot":"","sources":["../../src/client/http-client.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CAC/C;AAUD,eAAO,MAAM,MAAM,EAAE,MAIpB,CAAC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import dotenv from 'dotenv';
|
|
2
|
+
dotenv.config();
|
|
3
|
+
function getRequiredEnv(key) {
|
|
4
|
+
const value = process.env[key];
|
|
5
|
+
if (!value) {
|
|
6
|
+
throw new Error(`Missing required environment variable: ${key}`);
|
|
7
|
+
}
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
export const config = {
|
|
11
|
+
apiUrl: getRequiredEnv('MCP_API_URL'),
|
|
12
|
+
apiKey: getRequiredEnv('MCP_API_KEY'),
|
|
13
|
+
logLevel: process.env.MCP_LOG_LEVEL || 'info',
|
|
14
|
+
};
|
|
15
|
+
// Log configuration on startup for debugging (must use stderr, stdout is for MCP JSON-RPC)
|
|
16
|
+
console.error('[MCP Server] Configuration loaded:');
|
|
17
|
+
console.error('[MCP Server] API URL:', config.apiUrl);
|
|
18
|
+
console.error('[MCP Server] Log Level:', config.logLevel);
|
|
19
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,MAAM,CAAC,MAAM,EAAE,CAAC;AAQhB,SAAS,cAAc,CAAC,GAAW;IACjC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,0CAA0C,GAAG,EAAE,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAW;IAC5B,MAAM,EAAE,cAAc,CAAC,aAAa,CAAC;IACrC,MAAM,EAAE,cAAc,CAAC,aAAa,CAAC;IACrC,QAAQ,EAAG,OAAO,CAAC,GAAG,CAAC,aAAoC,IAAI,MAAM;CACtE,CAAC;AAEF,2FAA2F;AAC3F,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;AACpD,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;AACtD,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
+
import { config } from './config.js';
|
|
6
|
+
import { logger } from './utils/logger.js';
|
|
7
|
+
import { formatError, isAuthError } from './utils/errors.js';
|
|
8
|
+
import { allTools, handleToolCall } from './tools/index.js';
|
|
9
|
+
import { allResources, handleResourceRead } from './resources/index.js';
|
|
10
|
+
// Log startup configuration
|
|
11
|
+
logger.info('MCP Server starting', {
|
|
12
|
+
apiUrl: config.apiUrl,
|
|
13
|
+
apiKeyPrefix: config.apiKey.substring(0, 7) + '...',
|
|
14
|
+
});
|
|
15
|
+
// Create MCP server
|
|
16
|
+
const server = new Server({
|
|
17
|
+
name: 'nexup-crm',
|
|
18
|
+
version: '1.0.0',
|
|
19
|
+
}, {
|
|
20
|
+
capabilities: {
|
|
21
|
+
tools: {},
|
|
22
|
+
resources: {},
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
// List available tools
|
|
26
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
27
|
+
return {
|
|
28
|
+
tools: allTools,
|
|
29
|
+
};
|
|
30
|
+
});
|
|
31
|
+
// Handle tool calls
|
|
32
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
33
|
+
const { name, arguments: params } = request.params;
|
|
34
|
+
logger.info('Tool call received', { tool: name, params });
|
|
35
|
+
try {
|
|
36
|
+
const result = await handleToolCall(name, params || {});
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
logger.error('Tool call failed', {
|
|
41
|
+
tool: name,
|
|
42
|
+
error: formatError(error),
|
|
43
|
+
});
|
|
44
|
+
// Provide user-friendly error messages
|
|
45
|
+
if (isAuthError(error)) {
|
|
46
|
+
return {
|
|
47
|
+
content: [
|
|
48
|
+
{
|
|
49
|
+
type: 'text',
|
|
50
|
+
text: `❌ Authentication Error: ${formatError(error)}\n\nPlease check your MCP API key in Settings → MCP Setup.`,
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
isError: true,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
content: [
|
|
58
|
+
{
|
|
59
|
+
type: 'text',
|
|
60
|
+
text: `❌ Error: ${formatError(error)}`,
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
isError: true,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
// List available resources
|
|
68
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
69
|
+
return {
|
|
70
|
+
resources: allResources,
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
// Handle resource reads
|
|
74
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
75
|
+
const { uri } = request.params;
|
|
76
|
+
logger.info('Resource read received', { uri });
|
|
77
|
+
try {
|
|
78
|
+
const result = await handleResourceRead(uri);
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
logger.error('Resource read failed', {
|
|
83
|
+
uri,
|
|
84
|
+
error: formatError(error),
|
|
85
|
+
});
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
// Start server
|
|
90
|
+
async function main() {
|
|
91
|
+
const transport = new StdioServerTransport();
|
|
92
|
+
await server.connect(transport);
|
|
93
|
+
logger.info('MCP Server connected via stdio', {
|
|
94
|
+
tools: allTools.length,
|
|
95
|
+
resources: allResources.length,
|
|
96
|
+
});
|
|
97
|
+
// Handle graceful shutdown
|
|
98
|
+
process.on('SIGINT', async () => {
|
|
99
|
+
logger.info('Shutting down MCP server');
|
|
100
|
+
await server.close();
|
|
101
|
+
process.exit(0);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
main().catch((error) => {
|
|
105
|
+
logger.error('Fatal error', { error: formatError(error) });
|
|
106
|
+
process.exit(1);
|
|
107
|
+
});
|
|
108
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crm-resources.d.ts","sourceRoot":"","sources":["../../src/resources/crm-resources.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,YAAY;;;;;GAyExB,CAAC;AAEF,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CA+DlE"}
|