@rv404/mcp-launchpad 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 (139) hide show
  1. package/.env.example +29 -0
  2. package/README.md +248 -0
  3. package/dist/backends/clickup.d.ts +3 -0
  4. package/dist/backends/clickup.d.ts.map +1 -0
  5. package/dist/backends/clickup.js +1550 -0
  6. package/dist/backends/clickup.js.map +1 -0
  7. package/dist/backends/email.d.ts +9 -0
  8. package/dist/backends/email.d.ts.map +1 -0
  9. package/dist/backends/email.js +452 -0
  10. package/dist/backends/email.js.map +1 -0
  11. package/dist/backends/firecrawl.d.ts +3 -0
  12. package/dist/backends/firecrawl.d.ts.map +1 -0
  13. package/dist/backends/firecrawl.js +297 -0
  14. package/dist/backends/firecrawl.js.map +1 -0
  15. package/dist/backends/gemini.d.ts +3 -0
  16. package/dist/backends/gemini.d.ts.map +1 -0
  17. package/dist/backends/gemini.js +702 -0
  18. package/dist/backends/gemini.js.map +1 -0
  19. package/dist/backends/github.d.ts +3 -0
  20. package/dist/backends/github.d.ts.map +1 -0
  21. package/dist/backends/github.js +2129 -0
  22. package/dist/backends/github.js.map +1 -0
  23. package/dist/backends/index.d.ts +2 -0
  24. package/dist/backends/index.d.ts.map +1 -0
  25. package/dist/backends/index.js +27 -0
  26. package/dist/backends/index.js.map +1 -0
  27. package/dist/backends/kie.d.ts +3 -0
  28. package/dist/backends/kie.d.ts.map +1 -0
  29. package/dist/backends/kie.js +399 -0
  30. package/dist/backends/kie.js.map +1 -0
  31. package/dist/backends/n8n.d.ts +3 -0
  32. package/dist/backends/n8n.d.ts.map +1 -0
  33. package/dist/backends/n8n.js +414 -0
  34. package/dist/backends/n8n.js.map +1 -0
  35. package/dist/backends/notion.d.ts +3 -0
  36. package/dist/backends/notion.d.ts.map +1 -0
  37. package/dist/backends/notion.js +375 -0
  38. package/dist/backends/notion.js.map +1 -0
  39. package/dist/backends/quickbooks.d.ts +3 -0
  40. package/dist/backends/quickbooks.d.ts.map +1 -0
  41. package/dist/backends/quickbooks.js +2183 -0
  42. package/dist/backends/quickbooks.js.map +1 -0
  43. package/dist/backends/slack.d.ts +3 -0
  44. package/dist/backends/slack.d.ts.map +1 -0
  45. package/dist/backends/slack.js +1725 -0
  46. package/dist/backends/slack.js.map +1 -0
  47. package/dist/backends/youtube.d.ts +3 -0
  48. package/dist/backends/youtube.d.ts.map +1 -0
  49. package/dist/backends/youtube.js +936 -0
  50. package/dist/backends/youtube.js.map +1 -0
  51. package/dist/index.d.ts +3 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +150 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/router.d.ts +36 -0
  56. package/dist/router.d.ts.map +1 -0
  57. package/dist/router.js +283 -0
  58. package/dist/router.js.map +1 -0
  59. package/dist/types.d.ts +103 -0
  60. package/dist/types.d.ts.map +1 -0
  61. package/dist/types.js +65 -0
  62. package/dist/types.js.map +1 -0
  63. package/lib/mcp-file-output/dist/index.d.ts +99 -0
  64. package/lib/mcp-file-output/dist/index.d.ts.map +1 -0
  65. package/lib/mcp-file-output/dist/index.js +215 -0
  66. package/lib/mcp-file-output/dist/index.js.map +1 -0
  67. package/lib/mcp-file-output/node_modules/@types/node/LICENSE +21 -0
  68. package/lib/mcp-file-output/node_modules/@types/node/README.md +15 -0
  69. package/lib/mcp-file-output/node_modules/@types/node/assert/strict.d.ts +8 -0
  70. package/lib/mcp-file-output/node_modules/@types/node/assert.d.ts +1062 -0
  71. package/lib/mcp-file-output/node_modules/@types/node/async_hooks.d.ts +605 -0
  72. package/lib/mcp-file-output/node_modules/@types/node/buffer.buffer.d.ts +471 -0
  73. package/lib/mcp-file-output/node_modules/@types/node/buffer.d.ts +1936 -0
  74. package/lib/mcp-file-output/node_modules/@types/node/child_process.d.ts +1475 -0
  75. package/lib/mcp-file-output/node_modules/@types/node/cluster.d.ts +577 -0
  76. package/lib/mcp-file-output/node_modules/@types/node/compatibility/disposable.d.ts +16 -0
  77. package/lib/mcp-file-output/node_modules/@types/node/compatibility/index.d.ts +9 -0
  78. package/lib/mcp-file-output/node_modules/@types/node/compatibility/indexable.d.ts +20 -0
  79. package/lib/mcp-file-output/node_modules/@types/node/compatibility/iterators.d.ts +21 -0
  80. package/lib/mcp-file-output/node_modules/@types/node/console.d.ts +452 -0
  81. package/lib/mcp-file-output/node_modules/@types/node/constants.d.ts +21 -0
  82. package/lib/mcp-file-output/node_modules/@types/node/crypto.d.ts +4590 -0
  83. package/lib/mcp-file-output/node_modules/@types/node/dgram.d.ts +597 -0
  84. package/lib/mcp-file-output/node_modules/@types/node/diagnostics_channel.d.ts +578 -0
  85. package/lib/mcp-file-output/node_modules/@types/node/dns/promises.d.ts +479 -0
  86. package/lib/mcp-file-output/node_modules/@types/node/dns.d.ts +871 -0
  87. package/lib/mcp-file-output/node_modules/@types/node/domain.d.ts +170 -0
  88. package/lib/mcp-file-output/node_modules/@types/node/events.d.ts +977 -0
  89. package/lib/mcp-file-output/node_modules/@types/node/fs/promises.d.ts +1270 -0
  90. package/lib/mcp-file-output/node_modules/@types/node/fs.d.ts +4375 -0
  91. package/lib/mcp-file-output/node_modules/@types/node/globals.d.ts +172 -0
  92. package/lib/mcp-file-output/node_modules/@types/node/globals.typedarray.d.ts +38 -0
  93. package/lib/mcp-file-output/node_modules/@types/node/http.d.ts +2049 -0
  94. package/lib/mcp-file-output/node_modules/@types/node/http2.d.ts +2631 -0
  95. package/lib/mcp-file-output/node_modules/@types/node/https.d.ts +578 -0
  96. package/lib/mcp-file-output/node_modules/@types/node/index.d.ts +93 -0
  97. package/lib/mcp-file-output/node_modules/@types/node/inspector.generated.d.ts +3966 -0
  98. package/lib/mcp-file-output/node_modules/@types/node/module.d.ts +539 -0
  99. package/lib/mcp-file-output/node_modules/@types/node/net.d.ts +1012 -0
  100. package/lib/mcp-file-output/node_modules/@types/node/os.d.ts +506 -0
  101. package/lib/mcp-file-output/node_modules/@types/node/package.json +140 -0
  102. package/lib/mcp-file-output/node_modules/@types/node/path.d.ts +200 -0
  103. package/lib/mcp-file-output/node_modules/@types/node/perf_hooks.d.ts +961 -0
  104. package/lib/mcp-file-output/node_modules/@types/node/process.d.ts +1957 -0
  105. package/lib/mcp-file-output/node_modules/@types/node/punycode.d.ts +117 -0
  106. package/lib/mcp-file-output/node_modules/@types/node/querystring.d.ts +152 -0
  107. package/lib/mcp-file-output/node_modules/@types/node/readline/promises.d.ts +162 -0
  108. package/lib/mcp-file-output/node_modules/@types/node/readline.d.ts +589 -0
  109. package/lib/mcp-file-output/node_modules/@types/node/repl.d.ts +430 -0
  110. package/lib/mcp-file-output/node_modules/@types/node/sea.d.ts +153 -0
  111. package/lib/mcp-file-output/node_modules/@types/node/stream/consumers.d.ts +38 -0
  112. package/lib/mcp-file-output/node_modules/@types/node/stream/promises.d.ts +90 -0
  113. package/lib/mcp-file-output/node_modules/@types/node/stream/web.d.ts +533 -0
  114. package/lib/mcp-file-output/node_modules/@types/node/stream.d.ts +1675 -0
  115. package/lib/mcp-file-output/node_modules/@types/node/string_decoder.d.ts +67 -0
  116. package/lib/mcp-file-output/node_modules/@types/node/test.d.ts +1787 -0
  117. package/lib/mcp-file-output/node_modules/@types/node/timers/promises.d.ts +108 -0
  118. package/lib/mcp-file-output/node_modules/@types/node/timers.d.ts +286 -0
  119. package/lib/mcp-file-output/node_modules/@types/node/tls.d.ts +1255 -0
  120. package/lib/mcp-file-output/node_modules/@types/node/trace_events.d.ts +197 -0
  121. package/lib/mcp-file-output/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +468 -0
  122. package/lib/mcp-file-output/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +34 -0
  123. package/lib/mcp-file-output/node_modules/@types/node/ts5.6/index.d.ts +93 -0
  124. package/lib/mcp-file-output/node_modules/@types/node/tty.d.ts +208 -0
  125. package/lib/mcp-file-output/node_modules/@types/node/url.d.ts +964 -0
  126. package/lib/mcp-file-output/node_modules/@types/node/util.d.ts +2331 -0
  127. package/lib/mcp-file-output/node_modules/@types/node/v8.d.ts +809 -0
  128. package/lib/mcp-file-output/node_modules/@types/node/vm.d.ts +1001 -0
  129. package/lib/mcp-file-output/node_modules/@types/node/wasi.d.ts +181 -0
  130. package/lib/mcp-file-output/node_modules/@types/node/web-globals/abortcontroller.d.ts +34 -0
  131. package/lib/mcp-file-output/node_modules/@types/node/web-globals/domexception.d.ts +68 -0
  132. package/lib/mcp-file-output/node_modules/@types/node/web-globals/events.d.ts +97 -0
  133. package/lib/mcp-file-output/node_modules/@types/node/web-globals/fetch.d.ts +46 -0
  134. package/lib/mcp-file-output/node_modules/@types/node/worker_threads.d.ts +715 -0
  135. package/lib/mcp-file-output/node_modules/@types/node/zlib.d.ts +540 -0
  136. package/lib/mcp-file-output/package.json +19 -0
  137. package/lib/mcp-file-output/src/index.ts +309 -0
  138. package/lib/mcp-file-output/tsconfig.json +20 -0
  139. package/package.json +64 -0
@@ -0,0 +1,309 @@
1
+ import { promises as fs } from 'fs';
2
+ import path from 'path';
3
+
4
+ // ============================================================================
5
+ // Configuration
6
+ // ============================================================================
7
+
8
+ // Default data root - can be overridden via environment variable or init()
9
+ // Uses environment variable, or falls back to a folder in user's home directory
10
+ const getDefaultDataRoot = (): string => {
11
+ const homeDir = process.env.HOME || process.env.USERPROFILE || '.';
12
+ return path.join(homeDir, '.router-mcp', 'data');
13
+ };
14
+ let DATA_ROOT = process.env.MCP_FILE_OUTPUT_DIR || process.env.ROUTER_MCP_DATA_DIR || getDefaultDataRoot();
15
+ const TOKEN_THRESHOLD = 20000; // Auto-save responses exceeding this estimated token count
16
+ const CHARS_PER_TOKEN = 4; // Rough estimate for token calculation
17
+
18
+ /**
19
+ * Initialize the file output utility with a custom data root
20
+ */
21
+ export function init(dataRoot: string): void {
22
+ DATA_ROOT = dataRoot;
23
+ }
24
+
25
+ /**
26
+ * Get the current data root directory
27
+ */
28
+ export function getDataRoot(): string {
29
+ return DATA_ROOT;
30
+ }
31
+
32
+ // ============================================================================
33
+ // Types
34
+ // ============================================================================
35
+
36
+ export interface FileOutputConfig {
37
+ service: string;
38
+ action: string;
39
+ outputType?: 'temp' | 'outputs' | 'cache';
40
+ filename?: string;
41
+ subdir?: string;
42
+ }
43
+
44
+ export interface FileOutputResult {
45
+ saved: boolean;
46
+ path?: string;
47
+ dir?: string;
48
+ files?: string[];
49
+ manifest?: string;
50
+ bytesSaved?: number;
51
+ reason?: string;
52
+ }
53
+
54
+ export interface ManifestEntry {
55
+ filename: string;
56
+ url?: string;
57
+ title?: string;
58
+ timestamp: string;
59
+ bytes: number;
60
+ }
61
+
62
+ export interface OutputManifest {
63
+ service: string;
64
+ action: string;
65
+ created: string;
66
+ totalFiles: number;
67
+ totalBytes: number;
68
+ files: ManifestEntry[];
69
+ metadata?: Record<string, unknown>;
70
+ }
71
+
72
+ // ============================================================================
73
+ // Utility Functions
74
+ // ============================================================================
75
+
76
+ function estimateTokens(data: unknown): number {
77
+ const str = typeof data === 'string' ? data : JSON.stringify(data);
78
+ return Math.ceil(str.length / CHARS_PER_TOKEN);
79
+ }
80
+
81
+ function sanitizeFilename(name: string): string {
82
+ return name
83
+ .replace(/[<>:"/\\|?*]/g, '-')
84
+ .replace(/\s+/g, '-')
85
+ .replace(/-+/g, '-')
86
+ .replace(/^-|-$/g, '')
87
+ .substring(0, 100);
88
+ }
89
+
90
+ function generateTimestamp(): string {
91
+ return new Date().toISOString().replace(/[:.]/g, '-').substring(0, 19);
92
+ }
93
+
94
+ async function ensureDir(dirPath: string): Promise<void> {
95
+ await fs.mkdir(dirPath, { recursive: true });
96
+ }
97
+
98
+ // ============================================================================
99
+ // Core Functions
100
+ // ============================================================================
101
+
102
+ /**
103
+ * Determines if a response should be saved to disk based on size
104
+ */
105
+ export function shouldSaveToDisk(data: unknown, forceFile?: boolean): boolean {
106
+ if (forceFile) return true;
107
+ return estimateTokens(data) > TOKEN_THRESHOLD;
108
+ }
109
+
110
+ /**
111
+ * Gets the output directory path for a given configuration
112
+ */
113
+ export function getOutputDir(config: FileOutputConfig): string {
114
+ const { service, outputType = 'outputs', subdir } = config;
115
+ const parts = [DATA_ROOT, outputType, service];
116
+ if (subdir) parts.push(subdir);
117
+ return path.join(...parts);
118
+ }
119
+
120
+ /**
121
+ * Saves a single file and returns the result
122
+ */
123
+ export async function saveFile(
124
+ data: string | Buffer,
125
+ config: FileOutputConfig
126
+ ): Promise<FileOutputResult> {
127
+ const dir = getOutputDir(config);
128
+ await ensureDir(dir);
129
+
130
+ const filename = config.filename || `${config.action}-${generateTimestamp()}`;
131
+ const ext = typeof data === 'string' ? '.json' : '';
132
+ const fullFilename = filename.includes('.') ? filename : `${filename}${ext}`;
133
+ const filePath = path.join(dir, fullFilename);
134
+
135
+ const content = typeof data === 'string' ? data : data;
136
+ await fs.writeFile(filePath, content, typeof data === 'string' ? 'utf-8' : undefined);
137
+
138
+ const stats = await fs.stat(filePath);
139
+
140
+ return {
141
+ saved: true,
142
+ path: filePath,
143
+ bytesSaved: stats.size,
144
+ };
145
+ }
146
+
147
+ /**
148
+ * Saves multiple files with a manifest - ideal for crawl results
149
+ */
150
+ export async function saveMultipleFiles(
151
+ files: Array<{ filename: string; content: string; url?: string; title?: string }>,
152
+ config: FileOutputConfig,
153
+ metadata?: Record<string, unknown>
154
+ ): Promise<FileOutputResult> {
155
+ const timestamp = generateTimestamp();
156
+ const subdir = config.subdir || timestamp;
157
+ const dir = getOutputDir({ ...config, subdir });
158
+ await ensureDir(dir);
159
+
160
+ const manifestEntries: ManifestEntry[] = [];
161
+ let totalBytes = 0;
162
+
163
+ // Save each file
164
+ for (const file of files) {
165
+ const safeName = sanitizeFilename(file.filename);
166
+ const filePath = path.join(dir, safeName);
167
+ await fs.writeFile(filePath, file.content, 'utf-8');
168
+
169
+ const stats = await fs.stat(filePath);
170
+ totalBytes += stats.size;
171
+
172
+ manifestEntries.push({
173
+ filename: safeName,
174
+ url: file.url,
175
+ title: file.title,
176
+ timestamp: new Date().toISOString(),
177
+ bytes: stats.size,
178
+ });
179
+ }
180
+
181
+ // Create manifest
182
+ const manifest: OutputManifest = {
183
+ service: config.service,
184
+ action: config.action,
185
+ created: new Date().toISOString(),
186
+ totalFiles: files.length,
187
+ totalBytes,
188
+ files: manifestEntries,
189
+ metadata,
190
+ };
191
+
192
+ const manifestPath = path.join(dir, 'manifest.json');
193
+ await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2), 'utf-8');
194
+
195
+ return {
196
+ saved: true,
197
+ dir,
198
+ files: manifestEntries.map(e => e.filename),
199
+ manifest: manifestPath,
200
+ bytesSaved: totalBytes,
201
+ };
202
+ }
203
+
204
+ /**
205
+ * Saves large response data automatically if it exceeds threshold
206
+ * Returns either the original data (if small) or a reference to saved file(s)
207
+ */
208
+ export async function handleLargeResponse<T>(
209
+ data: T,
210
+ config: FileOutputConfig,
211
+ options?: {
212
+ forceFile?: boolean;
213
+ returnData?: boolean;
214
+ }
215
+ ): Promise<{ data: T; fileOutput?: FileOutputResult } | { data: { savedToFile: true; location: string; summary: string }; fileOutput: FileOutputResult }> {
216
+ const shouldSave = shouldSaveToDisk(data, options?.forceFile);
217
+
218
+ if (!shouldSave) {
219
+ return { data };
220
+ }
221
+
222
+ const result = await saveFile(
223
+ JSON.stringify(data, null, 2),
224
+ config
225
+ );
226
+
227
+ const summary = generateSummary(data);
228
+
229
+ return {
230
+ data: {
231
+ savedToFile: true,
232
+ location: result.path!,
233
+ summary,
234
+ } as unknown as T,
235
+ fileOutput: result,
236
+ };
237
+ }
238
+
239
+ /**
240
+ * Generates a brief summary of saved data for the response
241
+ */
242
+ function generateSummary(data: unknown): string {
243
+ if (Array.isArray(data)) {
244
+ return `Array with ${data.length} items`;
245
+ }
246
+ if (typeof data === 'object' && data !== null) {
247
+ const keys = Object.keys(data);
248
+ return `Object with keys: ${keys.slice(0, 5).join(', ')}${keys.length > 5 ? '...' : ''}`;
249
+ }
250
+ return `${typeof data} data`;
251
+ }
252
+
253
+ /**
254
+ * Cleans up old temp files (utility for manual cleanup)
255
+ */
256
+ export async function cleanupTempFiles(olderThanDays?: number): Promise<{ deleted: number; freedBytes: number }> {
257
+ const tempDir = path.join(DATA_ROOT, 'temp');
258
+ let deleted = 0;
259
+ let freedBytes = 0;
260
+
261
+ try {
262
+ const services = await fs.readdir(tempDir);
263
+
264
+ for (const service of services) {
265
+ const serviceDir = path.join(tempDir, service);
266
+ const stats = await fs.stat(serviceDir);
267
+
268
+ if (stats.isDirectory()) {
269
+ const files = await fs.readdir(serviceDir);
270
+
271
+ for (const file of files) {
272
+ const filePath = path.join(serviceDir, file);
273
+ const fileStats = await fs.stat(filePath);
274
+
275
+ if (olderThanDays) {
276
+ const ageInDays = (Date.now() - fileStats.mtime.getTime()) / (1000 * 60 * 60 * 24);
277
+ if (ageInDays < olderThanDays) continue;
278
+ }
279
+
280
+ freedBytes += fileStats.size;
281
+ await fs.rm(filePath, { recursive: true });
282
+ deleted++;
283
+ }
284
+ }
285
+ }
286
+ } catch {
287
+ // Temp dir might not exist yet
288
+ }
289
+
290
+ return { deleted, freedBytes };
291
+ }
292
+
293
+ // ============================================================================
294
+ // Default Export
295
+ // ============================================================================
296
+
297
+ export const fileOutput = {
298
+ init,
299
+ getDataRoot,
300
+ shouldSaveToDisk,
301
+ getOutputDir,
302
+ saveFile,
303
+ saveMultipleFiles,
304
+ handleLargeResponse,
305
+ cleanupTempFiles,
306
+ TOKEN_THRESHOLD,
307
+ };
308
+
309
+ export default fileOutput;
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "lib": ["ES2022"],
7
+ "declaration": true,
8
+ "declarationMap": true,
9
+ "sourceMap": true,
10
+ "outDir": "./dist",
11
+ "rootDir": "./src",
12
+ "strict": true,
13
+ "esModuleInterop": true,
14
+ "skipLibCheck": true,
15
+ "forceConsistentCasingInFileNames": true,
16
+ "resolveJsonModule": true
17
+ },
18
+ "include": ["src/**/*"],
19
+ "exclude": ["node_modules", "dist"]
20
+ }
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@rv404/mcp-launchpad",
3
+ "version": "1.0.0",
4
+ "description": "Unified MCP router for Claude Code - ClickUp, Notion, GitHub, Slack, n8n, Gemini, QuickBooks, Firecrawl, YouTube, Kie.ai",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "mcp-launchpad": "./dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build:lib": "cd lib/mcp-file-output && npx tsc",
12
+ "build": "npm run build:lib && tsc",
13
+ "start": "node dist/index.js",
14
+ "dev": "tsc --watch",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "keywords": [
18
+ "mcp",
19
+ "model-context-protocol",
20
+ "claude",
21
+ "claude-code",
22
+ "router",
23
+ "notion",
24
+ "slack",
25
+ "github",
26
+ "n8n",
27
+ "gemini",
28
+ "quickbooks"
29
+ ],
30
+ "author": "404-rv",
31
+ "license": "MIT",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+https://github.com/404-rv/mcp-launchpad.git"
35
+ },
36
+ "bugs": {
37
+ "url": "https://github.com/404-rv/mcp-launchpad/issues"
38
+ },
39
+ "homepage": "https://github.com/404-rv/mcp-launchpad#readme",
40
+ "files": [
41
+ "dist",
42
+ "lib",
43
+ ".env.example"
44
+ ],
45
+ "engines": {
46
+ "node": ">=18.0.0"
47
+ },
48
+ "dependencies": {
49
+ "@mendable/firecrawl-js": "^4.9.1",
50
+ "@modelcontextprotocol/sdk": "^1.0.4",
51
+ "@octokit/rest": "^21.0.0",
52
+ "axios": "^1.7.9",
53
+ "dotenv": "^16.4.7",
54
+ "form-data": "^4.0.5",
55
+ "google-auth-library": "^9.14.0",
56
+ "googleapis": "^144.0.0",
57
+ "mcp-file-output": "file:./lib/mcp-file-output",
58
+ "zod": "^3.24.1"
59
+ },
60
+ "devDependencies": {
61
+ "@types/node": "^22.10.2",
62
+ "typescript": "^5.7.2"
63
+ }
64
+ }