@mediagraph/mcp 1.0.11 → 1.0.13
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/app/index.html +150 -0
- package/dist/index.js +318 -50
- package/package.json +16 -3
package/dist/index.js
CHANGED
|
@@ -12,6 +12,9 @@ import {
|
|
|
12
12
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
13
13
|
import { exec } from "child_process";
|
|
14
14
|
import { platform } from "os";
|
|
15
|
+
import { readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
|
|
16
|
+
import { fileURLToPath } from "url";
|
|
17
|
+
import { dirname as dirname2, join as join2 } from "path";
|
|
15
18
|
|
|
16
19
|
// src/auth/oauth.ts
|
|
17
20
|
import { createHash, randomBytes } from "crypto";
|
|
@@ -660,13 +663,32 @@ var MediagraphClient = class {
|
|
|
660
663
|
return this.request("GET", `/api/assets/${id}/face_taggings`);
|
|
661
664
|
}
|
|
662
665
|
async getAssetDownload(id, options) {
|
|
663
|
-
const
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
666
|
+
const prepareResponse = await this.createDownload({
|
|
667
|
+
asset_ids: [typeof id === "string" ? parseInt(id, 10) : id],
|
|
668
|
+
size: options?.size || "original",
|
|
669
|
+
watermarked: options?.watermarked,
|
|
670
|
+
via: options?.via,
|
|
671
|
+
skip_meta: options?.skip_meta
|
|
672
|
+
});
|
|
673
|
+
const downloadUrl = `${this.apiUrl}/api/downloads/${prepareResponse.token}`;
|
|
674
|
+
return {
|
|
675
|
+
url: downloadUrl,
|
|
676
|
+
filename: prepareResponse.filename || `asset-${id}`
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
async getBulkDownload(options) {
|
|
680
|
+
const prepareResponse = await this.createDownload({
|
|
681
|
+
asset_ids: options.asset_ids,
|
|
682
|
+
size: options.size || "original",
|
|
683
|
+
watermarked: options.watermarked,
|
|
684
|
+
via: options.via,
|
|
685
|
+
skip_meta: options.skip_meta
|
|
686
|
+
});
|
|
687
|
+
const downloadUrl = `${this.apiUrl}/api/downloads/${prepareResponse.token}`;
|
|
688
|
+
return {
|
|
689
|
+
url: downloadUrl,
|
|
690
|
+
filename: prepareResponse.filename || `mediagraph-download-${options.asset_ids.length}-assets.zip`
|
|
691
|
+
};
|
|
670
692
|
}
|
|
671
693
|
async addAssetVersion(id, data) {
|
|
672
694
|
return this.request("POST", `/api/assets/${id}/add_version`, { body: data });
|
|
@@ -1247,7 +1269,20 @@ var MediagraphClient = class {
|
|
|
1247
1269
|
return this.request("GET", `/api/downloads/${token}`);
|
|
1248
1270
|
}
|
|
1249
1271
|
async createDownload(data) {
|
|
1250
|
-
|
|
1272
|
+
const download = {
|
|
1273
|
+
asset_ids: data.asset_ids,
|
|
1274
|
+
size: data.size
|
|
1275
|
+
};
|
|
1276
|
+
if (data.watermarked === true) {
|
|
1277
|
+
download.watermarked = true;
|
|
1278
|
+
}
|
|
1279
|
+
if (data.via) {
|
|
1280
|
+
download.via = data.via;
|
|
1281
|
+
}
|
|
1282
|
+
if (data.skip_meta === true) {
|
|
1283
|
+
download.skip_meta = true;
|
|
1284
|
+
}
|
|
1285
|
+
return this.request("POST", "/api/downloads", { body: { download } });
|
|
1251
1286
|
}
|
|
1252
1287
|
// ============================================================================
|
|
1253
1288
|
// Webhooks
|
|
@@ -1649,6 +1684,29 @@ COMMON SEARCH FIELDS:
|
|
|
1649
1684
|
required: ["id"]
|
|
1650
1685
|
}
|
|
1651
1686
|
},
|
|
1687
|
+
{
|
|
1688
|
+
name: "bulk_download_assets",
|
|
1689
|
+
description: "Get a download URL for multiple assets (returns a ZIP file)",
|
|
1690
|
+
inputSchema: {
|
|
1691
|
+
type: "object",
|
|
1692
|
+
properties: {
|
|
1693
|
+
asset_ids: {
|
|
1694
|
+
type: "array",
|
|
1695
|
+
items: { type: "number" },
|
|
1696
|
+
description: "Array of asset IDs to download"
|
|
1697
|
+
},
|
|
1698
|
+
size: {
|
|
1699
|
+
type: "string",
|
|
1700
|
+
enum: ["small", "permalink", "full", "original"],
|
|
1701
|
+
description: "Maximum size for all assets in the download (default: original)"
|
|
1702
|
+
},
|
|
1703
|
+
watermarked: { type: "boolean", description: "Request watermarked versions" },
|
|
1704
|
+
via: { type: "string", description: "Description of the app or integration making the call" },
|
|
1705
|
+
skip_meta: { type: "boolean", description: "Do not write metadata to files" }
|
|
1706
|
+
},
|
|
1707
|
+
required: ["asset_ids"]
|
|
1708
|
+
}
|
|
1709
|
+
},
|
|
1652
1710
|
{
|
|
1653
1711
|
name: "get_asset_auto_tags",
|
|
1654
1712
|
description: "Get AI-generated auto tags for an asset",
|
|
@@ -1728,6 +1786,15 @@ COMMON SEARCH FIELDS:
|
|
|
1728
1786
|
version_number: args.version_number
|
|
1729
1787
|
}));
|
|
1730
1788
|
},
|
|
1789
|
+
async bulk_download_assets(args, { client: client2 }) {
|
|
1790
|
+
return successResult(await client2.getBulkDownload({
|
|
1791
|
+
asset_ids: args.asset_ids,
|
|
1792
|
+
size: args.size,
|
|
1793
|
+
watermarked: args.watermarked,
|
|
1794
|
+
via: args.via,
|
|
1795
|
+
skip_meta: args.skip_meta
|
|
1796
|
+
}));
|
|
1797
|
+
},
|
|
1731
1798
|
async get_asset_auto_tags(args, { client: client2 }) {
|
|
1732
1799
|
return successResult(await client2.getAssetAutoTags(args.id));
|
|
1733
1800
|
},
|
|
@@ -2647,8 +2714,8 @@ var downloadTools = {
|
|
|
2647
2714
|
asset_ids: { type: "array", items: { type: "number" } },
|
|
2648
2715
|
size: {
|
|
2649
2716
|
type: "string",
|
|
2650
|
-
enum: ["small", "
|
|
2651
|
-
description: "Maximum size requested for assets in the download"
|
|
2717
|
+
enum: ["small", "medium", "full", "original"],
|
|
2718
|
+
description: "Maximum size requested for assets in the download (default: original)"
|
|
2652
2719
|
}
|
|
2653
2720
|
},
|
|
2654
2721
|
required: ["asset_ids"]
|
|
@@ -2662,7 +2729,8 @@ var downloadTools = {
|
|
|
2662
2729
|
],
|
|
2663
2730
|
handlers: {
|
|
2664
2731
|
async create_download(args, { client: client2 }) {
|
|
2665
|
-
|
|
2732
|
+
const { asset_ids, size = "original" } = args;
|
|
2733
|
+
return successResult(await client2.createDownload({ asset_ids, size }));
|
|
2666
2734
|
},
|
|
2667
2735
|
async get_download(args, { client: client2 }) {
|
|
2668
2736
|
return successResult(await client2.getDownload(args.token));
|
|
@@ -3281,6 +3349,100 @@ var adminTools = {
|
|
|
3281
3349
|
}
|
|
3282
3350
|
};
|
|
3283
3351
|
|
|
3352
|
+
// src/tools/app.ts
|
|
3353
|
+
var appTools = {
|
|
3354
|
+
definitions: [
|
|
3355
|
+
{
|
|
3356
|
+
name: "search_assets_visual",
|
|
3357
|
+
description: `Search for assets and display results in an interactive visual gallery.
|
|
3358
|
+
|
|
3359
|
+
This tool provides a rich visual interface for browsing search results with:
|
|
3360
|
+
- Thumbnail grid with hover previews
|
|
3361
|
+
- Click to view full asset details
|
|
3362
|
+
- Inline editing of metadata
|
|
3363
|
+
- Rating, tagging, and download options
|
|
3364
|
+
- Pagination controls
|
|
3365
|
+
|
|
3366
|
+
Use this when the user wants to visually browse or explore assets.`,
|
|
3367
|
+
inputSchema: {
|
|
3368
|
+
type: "object",
|
|
3369
|
+
properties: {
|
|
3370
|
+
q: { type: "string", description: "Search query with optional advanced operators (AND, OR, NOT, field:value, wildcards)" },
|
|
3371
|
+
...paginationParams,
|
|
3372
|
+
ids: { type: "array", items: { type: "number" }, description: "Filter by specific asset IDs" },
|
|
3373
|
+
guids: { type: "array", items: { type: "string" }, description: "Filter by specific asset GUIDs" },
|
|
3374
|
+
tags: { type: "array", items: { type: "string" }, description: "Filter by tags" },
|
|
3375
|
+
collection_id: { type: "number", description: "Filter by collection ID" },
|
|
3376
|
+
storage_folder_id: { type: "number", description: "Filter by storage folder ID" },
|
|
3377
|
+
lightbox_id: { type: "number", description: "Filter by lightbox ID" },
|
|
3378
|
+
exts: { type: "array", items: { type: "string" }, description: "Filter by file extensions" },
|
|
3379
|
+
rating: { type: "array", items: { type: "number" }, description: "Filter by rating range [min, max]" },
|
|
3380
|
+
aspect: { type: "string", enum: ["square", "portrait", "landscape", "panorama"] },
|
|
3381
|
+
has_people: { type: "string", enum: ["yes", "no", "untagged"] },
|
|
3382
|
+
has_alt_text: { type: "string", enum: ["yes", "no"] },
|
|
3383
|
+
gps: { type: "boolean", description: "Filter for assets with GPS data" },
|
|
3384
|
+
captured_at: { type: "array", items: { type: "string" }, description: "Date range [start, end] in ISO 8601" },
|
|
3385
|
+
created_at: { type: "array", items: { type: "string" }, description: "Date range [start, end] in ISO 8601" }
|
|
3386
|
+
},
|
|
3387
|
+
required: []
|
|
3388
|
+
},
|
|
3389
|
+
// MCP Apps metadata - tells the host to display the UI
|
|
3390
|
+
// Include both formats for compatibility with different host versions
|
|
3391
|
+
_meta: {
|
|
3392
|
+
ui: {
|
|
3393
|
+
resourceUri: "ui://mediagraph/gallery"
|
|
3394
|
+
},
|
|
3395
|
+
"ui/resourceUri": "ui://mediagraph/gallery"
|
|
3396
|
+
// Legacy format for older hosts
|
|
3397
|
+
}
|
|
3398
|
+
}
|
|
3399
|
+
],
|
|
3400
|
+
handlers: {
|
|
3401
|
+
async search_assets_visual(args, { client: client2, organizationSlug }) {
|
|
3402
|
+
const params = {
|
|
3403
|
+
...args,
|
|
3404
|
+
include_renditions: false,
|
|
3405
|
+
// Don't include all renditions to reduce size
|
|
3406
|
+
include_totals: true,
|
|
3407
|
+
per_page: args.per_page || 24
|
|
3408
|
+
// Reasonable default
|
|
3409
|
+
};
|
|
3410
|
+
const response = await client2.searchAssets(params);
|
|
3411
|
+
const lightAssets = response.assets.map((asset) => ({
|
|
3412
|
+
id: asset.id,
|
|
3413
|
+
guid: asset.guid,
|
|
3414
|
+
filename: asset.filename,
|
|
3415
|
+
title: asset.title,
|
|
3416
|
+
description: asset.description,
|
|
3417
|
+
alt_text: asset.alt_text,
|
|
3418
|
+
type: asset.type || asset.file_type,
|
|
3419
|
+
ext: asset.ext,
|
|
3420
|
+
width: asset.width,
|
|
3421
|
+
height: asset.height,
|
|
3422
|
+
duration: asset.duration,
|
|
3423
|
+
rating: asset.rating,
|
|
3424
|
+
// Tags come as objects from API, extract just the names
|
|
3425
|
+
tags: asset.tags?.map((tag) => typeof tag === "string" ? tag : tag.name).filter(Boolean),
|
|
3426
|
+
thumb_url: asset.thumb_url,
|
|
3427
|
+
grid_url: asset.grid_url,
|
|
3428
|
+
small_url: asset.small_url,
|
|
3429
|
+
preview_url: asset.preview_url,
|
|
3430
|
+
created_at: asset.created_at,
|
|
3431
|
+
updated_at: asset.updated_at,
|
|
3432
|
+
captured_at: asset.captured_at
|
|
3433
|
+
}));
|
|
3434
|
+
return successResult({
|
|
3435
|
+
assets: lightAssets,
|
|
3436
|
+
total: response.total,
|
|
3437
|
+
page: response.page,
|
|
3438
|
+
per_page: response.per_page,
|
|
3439
|
+
total_pages: response.total_pages,
|
|
3440
|
+
organization_slug: organizationSlug
|
|
3441
|
+
});
|
|
3442
|
+
}
|
|
3443
|
+
}
|
|
3444
|
+
};
|
|
3445
|
+
|
|
3284
3446
|
// src/tools/index.ts
|
|
3285
3447
|
var allToolModules = [
|
|
3286
3448
|
userTools,
|
|
@@ -3296,7 +3458,8 @@ var allToolModules = [
|
|
|
3296
3458
|
downloadTools,
|
|
3297
3459
|
uploadTools,
|
|
3298
3460
|
webhookTools,
|
|
3299
|
-
adminTools
|
|
3461
|
+
adminTools,
|
|
3462
|
+
appTools
|
|
3300
3463
|
];
|
|
3301
3464
|
var toolDefinitions = allToolModules.flatMap((m) => m.definitions);
|
|
3302
3465
|
var allHandlers = {};
|
|
@@ -3495,31 +3658,56 @@ function openBrowser(url) {
|
|
|
3495
3658
|
}
|
|
3496
3659
|
async function runAutoAuth() {
|
|
3497
3660
|
if (isAuthInProgress) {
|
|
3498
|
-
|
|
3499
|
-
|
|
3661
|
+
console.error("[MCP] OAuth already in progress, waiting for completion...");
|
|
3662
|
+
const waitStart = Date.now();
|
|
3663
|
+
const maxWait = 12e4;
|
|
3664
|
+
while (isAuthInProgress && Date.now() - waitStart < maxWait) {
|
|
3665
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
3666
|
+
}
|
|
3667
|
+
if (isAuthInProgress) {
|
|
3668
|
+
console.error("[MCP] Timed out waiting for existing OAuth flow");
|
|
3669
|
+
return false;
|
|
3500
3670
|
}
|
|
3501
3671
|
return currentTokens !== null;
|
|
3502
3672
|
}
|
|
3503
3673
|
isAuthInProgress = true;
|
|
3674
|
+
console.error("[MCP] Starting OAuth flow...");
|
|
3504
3675
|
try {
|
|
3505
3676
|
const authUrl = oauthHandler.getAuthorizationUrl();
|
|
3506
3677
|
await oauthHandler.startCallbackServer();
|
|
3678
|
+
console.error("[MCP] Callback server ready, opening browser...");
|
|
3507
3679
|
openBrowser(authUrl);
|
|
3680
|
+
console.error("[MCP] Waiting for OAuth callback...");
|
|
3508
3681
|
const { code } = await oauthHandler.waitForCallback();
|
|
3682
|
+
console.error("[MCP] OAuth callback received, exchanging code...");
|
|
3509
3683
|
const tokens = await oauthHandler.exchangeCode(code);
|
|
3510
3684
|
currentTokens = tokens;
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
tokens,
|
|
3514
|
-
organizationId: whoami.organization.id,
|
|
3515
|
-
organizationName: whoami.organization.name,
|
|
3516
|
-
userId: whoami.user.id,
|
|
3517
|
-
userEmail: whoami.user.email
|
|
3518
|
-
};
|
|
3685
|
+
console.error("[MCP] Token exchange successful");
|
|
3686
|
+
let storedData = { tokens };
|
|
3519
3687
|
tokenStore.save(storedData);
|
|
3688
|
+
try {
|
|
3689
|
+
const whoami = await client.whoami();
|
|
3690
|
+
if (whoami?.organization?.id) {
|
|
3691
|
+
const org = whoami.organization;
|
|
3692
|
+
storedData = {
|
|
3693
|
+
tokens,
|
|
3694
|
+
organizationId: org.id,
|
|
3695
|
+
organizationName: org.title || org.name,
|
|
3696
|
+
organizationSlug: org.slug,
|
|
3697
|
+
userId: whoami.user?.id,
|
|
3698
|
+
userEmail: whoami.user?.email
|
|
3699
|
+
};
|
|
3700
|
+
tokenStore.save(storedData);
|
|
3701
|
+
console.error(`[MCP] Authenticated as ${whoami.user?.email} in ${org.title || org.name}`);
|
|
3702
|
+
} else {
|
|
3703
|
+
console.error("[MCP] Authenticated (whoami returned incomplete data)");
|
|
3704
|
+
}
|
|
3705
|
+
} catch (whoamiError) {
|
|
3706
|
+
console.error("[MCP] Authenticated (whoami failed, tokens saved):", whoamiError);
|
|
3707
|
+
}
|
|
3520
3708
|
return true;
|
|
3521
3709
|
} catch (error) {
|
|
3522
|
-
console.error("Auto-auth failed:", error);
|
|
3710
|
+
console.error("[MCP] Auto-auth failed:", error);
|
|
3523
3711
|
oauthHandler.stopCallbackServer();
|
|
3524
3712
|
return false;
|
|
3525
3713
|
} finally {
|
|
@@ -3558,6 +3746,10 @@ var client = new MediagraphClient({
|
|
|
3558
3746
|
});
|
|
3559
3747
|
var toolContext = { client };
|
|
3560
3748
|
var resourceContext = { client };
|
|
3749
|
+
function getOrganizationSlug() {
|
|
3750
|
+
const stored = tokenStore.load();
|
|
3751
|
+
return stored?.organizationSlug;
|
|
3752
|
+
}
|
|
3561
3753
|
var server = new Server(
|
|
3562
3754
|
{
|
|
3563
3755
|
name: "mediagraph-mcp",
|
|
@@ -3579,33 +3771,48 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3579
3771
|
const { name, arguments: args } = request.params;
|
|
3580
3772
|
let token = await getAccessToken();
|
|
3581
3773
|
if (!token) {
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
}
|
|
3774
|
+
if (isAuthInProgress) {
|
|
3775
|
+
console.error("[MCP] OAuth in progress, waiting...");
|
|
3776
|
+
const waitStart = Date.now();
|
|
3777
|
+
const maxWait = 12e4;
|
|
3778
|
+
while (isAuthInProgress && Date.now() - waitStart < maxWait) {
|
|
3779
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
3780
|
+
}
|
|
3781
|
+
token = await getAccessToken();
|
|
3782
|
+
if (token) {
|
|
3783
|
+
console.error("[MCP] OAuth completed, proceeding with request");
|
|
3784
|
+
}
|
|
3593
3785
|
}
|
|
3594
|
-
token = await getAccessToken();
|
|
3595
3786
|
if (!token) {
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3787
|
+
const authSuccess = await runAutoAuth();
|
|
3788
|
+
if (!authSuccess) {
|
|
3789
|
+
return {
|
|
3790
|
+
content: [
|
|
3791
|
+
{
|
|
3792
|
+
type: "text",
|
|
3793
|
+
text: "Authorization is in progress. Please complete the login in your browser, then try this request again."
|
|
3794
|
+
}
|
|
3795
|
+
],
|
|
3796
|
+
isError: true
|
|
3797
|
+
};
|
|
3798
|
+
}
|
|
3799
|
+
token = await getAccessToken();
|
|
3800
|
+
if (!token) {
|
|
3801
|
+
return {
|
|
3802
|
+
content: [
|
|
3803
|
+
{
|
|
3804
|
+
type: "text",
|
|
3805
|
+
text: "Authentication completed but failed to retrieve access token. Please try again."
|
|
3806
|
+
}
|
|
3807
|
+
],
|
|
3808
|
+
isError: true
|
|
3809
|
+
};
|
|
3810
|
+
}
|
|
3605
3811
|
}
|
|
3606
3812
|
}
|
|
3607
3813
|
console.error(`[MCP] Tool call: ${name}`);
|
|
3608
3814
|
console.error(`[MCP] Arguments: ${JSON.stringify(args, null, 2)}`);
|
|
3815
|
+
toolContext.organizationSlug = getOrganizationSlug();
|
|
3609
3816
|
const result = await handleTool(name, args || {}, toolContext);
|
|
3610
3817
|
if (result.isError) {
|
|
3611
3818
|
console.error(`[MCP] Tool error: ${result.content[0]?.text}`);
|
|
@@ -3632,6 +3839,9 @@ server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
|
3632
3839
|
});
|
|
3633
3840
|
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
3634
3841
|
const { uri } = request.params;
|
|
3842
|
+
if (uri.startsWith("ui://mediagraph/")) {
|
|
3843
|
+
return handleAppResource(uri);
|
|
3844
|
+
}
|
|
3635
3845
|
let token = await getAccessToken();
|
|
3636
3846
|
if (!token) {
|
|
3637
3847
|
const authSuccess = await runAutoAuth();
|
|
@@ -3664,6 +3874,57 @@ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
|
3664
3874
|
contents: [content]
|
|
3665
3875
|
};
|
|
3666
3876
|
});
|
|
3877
|
+
function handleAppResource(uri) {
|
|
3878
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
3879
|
+
const __dirname = dirname2(__filename);
|
|
3880
|
+
const appPath = join2(__dirname, "app", "index.html");
|
|
3881
|
+
if (!existsSync2(appPath)) {
|
|
3882
|
+
console.error(`[MCP] App resource not found at: ${appPath}`);
|
|
3883
|
+
return {
|
|
3884
|
+
contents: [
|
|
3885
|
+
{
|
|
3886
|
+
uri,
|
|
3887
|
+
mimeType: "text/plain",
|
|
3888
|
+
text: "MCP App UI not found. Please rebuild the project with npm run build."
|
|
3889
|
+
}
|
|
3890
|
+
]
|
|
3891
|
+
};
|
|
3892
|
+
}
|
|
3893
|
+
try {
|
|
3894
|
+
const html = readFileSync2(appPath, "utf-8");
|
|
3895
|
+
return {
|
|
3896
|
+
contents: [
|
|
3897
|
+
{
|
|
3898
|
+
uri,
|
|
3899
|
+
mimeType: "text/html;profile=mcp-app",
|
|
3900
|
+
text: html,
|
|
3901
|
+
// CSP configuration to allow loading images from Mediagraph CDN
|
|
3902
|
+
_meta: {
|
|
3903
|
+
ui: {
|
|
3904
|
+
csp: {
|
|
3905
|
+
// Allow images from CloudFront CDN
|
|
3906
|
+
resourceDomains: ["https://*.cloudfront.net"],
|
|
3907
|
+
// Allow API calls to Mediagraph (for future use)
|
|
3908
|
+
connectDomains: ["https://api.mediagraph.io"]
|
|
3909
|
+
}
|
|
3910
|
+
}
|
|
3911
|
+
}
|
|
3912
|
+
}
|
|
3913
|
+
]
|
|
3914
|
+
};
|
|
3915
|
+
} catch (error) {
|
|
3916
|
+
console.error("[MCP] Failed to read app resource:", error);
|
|
3917
|
+
return {
|
|
3918
|
+
contents: [
|
|
3919
|
+
{
|
|
3920
|
+
uri,
|
|
3921
|
+
mimeType: "text/plain",
|
|
3922
|
+
text: "Failed to load MCP App UI."
|
|
3923
|
+
}
|
|
3924
|
+
]
|
|
3925
|
+
};
|
|
3926
|
+
}
|
|
3927
|
+
}
|
|
3667
3928
|
async function runAuthorize() {
|
|
3668
3929
|
if (!config.clientId) {
|
|
3669
3930
|
console.error("Error: MEDIAGRAPH_CLIENT_ID environment variable is required");
|
|
@@ -3690,18 +3951,25 @@ async function runAuthorize() {
|
|
|
3690
3951
|
console.log("Tokens received successfully.");
|
|
3691
3952
|
currentTokens = tokens;
|
|
3692
3953
|
const whoami = await client.whoami();
|
|
3954
|
+
console.log("Whoami response:", JSON.stringify(whoami, null, 2));
|
|
3955
|
+
const org = whoami.organization;
|
|
3693
3956
|
const storedData = {
|
|
3694
3957
|
tokens,
|
|
3695
|
-
organizationId:
|
|
3696
|
-
organizationName:
|
|
3697
|
-
|
|
3698
|
-
|
|
3958
|
+
organizationId: org?.id,
|
|
3959
|
+
organizationName: org?.title || org?.name,
|
|
3960
|
+
organizationSlug: org?.slug,
|
|
3961
|
+
userId: whoami.user?.id,
|
|
3962
|
+
userEmail: whoami.user?.email
|
|
3699
3963
|
};
|
|
3700
3964
|
tokenStore.save(storedData);
|
|
3701
3965
|
console.log("");
|
|
3702
3966
|
console.log("Successfully authorized!");
|
|
3703
|
-
|
|
3704
|
-
|
|
3967
|
+
if (org) {
|
|
3968
|
+
console.log(`Organization: ${org.title || org.name} (${org.slug})`);
|
|
3969
|
+
}
|
|
3970
|
+
if (whoami.user) {
|
|
3971
|
+
console.log(`User: ${whoami.user.full_name || whoami.user.email} (${whoami.user.email})`);
|
|
3972
|
+
}
|
|
3705
3973
|
console.log("");
|
|
3706
3974
|
console.log("You can now use the Mediagraph MCP server.");
|
|
3707
3975
|
} catch (error) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mediagraph/mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "MCP server for Mediagraph - Media Asset Management Platform",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -8,10 +8,15 @@
|
|
|
8
8
|
"mediagraph-mcp": "./dist/index.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"build": "tsup src/index.ts --format esm --dts --clean",
|
|
11
|
+
"build": "NODE_ENV=production tsup src/index.ts --format esm --dts --clean && npm run build:app:prod",
|
|
12
|
+
"build:dev": "tsup src/index.ts --format esm --dts --clean && npm run build:app:dev",
|
|
13
|
+
"build:app:prod": "NODE_ENV=production vite build --config vite.config.ts",
|
|
14
|
+
"build:app:dev": "NODE_ENV=development vite build --config vite.config.ts",
|
|
15
|
+
"build:app": "vite build --config vite.config.ts",
|
|
12
16
|
"dev": "tsup src/index.ts --format esm --watch",
|
|
17
|
+
"dev:app": "vite --config vite.config.ts",
|
|
13
18
|
"start": "node dist/index.js",
|
|
14
|
-
"typecheck": "tsc --noEmit",
|
|
19
|
+
"typecheck": "tsc --noEmit && tsc --project tsconfig.app.json --noEmit",
|
|
15
20
|
"lint": "eslint src/**/*.ts",
|
|
16
21
|
"test": "vitest run",
|
|
17
22
|
"test:watch": "vitest",
|
|
@@ -46,13 +51,21 @@
|
|
|
46
51
|
"LICENSE"
|
|
47
52
|
],
|
|
48
53
|
"dependencies": {
|
|
54
|
+
"@modelcontextprotocol/ext-apps": "^1.0.1",
|
|
49
55
|
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
50
56
|
},
|
|
51
57
|
"devDependencies": {
|
|
52
58
|
"@types/node": "^20.10.0",
|
|
59
|
+
"@types/react": "^18.3.0",
|
|
60
|
+
"@types/react-dom": "^18.3.0",
|
|
61
|
+
"@vitejs/plugin-react": "^4.3.0",
|
|
53
62
|
"eslint": "^8.56.0",
|
|
63
|
+
"react": "^18.3.1",
|
|
64
|
+
"react-dom": "^18.3.1",
|
|
54
65
|
"tsup": "^8.0.1",
|
|
55
66
|
"typescript": "^5.3.3",
|
|
67
|
+
"vite": "^5.4.0",
|
|
68
|
+
"vite-plugin-singlefile": "^2.0.0",
|
|
56
69
|
"vitest": "^1.1.0"
|
|
57
70
|
}
|
|
58
71
|
}
|