@platoona/mcp 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/dist/index.js ADDED
@@ -0,0 +1,504 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Platoona MCP Server
4
+ *
5
+ * An MCP server that provides tools for:
6
+ * 1. search-tools - Search for integration tools using RAG
7
+ * 2. connect-app - Connect to integrations (OAuth or API key)
8
+ * 3. execute-tool - Execute integration actions
9
+ *
10
+ * Prerequisites:
11
+ * - PLATOONA_API_KEY environment variable must be set
12
+ * - Optionally set PLATOONA_BASE_URL for custom API endpoint
13
+ *
14
+ * User ID is automatically derived from the API key for consistent identification.
15
+ */
16
+ import { createHash } from 'crypto';
17
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
18
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
19
+ import * as z from 'zod';
20
+ import { PlatoonaClient } from './api-client.js';
21
+ // ============================================================================
22
+ // Configuration
23
+ // ============================================================================
24
+ const PLATOONA_BASE_URL = process.env.PLATOONA_BASE_URL;
25
+ // Validate required configuration
26
+ if (!process.env.PLATOONA_API_KEY) {
27
+ console.error('Error: PLATOONA_API_KEY environment variable is required');
28
+ console.error('Get your API key from https://app.platoona.com/connect');
29
+ process.exit(1);
30
+ }
31
+ // API key is guaranteed to be defined after validation
32
+ const PLATOONA_API_KEY = process.env.PLATOONA_API_KEY;
33
+ // ============================================================================
34
+ // MCP User ID Generation
35
+ // ============================================================================
36
+ /**
37
+ * Generate a deterministic MCP user ID from the API key.
38
+ * This ensures the same API key always maps to the same user ID,
39
+ * providing consistent connection isolation per API key holder.
40
+ *
41
+ * Format: mcp_<first 16 chars of SHA-256 hash>
42
+ *
43
+ * @param apiKey - The Platoona API key
44
+ * @returns Deterministic user ID for MCP operations
45
+ */
46
+ function generateMcpUserId(apiKey) {
47
+ const hash = createHash('sha256').update(apiKey).digest('hex');
48
+ return `mcp_${hash.slice(0, 16)}`;
49
+ }
50
+ // Generate the MCP user ID from the API key
51
+ const MCP_USER_ID = generateMcpUserId(PLATOONA_API_KEY);
52
+ // Initialize the Platoona API client
53
+ const client = new PlatoonaClient({
54
+ apiKey: PLATOONA_API_KEY,
55
+ baseUrl: PLATOONA_BASE_URL,
56
+ });
57
+ // ============================================================================
58
+ // MCP Server Setup
59
+ // ============================================================================
60
+ const server = new McpServer({
61
+ name: 'platoona',
62
+ version: '1.0.0',
63
+ });
64
+ // ============================================================================
65
+ // Tool: search-tools
66
+ // ============================================================================
67
+ server.registerTool('search-tools', {
68
+ title: 'Search Tools',
69
+ description: 'Search for available integration tools/actions using semantic search (RAG). ' +
70
+ 'Use this to discover what tools are available for a specific task or integration.',
71
+ inputSchema: {
72
+ query: z
73
+ .string()
74
+ .describe('Search query describing what you want to do (e.g., "send email", "create github issue")'),
75
+ integrationFilter: z
76
+ .string()
77
+ .optional()
78
+ .describe('Optional: Filter by integration name (e.g., "slack", "github")'),
79
+ limit: z
80
+ .number()
81
+ .min(1)
82
+ .max(50)
83
+ .optional()
84
+ .describe('Maximum number of results to return (default: 10)'),
85
+ },
86
+ outputSchema: {
87
+ tools: z.array(z.object({
88
+ id: z.string(),
89
+ name: z.string(),
90
+ description: z.string().optional(),
91
+ integrationName: z.string().optional(),
92
+ integrationSlug: z.string().optional(),
93
+ category: z.string().optional(),
94
+ similarity: z.number().optional(),
95
+ inputSchema: z.record(z.unknown()).optional(),
96
+ })),
97
+ totalFound: z.number(),
98
+ },
99
+ }, async ({ query, integrationFilter, limit }) => {
100
+ // Search for matching actions
101
+ const result = await client.searchActions({
102
+ query,
103
+ limit: limit || 10,
104
+ minSimilarity: 0.3,
105
+ });
106
+ if (!result.success) {
107
+ return {
108
+ content: [
109
+ {
110
+ type: 'text',
111
+ text: `Error searching tools: ${result.message || 'Unknown error'}`,
112
+ },
113
+ ],
114
+ isError: true,
115
+ };
116
+ }
117
+ // Filter by integration if specified
118
+ let tools = result.data;
119
+ if (integrationFilter) {
120
+ const filterLower = integrationFilter.toLowerCase();
121
+ tools = tools.filter((t) => t.integrationName?.toLowerCase().includes(filterLower) ||
122
+ t.integrationSlug?.toLowerCase().includes(filterLower));
123
+ }
124
+ // Format output
125
+ const output = {
126
+ tools: tools.map((t) => ({
127
+ id: t.id,
128
+ name: t.name,
129
+ description: t.description,
130
+ integrationName: t.integrationName,
131
+ integrationSlug: t.integrationSlug,
132
+ category: t.category,
133
+ similarity: t.similarity,
134
+ inputSchema: t.inputSchema,
135
+ })),
136
+ totalFound: tools.length,
137
+ };
138
+ // Create human-readable summary
139
+ const summary = tools.length > 0
140
+ ? tools
141
+ .map((t, i) => `${i + 1}. **${t.name}** (${t.integrationName || 'Unknown'})\n` +
142
+ ` ID: ${t.id}\n` +
143
+ ` ${t.description || 'No description'}\n` +
144
+ ` Similarity: ${((t.similarity || 0) * 100).toFixed(1)}%`)
145
+ .join('\n\n')
146
+ : 'No tools found matching your query.';
147
+ return {
148
+ content: [
149
+ {
150
+ type: 'text',
151
+ text: `Found ${tools.length} tool(s):\n\n${summary}`,
152
+ },
153
+ ],
154
+ structuredContent: output,
155
+ };
156
+ });
157
+ // ============================================================================
158
+ // Tool: list-integrations
159
+ // ============================================================================
160
+ server.registerTool('list-integrations', {
161
+ title: 'List Integrations',
162
+ description: 'List available integrations/apps that can be connected.',
163
+ inputSchema: {
164
+ search: z
165
+ .string()
166
+ .optional()
167
+ .describe('Optional: Search term to filter integrations'),
168
+ limit: z
169
+ .number()
170
+ .min(1)
171
+ .max(100)
172
+ .optional()
173
+ .describe('Maximum number of results (default: 20)'),
174
+ },
175
+ outputSchema: {
176
+ integrations: z.array(z.object({
177
+ id: z.string(),
178
+ name: z.string(),
179
+ slug: z.string(),
180
+ description: z.string().optional(),
181
+ })),
182
+ totalFound: z.number(),
183
+ },
184
+ }, async ({ search, limit }) => {
185
+ const result = await client.listIntegrations(search, limit || 20);
186
+ if (!result.success) {
187
+ return {
188
+ content: [
189
+ {
190
+ type: 'text',
191
+ text: `Error listing integrations: ${result.error || 'Unknown error'}`,
192
+ },
193
+ ],
194
+ isError: true,
195
+ };
196
+ }
197
+ const integrations = result.data || [];
198
+ const output = {
199
+ integrations: integrations.map((i) => ({
200
+ id: i.id,
201
+ name: i.name,
202
+ slug: i.slug,
203
+ description: i.description,
204
+ })),
205
+ totalFound: integrations.length,
206
+ };
207
+ const summary = integrations.length > 0
208
+ ? integrations
209
+ .map((i, idx) => `${idx + 1}. **${i.name}** (${i.slug})\n` +
210
+ ` ID: ${i.id}\n` +
211
+ (i.description ? ` ${i.description}` : ''))
212
+ .join('\n\n')
213
+ : 'No integrations found.';
214
+ return {
215
+ content: [
216
+ {
217
+ type: 'text',
218
+ text: `Found ${integrations.length} integration(s):\n\n${summary}`,
219
+ },
220
+ ],
221
+ structuredContent: output,
222
+ };
223
+ });
224
+ // ============================================================================
225
+ // Tool: list-connections
226
+ // ============================================================================
227
+ server.registerTool('list-connections', {
228
+ title: 'List Connections',
229
+ description: 'List all active integration connections. ' +
230
+ 'Use this to see which integrations are already connected.',
231
+ inputSchema: {},
232
+ outputSchema: {
233
+ connections: z.array(z.object({
234
+ id: z.string(),
235
+ integrationName: z.string().nullable().optional(),
236
+ status: z.string(),
237
+ expiresAt: z.string().nullable().optional(),
238
+ })),
239
+ totalConnections: z.number(),
240
+ },
241
+ }, async () => {
242
+ const result = await client.listConnections();
243
+ if (!result.success) {
244
+ return {
245
+ content: [
246
+ {
247
+ type: 'text',
248
+ text: `Error listing connections: ${result.error || 'Unknown error'}`,
249
+ },
250
+ ],
251
+ isError: true,
252
+ };
253
+ }
254
+ const connections = result.data || [];
255
+ const output = {
256
+ connections: connections.map((c) => ({
257
+ id: c.id,
258
+ integrationName: c.integrationName ?? null,
259
+ status: c.status,
260
+ expiresAt: c.expiresAt ?? null,
261
+ })),
262
+ totalConnections: connections.length,
263
+ };
264
+ const summary = connections.length > 0
265
+ ? connections
266
+ .map((c, i) => `${i + 1}. **${c.integrationName || 'Unknown'}**\n` +
267
+ ` Connection ID: ${c.id}\n` +
268
+ ` Status: ${c.status}\n` +
269
+ (c.expiresAt ? ` Expires: ${c.expiresAt}` : ''))
270
+ .join('\n\n')
271
+ : 'No connections found.';
272
+ return {
273
+ content: [
274
+ {
275
+ type: 'text',
276
+ text: `Found ${connections.length} connection(s):\n\n${summary}`,
277
+ },
278
+ ],
279
+ structuredContent: output,
280
+ };
281
+ });
282
+ // ============================================================================
283
+ // Tool: connect-app
284
+ // ============================================================================
285
+ server.registerTool('connect-app', {
286
+ title: 'Connect App',
287
+ description: 'Connect to an integration/app. For API key integrations, provide the API key directly. ' +
288
+ 'For OAuth integrations, this will return an authorization URL for the user to complete.',
289
+ inputSchema: {
290
+ integration: z
291
+ .string()
292
+ .describe('Integration ID or slug to connect (e.g., "slack", "github")'),
293
+ apiKey: z
294
+ .string()
295
+ .optional()
296
+ .describe('API key for the integration (required for API key auth type)'),
297
+ scopes: z
298
+ .array(z.string())
299
+ .optional()
300
+ .describe('OAuth scopes to request (for OAuth integrations)'),
301
+ },
302
+ outputSchema: {
303
+ connectionId: z.string().optional(),
304
+ authUrl: z.string().optional(),
305
+ status: z.string(),
306
+ message: z.string(),
307
+ },
308
+ }, async ({ integration, apiKey, scopes }) => {
309
+ const result = await client.initiateConnection({
310
+ integrationId: integration,
311
+ apiKey,
312
+ scopes,
313
+ });
314
+ if (!result.success) {
315
+ return {
316
+ content: [
317
+ {
318
+ type: 'text',
319
+ text: `Error connecting to integration: ${result.message || 'Unknown error'}`,
320
+ },
321
+ ],
322
+ isError: true,
323
+ };
324
+ }
325
+ const data = result.data;
326
+ // OAuth flow - return auth URL
327
+ if (data?.authUrl) {
328
+ const output = {
329
+ authUrl: data.authUrl,
330
+ status: 'pending_authorization',
331
+ message: 'Please open the authorization URL to complete the connection.',
332
+ };
333
+ return {
334
+ content: [
335
+ {
336
+ type: 'text',
337
+ text: `**OAuth Authorization Required**\n\n` +
338
+ `Please open this URL in a browser to authorize the connection:\n\n` +
339
+ `${data.authUrl}\n\n` +
340
+ `After authorization, the connection will be active.`,
341
+ },
342
+ ],
343
+ structuredContent: output,
344
+ };
345
+ }
346
+ // API key auth - connection created directly
347
+ if (data?.connectionId) {
348
+ const output = {
349
+ connectionId: data.connectionId,
350
+ status: data.status || 'active',
351
+ message: 'Connection created successfully.',
352
+ };
353
+ return {
354
+ content: [
355
+ {
356
+ type: 'text',
357
+ text: `**Connection Created Successfully**\n\n` +
358
+ `Connection ID: ${data.connectionId}\n` +
359
+ `Status: ${data.status || 'active'}\n\n` +
360
+ `You can now use execute-tool with this connection.`,
361
+ },
362
+ ],
363
+ structuredContent: output,
364
+ };
365
+ }
366
+ return {
367
+ content: [
368
+ {
369
+ type: 'text',
370
+ text: 'Unexpected response from connection initiation.',
371
+ },
372
+ ],
373
+ isError: true,
374
+ };
375
+ });
376
+ // ============================================================================
377
+ // Tool: execute-tool
378
+ // ============================================================================
379
+ server.registerTool('execute-tool', {
380
+ title: 'Execute Tool',
381
+ description: 'Execute an integration action/tool. Requires an active connection for the integration.',
382
+ inputSchema: {
383
+ action: z
384
+ .string()
385
+ .describe('Action ID or slug to execute (get this from search-tools)'),
386
+ parameters: z
387
+ .record(z.unknown())
388
+ .describe('Parameters for the action (check inputSchema from search-tools)'),
389
+ timeout: z
390
+ .number()
391
+ .optional()
392
+ .describe('Execution timeout in milliseconds (default: 30000)'),
393
+ },
394
+ outputSchema: {
395
+ success: z.boolean(),
396
+ output: z.record(z.unknown()).optional(),
397
+ duration: z.number().optional(),
398
+ status: z.string(),
399
+ error: z.string().optional(),
400
+ },
401
+ }, async ({ action, parameters, timeout }) => {
402
+ const result = await client.executeAction({
403
+ actionId: action,
404
+ parameters,
405
+ timeout: timeout || 30000,
406
+ });
407
+ if (!result.success) {
408
+ const output = {
409
+ success: false,
410
+ status: 'failure',
411
+ error: result.error || 'Execution failed',
412
+ };
413
+ return {
414
+ content: [
415
+ {
416
+ type: 'text',
417
+ text: `**Execution Failed**\n\nError: ${output.error}`,
418
+ },
419
+ ],
420
+ structuredContent: output,
421
+ isError: true,
422
+ };
423
+ }
424
+ const data = result.data;
425
+ const output = {
426
+ success: true,
427
+ output: data?.output,
428
+ duration: data?.duration,
429
+ status: data?.status || 'success',
430
+ };
431
+ // Format output for display
432
+ const outputStr = data?.output
433
+ ? JSON.stringify(data.output, null, 2)
434
+ : 'No output';
435
+ return {
436
+ content: [
437
+ {
438
+ type: 'text',
439
+ text: `**Execution Successful**\n\n` +
440
+ `Status: ${data?.status || 'success'}\n` +
441
+ (data?.duration ? `Duration: ${data.duration}ms\n` : '') +
442
+ `\nOutput:\n\`\`\`json\n${outputStr}\n\`\`\``,
443
+ },
444
+ ],
445
+ structuredContent: output,
446
+ };
447
+ });
448
+ // ============================================================================
449
+ // Tool: disconnect-app
450
+ // ============================================================================
451
+ server.registerTool('disconnect-app', {
452
+ title: 'Disconnect App',
453
+ description: 'Disconnect from an integration, revoking all connections.',
454
+ inputSchema: {
455
+ integration: z
456
+ .string()
457
+ .describe('Integration ID or slug to disconnect'),
458
+ },
459
+ outputSchema: {
460
+ success: z.boolean(),
461
+ message: z.string(),
462
+ },
463
+ }, async ({ integration }) => {
464
+ const result = await client.disconnectConnection(integration);
465
+ if (!result.success) {
466
+ return {
467
+ content: [
468
+ {
469
+ type: 'text',
470
+ text: `Error disconnecting: ${result.error || 'Unknown error'}`,
471
+ },
472
+ ],
473
+ isError: true,
474
+ };
475
+ }
476
+ return {
477
+ content: [
478
+ {
479
+ type: 'text',
480
+ text: `**Disconnected Successfully**\n\nIntegration "${integration}" has been disconnected.`,
481
+ },
482
+ ],
483
+ structuredContent: {
484
+ success: true,
485
+ message: 'Disconnected successfully',
486
+ },
487
+ };
488
+ });
489
+ // ============================================================================
490
+ // Start Server
491
+ // ============================================================================
492
+ async function main() {
493
+ const transport = new StdioServerTransport();
494
+ await server.connect(transport);
495
+ // Log to stderr (stdout is used for MCP communication)
496
+ console.error('Platoona MCP server started');
497
+ console.error(`API Key: ${PLATOONA_API_KEY.slice(0, 8)}...`);
498
+ console.error(`MCP User ID: ${MCP_USER_ID}`);
499
+ }
500
+ main().catch((error) => {
501
+ console.error('Failed to start server:', error);
502
+ process.exit(1);
503
+ });
504
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}