@carbonvoice/cv-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.
Files changed (152) hide show
  1. package/dist/bootstrap.js +3 -0
  2. package/dist/carbon-voice.js +20 -0
  3. package/dist/config/env.js +28 -0
  4. package/dist/config/index.js +17 -0
  5. package/dist/constants.js +9 -0
  6. package/dist/generated/carbon-voice-api/CarbonVoiceSimplifiedAPI.zod.js +1416 -0
  7. package/dist/generated/carbon-voice-api.js +377 -0
  8. package/dist/generated/index.js +17 -0
  9. package/dist/generated/models/AIPrompt.js +2 -0
  10. package/dist/generated/models/AIPromptControllerGetPromptsOwnerType.js +87 -0
  11. package/dist/generated/models/AIPromptControllerGetPromptsParams.js +2 -0
  12. package/dist/generated/models/AIPromptOwnerType.js +87 -0
  13. package/dist/generated/models/AIPromptResponseFormat.js +86 -0
  14. package/dist/generated/models/AIPromptWithMessagesResponse.js +2 -0
  15. package/dist/generated/models/AIPromptWithMessagesResult.js +2 -0
  16. package/dist/generated/models/AIResponse.js +2 -0
  17. package/dist/generated/models/AIResponseControllerGetAllResponsesDirection.js +86 -0
  18. package/dist/generated/models/AIResponseControllerGetAllResponsesParams.js +2 -0
  19. package/dist/generated/models/AIShareLinkResponse.js +2 -0
  20. package/dist/generated/models/AddAttachmentsResponse.js +2 -0
  21. package/dist/generated/models/AddLinkAttachmentPayload.js +80 -0
  22. package/dist/generated/models/AddMessageToFolderPayload.js +80 -0
  23. package/dist/generated/models/AllConversationsResponse.js +2 -0
  24. package/dist/generated/models/App.js +2 -0
  25. package/dist/generated/models/AppWebhooksAuthenticationHeader.js +80 -0
  26. package/dist/generated/models/AppWebhooksUrlMode.js +86 -0
  27. package/dist/generated/models/AsyncConversationStats.js +2 -0
  28. package/dist/generated/models/Attachment.js +2 -0
  29. package/dist/generated/models/AttachmentLocation.js +80 -0
  30. package/dist/generated/models/AttachmentType.js +87 -0
  31. package/dist/generated/models/AudioModelV2.js +80 -0
  32. package/dist/generated/models/Conversation.js +2 -0
  33. package/dist/generated/models/ConversationResponse.js +2 -0
  34. package/dist/generated/models/ConversationResponseType.js +88 -0
  35. package/dist/generated/models/ConversationType.js +88 -0
  36. package/dist/generated/models/ConversationVisibility.js +87 -0
  37. package/dist/generated/models/CreateAIPrompt.js +2 -0
  38. package/dist/generated/models/CreateAIPromptOwnerType.js +87 -0
  39. package/dist/generated/models/CreateAIPromptResponseFormat.js +86 -0
  40. package/dist/generated/models/CreateAIResponse.js +80 -0
  41. package/dist/generated/models/CreateConversationMessage.js +2 -0
  42. package/dist/generated/models/CreateConversationMessageFromMessageType.js +87 -0
  43. package/dist/generated/models/CreateFolderPayload.js +2 -0
  44. package/dist/generated/models/CreateFolderPayloadType.js +86 -0
  45. package/dist/generated/models/CreateShareLinkAIResponse.js +80 -0
  46. package/dist/generated/models/CreateVoicememoMessage.js +80 -0
  47. package/dist/generated/models/Folder.js +2 -0
  48. package/dist/generated/models/FolderType.js +86 -0
  49. package/dist/generated/models/FolderWithMessages.js +2 -0
  50. package/dist/generated/models/GetAllRootFoldersParams.js +2 -0
  51. package/dist/generated/models/GetAllRootFoldersSortBy.js +87 -0
  52. package/dist/generated/models/GetAllRootFoldersSortDirection.js +86 -0
  53. package/dist/generated/models/GetAllRootFoldersType.js +86 -0
  54. package/dist/generated/models/GetByIdDirection.js +85 -0
  55. package/dist/generated/models/GetByIdParams.js +2 -0
  56. package/dist/generated/models/GetCountsGroupedByWorkspaceParams.js +2 -0
  57. package/dist/generated/models/GetCountsGroupedByWorkspaceType.js +86 -0
  58. package/dist/generated/models/GetFolderByIdDirection.js +86 -0
  59. package/dist/generated/models/GetFolderByIdParams.js +2 -0
  60. package/dist/generated/models/GetMessageByIdParams.js +80 -0
  61. package/dist/generated/models/GetMessageResponse.js +2 -0
  62. package/dist/generated/models/GetTenRecentAIPromptResponse.js +2 -0
  63. package/dist/generated/models/GetTenRecentMessagesResponse.js +2 -0
  64. package/dist/generated/models/GetTenRecentMessagesResponseParams.js +80 -0
  65. package/dist/generated/models/Label.js +2 -0
  66. package/dist/generated/models/LabelBehavior.js +87 -0
  67. package/dist/generated/models/LabelType.js +88 -0
  68. package/dist/generated/models/Language.js +2 -0
  69. package/dist/generated/models/ListCountFoldersGroupedByWorkspace.js +2 -0
  70. package/dist/generated/models/ListFoldersResponse.js +2 -0
  71. package/dist/generated/models/ListFoldersResponseSortBy.js +87 -0
  72. package/dist/generated/models/ListFoldersResponseSortDirection.js +86 -0
  73. package/dist/generated/models/ListFoldersResponseType.js +86 -0
  74. package/dist/generated/models/ListMessagesFilter.js +2 -0
  75. package/dist/generated/models/ListMessagesFilterType.js +89 -0
  76. package/dist/generated/models/ListMessagesParams.js +2 -0
  77. package/dist/generated/models/ListMessagesResponse.js +2 -0
  78. package/dist/generated/models/ListMessagesResponseSortDirection.js +86 -0
  79. package/dist/generated/models/ListMessagesSortDirection.js +86 -0
  80. package/dist/generated/models/ListMessagesType.js +89 -0
  81. package/dist/generated/models/Message.js +2 -0
  82. package/dist/generated/models/MessageStatus.js +95 -0
  83. package/dist/generated/models/MessageType.js +89 -0
  84. package/dist/generated/models/MessageV2.js +2 -0
  85. package/dist/generated/models/MessageV2AudioDelivery.js +86 -0
  86. package/dist/generated/models/MessageV2Status.js +95 -0
  87. package/dist/generated/models/MessageV2Type.js +89 -0
  88. package/dist/generated/models/MessageV2UsersCaughtUp.js +87 -0
  89. package/dist/generated/models/MessageV2UtmData.js +2 -0
  90. package/dist/generated/models/MoveFolderPayload.js +80 -0
  91. package/dist/generated/models/PromptResponse.js +2 -0
  92. package/dist/generated/models/ReactionSummary.js +2 -0
  93. package/dist/generated/models/ReactionSummaryReactionCounts.js +80 -0
  94. package/dist/generated/models/ResponseByLanguage.js +2 -0
  95. package/dist/generated/models/ResponseByLanguageJson.js +80 -0
  96. package/dist/generated/models/SearchUserParams.js +80 -0
  97. package/dist/generated/models/SearchUsersBody.js +80 -0
  98. package/dist/generated/models/SendDirectMessage.js +2 -0
  99. package/dist/generated/models/SendDirectMessageFromMessageType.js +87 -0
  100. package/dist/generated/models/SimplifiedAIPrompt.js +80 -0
  101. package/dist/generated/models/Stats.js +80 -0
  102. package/dist/generated/models/SubFolder.js +2 -0
  103. package/dist/generated/models/SubFolderType.js +86 -0
  104. package/dist/generated/models/SubscribeUserPayload.js +2 -0
  105. package/dist/generated/models/SubscribeUserPayloadSubscriptionsItem.js +116 -0
  106. package/dist/generated/models/SubscribedUser.js +2 -0
  107. package/dist/generated/models/SubscribedUserSubscriptionsItem.js +116 -0
  108. package/dist/generated/models/SubscriptionAction.js +2 -0
  109. package/dist/generated/models/SubscriptionActionActionId.js +85 -0
  110. package/dist/generated/models/SubscriptionActionEntityType.js +85 -0
  111. package/dist/generated/models/SubscriptionFilter.js +2 -0
  112. package/dist/generated/models/SubscriptionFilterOperator.js +87 -0
  113. package/dist/generated/models/SubscriptionFilterValue.js +80 -0
  114. package/dist/generated/models/TextModel.js +2 -0
  115. package/dist/generated/models/TextModelType.js +89 -0
  116. package/dist/generated/models/TimedText.js +80 -0
  117. package/dist/generated/models/ToRecipient.js +80 -0
  118. package/dist/generated/models/UpdateFolderNamePayload.js +80 -0
  119. package/dist/generated/models/User.js +80 -0
  120. package/dist/generated/models/UserReaction.js +80 -0
  121. package/dist/generated/models/UserStats.js +80 -0
  122. package/dist/generated/models/UsersNotAllowedReceiveNotifications.js +80 -0
  123. package/dist/generated/models/UsersNotAllowedReceiveNotificationsV2.js +80 -0
  124. package/dist/generated/models/UtmData.js +80 -0
  125. package/dist/generated/models/Voice.js +2 -0
  126. package/dist/generated/models/VoiceGender.js +86 -0
  127. package/dist/generated/models/VoiceQuality.js +87 -0
  128. package/dist/generated/models/VoiceType.js +88 -0
  129. package/dist/generated/models/WorkspaceBasicInfo.js +80 -0
  130. package/dist/generated/models/index.js +215 -0
  131. package/dist/index-v1.js +80 -0
  132. package/dist/interfaces/folder.interface.js +2 -0
  133. package/dist/interfaces/get-by-id.interface.js +2 -0
  134. package/dist/interfaces/index.js +20 -0
  135. package/dist/interfaces/mcp-tool-response.interface.js +2 -0
  136. package/dist/interfaces/message.interface.js +2 -0
  137. package/dist/schemas/index.js +17 -0
  138. package/dist/schemas/message.js +10 -0
  139. package/dist/server-delete.js +624 -0
  140. package/dist/server-test.js +93 -0
  141. package/dist/server.js +365 -0
  142. package/dist/sse.js +134 -0
  143. package/dist/sse.v2.js +29 -0
  144. package/dist/stdio.js +39 -0
  145. package/dist/utils/axios-instance.js +234 -0
  146. package/dist/utils/errors.js +22 -0
  147. package/dist/utils/format-to-mcp-tool-response.js +40 -0
  148. package/dist/utils/index.js +19 -0
  149. package/dist/utils/logger.js +111 -0
  150. package/dist/utils/zod-schema-transformer.js +66 -0
  151. package/dist/utils/zod-transformer.js +24 -0
  152. package/package.json +66 -0
@@ -0,0 +1,234 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.customAxios = void 0;
7
+ exports.mutator = mutator;
8
+ const axios_1 = __importDefault(require("axios"));
9
+ const logger_1 = require("./logger");
10
+ const config_1 = require("../config");
11
+ // Create the axios instance
12
+ const getAxiosInstance = () => {
13
+ const baseUrl = config_1.env.CARBON_VOICE_BASE_URL || 'https://api.carbonvoice.app';
14
+ if (!config_1.env.CARBON_VOICE_API_KEY) {
15
+ throw {
16
+ statusCode: 0,
17
+ body: {
18
+ error: {
19
+ code: 'CONFIGURATION_ERROR',
20
+ message: 'CARBON_VOICE_API_KEY is not set',
21
+ details: { api_key: config_1.env.CARBON_VOICE_API_KEY },
22
+ },
23
+ },
24
+ };
25
+ }
26
+ const instance = axios_1.default.create({
27
+ baseURL: baseUrl,
28
+ headers: {
29
+ 'Content-Type': 'application/json',
30
+ 'x-api-key': config_1.env.CARBON_VOICE_API_KEY,
31
+ },
32
+ });
33
+ // Add request interceptor for logging
34
+ instance.interceptors.request.use((config) => {
35
+ logger_1.logger.debug('Making API request', {
36
+ url: config.url,
37
+ method: config.method,
38
+ params: config.params,
39
+ data: config.data,
40
+ headers: { ...config.headers, 'x-api-key': '[REDACTED]' },
41
+ });
42
+ return config;
43
+ }, (error) => {
44
+ var _a, _b;
45
+ logger_1.logger.error('Request setup error', {
46
+ url: (_a = error.config) === null || _a === void 0 ? void 0 : _a.url,
47
+ method: (_b = error.config) === null || _b === void 0 ? void 0 : _b.method,
48
+ message: error.message,
49
+ });
50
+ return Promise.reject(error);
51
+ });
52
+ // Add response interceptor for logging
53
+ instance.interceptors.response.use((response) => {
54
+ logger_1.logger.debug('API response received', {
55
+ url: response.config.url,
56
+ method: response.config.method,
57
+ status: response.status,
58
+ statusText: response.statusText,
59
+ });
60
+ return response;
61
+ }, (error) => {
62
+ var _a, _b, _c, _d, _e, _f;
63
+ if (axios_1.default.isAxiosError(error)) {
64
+ const axiosError = handleAxiosError(error);
65
+ // Log the error with all relevant details
66
+ logger_1.logger.error('API request failed', {
67
+ error: axiosError,
68
+ url: (_a = error.config) === null || _a === void 0 ? void 0 : _a.url,
69
+ method: (_b = error.config) === null || _b === void 0 ? void 0 : _b.method,
70
+ status: (_c = error.response) === null || _c === void 0 ? void 0 : _c.status,
71
+ statusText: (_d = error.response) === null || _d === void 0 ? void 0 : _d.statusText,
72
+ requestData: (_e = error.config) === null || _e === void 0 ? void 0 : _e.data,
73
+ responseData: (_f = error.response) === null || _f === void 0 ? void 0 : _f.data,
74
+ });
75
+ }
76
+ else {
77
+ logger_1.logger.error('Unexpected error in API request', error);
78
+ }
79
+ return Promise.reject(error);
80
+ });
81
+ return instance;
82
+ };
83
+ // Error handling function
84
+ function handleAxiosError(error) {
85
+ if (error.response) {
86
+ const statusCode = error.response.status;
87
+ const errorData = error.response.data;
88
+ // Handle different HTTP status codes
89
+ switch (statusCode) {
90
+ case 400:
91
+ return {
92
+ statusCode,
93
+ body: {
94
+ error: {
95
+ code: 'BAD_REQUEST',
96
+ message: (errorData === null || errorData === void 0 ? void 0 : errorData.message) || 'Invalid request parameters',
97
+ details: (errorData === null || errorData === void 0 ? void 0 : errorData.details) || errorData,
98
+ },
99
+ },
100
+ };
101
+ case 401:
102
+ return {
103
+ statusCode,
104
+ body: {
105
+ error: {
106
+ code: 'UNAUTHORIZED',
107
+ message: 'Authentication required',
108
+ details: { reason: 'Invalid or missing API key' },
109
+ },
110
+ },
111
+ };
112
+ case 403:
113
+ return {
114
+ statusCode,
115
+ body: {
116
+ error: {
117
+ code: 'FORBIDDEN',
118
+ message: 'Access denied',
119
+ details: { reason: 'Insufficient permissions' },
120
+ },
121
+ },
122
+ };
123
+ case 404:
124
+ return {
125
+ statusCode,
126
+ body: {
127
+ error: {
128
+ code: 'NOT_FOUND',
129
+ message: (errorData === null || errorData === void 0 ? void 0 : errorData.message) || 'Resource not found',
130
+ details: errorData === null || errorData === void 0 ? void 0 : errorData.details,
131
+ },
132
+ },
133
+ };
134
+ case 429:
135
+ return {
136
+ statusCode,
137
+ body: {
138
+ error: {
139
+ code: 'RATE_LIMITED',
140
+ message: 'Too many requests',
141
+ details: { retryAfter: error.response.headers['retry-after'] },
142
+ },
143
+ },
144
+ };
145
+ case 500:
146
+ case 502:
147
+ case 503:
148
+ case 504:
149
+ return {
150
+ statusCode,
151
+ body: {
152
+ error: {
153
+ code: 'SERVER_ERROR',
154
+ message: 'Internal server error',
155
+ details: { originalError: errorData },
156
+ },
157
+ },
158
+ };
159
+ default:
160
+ return {
161
+ statusCode,
162
+ body: {
163
+ error: {
164
+ code: 'UNKNOWN_ERROR',
165
+ message: (errorData === null || errorData === void 0 ? void 0 : errorData.message) || 'An unexpected error occurred',
166
+ details: errorData,
167
+ },
168
+ },
169
+ };
170
+ }
171
+ }
172
+ else if (error.request) {
173
+ return {
174
+ statusCode: 0,
175
+ body: {
176
+ error: {
177
+ code: 'NETWORK_ERROR',
178
+ message: 'No response received from server',
179
+ details: {
180
+ request: error.request,
181
+ message: error.message,
182
+ },
183
+ },
184
+ },
185
+ };
186
+ }
187
+ else {
188
+ return {
189
+ statusCode: 0,
190
+ body: {
191
+ error: {
192
+ code: 'REQUEST_ERROR',
193
+ message: error.message || 'Error setting up the request',
194
+ details: { originalError: error },
195
+ },
196
+ },
197
+ };
198
+ }
199
+ }
200
+ // Create the singleton instance
201
+ const axiosInstance = getAxiosInstance();
202
+ // Define the mutator function that Orval expects
203
+ async function mutator({ url, method, params, data, headers, }) {
204
+ try {
205
+ const response = await axiosInstance({
206
+ url,
207
+ method,
208
+ params,
209
+ data,
210
+ headers,
211
+ });
212
+ return response.data;
213
+ }
214
+ catch (error) {
215
+ if (axios_1.default.isAxiosError(error)) {
216
+ const axiosError = handleAxiosError(error);
217
+ throw axiosError;
218
+ }
219
+ // Handle non-axios errors
220
+ const errorMessage = error instanceof Error ? error.message : 'An unexpected error occurred';
221
+ throw {
222
+ statusCode: 0,
223
+ body: {
224
+ error: {
225
+ code: 'UNKNOWN_ERROR',
226
+ message: errorMessage,
227
+ details: { originalError: error },
228
+ },
229
+ },
230
+ };
231
+ }
232
+ }
233
+ // Export the instance for other uses
234
+ exports.customAxios = axiosInstance;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ // import { ErrorResponse } from '../interfaces';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ // export const handleError = (error: any): ErrorResponse => {
5
+ // const status = error.status;
6
+ // // return {
7
+ // // isError: true,
8
+ // // content: [{ type: 'text', text: `Error: ${error.message}` }],
9
+ // // };
10
+ // const resource = 'user';
11
+ // const id = 'xxx-1234';
12
+ // return {
13
+ // statusCode: 404,
14
+ // body: {
15
+ // error: {
16
+ // code: 'RESOURCE_NOT_FOUND',
17
+ // message: `The requested ${resource} with ID ${id} was not found.`,
18
+ // details: { resource, id },
19
+ // },
20
+ // },
21
+ // } as any;
22
+ // };
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatToMCPToolResponse = void 0;
4
+ const logger_1 = require("./logger");
5
+ const isErrorWithDetails = (error) => {
6
+ return typeof error === 'object' && error !== null;
7
+ };
8
+ const formatToMCPToolResponse = (data) => {
9
+ try {
10
+ return {
11
+ content: [{ type: 'text', text: JSON.stringify(data) }],
12
+ };
13
+ }
14
+ catch (error) {
15
+ logger_1.logger.error('Error formatting response:', { data, error });
16
+ let code = 'UNKNOWN_ERROR';
17
+ let message = 'Error formatting response';
18
+ let details;
19
+ if (isErrorWithDetails(error)) {
20
+ code = (error === null || error === void 0 ? void 0 : error.code) || code;
21
+ message = (error === null || error === void 0 ? void 0 : error.message) || message;
22
+ details = error === null || error === void 0 ? void 0 : error.details;
23
+ }
24
+ return {
25
+ content: [
26
+ {
27
+ type: 'text',
28
+ text: JSON.stringify({
29
+ error: {
30
+ code,
31
+ message,
32
+ details,
33
+ },
34
+ }),
35
+ },
36
+ ],
37
+ };
38
+ }
39
+ };
40
+ exports.formatToMCPToolResponse = formatToMCPToolResponse;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./logger"), exports);
18
+ __exportStar(require("./format-to-mcp-tool-response"), exports);
19
+ __exportStar(require("./axios-instance"), exports);
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createLogger = exports.stream = exports.logger = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const winston_1 = __importDefault(require("winston"));
10
+ const config_1 = require("../config");
11
+ // Custom log levels
12
+ const levels = {
13
+ error: 0,
14
+ warn: 1,
15
+ info: 2,
16
+ http: 3,
17
+ debug: 4,
18
+ };
19
+ // Colors for console output
20
+ const colors = {
21
+ error: 'red',
22
+ warn: 'yellow',
23
+ info: 'green',
24
+ http: 'magenta',
25
+ debug: 'white',
26
+ };
27
+ // Add colors to winston
28
+ winston_1.default.addColors(colors);
29
+ // Console format with colors
30
+ const consoleFormat = winston_1.default.format.combine(winston_1.default.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss:SSS' }), winston_1.default.format.colorize({ all: true }), winston_1.default.format.printf(({ timestamp, level, message, ...metadata }) => {
31
+ let output = `${timestamp} ${level}: ${message}`;
32
+ if (Object.keys(metadata).length > 0) {
33
+ output += '\n' + JSON.stringify(metadata, null, 2);
34
+ }
35
+ return output;
36
+ }));
37
+ // File format (JSON)
38
+ const fileFormat = winston_1.default.format.combine(winston_1.default.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss:SSS' }), winston_1.default.format.json());
39
+ const getLogLevel = () => {
40
+ return config_1.env.LOG_LEVEL || 'info';
41
+ };
42
+ // Create file transports
43
+ // const logDir = path.join(process.cwd(), 'logs');
44
+ // Prefer env var, fallback to project-relative folder
45
+ const logDir = process.env.LOG_DIR || path_1.default.join(process.cwd(), 'logs');
46
+ if (!fs_1.default.existsSync(logDir)) {
47
+ fs_1.default.mkdirSync(logDir, { recursive: true });
48
+ }
49
+ console.error('logs_dir', logDir);
50
+ if (!fs_1.default.existsSync(logDir)) {
51
+ fs_1.default.mkdirSync(logDir, { recursive: true });
52
+ }
53
+ // Create log files
54
+ const errorLogFile = path_1.default.join(logDir, 'error.log');
55
+ const combinedLogFile = path_1.default.join(logDir, 'combined.log');
56
+ const fileTransports = [
57
+ // Error log file
58
+ new winston_1.default.transports.File({
59
+ filename: errorLogFile,
60
+ level: 'error',
61
+ maxsize: 5 * 1024 * 1024, // 5MB
62
+ maxFiles: 5,
63
+ tailable: true,
64
+ }),
65
+ // Combined log file - set to same level as logger
66
+ new winston_1.default.transports.File({
67
+ filename: combinedLogFile,
68
+ level: getLogLevel(), // Use same level as logger
69
+ maxsize: 5 * 1024 * 1024, // 5MB
70
+ maxFiles: 5,
71
+ tailable: true,
72
+ }),
73
+ ];
74
+ const consoleTransport = process.env.MCP_STDIO_MODE === 'true'
75
+ ? [
76
+ new winston_1.default.transports.Console({
77
+ format: consoleFormat,
78
+ }),
79
+ ]
80
+ : [];
81
+ // Create the logger
82
+ exports.logger = winston_1.default.createLogger({
83
+ level: getLogLevel(),
84
+ levels,
85
+ format: fileFormat,
86
+ transports: [...consoleTransport, ...fileTransports],
87
+ });
88
+ // Add a startup log to verify the logger is working
89
+ // logger.debug('Logger initialized', {
90
+ // currentLevel: getLogLevel(),
91
+ // availableLevels: levels,
92
+ // transports: logger.transports.map((t) => ({
93
+ // level: t.level,
94
+ // })),
95
+ // logDir,
96
+ // logFiles: {
97
+ // error: errorLogFile,
98
+ // combined: combinedLogFile,
99
+ // },
100
+ // });
101
+ // Export a stream object for Morgan
102
+ exports.stream = {
103
+ write: (message) => {
104
+ exports.logger.http(message.trim());
105
+ },
106
+ };
107
+ // Helper to create child loggers with context
108
+ const createLogger = (context) => {
109
+ return exports.logger.child({ context });
110
+ };
111
+ exports.createLogger = createLogger;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ // import { OpenAPIV3 } from 'openapi-types';
3
+ // import { z } from 'zod';
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ // function generateZodSchema(schema: OpenAPIV3.SchemaObject): z.ZodType<any> {
6
+ // if (!schema) {
7
+ // return z.any();
8
+ // }
9
+ // switch (schema.type) {
10
+ // case 'string':
11
+ // return schema.enum
12
+ // ? z.enum(schema.enum as [string, ...string[]])
13
+ // : z.string();
14
+ // case 'number':
15
+ // case 'integer':
16
+ // return z.number();
17
+ // case 'boolean':
18
+ // return z.boolean();
19
+ // case 'array':
20
+ // return z.array(generateZodSchema(schema.items as OpenAPIV3.SchemaObject));
21
+ // case 'object':
22
+ // if (schema.properties) {
23
+ // const shape: { [key: string]: z.ZodType<any> } = {};
24
+ // for (const [key, prop] of Object.entries(schema.properties)) {
25
+ // const isRequired = schema.required?.includes(key);
26
+ // shape[key] = isRequired
27
+ // ? generateZodSchema(prop as OpenAPIV3.SchemaObject)
28
+ // : generateZodSchema(prop as OpenAPIV3.SchemaObject).optional();
29
+ // }
30
+ // return z.object(shape);
31
+ // }
32
+ // return z.record(z.any());
33
+ // default:
34
+ // return z.any();
35
+ // }
36
+ // }
37
+ // export const transformer = async (args: any) => {
38
+ // if (!args || !args.schema) {
39
+ // throw new Error(
40
+ // 'Transformer received undefined or missing schema! Args: ' +
41
+ // JSON.stringify(args),
42
+ // );
43
+ // }
44
+ // const schemas: { [key: string]: z.ZodType<any> } = {};
45
+ // // Process all schemas in the OpenAPI document
46
+ // if (args.schema.components?.schemas) {
47
+ // for (const [name, schema] of Object.entries(
48
+ // args.schema.components.schemas,
49
+ // )) {
50
+ // schemas[name] = generateZodSchema(schema as OpenAPIV3.SchemaObject);
51
+ // }
52
+ // }
53
+ // // Generate the output file content
54
+ // const output = `import { z } from 'zod';
55
+ // // Generated Zod schemas
56
+ // ${Object.entries(schemas)
57
+ // .map(([name, schema]) => `export const ${name}Schema = ${schema.toString()};`)
58
+ // .join('\n')}
59
+ // // Type exports
60
+ // ${Object.entries(schemas)
61
+ // .map(([name]) => `export type ${name} = z.infer<typeof ${name}Schema>;`)
62
+ // .join('\n')}
63
+ // `;
64
+ // return output;
65
+ // };
66
+ // export default transformer;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ // import { generateZodClientFromOpenAPI } from 'openapi-zod-client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ // const transformer = async (args: any) => {
5
+ // if (!args || !args.schema) {
6
+ // throw new Error(
7
+ // 'Transformer received undefined or missing schema! Args: ' +
8
+ // JSON.stringify(args),
9
+ // );
10
+ // }
11
+ // if (!args.path) {
12
+ // throw new Error(
13
+ // 'Transformer received undefined or missing path! Args: ' +
14
+ // JSON.stringify(args),
15
+ // );
16
+ // }
17
+ // return generateZodClientFromOpenAPI({
18
+ // openApiDoc: args.schema,
19
+ // distPath: args.path,
20
+ // });
21
+ // };
22
+ // // Use both CommonJS and ESM exports for compatibility
23
+ // module.exports = transformer;
24
+ // export default transformer;
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@carbonvoice/cv-mcp-server",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for using the Carbon Voice Simplified API",
5
+ "author": "Carbon Voice",
6
+ "license": "ISC",
7
+ "private": false,
8
+ "homepage": "https://getcarbon.app",
9
+ "bugs": "https://github.com/PhononX/cv-mcp-server/issues",
10
+ "main": "dist/stdio.js",
11
+ "bin": {
12
+ "mcp-server-carbonvoice": "./dist/stdio.js"
13
+ },
14
+ "scripts": {
15
+ "build": "rm -rf dist && tsc && chmod 755 dist/stdio.js",
16
+ "start": "node dist/index.js",
17
+ "pre": "npm run build",
18
+ "mcp:inspector": "npx --env-file=.env @modelcontextprotocol/inspector node dist/stdio.js",
19
+ "dev": "dotenv -e .env -- node dist/index.js",
20
+ "debug": "dotenv -e .env -- nodemon --watch src --ext ts --exec \"node --loader ts-node/esm\" src/server.ts",
21
+ "debug:stdio": "dotenv -e .env -- nodemon --watch src --ext ts --exec \"node --loader ts-node/esm\" src/stdio.ts",
22
+ "auto:build": "nodemon --watch src --ext ts --exec npm run build",
23
+ "pregenerate:api": "tsc src/utils/zod-transformer.ts --outDir dist/utils && mv dist/utils/zod-transformer.js dist/utils/zod-transformer.cjs",
24
+ "generate:api": "npm run pregenerate:api && orval --config orval.config.ts",
25
+ "lint:fix": "eslint src --fix"
26
+ },
27
+ "files": [
28
+ "dist"
29
+ ],
30
+ "keywords": [
31
+ "mcp",
32
+ "mcp-server",
33
+ "mcp-server-carbonvoice",
34
+ "carbonvoice",
35
+ "carbonvoice-mcp-server"
36
+ ],
37
+ "dependencies": {
38
+ "@modelcontextprotocol/sdk": "^1.12.1",
39
+ "axios": "^1.9.0",
40
+ "dotenv": "^16.5.0",
41
+ "openapi-zod-client": "^1.18.3",
42
+ "winston": "^3.17.0"
43
+ },
44
+ "devDependencies": {
45
+ "@eslint/js": "^9.29.0",
46
+ "@orval/zod": "^7.9.0",
47
+ "@types/handlebars": "^4.0.40",
48
+ "@types/node": "^22.15.29",
49
+ "@typescript-eslint/eslint-plugin": "^8.33.1",
50
+ "@typescript-eslint/parser": "^8.33.1",
51
+ "eslint": "^9.29.0",
52
+ "eslint-config-prettier": "^10.1.5",
53
+ "eslint-plugin-prettier": "^5.4.1",
54
+ "eslint-plugin-simple-import-sort": "^12.1.1",
55
+ "eslint-plugin-unused-imports": "^4.1.4",
56
+ "globals": "^16.2.0",
57
+ "nodemon": "^3.1.10",
58
+ "orval": "^7.9.0",
59
+ "prettier": "^3.5.3",
60
+ "ts-node": "^10.9.2",
61
+ "ts-node-dev": "^2.0.0",
62
+ "typescript": "^5.8.3",
63
+ "typescript-eslint": "^8.34.1",
64
+ "zod": "^3.25.58"
65
+ }
66
+ }