@fruition/fcp-mcp-server 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -234,4 +234,4 @@ The system learns from this and saves the mapping permanently, so you only need
234
234
 
235
235
  ### Viewing Time
236
236
 
237
- Log in to [Unroo](https://chat.frugpt.com) and check My Day or Timesheet to see your tracked sessions.
237
+ Log in to [Unroo](https://app.unroo.io) and check My Day or Timesheet to see your tracked sessions.
@@ -15,7 +15,7 @@
15
15
  #
16
16
  # Environment variables:
17
17
  # UNROO_API_KEY - Required: Your UnRoo API key with time tracking enabled
18
- # UNROO_API_ENDPOINT - Optional: API base URL (default: https://chat.frugpt.com)
18
+ # UNROO_API_ENDPOINT - Optional: API base URL (default: https://app.unroo.io)
19
19
  # TOOL_NAME - Optional: Name of the tool that was used
20
20
  # TOOL_DESCRIPTION - Optional: Description of what the tool did
21
21
  #
@@ -31,7 +31,7 @@
31
31
 
32
32
  # Configuration
33
33
  EVENT_TYPE="${1:-tool_end}"
34
- API_ENDPOINT="${UNROO_API_ENDPOINT:-https://chat.frugpt.com}"
34
+ API_ENDPOINT="${UNROO_API_ENDPOINT:-https://app.unroo.io}"
35
35
  API_URL="${API_ENDPOINT}/api/unroo/claude-tracker/heartbeat"
36
36
 
37
37
  # Check for API key
package/dist/index.js CHANGED
@@ -39,7 +39,7 @@ const FCP_API_URL = process.env.FCP_API_URL || 'https://fcp.fru.io';
39
39
  const FCP_API_TOKEN = process.env.FCP_API_TOKEN || '';
40
40
  // Unroo API can be called directly (legacy) or proxied through FCP (recommended)
41
41
  // When UNROO_API_KEY is not set, Unroo calls go through FCP's proxy at /api/mcp/unroo/*
42
- const UNROO_API_URL = process.env.UNROO_API_URL || 'https://chat.frugpt.com';
42
+ const UNROO_API_URL = process.env.UNROO_API_URL || 'https://app.unroo.io';
43
43
  const UNROO_API_KEY = process.env.UNROO_API_KEY || '';
44
44
  // If no Unroo key, use FCP as proxy (unified key setup)
45
45
  const USE_FCP_UNROO_PROXY = !UNROO_API_KEY;
@@ -367,6 +367,72 @@ class FCPClient {
367
367
  method: 'POST',
368
368
  });
369
369
  }
370
+ // ============================================================================
371
+ // Backup Management Methods
372
+ // ============================================================================
373
+ async backupListSites() {
374
+ return this.fetch('/api/backup/sites');
375
+ }
376
+ async backupGetConfig() {
377
+ return this.fetch('/api/backup/config');
378
+ }
379
+ async backupListEligible() {
380
+ return this.fetch('/api/backup/eligible');
381
+ }
382
+ async backupEnable(siteId) {
383
+ return this.fetch('/api/backup/enable', {
384
+ method: 'POST',
385
+ body: JSON.stringify({ siteId }),
386
+ });
387
+ }
388
+ async backupTrigger(websiteId, triggerType) {
389
+ return this.fetch('/api/backup/trigger', {
390
+ method: 'POST',
391
+ body: JSON.stringify({ websiteId, triggerType }),
392
+ });
393
+ }
394
+ async backupCheckTrigger(websiteId) {
395
+ return this.fetch(`/api/backup/trigger?websiteId=${websiteId}`);
396
+ }
397
+ async backupListBackups(siteId) {
398
+ return this.fetch(`/api/backup/list?siteId=${encodeURIComponent(siteId)}`);
399
+ }
400
+ async backupGetStatus(options) {
401
+ const params = new URLSearchParams();
402
+ if (options.backupId)
403
+ params.set('backupId', options.backupId);
404
+ if (options.websiteId)
405
+ params.set('websiteId', options.websiteId.toString());
406
+ const query = params.toString();
407
+ return this.fetch(`/api/backup/status${query ? `?${query}` : ''}`);
408
+ }
409
+ async backupDownload(backupId) {
410
+ return this.fetch(`/api/backup/download?backupId=${encodeURIComponent(backupId)}`);
411
+ }
412
+ async backupDownloadPrepared(input) {
413
+ return this.fetch('/api/backup/download', {
414
+ method: 'POST',
415
+ body: JSON.stringify(input),
416
+ });
417
+ }
418
+ async backupListPairings(siteId) {
419
+ const params = new URLSearchParams();
420
+ if (siteId)
421
+ params.set('siteId', siteId.toString());
422
+ const query = params.toString();
423
+ return this.fetch(`/api/backup/pairing${query ? `?${query}` : ''}`);
424
+ }
425
+ async backupUpdatePairing(siteId, pairingConfig) {
426
+ return this.fetch('/api/backup/pairing', {
427
+ method: 'POST',
428
+ body: JSON.stringify({ siteId, pairingConfig }),
429
+ });
430
+ }
431
+ async backupDeletePairing(siteId) {
432
+ return this.fetch(`/api/backup/pairing?siteId=${siteId}`, {
433
+ method: 'DELETE',
434
+ });
435
+ }
370
436
  }
371
437
  // Unroo API Client
372
438
  // Supports two modes:
@@ -1955,6 +2021,10 @@ const TOOLS = [
1955
2021
  type: 'string',
1956
2022
  description: 'Updated backup cron schedule',
1957
2023
  },
2024
+ multisite_root_id: {
2025
+ type: 'number',
2026
+ description: 'Root site ID for WordPress multisite networks. Set to link as a subsite, null to unlink.',
2027
+ },
1958
2028
  },
1959
2029
  required: ['website_id'],
1960
2030
  },
@@ -2104,6 +2174,207 @@ const TOOLS = [
2104
2174
  properties: {},
2105
2175
  },
2106
2176
  },
2177
+ // ============================================================================
2178
+ // Backup Management Tools
2179
+ // ============================================================================
2180
+ {
2181
+ name: 'fcp_backup_list_sites',
2182
+ description: 'List websites with backups enabled. Returns site details including domain, cluster, namespace, and backup schedule.',
2183
+ inputSchema: {
2184
+ type: 'object',
2185
+ properties: {},
2186
+ },
2187
+ },
2188
+ {
2189
+ name: 'fcp_backup_get_config',
2190
+ description: 'Get S3 backup configuration. Admin only. Returns bucket, region, endpoint info (credentials are excluded).',
2191
+ inputSchema: {
2192
+ type: 'object',
2193
+ properties: {},
2194
+ },
2195
+ },
2196
+ {
2197
+ name: 'fcp_backup_list_eligible',
2198
+ description: 'List sites eligible for backup but not yet enabled. Returns sites grouped by environment (production, staging, development).',
2199
+ inputSchema: {
2200
+ type: 'object',
2201
+ properties: {},
2202
+ },
2203
+ },
2204
+ {
2205
+ name: 'fcp_backup_enable',
2206
+ description: 'Enable backup for a site and trigger the first backup automatically.',
2207
+ inputSchema: {
2208
+ type: 'object',
2209
+ properties: {
2210
+ siteId: {
2211
+ type: 'number',
2212
+ description: 'The website ID to enable backups for',
2213
+ },
2214
+ },
2215
+ required: ['siteId'],
2216
+ },
2217
+ },
2218
+ {
2219
+ name: 'fcp_backup_trigger',
2220
+ description: 'Manually trigger a backup for a website. Admin only. Creates a queued backup job.',
2221
+ inputSchema: {
2222
+ type: 'object',
2223
+ properties: {
2224
+ websiteId: {
2225
+ type: 'number',
2226
+ description: 'The website ID to backup',
2227
+ },
2228
+ triggerType: {
2229
+ type: 'string',
2230
+ description: 'Trigger type (default: manual)',
2231
+ },
2232
+ },
2233
+ required: ['websiteId'],
2234
+ },
2235
+ },
2236
+ {
2237
+ name: 'fcp_backup_check_trigger',
2238
+ description: 'Check if a backup can be triggered for a website. Returns hosting status, K8s config, enabled status, and queue length.',
2239
+ inputSchema: {
2240
+ type: 'object',
2241
+ properties: {
2242
+ websiteId: {
2243
+ type: 'number',
2244
+ description: 'The website ID to check',
2245
+ },
2246
+ },
2247
+ required: ['websiteId'],
2248
+ },
2249
+ },
2250
+ {
2251
+ name: 'fcp_backup_list_backups',
2252
+ description: 'List backup history for a site. Returns backup jobs with status, size, duration, and location.',
2253
+ inputSchema: {
2254
+ type: 'object',
2255
+ properties: {
2256
+ siteId: {
2257
+ type: 'number',
2258
+ description: 'The website ID (will be formatted as site-{id} for the API)',
2259
+ },
2260
+ },
2261
+ required: ['siteId'],
2262
+ },
2263
+ },
2264
+ {
2265
+ name: 'fcp_backup_get_status',
2266
+ description: 'Get backup job status. Provide backupId for a specific job, or websiteId for backup history of a site.',
2267
+ inputSchema: {
2268
+ type: 'object',
2269
+ properties: {
2270
+ backupId: {
2271
+ type: 'string',
2272
+ description: 'Specific backup job ID to get status for',
2273
+ },
2274
+ websiteId: {
2275
+ type: 'number',
2276
+ description: 'Website ID to get backup history for',
2277
+ },
2278
+ },
2279
+ },
2280
+ },
2281
+ {
2282
+ name: 'fcp_backup_download',
2283
+ description: 'Generate a presigned S3 download URL for a completed backup. URL expires in 1 hour.',
2284
+ inputSchema: {
2285
+ type: 'object',
2286
+ properties: {
2287
+ backupId: {
2288
+ type: 'string',
2289
+ description: 'The backup ID to download',
2290
+ },
2291
+ },
2292
+ required: ['backupId'],
2293
+ },
2294
+ },
2295
+ {
2296
+ name: 'fcp_backup_download_prepared',
2297
+ description: 'Prepare a backup download with optional sanitization. Returns a presigned download URL with metadata.',
2298
+ inputSchema: {
2299
+ type: 'object',
2300
+ properties: {
2301
+ siteId: {
2302
+ type: 'string',
2303
+ description: 'The site ID (e.g., site-123)',
2304
+ },
2305
+ backupId: {
2306
+ type: 'string',
2307
+ description: 'The backup ID to download',
2308
+ },
2309
+ downloadType: {
2310
+ type: 'string',
2311
+ description: 'Type of download (e.g., database, files)',
2312
+ },
2313
+ format: {
2314
+ type: 'string',
2315
+ description: 'Download format (optional)',
2316
+ },
2317
+ sanitize: {
2318
+ type: 'boolean',
2319
+ description: 'Whether to sanitize production data (optional)',
2320
+ },
2321
+ },
2322
+ required: ['siteId', 'backupId', 'downloadType'],
2323
+ },
2324
+ },
2325
+ {
2326
+ name: 'fcp_backup_list_pairings',
2327
+ description: 'List site pairings for backup management. Optionally filter by site ID. Shows production/staging/dev relationships grouped by account.',
2328
+ inputSchema: {
2329
+ type: 'object',
2330
+ properties: {
2331
+ siteId: {
2332
+ type: 'number',
2333
+ description: 'Optional: specific site ID to get pairing for',
2334
+ },
2335
+ },
2336
+ },
2337
+ },
2338
+ {
2339
+ name: 'fcp_backup_update_pairing',
2340
+ description: 'Create or update a site pairing configuration. Defines staging/development relationships for a site.',
2341
+ inputSchema: {
2342
+ type: 'object',
2343
+ properties: {
2344
+ siteId: {
2345
+ type: 'number',
2346
+ description: 'The site ID to update pairing for',
2347
+ },
2348
+ pairingConfig: {
2349
+ type: 'object',
2350
+ description: 'Pairing configuration with staging (string|null) and development (array) site references',
2351
+ properties: {
2352
+ staging: { type: 'string', description: 'Staging site domain or null' },
2353
+ development: {
2354
+ type: 'array',
2355
+ items: { type: 'string' },
2356
+ description: 'Development site domains',
2357
+ },
2358
+ },
2359
+ },
2360
+ },
2361
+ required: ['siteId', 'pairingConfig'],
2362
+ },
2363
+ },
2364
+ {
2365
+ name: 'fcp_backup_delete_pairing',
2366
+ description: 'Remove a site pairing configuration. Clears the pairing config for a site.',
2367
+ inputSchema: {
2368
+ type: 'object',
2369
+ properties: {
2370
+ siteId: {
2371
+ type: 'number',
2372
+ description: 'The site ID to remove pairing for',
2373
+ },
2374
+ },
2375
+ required: ['siteId'],
2376
+ },
2377
+ },
2107
2378
  ];
2108
2379
  // Register tool handlers
2109
2380
  server.setRequestHandler(ListToolsRequestSchema, async () => {
@@ -2989,6 +3260,97 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
2989
3260
  content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
2990
3261
  };
2991
3262
  }
3263
+ // ============================================================================
3264
+ // Backup Management Handlers
3265
+ // ============================================================================
3266
+ case 'fcp_backup_list_sites': {
3267
+ const result = await client.backupListSites();
3268
+ return {
3269
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
3270
+ };
3271
+ }
3272
+ case 'fcp_backup_get_config': {
3273
+ const result = await client.backupGetConfig();
3274
+ return {
3275
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
3276
+ };
3277
+ }
3278
+ case 'fcp_backup_list_eligible': {
3279
+ const result = await client.backupListEligible();
3280
+ return {
3281
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
3282
+ };
3283
+ }
3284
+ case 'fcp_backup_enable': {
3285
+ const { siteId } = args;
3286
+ const result = await client.backupEnable(siteId);
3287
+ return {
3288
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
3289
+ };
3290
+ }
3291
+ case 'fcp_backup_trigger': {
3292
+ const { websiteId, triggerType } = args;
3293
+ const result = await client.backupTrigger(websiteId, triggerType);
3294
+ return {
3295
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
3296
+ };
3297
+ }
3298
+ case 'fcp_backup_check_trigger': {
3299
+ const { websiteId } = args;
3300
+ const result = await client.backupCheckTrigger(websiteId);
3301
+ return {
3302
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
3303
+ };
3304
+ }
3305
+ case 'fcp_backup_list_backups': {
3306
+ const { siteId } = args;
3307
+ const result = await client.backupListBackups(`site-${siteId}`);
3308
+ return {
3309
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
3310
+ };
3311
+ }
3312
+ case 'fcp_backup_get_status': {
3313
+ const { backupId, websiteId } = args;
3314
+ const result = await client.backupGetStatus({ backupId, websiteId });
3315
+ return {
3316
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
3317
+ };
3318
+ }
3319
+ case 'fcp_backup_download': {
3320
+ const { backupId } = args;
3321
+ const result = await client.backupDownload(backupId);
3322
+ return {
3323
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
3324
+ };
3325
+ }
3326
+ case 'fcp_backup_download_prepared': {
3327
+ const { siteId, backupId, downloadType, format, sanitize } = args;
3328
+ const result = await client.backupDownloadPrepared({ siteId, backupId, downloadType, format, sanitize });
3329
+ return {
3330
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
3331
+ };
3332
+ }
3333
+ case 'fcp_backup_list_pairings': {
3334
+ const { siteId } = args;
3335
+ const result = await client.backupListPairings(siteId);
3336
+ return {
3337
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
3338
+ };
3339
+ }
3340
+ case 'fcp_backup_update_pairing': {
3341
+ const { siteId, pairingConfig } = args;
3342
+ const result = await client.backupUpdatePairing(siteId, pairingConfig);
3343
+ return {
3344
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
3345
+ };
3346
+ }
3347
+ case 'fcp_backup_delete_pairing': {
3348
+ const { siteId } = args;
3349
+ const result = await client.backupDeletePairing(siteId);
3350
+ return {
3351
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
3352
+ };
3353
+ }
2992
3354
  default:
2993
3355
  throw new Error(`Unknown tool: ${name}`);
2994
3356
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fruition/fcp-mcp-server",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "description": "MCP Server for FCP Launch Coordination System - enables Claude Code to interact with FCP launches and track development time",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",