@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 +1 -1
- package/bin/unroo-heartbeat.sh +2 -2
- package/dist/index.js +363 -1
- package/package.json +1 -1
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://
|
|
237
|
+
Log in to [Unroo](https://app.unroo.io) and check My Day or Timesheet to see your tracked sessions.
|
package/bin/unroo-heartbeat.sh
CHANGED
|
@@ -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://
|
|
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://
|
|
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://
|
|
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.
|
|
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",
|