@carbonvoice/cv-mcp-server 1.0.10 → 1.0.12

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.
@@ -640,7 +640,8 @@ exports.listMessagesResponse = zod_1.z.object({
640
640
  "conversation_id": zod_1.z.string().optional().describe('Conversation ID (optional)'),
641
641
  "language": zod_1.z.string().optional().describe('Language (optional)'),
642
642
  "type": zod_1.z.enum(['channel', 'prerecorded', 'voicememo', 'stored', 'welcome']).optional().describe('Type (optional)'),
643
- "folder_id": zod_1.z.string().optional().describe('Folder ID (optional)')
643
+ "folder_id": zod_1.z.string().optional().describe('Folder ID (optional)'),
644
+ "user_ids": zod_1.z.array(zod_1.z.string()).optional().describe('User IDs (optional). List of user IDs to filter messages by. If not provided, all users will be included.')
644
645
  }).optional().describe('Filters'),
645
646
  "results": zod_1.z.array(zod_1.z.object({
646
647
  "id": zod_1.z.string().describe('ID'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carbonvoice/cv-mcp-server",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "Server implementation for integrating with Carbon Voice's API, providing tools and endpoints for voice messaging, conversations, and workspace management through MCP (Model Context Protocol)",
5
5
  "author": "Carbon Voice",
6
6
  "license": "ISC",
package/readme.md ADDED
@@ -0,0 +1,198 @@
1
+ # Carbon Voice MCP Server
2
+
3
+ A Model Context Protocol (MCP) server implementation for integrating with Carbon Voice's API, providing AI assistants with comprehensive tools for voice messaging, conversations, and workspace management.
4
+
5
+ ## Features
6
+
7
+ - **Message Management**: Create, list, and retrieve voice messages, conversation messages, and direct messages
8
+ - **User Operations**: Search and retrieve user information
9
+ - **Conversation Management**: Access and manage conversations and their participants
10
+ - **Folder Operations**: Create, organize, move, and manage folders and their contents
11
+ - **Workspace Administration**: Get workspace information
12
+ - **AI Actions**: Run AI prompts and retrieve AI-generated responses
13
+ - **Attachment Support**: Add link attachments to messages
14
+
15
+ ## Prerequisites
16
+
17
+ ### API Key Required
18
+
19
+ To use this MCP server, you need a Carbon Voice API key. Please contact the Carbon Voice development team to request your API key:
20
+
21
+ **📧 Contact**: devsupport@phononx.com
22
+
23
+ ## Configuration
24
+
25
+ ### For Cursor
26
+
27
+ 1. Open Cursor
28
+ 2. Go to **Cursor Settings** > **Features** > **Model Context Protocol**
29
+ 3. Add a new MCP server configuration:
30
+
31
+ ```json
32
+ {
33
+ "mcpServers": {
34
+ "Carbon-Voice": {
35
+ "command": "npx",
36
+ "env": {
37
+ "CARBON_VOICE_API_KEY": "your_api_key_here"
38
+ },
39
+ "args": ["-y", "@carbonvoice/cv-mcp-server"]
40
+ }
41
+ }
42
+ }
43
+ ```
44
+
45
+ 4. Replace `"your_api_key_here"` with your actual Carbon Voice API key
46
+ 5. Save and restart Cursor
47
+
48
+ ### For Claude Desktop
49
+
50
+ 1. Open your Claude Desktop configuration file:
51
+
52
+ - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
53
+ - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
54
+
55
+ 2. Add the Carbon Voice MCP server configuration:
56
+
57
+ ```json
58
+ {
59
+ "mcpServers": {
60
+ "Carbon-Voice": {
61
+ "command": "npx",
62
+ "env": {
63
+ "CARBON_VOICE_API_KEY": "your_api_key_here"
64
+ },
65
+ "args": ["-y", "@carbonvoice/cv-mcp-server"]
66
+ }
67
+ }
68
+ }
69
+ ```
70
+
71
+ 3. Replace `"your_api_key_here"` with your actual Carbon Voice API key
72
+ 4. Save the file and restart Claude Desktop
73
+
74
+ ## Available Tools
75
+
76
+ ### Messages
77
+
78
+ - **`list_messages`** - List messages with date filtering (max 31-day range)
79
+ - **`get_message`** - Retrieve a specific message by ID
80
+ - **`get_recent_messages`** - Get the 10 most recent messages with full context
81
+ - **`create_conversation_message`** - Send a message to a conversation
82
+ - **`create_direct_message`** - Send direct messages to users or groups
83
+ - **`create_voicememo_message`** - Create voice memo messages
84
+ - **`add_attachments_to_message`** - Add link attachments to existing messages
85
+
86
+ ### Users
87
+
88
+ - **`get_user`** - Retrieve user information by ID
89
+ - **`search_user`** - Find a user by phone number or email
90
+ - **`search_users`** - Search multiple users by various identifiers
91
+
92
+ ### Conversations
93
+
94
+ - **`list_conversations`** - Get all conversations from the last 6 months
95
+ - **`get_conversation`** - Retrieve conversation details by ID
96
+ - **`get_conversation_users`** - Get all users in a conversation
97
+
98
+ ### Folders
99
+
100
+ - **`get_workspace_folders_and_message_counts`** - Get folder and message statistics
101
+ - **`get_root_folders`** - List root folders for a workspace
102
+ - **`create_folder`** - Create new folders
103
+ - **`get_folder`** - Retrieve folder information
104
+ - **`get_folder_with_messages`** - Get folder with its messages
105
+ - **`update_folder_name`** - Rename folders
106
+ - **`delete_folder`** - Delete folders (⚠️ destructive operation)
107
+ - **`move_folder`** - Move folders between locations
108
+ - **`move_message_to_folder`** - Organize messages into folders
109
+
110
+ ### Workspace
111
+
112
+ - **`get_workspaces_basic_info`** - Get basic workspace information
113
+
114
+ ### AI Actions
115
+
116
+ - **`list_ai_actions`** - List available AI prompts/actions
117
+ - **`run_ai_action`** - Execute AI actions on messages
118
+ - **`run_ai_action_for_shared_link`** - Run AI actions on shared content
119
+ - **`get_ai_action_responses`** - Retrieve AI-generated responses
120
+
121
+ ## Usage Examples
122
+
123
+ ### Getting Started
124
+
125
+ After configuration, you can interact with Carbon Voice through your AI assistant. Here are some example requests:
126
+
127
+ ```
128
+ "Show me my recent messages"
129
+ "Create a voice memo about today's meeting"
130
+ "Search for user john@example.com"
131
+ "Show me my workspace information"
132
+ "List my conversations from this week"
133
+ ```
134
+
135
+ ### Working with Folders
136
+
137
+ ```
138
+ "Create a folder called 'Project Updates'"
139
+ "Move message ID 12345 to the Project Updates folder"
140
+ "Show me all messages in the Marketing folder"
141
+ ```
142
+
143
+ ### AI Actions
144
+
145
+ ```
146
+ "Run a summary AI action on message ID 67890"
147
+ "List all available AI prompts"
148
+ "Get AI responses for conversation ID 123"
149
+ ```
150
+
151
+ ## Error Handling
152
+
153
+ The server includes comprehensive error handling and logging. Errors are returned in a structured format that includes:
154
+
155
+ - Error messages
156
+ - HTTP status codes
157
+ - Request context
158
+ - Debugging information
159
+
160
+ ## Development
161
+
162
+ ### Building from Source
163
+
164
+ ```bash
165
+ npm run build
166
+ ```
167
+
168
+ ### Running in Development Mode
169
+
170
+ ```bash
171
+ npm run auto:build # Watch mode with auto-rebuild
172
+ ```
173
+
174
+ ### Linting
175
+
176
+ ```bash
177
+ npm run lint:fix
178
+ ```
179
+
180
+ ### Testing with MCP Inspector
181
+
182
+ ```bash
183
+ npm run mcp:inspector
184
+ ```
185
+
186
+ ## Support
187
+
188
+ - **Issues**: [GitHub Issues](https://github.com/PhononX/cv-mcp-server/issues)
189
+ - **API Key Requests**: devsupport@phononx.com
190
+ - **Website**: [https://getcarbon.app](https://getcarbon.app)
191
+
192
+ ## License
193
+
194
+ ISC License - See LICENSE file for details.
195
+
196
+ ---
197
+
198
+ **Note**: This MCP server requires a valid Carbon Voice API key to function. Please ensure you have obtained your API key from the Carbon Voice team before attempting to use the server.
package/dist/bootstrap.js DELETED
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- require("@dotenvx/dotenvx/config");
@@ -1,20 +0,0 @@
1
- "use strict";
2
- // export class CarbonVoiceClient {
3
- // private static instance: CarbonVoiceClient;
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- // static getInstance() {
6
- // if (!CarbonVoiceClient.instance) {
7
- // CarbonVoiceClient.instance = new CarbonVoiceClient();
8
- // }
9
- // return CarbonVoiceClient.instance;
10
- // }
11
- // async listAllConversations(): Promise<any> {
12
- // try {
13
- // // const response = await getAllConversations();
14
- // return {} as any;
15
- // } catch (error) {
16
- // // console.error('Error listing all conversations:', error);
17
- // return error;
18
- // }
19
- // }
20
- // }
package/dist/index-v1.js DELETED
@@ -1,80 +0,0 @@
1
- "use strict";
2
- // #!/usr/bin/env node
3
- // import { Server } from '@modelcontextprotocol/sdk/server/index.js';
4
- // import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
- // import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
6
- // import {
7
- // CallToolRequest,
8
- // CallToolRequestSchema,
9
- // ListToolsRequestSchema,
10
- // Tool,
11
- // } from '@modelcontextprotocol/sdk/types.js';
12
- // import { z } from 'zod';
13
- // import { CarbonVoiceClient } from './carbon-voice.js';
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- // /**
16
- // * Environment variables
17
- // */
18
- // const CV_API_BASE_URL = 'https://wf5whhzd-8081.brs.devtunnels.ms';
19
- // const CV_API_SIMPLIFIED_BASE_URL = `${CV_API_BASE_URL}/simplified`;
20
- // const USER_AGENT = 'carbonvoice-app/1.0';
21
- // // Type definitions for tool arguments
22
- // interface ListConversationArgs {
23
- // limit?: number;
24
- // cursor?: string;
25
- // }
26
- // const apiKey = process.env.CARBON_VOICE_API_KEY;
27
- // if (!apiKey) {
28
- // console.error('Please set CARBON_VOICE_API_KEY environment variable');
29
- // process.exit(1);
30
- // }
31
- // // Carbon Voice Client
32
- // const client = new CarbonVoiceClient(apiKey);
33
- // console.error('Starting Carbon Voice MCP Server...');
34
- // // Create server instance
35
- // const server = new McpServer({
36
- // name: 'Carbon Voice MCP Server',
37
- // version: '1.0.0',
38
- // capabilities: {
39
- // resources: {},
40
- // tools: {},
41
- // },
42
- // });
43
- // server.tool(
44
- // 'list_all_conversations',
45
- // 'List all conversations',
46
- // {
47
- // workspace_id: z.string().optional().describe('Carbon Voice workspace ID'),
48
- // },
49
- // async ({ workspace_id }) => {
50
- // const channelsData = await client.listAllConversations();
51
- // if (!channelsData) {
52
- // return {
53
- // content: [
54
- // {
55
- // type: 'text',
56
- // text: 'Failed to retrieve all conversations',
57
- // },
58
- // ],
59
- // };
60
- // }
61
- // return {
62
- // content: [
63
- // {
64
- // type: 'text',
65
- // text: JSON.stringify(channelsData),
66
- // },
67
- // ],
68
- // };
69
- // },
70
- // );
71
- // async function runServer() {
72
- // const transport = new StdioServerTransport();
73
- // console.error('Connecting server to transport...');
74
- // await server.connect(transport);
75
- // console.error('Carbon Voice MCP Server running on stdio');
76
- // }
77
- // runServer().catch((error) => {
78
- // console.error('Fatal error in runServer():', error);
79
- // process.exit(1);
80
- // });
@@ -1,624 +0,0 @@
1
- "use strict";
2
- // import { z } from 'zod';
3
- // import { zodToJsonSchema } from 'zod-to-json-schema';
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- // import { Server } from '@modelcontextprotocol/sdk/server/index.js';
6
- // import {
7
- // CallToolRequestSchema,
8
- // CompleteRequestSchema,
9
- // CreateMessageRequest,
10
- // CreateMessageResultSchema,
11
- // GetPromptRequestSchema,
12
- // ListPromptsRequestSchema,
13
- // ListResourcesRequestSchema,
14
- // ListResourceTemplatesRequestSchema,
15
- // ListToolsRequestSchema,
16
- // LoggingLevel,
17
- // ReadResourceRequestSchema,
18
- // Resource,
19
- // SetLevelRequestSchema,
20
- // SubscribeRequestSchema,
21
- // Tool,
22
- // ToolSchema,
23
- // UnsubscribeRequestSchema,
24
- // } from '@modelcontextprotocol/sdk/types.js';
25
- // const ToolInputSchema = ToolSchema.shape.inputSchema;
26
- // type ToolInput = z.infer<typeof ToolInputSchema>;
27
- // /* Input schemas for tools implemented in this server */
28
- // const EchoSchema = z.object({
29
- // message: z.string().describe('Message to echo'),
30
- // });
31
- // const AddSchema = z.object({
32
- // a: z.number().describe('First number'),
33
- // b: z.number().describe('Second number'),
34
- // });
35
- // const LongRunningOperationSchema = z.object({
36
- // duration: z
37
- // .number()
38
- // .default(10)
39
- // .describe('Duration of the operation in seconds'),
40
- // steps: z.number().default(5).describe('Number of steps in the operation'),
41
- // });
42
- // const PrintEnvSchema = z.object({});
43
- // const SampleLLMSchema = z.object({
44
- // prompt: z.string().describe('The prompt to send to the LLM'),
45
- // maxTokens: z
46
- // .number()
47
- // .default(100)
48
- // .describe('Maximum number of tokens to generate'),
49
- // });
50
- // // Example completion values
51
- // const EXAMPLE_COMPLETIONS = {
52
- // style: ['casual', 'formal', 'technical', 'friendly'],
53
- // temperature: ['0', '0.5', '0.7', '1.0'],
54
- // resourceId: ['1', '2', '3', '4', '5'],
55
- // };
56
- // const GetTinyImageSchema = z.object({});
57
- // const AnnotatedMessageSchema = z.object({
58
- // messageType: z
59
- // .enum(['error', 'success', 'debug'])
60
- // .describe('Type of message to demonstrate different annotation patterns'),
61
- // includeImage: z
62
- // .boolean()
63
- // .default(false)
64
- // .describe('Whether to include an example image'),
65
- // });
66
- // const GetResourceReferenceSchema = z.object({
67
- // resourceId: z
68
- // .number()
69
- // .min(1)
70
- // .max(100)
71
- // .describe('ID of the resource to reference (1-100)'),
72
- // });
73
- // enum ToolName {
74
- // ECHO = 'echo',
75
- // ADD = 'add',
76
- // LONG_RUNNING_OPERATION = 'longRunningOperation',
77
- // PRINT_ENV = 'printEnv',
78
- // SAMPLE_LLM = 'sampleLLM',
79
- // GET_TINY_IMAGE = 'getTinyImage',
80
- // ANNOTATED_MESSAGE = 'annotatedMessage',
81
- // GET_RESOURCE_REFERENCE = 'getResourceReference',
82
- // }
83
- // enum PromptName {
84
- // SIMPLE = 'simple_prompt',
85
- // COMPLEX = 'complex_prompt',
86
- // RESOURCE = 'resource_prompt',
87
- // }
88
- // export const createServer = () => {
89
- // const server = new Server(
90
- // {
91
- // name: 'example-servers/everything',
92
- // version: '1.0.0',
93
- // },
94
- // {
95
- // capabilities: {
96
- // prompts: {},
97
- // resources: { subscribe: true },
98
- // tools: {},
99
- // logging: {},
100
- // completions: {},
101
- // },
102
- // },
103
- // );
104
- // const subscriptions: Set<string> = new Set();
105
- // let subsUpdateInterval: NodeJS.Timeout | undefined;
106
- // let stdErrUpdateInterval: NodeJS.Timeout | undefined;
107
- // // Set up update interval for subscribed resources
108
- // subsUpdateInterval = setInterval(() => {
109
- // for (const uri of subscriptions) {
110
- // server.notification({
111
- // method: 'notifications/resources/updated',
112
- // params: { uri },
113
- // });
114
- // }
115
- // }, 10000);
116
- // let logLevel: LoggingLevel = 'debug';
117
- // let logsUpdateInterval: NodeJS.Timeout | undefined;
118
- // const messages = [
119
- // { level: 'debug', data: 'Debug-level message' },
120
- // { level: 'info', data: 'Info-level message' },
121
- // { level: 'notice', data: 'Notice-level message' },
122
- // { level: 'warning', data: 'Warning-level message' },
123
- // { level: 'error', data: 'Error-level message' },
124
- // { level: 'critical', data: 'Critical-level message' },
125
- // { level: 'alert', data: 'Alert level-message' },
126
- // { level: 'emergency', data: 'Emergency-level message' },
127
- // ];
128
- // const isMessageIgnored = (level: LoggingLevel): boolean => {
129
- // const currentLevel = messages.findIndex((msg) => logLevel === msg.level);
130
- // const messageLevel = messages.findIndex((msg) => level === msg.level);
131
- // return messageLevel < currentLevel;
132
- // };
133
- // // Set up update interval for random log messages
134
- // logsUpdateInterval = setInterval(() => {
135
- // const message = {
136
- // method: 'notifications/message',
137
- // params: messages[Math.floor(Math.random() * messages.length)],
138
- // };
139
- // if (!isMessageIgnored(message.params.level as LoggingLevel))
140
- // server.notification(message);
141
- // }, 20000);
142
- // // Set up update interval for stderr messages
143
- // stdErrUpdateInterval = setInterval(() => {
144
- // const shortTimestamp = new Date().toLocaleTimeString([], {
145
- // hour: '2-digit',
146
- // minute: '2-digit',
147
- // second: '2-digit',
148
- // });
149
- // server.notification({
150
- // method: 'notifications/stderr',
151
- // params: { content: `${shortTimestamp}: A stderr message` },
152
- // });
153
- // }, 30000);
154
- // // Helper method to request sampling from client
155
- // const requestSampling = async (
156
- // context: string,
157
- // uri: string,
158
- // maxTokens: number = 100,
159
- // ) => {
160
- // const request: CreateMessageRequest = {
161
- // method: 'sampling/createMessage',
162
- // params: {
163
- // messages: [
164
- // {
165
- // role: 'user',
166
- // content: {
167
- // type: 'text',
168
- // text: `Resource ${uri} context: ${context}`,
169
- // },
170
- // },
171
- // ],
172
- // systemPrompt: 'You are a helpful test server.',
173
- // maxTokens,
174
- // temperature: 0.7,
175
- // includeContext: 'thisServer',
176
- // },
177
- // };
178
- // return await server.request(request, CreateMessageResultSchema);
179
- // };
180
- // const ALL_RESOURCES: Resource[] = Array.from({ length: 100 }, (_, i) => {
181
- // const uri = `test://static/resource/${i + 1}`;
182
- // if (i % 2 === 0) {
183
- // return {
184
- // uri,
185
- // name: `Resource ${i + 1}`,
186
- // mimeType: 'text/plain',
187
- // text: `Resource ${i + 1}: This is a plaintext resource`,
188
- // };
189
- // } else {
190
- // const buffer = Buffer.from(`Resource ${i + 1}: This is a base64 blob`);
191
- // return {
192
- // uri,
193
- // name: `Resource ${i + 1}`,
194
- // mimeType: 'application/octet-stream',
195
- // blob: buffer.toString('base64'),
196
- // };
197
- // }
198
- // });
199
- // const PAGE_SIZE = 10;
200
- // server.setRequestHandler(ListResourcesRequestSchema, async (request) => {
201
- // const cursor = request.params?.cursor;
202
- // let startIndex = 0;
203
- // if (cursor) {
204
- // const decodedCursor = parseInt(atob(cursor), 10);
205
- // if (!isNaN(decodedCursor)) {
206
- // startIndex = decodedCursor;
207
- // }
208
- // }
209
- // const endIndex = Math.min(startIndex + PAGE_SIZE, ALL_RESOURCES.length);
210
- // const resources = ALL_RESOURCES.slice(startIndex, endIndex);
211
- // let nextCursor: string | undefined;
212
- // if (endIndex < ALL_RESOURCES.length) {
213
- // nextCursor = btoa(endIndex.toString());
214
- // }
215
- // return {
216
- // resources,
217
- // nextCursor,
218
- // };
219
- // });
220
- // server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => {
221
- // return {
222
- // resourceTemplates: [
223
- // {
224
- // uriTemplate: 'test://static/resource/{id}',
225
- // name: 'Static Resource',
226
- // description: 'A static resource with a numeric ID',
227
- // },
228
- // ],
229
- // };
230
- // });
231
- // server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
232
- // const uri = request.params.uri;
233
- // if (uri.startsWith('test://static/resource/')) {
234
- // const index = parseInt(uri.split('/').pop() ?? '', 10) - 1;
235
- // if (index >= 0 && index < ALL_RESOURCES.length) {
236
- // const resource = ALL_RESOURCES[index];
237
- // return {
238
- // contents: [resource],
239
- // };
240
- // }
241
- // }
242
- // throw new Error(`Unknown resource: ${uri}`);
243
- // });
244
- // server.setRequestHandler(SubscribeRequestSchema, async (request) => {
245
- // const { uri } = request.params;
246
- // subscriptions.add(uri);
247
- // // Request sampling from client when someone subscribes
248
- // await requestSampling('A new subscription was started', uri);
249
- // return {};
250
- // });
251
- // server.setRequestHandler(UnsubscribeRequestSchema, async (request) => {
252
- // subscriptions.delete(request.params.uri);
253
- // return {};
254
- // });
255
- // server.setRequestHandler(ListPromptsRequestSchema, async () => {
256
- // return {
257
- // prompts: [
258
- // {
259
- // name: PromptName.SIMPLE,
260
- // description: 'A prompt without arguments',
261
- // },
262
- // {
263
- // name: PromptName.COMPLEX,
264
- // description: 'A prompt with arguments',
265
- // arguments: [
266
- // {
267
- // name: 'temperature',
268
- // description: 'Temperature setting',
269
- // required: true,
270
- // },
271
- // {
272
- // name: 'style',
273
- // description: 'Output style',
274
- // required: false,
275
- // },
276
- // ],
277
- // },
278
- // {
279
- // name: PromptName.RESOURCE,
280
- // description: 'A prompt that includes an embedded resource reference',
281
- // arguments: [
282
- // {
283
- // name: 'resourceId',
284
- // description: 'Resource ID to include (1-100)',
285
- // required: true,
286
- // },
287
- // ],
288
- // },
289
- // ],
290
- // };
291
- // });
292
- // server.setRequestHandler(GetPromptRequestSchema, async (request) => {
293
- // const { name, arguments: args } = request.params;
294
- // if (name === PromptName.SIMPLE) {
295
- // return {
296
- // messages: [
297
- // {
298
- // role: 'user',
299
- // content: {
300
- // type: 'text',
301
- // text: 'This is a simple prompt without arguments.',
302
- // },
303
- // },
304
- // ],
305
- // };
306
- // }
307
- // if (name === PromptName.COMPLEX) {
308
- // return {
309
- // messages: [
310
- // {
311
- // role: 'user',
312
- // content: {
313
- // type: 'text',
314
- // text: `This is a complex prompt with arguments: temperature=${args?.temperature}, style=${args?.style}`,
315
- // },
316
- // },
317
- // {
318
- // role: 'assistant',
319
- // content: {
320
- // type: 'text',
321
- // text: "I understand. You've provided a complex prompt with temperature and style arguments.
322
- // How would you like me to proceed?",
323
- // },
324
- // },
325
- // {
326
- // role: 'user',
327
- // content: {
328
- // type: 'image',
329
- // data: MCP_TINY_IMAGE,
330
- // mimeType: 'image/png',
331
- // },
332
- // },
333
- // ],
334
- // };
335
- // }
336
- // if (name === PromptName.RESOURCE) {
337
- // const resourceId = parseInt(args?.resourceId as string, 10);
338
- // if (isNaN(resourceId) || resourceId < 1 || resourceId > 100) {
339
- // throw new Error(
340
- // `Invalid resourceId: ${args?.resourceId}. Must be a number between 1 and 100.`,
341
- // );
342
- // }
343
- // const resourceIndex = resourceId - 1;
344
- // const resource = ALL_RESOURCES[resourceIndex];
345
- // return {
346
- // messages: [
347
- // {
348
- // role: 'user',
349
- // content: {
350
- // type: 'text',
351
- // text: `This prompt includes Resource ${resourceId}. Please analyze the following resource:`,
352
- // },
353
- // },
354
- // {
355
- // role: 'user',
356
- // content: {
357
- // type: 'resource',
358
- // resource: resource,
359
- // },
360
- // },
361
- // ],
362
- // };
363
- // }
364
- // throw new Error(`Unknown prompt: ${name}`);
365
- // });
366
- // server.setRequestHandler(ListToolsRequestSchema, async () => {
367
- // const tools: Tool[] = [
368
- // {
369
- // name: ToolName.ECHO,
370
- // description: 'Echoes back the input',
371
- // inputSchema: zodToJsonSchema(EchoSchema) as ToolInput,
372
- // },
373
- // {
374
- // name: ToolName.ADD,
375
- // description: 'Adds two numbers',
376
- // inputSchema: zodToJsonSchema(AddSchema) as ToolInput,
377
- // },
378
- // {
379
- // name: ToolName.PRINT_ENV,
380
- // description:
381
- // 'Prints all environment variables, helpful for debugging MCP server configuration',
382
- // inputSchema: zodToJsonSchema(PrintEnvSchema) as ToolInput,
383
- // },
384
- // {
385
- // name: ToolName.LONG_RUNNING_OPERATION,
386
- // description:
387
- // 'Demonstrates a long running operation with progress updates',
388
- // inputSchema: zodToJsonSchema(LongRunningOperationSchema) as ToolInput,
389
- // },
390
- // {
391
- // name: ToolName.SAMPLE_LLM,
392
- // description: "Samples from an LLM using MCP's sampling feature",
393
- // inputSchema: zodToJsonSchema(SampleLLMSchema) as ToolInput,
394
- // },
395
- // {
396
- // name: ToolName.GET_TINY_IMAGE,
397
- // description: 'Returns the MCP_TINY_IMAGE',
398
- // inputSchema: zodToJsonSchema(GetTinyImageSchema) as ToolInput,
399
- // },
400
- // {
401
- // name: ToolName.ANNOTATED_MESSAGE,
402
- // description:
403
- // 'Demonstrates how annotations can be used to provide metadata about content',
404
- // inputSchema: zodToJsonSchema(AnnotatedMessageSchema) as ToolInput,
405
- // },
406
- // {
407
- // name: ToolName.GET_RESOURCE_REFERENCE,
408
- // description:
409
- // 'Returns a resource reference that can be used by MCP clients',
410
- // inputSchema: zodToJsonSchema(GetResourceReferenceSchema) as ToolInput,
411
- // },
412
- // ];
413
- // return { tools };
414
- // });
415
- // server.setRequestHandler(CallToolRequestSchema, async (request) => {
416
- // const { name, arguments: args } = request.params;
417
- // if (name === ToolName.ECHO) {
418
- // const validatedArgs = EchoSchema.parse(args);
419
- // return {
420
- // content: [{ type: 'text', text: `Echo: ${validatedArgs.message}` }],
421
- // };
422
- // }
423
- // if (name === ToolName.ADD) {
424
- // const validatedArgs = AddSchema.parse(args);
425
- // const sum = validatedArgs.a + validatedArgs.b;
426
- // return {
427
- // content: [
428
- // {
429
- // type: 'text',
430
- // text: `The sum of ${validatedArgs.a} and ${validatedArgs.b} is ${sum}.`,
431
- // },
432
- // ],
433
- // };
434
- // }
435
- // if (name === ToolName.LONG_RUNNING_OPERATION) {
436
- // const validatedArgs = LongRunningOperationSchema.parse(args);
437
- // const { duration, steps } = validatedArgs;
438
- // const stepDuration = duration / steps;
439
- // const progressToken = request.params._meta?.progressToken;
440
- // for (let i = 1; i < steps + 1; i++) {
441
- // await new Promise((resolve) =>
442
- // setTimeout(resolve, stepDuration * 1000),
443
- // );
444
- // if (progressToken !== undefined) {
445
- // await server.notification({
446
- // method: 'notifications/progress',
447
- // params: {
448
- // progress: i,
449
- // total: steps,
450
- // progressToken,
451
- // },
452
- // });
453
- // }
454
- // }
455
- // return {
456
- // content: [
457
- // {
458
- // type: 'text',
459
- // text: `Long running operation completed. Duration: ${duration} seconds, Steps: ${steps}.`,
460
- // },
461
- // ],
462
- // };
463
- // }
464
- // if (name === ToolName.PRINT_ENV) {
465
- // return {
466
- // content: [
467
- // {
468
- // type: 'text',
469
- // text: JSON.stringify(process.env, null, 2),
470
- // },
471
- // ],
472
- // };
473
- // }
474
- // if (name === ToolName.SAMPLE_LLM) {
475
- // const validatedArgs = SampleLLMSchema.parse(args);
476
- // const { prompt, maxTokens } = validatedArgs;
477
- // const result = await requestSampling(
478
- // prompt,
479
- // ToolName.SAMPLE_LLM,
480
- // maxTokens,
481
- // );
482
- // return {
483
- // content: [
484
- // { type: 'text', text: `LLM sampling result: ${result.content.text}` },
485
- // ],
486
- // };
487
- // }
488
- // if (name === ToolName.GET_TINY_IMAGE) {
489
- // GetTinyImageSchema.parse(args);
490
- // return {
491
- // content: [
492
- // {
493
- // type: 'text',
494
- // text: 'This is a tiny image:',
495
- // },
496
- // {
497
- // type: 'image',
498
- // data: MCP_TINY_IMAGE,
499
- // mimeType: 'image/png',
500
- // },
501
- // {
502
- // type: 'text',
503
- // text: 'The image above is the MCP tiny image.',
504
- // },
505
- // ],
506
- // };
507
- // }
508
- // if (name === ToolName.GET_RESOURCE_REFERENCE) {
509
- // const validatedArgs = GetResourceReferenceSchema.parse(args);
510
- // const resourceId = validatedArgs.resourceId;
511
- // const resourceIndex = resourceId - 1;
512
- // if (resourceIndex < 0 || resourceIndex >= ALL_RESOURCES.length) {
513
- // throw new Error(`Resource with ID ${resourceId} does not exist`);
514
- // }
515
- // const resource = ALL_RESOURCES[resourceIndex];
516
- // return {
517
- // content: [
518
- // {
519
- // type: 'text',
520
- // text: `Returning resource reference for Resource ${resourceId}:`,
521
- // },
522
- // {
523
- // type: 'resource',
524
- // resource: resource,
525
- // },
526
- // {
527
- // type: 'text',
528
- // text: `You can access this resource using the URI: ${resource.uri}`,
529
- // },
530
- // ],
531
- // };
532
- // }
533
- // if (name === ToolName.ANNOTATED_MESSAGE) {
534
- // const { messageType, includeImage } = AnnotatedMessageSchema.parse(args);
535
- // const content = [];
536
- // // Main message with different priorities/audiences based on type
537
- // if (messageType === 'error') {
538
- // content.push({
539
- // type: 'text',
540
- // text: 'Error: Operation failed',
541
- // annotations: {
542
- // priority: 1.0, // Errors are highest priority
543
- // audience: ['user', 'assistant'], // Both need to know about errors
544
- // },
545
- // });
546
- // } else if (messageType === 'success') {
547
- // content.push({
548
- // type: 'text',
549
- // text: 'Operation completed successfully',
550
- // annotations: {
551
- // priority: 0.7, // Success messages are important but not critical
552
- // audience: ['user'], // Success mainly for user consumption
553
- // },
554
- // });
555
- // } else if (messageType === 'debug') {
556
- // content.push({
557
- // type: 'text',
558
- // text: 'Debug: Cache hit ratio 0.95, latency 150ms',
559
- // annotations: {
560
- // priority: 0.3, // Debug info is low priority
561
- // audience: ['assistant'], // Technical details for assistant
562
- // },
563
- // });
564
- // }
565
- // // Optional image with its own annotations
566
- // if (includeImage) {
567
- // content.push({
568
- // type: 'image',
569
- // data: MCP_TINY_IMAGE,
570
- // mimeType: 'image/png',
571
- // annotations: {
572
- // priority: 0.5,
573
- // audience: ['user'], // Images primarily for user visualization
574
- // },
575
- // });
576
- // }
577
- // return { content };
578
- // }
579
- // throw new Error(`Unknown tool: ${name}`);
580
- // });
581
- // server.setRequestHandler(CompleteRequestSchema, async (request) => {
582
- // const { ref, argument } = request.params;
583
- // if (ref.type === 'ref/resource') {
584
- // const resourceId = ref.uri.split('/').pop();
585
- // if (!resourceId) return { completion: { values: [] } };
586
- // // Filter resource IDs that start with the input value
587
- // const values = EXAMPLE_COMPLETIONS.resourceId.filter((id) =>
588
- // id.startsWith(argument.value),
589
- // );
590
- // return { completion: { values, hasMore: false, total: values.length } };
591
- // }
592
- // if (ref.type === 'ref/prompt') {
593
- // // Handle completion for prompt arguments
594
- // const completions =
595
- // EXAMPLE_COMPLETIONS[argument.name as keyof typeof EXAMPLE_COMPLETIONS];
596
- // if (!completions) return { completion: { values: [] } };
597
- // const values = completions.filter((value) =>
598
- // value.startsWith(argument.value),
599
- // );
600
- // return { completion: { values, hasMore: false, total: values.length } };
601
- // }
602
- // throw new Error(`Unknown reference type`);
603
- // });
604
- // server.setRequestHandler(SetLevelRequestSchema, async (request) => {
605
- // const { level } = request.params;
606
- // logLevel = level;
607
- // // Demonstrate different log levels
608
- // await server.notification({
609
- // method: 'notifications/message',
610
- // params: {
611
- // level: 'debug',
612
- // logger: 'test-server',
613
- // data: `Logging level set to: ${logLevel}`,
614
- // },
615
- // });
616
- // return {};
617
- // });
618
- // const cleanup = async () => {
619
- // if (subsUpdateInterval) clearInterval(subsUpdateInterval);
620
- // if (logsUpdateInterval) clearInterval(logsUpdateInterval);
621
- // if (stdErrUpdateInterval) clearInterval(stdErrUpdateInterval);
622
- // };
623
- // return { server, cleanup };
624
- // };
@@ -1,93 +0,0 @@
1
- "use strict";
2
- // import express from 'express';
3
- // import { randomUUID } from 'node:crypto';
4
- // import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
- // import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
6
- // import { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js';
7
- // import { z } from 'zod';
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- // const app = express();
10
- // app.use(express.json());
11
- // // Map to store transports by session ID
12
- // const transports: { [sessionId: string]: StreamableHTTPServerTransport } = {};
13
- // // Handle POST requests for client-to-server communication
14
- // app.post('/mcp', async (req, res) => {
15
- // console.log('🚀 POST request received');
16
- // // Check for existing session ID
17
- // const sessionId = req.headers['mcp-session-id'] as string | undefined;
18
- // let transport: StreamableHTTPServerTransport;
19
- // if (sessionId && transports[sessionId]) {
20
- // // Reuse existing transport
21
- // transport = transports[sessionId];
22
- // } else if (!sessionId && isInitializeRequest(req.body)) {
23
- // // New initialization request
24
- // transport = new StreamableHTTPServerTransport({
25
- // sessionIdGenerator: () => randomUUID(),
26
- // onsessioninitialized: (sessionId) => {
27
- // // Store the transport by session ID
28
- // transports[sessionId] = transport;
29
- // },
30
- // });
31
- // // Clean up transport when closed
32
- // transport.onclose = () => {
33
- // if (transport.sessionId) {
34
- // console.log('🚀 Disconnecting from MCP server');
35
- // delete transports[transport.sessionId];
36
- // }
37
- // };
38
- // const server = new McpServer({
39
- // name: 'example-server',
40
- // version: '1.0.0',
41
- // });
42
- // // ... set up server resources, tools, and prompts ...
43
- // server.tool(
44
- // 'hello_world',
45
- // 'Simple Hello World tool',
46
- // {
47
- // name: z.string().optional().describe('Your name'),
48
- // },
49
- // async ({ name }) => ({
50
- // content: [
51
- // {
52
- // type: 'text',
53
- // text: `Hello, ${name ?? 'World'}! This response comes from an SSE MCP server.`,
54
- // },
55
- // ],
56
- // }),
57
- // );
58
- // // Connect to the MCP server
59
- // console.log('🚀 Connecting to MCP server');
60
- // await server.connect(transport);
61
- // } else {
62
- // // Invalid request
63
- // res.status(400).json({
64
- // jsonrpc: '2.0',
65
- // error: {
66
- // code: -32000,
67
- // message: 'Bad Request: No valid session ID provided',
68
- // },
69
- // id: null,
70
- // });
71
- // return;
72
- // }
73
- // // Handle the request
74
- // await transport.handleRequest(req, res, req.body);
75
- // });
76
- // // Reusable handler for GET and DELETE requests
77
- // const handleSessionRequest = async (
78
- // req: express.Request,
79
- // res: express.Response,
80
- // ) => {
81
- // const sessionId = req.headers['mcp-session-id'] as string | undefined;
82
- // if (!sessionId || !transports[sessionId]) {
83
- // res.status(400).send('Invalid or missing session ID');
84
- // return;
85
- // }
86
- // const transport = transports[sessionId];
87
- // await transport.handleRequest(req, res);
88
- // };
89
- // // Handle GET requests for server-to-client notifications via SSE
90
- // app.get('/mcp', handleSessionRequest);
91
- // // Handle DELETE requests for session termination
92
- // app.delete('/mcp', handleSessionRequest);
93
- // app.listen(4000);
package/dist/sse.js DELETED
@@ -1,134 +0,0 @@
1
- "use strict";
2
- // #!/usr/bin/env node
3
- // import express, { Request, Response } from 'express';
4
- // import cors from 'cors';
5
- // import dotenv from 'dotenv';
6
- // import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
7
- // import { z } from 'zod';
8
- // import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- // // Load .env
11
- // dotenv.config();
12
- // // Environment variables
13
- // const CV_API_BASE_URL = 'https://wf5whhzd-8081.brs.devtunnels.ms';
14
- // const CV_API_SIMPLIFIED_BASE_URL = `${CV_API_BASE_URL}/simplified`;
15
- // const API_KEY = process.env.CARBON_VOICE_API_KEY;
16
- // if (!API_KEY) {
17
- // console.error('❌ Missing CARBON_VOICE_API_KEY');
18
- // process.exit(1);
19
- // }
20
- // // ---- API CLIENT ---- //
21
- // class CarbonVoiceClient {
22
- // constructor(private apiKey: string) {}
23
- // async listChannels(limit = 100, cursor = '') {
24
- // try {
25
- // const res = await fetch(
26
- // `${CV_API_SIMPLIFIED_BASE_URL}/conversations/all`,
27
- // {
28
- // headers: {
29
- // 'x-api-key': this.apiKey,
30
- // 'Content-Type': 'application/json',
31
- // },
32
- // },
33
- // );
34
- // if (!res.ok) throw new Error(`Failed with status ${res.status}`);
35
- // return await res.json();
36
- // } catch (error) {
37
- // console.error('🔴 Error in listChannels:', error);
38
- // return null;
39
- // }
40
- // }
41
- // }
42
- // const client = new CarbonVoiceClient(API_KEY);
43
- // // ---- MCP SERVER ---- //
44
- // const server = new McpServer({
45
- // name: 'Carbon Voice MCP Server (SSE)',
46
- // version: '1.0.0',
47
- // capabilities: {
48
- // resources: {},
49
- // tools: {},
50
- // },
51
- // });
52
- // server.tool(
53
- // 'list_channels',
54
- // 'List channels',
55
- // {
56
- // workspace_id: z.string().optional().describe('Carbon Voice workspace ID'),
57
- // },
58
- // async ({ workspace_id }) => {
59
- // const channelsData = await client.listChannels(100, '');
60
- // if (!channelsData) {
61
- // return {
62
- // content: [
63
- // {
64
- // type: 'text',
65
- // text: 'Failed to retrieve channels data',
66
- // },
67
- // ],
68
- // };
69
- // }
70
- // return {
71
- // content: [
72
- // {
73
- // type: 'text',
74
- // text: JSON.stringify(channelsData),
75
- // },
76
- // ],
77
- // };
78
- // },
79
- // );
80
- // // ---- EXPRESS + SSE ---- //
81
- // async function run() {
82
- // const app = express();
83
- // app.use(cors());
84
- // app.use(express.json());
85
- // const transports = new Map<string, SSEServerTransport>();
86
- // app.get('/mcp/stream', async (req: Request, res: Response) => {
87
- // const clientId = crypto.randomUUID();
88
- // const transport = new SSEServerTransport('/mcp/stream', res);
89
- // transports.set(clientId, transport);
90
- // // Connect the SSE transport (this writes SSE headers) BEFORE writing any response
91
- // await server.connect(transport);
92
- // // Send a "clientId" event (so the client knows its ID)
93
- // res.write(`event: clientId\ndata: ${clientId}\n\n`);
94
- // // Send a "list_tools" event (so the client sees available tools) – mimicking MCP protocol's tool discovery
95
- // const toolsList = {
96
- // type: 'list_tools',
97
- // tools: [
98
- // {
99
- // name: 'list_channels',
100
- // description: 'List channels',
101
- // args_schema: { workspace_id: 'string (optional)' },
102
- // },
103
- // ],
104
- // };
105
- // res.write(`event: list_tools\ndata: ${JSON.stringify(toolsList)}\n\n`);
106
- // req.on('close', () => transports.delete(clientId));
107
- // console.log('✅ SSE MCP server connected (transport started)');
108
- // });
109
- // app.post('/mcp/message', async (req: any, res: any) => {
110
- // // if (!transport) {
111
- // // return res.status(400).send('❌ SSE transport not initialized');
112
- // // }
113
- // // await transport.handlePostMessage(req, res, req.body);
114
- // const { clientId, ...body } = req.body;
115
- // const transport = transports.get(clientId);
116
- // if (!transport) {
117
- // return res.status(400).send('❌ SSE connection not established');
118
- // }
119
- // try {
120
- // return await transport.handlePostMessage(req, res, body);
121
- // } catch (error) {
122
- // console.error('🔴 Error in handlePostMessage:', error);
123
- // return res.status(500).send('❌ Error processing message');
124
- // }
125
- // });
126
- // const PORT = process.env.PORT ?? 3333;
127
- // app.listen(PORT, () =>
128
- // console.log(`✅ SSE MCP server listening at http://localhost:${PORT}/mcp`),
129
- // );
130
- // }
131
- // run().catch((err) => {
132
- // console.error('🛑 Fatal server error:', err);
133
- // process.exit(1);
134
- // });
package/dist/sse.v2.js DELETED
@@ -1,29 +0,0 @@
1
- "use strict";
2
- // import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
3
- // import { createServer } from './server.js';
4
- // import express from 'express';
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- // // Create Express app and MCP server
7
- // const app = express();
8
- // const mcpServer = createServer();
9
- // // Handle SSE connections
10
- // app.get('/mcp', (req, res) => {
11
- // const transport = new SSEServerTransport('/mcp', res);
12
- // // Set SSE headers
13
- // res.setHeader('Content-Type', 'text/event-stream');
14
- // res.setHeader('Cache-Control', 'no-cache');
15
- // res.setHeader('Connection', 'keep-alive');
16
- // res.setHeader('Access-Control-Allow-Origin', '*'); // For development, restrict in production
17
- // transport.handleMessage(req);
18
- // // Handle the SSE connection using the MCP server's connect method
19
- // mcpServer.connect(transport);
20
- // // Handle client disconnect
21
- // req.on('close', () => {
22
- // console.log('Client disconnected');
23
- // });
24
- // });
25
- // // Start the server
26
- // const PORT = process.env.PORT || 3000;
27
- // app.listen(PORT, () => {
28
- // console.log(`Server running on port ${PORT}`);
29
- // });