@buzzposter/mcp 0.3.6 → 0.3.7
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 +166 -4
- package/dist/tools.d.ts +16 -0
- package/dist/tools.js +166 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -118,6 +118,79 @@ var BuzzPosterClient = class {
|
|
|
118
118
|
async uploadFromUrl(data) {
|
|
119
119
|
return this.request("POST", "/api/v1/media/upload-from-url", data);
|
|
120
120
|
}
|
|
121
|
+
async uploadFile(filePath, filename) {
|
|
122
|
+
const fs4 = await import("fs");
|
|
123
|
+
const pathMod = await import("path");
|
|
124
|
+
const buffer = fs4.readFileSync(filePath);
|
|
125
|
+
const name = filename || pathMod.basename(filePath);
|
|
126
|
+
const ext = pathMod.extname(name).toLowerCase();
|
|
127
|
+
const mimeMap = {
|
|
128
|
+
".jpg": "image/jpeg",
|
|
129
|
+
".jpeg": "image/jpeg",
|
|
130
|
+
".png": "image/png",
|
|
131
|
+
".gif": "image/gif",
|
|
132
|
+
".webp": "image/webp",
|
|
133
|
+
".svg": "image/svg+xml",
|
|
134
|
+
".mp4": "video/mp4",
|
|
135
|
+
".mov": "video/quicktime",
|
|
136
|
+
".webm": "video/webm"
|
|
137
|
+
};
|
|
138
|
+
const mime = mimeMap[ext] || "application/octet-stream";
|
|
139
|
+
const formData = new FormData();
|
|
140
|
+
formData.append("file", new Blob([buffer], { type: mime }), name);
|
|
141
|
+
const url = new URL(`${this.baseUrl}/api/v1/media/upload`);
|
|
142
|
+
const headers = {
|
|
143
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
144
|
+
};
|
|
145
|
+
if (this.organizationId) {
|
|
146
|
+
headers["X-Organization-Id"] = this.organizationId;
|
|
147
|
+
}
|
|
148
|
+
const res = await fetch(url, { method: "POST", headers, body: formData });
|
|
149
|
+
if (!res.ok) {
|
|
150
|
+
const errorBody = await res.json().catch(() => ({ message: res.statusText }));
|
|
151
|
+
let message = `API error (${res.status})`;
|
|
152
|
+
if (errorBody && typeof errorBody === "object") {
|
|
153
|
+
const b = errorBody;
|
|
154
|
+
if (typeof b.message === "string" && b.message) message = b.message;
|
|
155
|
+
else if (typeof b.error === "string" && b.error) message = b.error;
|
|
156
|
+
}
|
|
157
|
+
throw new Error(`BuzzPoster API error (${res.status}): ${message}`);
|
|
158
|
+
}
|
|
159
|
+
const text = await res.text();
|
|
160
|
+
return text ? JSON.parse(text) : void 0;
|
|
161
|
+
}
|
|
162
|
+
async uploadBase64(data, filename, contentType) {
|
|
163
|
+
const buffer = Buffer.from(data, "base64");
|
|
164
|
+
const mime = contentType || "application/octet-stream";
|
|
165
|
+
const formData = new FormData();
|
|
166
|
+
formData.append("file", new Blob([buffer], { type: mime }), filename);
|
|
167
|
+
const url = new URL(`${this.baseUrl}/api/v1/media/upload`);
|
|
168
|
+
const headers = {
|
|
169
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
170
|
+
};
|
|
171
|
+
if (this.organizationId) {
|
|
172
|
+
headers["X-Organization-Id"] = this.organizationId;
|
|
173
|
+
}
|
|
174
|
+
const res = await fetch(url, { method: "POST", headers, body: formData });
|
|
175
|
+
if (!res.ok) {
|
|
176
|
+
const errorBody = await res.json().catch(() => ({ message: res.statusText }));
|
|
177
|
+
let message = `API error (${res.status})`;
|
|
178
|
+
if (errorBody && typeof errorBody === "object") {
|
|
179
|
+
const b = errorBody;
|
|
180
|
+
if (typeof b.message === "string" && b.message) message = b.message;
|
|
181
|
+
else if (typeof b.error === "string" && b.error) message = b.error;
|
|
182
|
+
}
|
|
183
|
+
throw new Error(`BuzzPoster API error (${res.status}): ${message}`);
|
|
184
|
+
}
|
|
185
|
+
const text = await res.text();
|
|
186
|
+
return text ? JSON.parse(text) : void 0;
|
|
187
|
+
}
|
|
188
|
+
async presignUpload(filename, contentType) {
|
|
189
|
+
return this.request("POST", "/api/v1/media/presign", { filename, content_type: contentType });
|
|
190
|
+
}
|
|
191
|
+
async confirmUpload(key, filename, contentType) {
|
|
192
|
+
return this.request("POST", "/api/v1/media/confirm-upload", { key, filename, content_type: contentType });
|
|
193
|
+
}
|
|
121
194
|
async listMedia() {
|
|
122
195
|
return this.request("GET", "/api/v1/media");
|
|
123
196
|
}
|
|
@@ -1258,14 +1331,17 @@ function registerMediaTools(server2, client2) {
|
|
|
1258
1331
|
"manage_media",
|
|
1259
1332
|
{
|
|
1260
1333
|
title: "Manage Media",
|
|
1261
|
-
description: "Browse assets gallery, upload from URL, list files, or delete media.",
|
|
1334
|
+
description: "Browse assets gallery, upload from URL, local file, or base64 data, list files, or delete media.",
|
|
1262
1335
|
inputSchema: {
|
|
1263
|
-
action: z3.enum(["get_assets", "upload", "list", "delete"]),
|
|
1336
|
+
action: z3.enum(["get_assets", "upload", "upload_file", "upload_base64", "presign", "confirm_upload", "list", "delete"]),
|
|
1264
1337
|
limit: z3.number().optional().describe("Max assets to return (get_assets, default 10, max 20)"),
|
|
1265
1338
|
url: z3.string().optional().describe("Public URL to upload (upload)"),
|
|
1266
|
-
|
|
1339
|
+
file_path: z3.string().optional().describe("Local file path to upload (upload_file)"),
|
|
1340
|
+
data: z3.string().optional().describe("Base64-encoded file contents (upload_base64)"),
|
|
1341
|
+
content_type: z3.string().optional().describe("MIME type e.g. image/png (upload_base64, presign, confirm_upload)"),
|
|
1342
|
+
filename: z3.string().optional().describe("Filename (upload, upload_file, upload_base64, presign, confirm_upload)"),
|
|
1267
1343
|
folder: z3.string().optional().describe("Storage folder path (upload)"),
|
|
1268
|
-
key: z3.string().optional().describe("Media file key/path (delete)"),
|
|
1344
|
+
key: z3.string().optional().describe("Media file key/path (delete, confirm_upload)"),
|
|
1269
1345
|
confirmed: z3.boolean().default(false).describe("Confirm deletion (delete)")
|
|
1270
1346
|
},
|
|
1271
1347
|
annotations: {
|
|
@@ -1342,6 +1418,92 @@ function registerMediaTools(server2, client2) {
|
|
|
1342
1418
|
content: [{ type: "text", text: lines.join("\n") }]
|
|
1343
1419
|
};
|
|
1344
1420
|
}
|
|
1421
|
+
if (args.action === "upload_file") {
|
|
1422
|
+
if (!args.file_path) {
|
|
1423
|
+
return { content: [{ type: "text", text: "file_path is required for upload_file." }], isError: true };
|
|
1424
|
+
}
|
|
1425
|
+
if (!fs2.existsSync(args.file_path)) {
|
|
1426
|
+
return { content: [{ type: "text", text: `File not found: ${args.file_path}` }], isError: true };
|
|
1427
|
+
}
|
|
1428
|
+
const result = await client2.uploadFile(args.file_path, args.filename);
|
|
1429
|
+
const lines = [];
|
|
1430
|
+
lines.push("## Upload Complete");
|
|
1431
|
+
lines.push("");
|
|
1432
|
+
lines.push(`**URL:** ${result.url ?? "unknown"}`);
|
|
1433
|
+
lines.push(`**Filename:** ${result.filename ?? "unknown"}`);
|
|
1434
|
+
lines.push(`**Size:** ${formatSize(result.size)}`);
|
|
1435
|
+
lines.push(`**Type:** ${result.mimeType ?? "unknown"}`);
|
|
1436
|
+
return {
|
|
1437
|
+
content: [{ type: "text", text: lines.join("\n") }]
|
|
1438
|
+
};
|
|
1439
|
+
}
|
|
1440
|
+
if (args.action === "upload_base64") {
|
|
1441
|
+
if (!args.data) {
|
|
1442
|
+
return { content: [{ type: "text", text: "data (base64 string) is required for upload_base64." }], isError: true };
|
|
1443
|
+
}
|
|
1444
|
+
if (!args.filename) {
|
|
1445
|
+
return { content: [{ type: "text", text: "filename is required for upload_base64." }], isError: true };
|
|
1446
|
+
}
|
|
1447
|
+
const result = await client2.uploadBase64(args.data, args.filename, args.content_type);
|
|
1448
|
+
const lines = [];
|
|
1449
|
+
lines.push("## Upload Complete");
|
|
1450
|
+
lines.push("");
|
|
1451
|
+
lines.push(`**URL:** ${result.url ?? "unknown"}`);
|
|
1452
|
+
lines.push(`**Filename:** ${result.filename ?? "unknown"}`);
|
|
1453
|
+
lines.push(`**Size:** ${formatSize(result.size)}`);
|
|
1454
|
+
lines.push(`**Type:** ${result.mimeType ?? "unknown"}`);
|
|
1455
|
+
return {
|
|
1456
|
+
content: [{ type: "text", text: lines.join("\n") }]
|
|
1457
|
+
};
|
|
1458
|
+
}
|
|
1459
|
+
if (args.action === "presign") {
|
|
1460
|
+
if (!args.filename) {
|
|
1461
|
+
return { content: [{ type: "text", text: "filename is required for presign." }], isError: true };
|
|
1462
|
+
}
|
|
1463
|
+
if (!args.content_type) {
|
|
1464
|
+
return { content: [{ type: "text", text: "content_type is required for presign (e.g. image/png)." }], isError: true };
|
|
1465
|
+
}
|
|
1466
|
+
const result = await client2.presignUpload(args.filename, args.content_type);
|
|
1467
|
+
const lines = [];
|
|
1468
|
+
lines.push("## Presigned Upload URL");
|
|
1469
|
+
lines.push("");
|
|
1470
|
+
lines.push(`**Upload URL:** ${result.upload_url}`);
|
|
1471
|
+
lines.push(`**CDN URL:** ${result.cdn_url}`);
|
|
1472
|
+
lines.push(`**Key:** ${result.key}`);
|
|
1473
|
+
lines.push(`**Expires:** ${result.expires_at}`);
|
|
1474
|
+
lines.push("");
|
|
1475
|
+
lines.push("**Step 1:** Upload the file:");
|
|
1476
|
+
lines.push("```");
|
|
1477
|
+
lines.push(`curl -X PUT -H "Content-Type: ${args.content_type}" --data-binary @${args.filename} "${result.upload_url}"`);
|
|
1478
|
+
lines.push("```");
|
|
1479
|
+
lines.push("");
|
|
1480
|
+
lines.push(`**Step 2:** Register the upload by calling this tool with action=confirm_upload, key="${result.key}", filename="${args.filename}", content_type="${args.content_type}"`);
|
|
1481
|
+
return {
|
|
1482
|
+
content: [{ type: "text", text: lines.join("\n") }]
|
|
1483
|
+
};
|
|
1484
|
+
}
|
|
1485
|
+
if (args.action === "confirm_upload") {
|
|
1486
|
+
if (!args.key) {
|
|
1487
|
+
return { content: [{ type: "text", text: "key is required for confirm_upload." }], isError: true };
|
|
1488
|
+
}
|
|
1489
|
+
if (!args.filename) {
|
|
1490
|
+
return { content: [{ type: "text", text: "filename is required for confirm_upload." }], isError: true };
|
|
1491
|
+
}
|
|
1492
|
+
if (!args.content_type) {
|
|
1493
|
+
return { content: [{ type: "text", text: "content_type is required for confirm_upload." }], isError: true };
|
|
1494
|
+
}
|
|
1495
|
+
const result = await client2.confirmUpload(args.key, args.filename, args.content_type);
|
|
1496
|
+
const lines = [];
|
|
1497
|
+
lines.push("## Upload Confirmed");
|
|
1498
|
+
lines.push("");
|
|
1499
|
+
lines.push(`**URL:** ${result.url}`);
|
|
1500
|
+
lines.push(`**Filename:** ${result.filename}`);
|
|
1501
|
+
lines.push(`**Size:** ${formatSize(result.size)}`);
|
|
1502
|
+
lines.push(`**Type:** ${result.mimeType}`);
|
|
1503
|
+
return {
|
|
1504
|
+
content: [{ type: "text", text: lines.join("\n") }]
|
|
1505
|
+
};
|
|
1506
|
+
}
|
|
1345
1507
|
if (args.action === "list") {
|
|
1346
1508
|
const result = await client2.listMedia();
|
|
1347
1509
|
const items = result?.media ?? [];
|
package/dist/tools.d.ts
CHANGED
|
@@ -32,6 +32,22 @@ declare class BuzzPosterClient {
|
|
|
32
32
|
filename?: string;
|
|
33
33
|
folder?: string;
|
|
34
34
|
}): Promise<unknown>;
|
|
35
|
+
uploadFile(filePath: string, filename?: string): Promise<any>;
|
|
36
|
+
uploadBase64(data: string, filename: string, contentType?: string): Promise<any>;
|
|
37
|
+
presignUpload(filename: string, contentType: string): Promise<{
|
|
38
|
+
upload_url: string;
|
|
39
|
+
cdn_url: string;
|
|
40
|
+
key: string;
|
|
41
|
+
expires_at: string;
|
|
42
|
+
}>;
|
|
43
|
+
confirmUpload(key: string, filename: string, contentType: string): Promise<{
|
|
44
|
+
id: number;
|
|
45
|
+
key: string;
|
|
46
|
+
filename: string;
|
|
47
|
+
mimeType: string;
|
|
48
|
+
size: number;
|
|
49
|
+
url: string;
|
|
50
|
+
}>;
|
|
35
51
|
listMedia(): Promise<unknown>;
|
|
36
52
|
deleteMedia(key: string): Promise<unknown>;
|
|
37
53
|
listSubscribers(params?: Record<string, string>): Promise<unknown>;
|
package/dist/tools.js
CHANGED
|
@@ -112,6 +112,79 @@ var BuzzPosterClient = class {
|
|
|
112
112
|
async uploadFromUrl(data) {
|
|
113
113
|
return this.request("POST", "/api/v1/media/upload-from-url", data);
|
|
114
114
|
}
|
|
115
|
+
async uploadFile(filePath, filename) {
|
|
116
|
+
const fs4 = await import("fs");
|
|
117
|
+
const pathMod = await import("path");
|
|
118
|
+
const buffer = fs4.readFileSync(filePath);
|
|
119
|
+
const name = filename || pathMod.basename(filePath);
|
|
120
|
+
const ext = pathMod.extname(name).toLowerCase();
|
|
121
|
+
const mimeMap = {
|
|
122
|
+
".jpg": "image/jpeg",
|
|
123
|
+
".jpeg": "image/jpeg",
|
|
124
|
+
".png": "image/png",
|
|
125
|
+
".gif": "image/gif",
|
|
126
|
+
".webp": "image/webp",
|
|
127
|
+
".svg": "image/svg+xml",
|
|
128
|
+
".mp4": "video/mp4",
|
|
129
|
+
".mov": "video/quicktime",
|
|
130
|
+
".webm": "video/webm"
|
|
131
|
+
};
|
|
132
|
+
const mime = mimeMap[ext] || "application/octet-stream";
|
|
133
|
+
const formData = new FormData();
|
|
134
|
+
formData.append("file", new Blob([buffer], { type: mime }), name);
|
|
135
|
+
const url = new URL(`${this.baseUrl}/api/v1/media/upload`);
|
|
136
|
+
const headers = {
|
|
137
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
138
|
+
};
|
|
139
|
+
if (this.organizationId) {
|
|
140
|
+
headers["X-Organization-Id"] = this.organizationId;
|
|
141
|
+
}
|
|
142
|
+
const res = await fetch(url, { method: "POST", headers, body: formData });
|
|
143
|
+
if (!res.ok) {
|
|
144
|
+
const errorBody = await res.json().catch(() => ({ message: res.statusText }));
|
|
145
|
+
let message = `API error (${res.status})`;
|
|
146
|
+
if (errorBody && typeof errorBody === "object") {
|
|
147
|
+
const b = errorBody;
|
|
148
|
+
if (typeof b.message === "string" && b.message) message = b.message;
|
|
149
|
+
else if (typeof b.error === "string" && b.error) message = b.error;
|
|
150
|
+
}
|
|
151
|
+
throw new Error(`BuzzPoster API error (${res.status}): ${message}`);
|
|
152
|
+
}
|
|
153
|
+
const text = await res.text();
|
|
154
|
+
return text ? JSON.parse(text) : void 0;
|
|
155
|
+
}
|
|
156
|
+
async uploadBase64(data, filename, contentType) {
|
|
157
|
+
const buffer = Buffer.from(data, "base64");
|
|
158
|
+
const mime = contentType || "application/octet-stream";
|
|
159
|
+
const formData = new FormData();
|
|
160
|
+
formData.append("file", new Blob([buffer], { type: mime }), filename);
|
|
161
|
+
const url = new URL(`${this.baseUrl}/api/v1/media/upload`);
|
|
162
|
+
const headers = {
|
|
163
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
164
|
+
};
|
|
165
|
+
if (this.organizationId) {
|
|
166
|
+
headers["X-Organization-Id"] = this.organizationId;
|
|
167
|
+
}
|
|
168
|
+
const res = await fetch(url, { method: "POST", headers, body: formData });
|
|
169
|
+
if (!res.ok) {
|
|
170
|
+
const errorBody = await res.json().catch(() => ({ message: res.statusText }));
|
|
171
|
+
let message = `API error (${res.status})`;
|
|
172
|
+
if (errorBody && typeof errorBody === "object") {
|
|
173
|
+
const b = errorBody;
|
|
174
|
+
if (typeof b.message === "string" && b.message) message = b.message;
|
|
175
|
+
else if (typeof b.error === "string" && b.error) message = b.error;
|
|
176
|
+
}
|
|
177
|
+
throw new Error(`BuzzPoster API error (${res.status}): ${message}`);
|
|
178
|
+
}
|
|
179
|
+
const text = await res.text();
|
|
180
|
+
return text ? JSON.parse(text) : void 0;
|
|
181
|
+
}
|
|
182
|
+
async presignUpload(filename, contentType) {
|
|
183
|
+
return this.request("POST", "/api/v1/media/presign", { filename, content_type: contentType });
|
|
184
|
+
}
|
|
185
|
+
async confirmUpload(key, filename, contentType) {
|
|
186
|
+
return this.request("POST", "/api/v1/media/confirm-upload", { key, filename, content_type: contentType });
|
|
187
|
+
}
|
|
115
188
|
async listMedia() {
|
|
116
189
|
return this.request("GET", "/api/v1/media");
|
|
117
190
|
}
|
|
@@ -1252,14 +1325,17 @@ function registerMediaTools(server, client) {
|
|
|
1252
1325
|
"manage_media",
|
|
1253
1326
|
{
|
|
1254
1327
|
title: "Manage Media",
|
|
1255
|
-
description: "Browse assets gallery, upload from URL, list files, or delete media.",
|
|
1328
|
+
description: "Browse assets gallery, upload from URL, local file, or base64 data, list files, or delete media.",
|
|
1256
1329
|
inputSchema: {
|
|
1257
|
-
action: z3.enum(["get_assets", "upload", "list", "delete"]),
|
|
1330
|
+
action: z3.enum(["get_assets", "upload", "upload_file", "upload_base64", "presign", "confirm_upload", "list", "delete"]),
|
|
1258
1331
|
limit: z3.number().optional().describe("Max assets to return (get_assets, default 10, max 20)"),
|
|
1259
1332
|
url: z3.string().optional().describe("Public URL to upload (upload)"),
|
|
1260
|
-
|
|
1333
|
+
file_path: z3.string().optional().describe("Local file path to upload (upload_file)"),
|
|
1334
|
+
data: z3.string().optional().describe("Base64-encoded file contents (upload_base64)"),
|
|
1335
|
+
content_type: z3.string().optional().describe("MIME type e.g. image/png (upload_base64, presign, confirm_upload)"),
|
|
1336
|
+
filename: z3.string().optional().describe("Filename (upload, upload_file, upload_base64, presign, confirm_upload)"),
|
|
1261
1337
|
folder: z3.string().optional().describe("Storage folder path (upload)"),
|
|
1262
|
-
key: z3.string().optional().describe("Media file key/path (delete)"),
|
|
1338
|
+
key: z3.string().optional().describe("Media file key/path (delete, confirm_upload)"),
|
|
1263
1339
|
confirmed: z3.boolean().default(false).describe("Confirm deletion (delete)")
|
|
1264
1340
|
},
|
|
1265
1341
|
annotations: {
|
|
@@ -1336,6 +1412,92 @@ function registerMediaTools(server, client) {
|
|
|
1336
1412
|
content: [{ type: "text", text: lines.join("\n") }]
|
|
1337
1413
|
};
|
|
1338
1414
|
}
|
|
1415
|
+
if (args.action === "upload_file") {
|
|
1416
|
+
if (!args.file_path) {
|
|
1417
|
+
return { content: [{ type: "text", text: "file_path is required for upload_file." }], isError: true };
|
|
1418
|
+
}
|
|
1419
|
+
if (!fs2.existsSync(args.file_path)) {
|
|
1420
|
+
return { content: [{ type: "text", text: `File not found: ${args.file_path}` }], isError: true };
|
|
1421
|
+
}
|
|
1422
|
+
const result = await client.uploadFile(args.file_path, args.filename);
|
|
1423
|
+
const lines = [];
|
|
1424
|
+
lines.push("## Upload Complete");
|
|
1425
|
+
lines.push("");
|
|
1426
|
+
lines.push(`**URL:** ${result.url ?? "unknown"}`);
|
|
1427
|
+
lines.push(`**Filename:** ${result.filename ?? "unknown"}`);
|
|
1428
|
+
lines.push(`**Size:** ${formatSize(result.size)}`);
|
|
1429
|
+
lines.push(`**Type:** ${result.mimeType ?? "unknown"}`);
|
|
1430
|
+
return {
|
|
1431
|
+
content: [{ type: "text", text: lines.join("\n") }]
|
|
1432
|
+
};
|
|
1433
|
+
}
|
|
1434
|
+
if (args.action === "upload_base64") {
|
|
1435
|
+
if (!args.data) {
|
|
1436
|
+
return { content: [{ type: "text", text: "data (base64 string) is required for upload_base64." }], isError: true };
|
|
1437
|
+
}
|
|
1438
|
+
if (!args.filename) {
|
|
1439
|
+
return { content: [{ type: "text", text: "filename is required for upload_base64." }], isError: true };
|
|
1440
|
+
}
|
|
1441
|
+
const result = await client.uploadBase64(args.data, args.filename, args.content_type);
|
|
1442
|
+
const lines = [];
|
|
1443
|
+
lines.push("## Upload Complete");
|
|
1444
|
+
lines.push("");
|
|
1445
|
+
lines.push(`**URL:** ${result.url ?? "unknown"}`);
|
|
1446
|
+
lines.push(`**Filename:** ${result.filename ?? "unknown"}`);
|
|
1447
|
+
lines.push(`**Size:** ${formatSize(result.size)}`);
|
|
1448
|
+
lines.push(`**Type:** ${result.mimeType ?? "unknown"}`);
|
|
1449
|
+
return {
|
|
1450
|
+
content: [{ type: "text", text: lines.join("\n") }]
|
|
1451
|
+
};
|
|
1452
|
+
}
|
|
1453
|
+
if (args.action === "presign") {
|
|
1454
|
+
if (!args.filename) {
|
|
1455
|
+
return { content: [{ type: "text", text: "filename is required for presign." }], isError: true };
|
|
1456
|
+
}
|
|
1457
|
+
if (!args.content_type) {
|
|
1458
|
+
return { content: [{ type: "text", text: "content_type is required for presign (e.g. image/png)." }], isError: true };
|
|
1459
|
+
}
|
|
1460
|
+
const result = await client.presignUpload(args.filename, args.content_type);
|
|
1461
|
+
const lines = [];
|
|
1462
|
+
lines.push("## Presigned Upload URL");
|
|
1463
|
+
lines.push("");
|
|
1464
|
+
lines.push(`**Upload URL:** ${result.upload_url}`);
|
|
1465
|
+
lines.push(`**CDN URL:** ${result.cdn_url}`);
|
|
1466
|
+
lines.push(`**Key:** ${result.key}`);
|
|
1467
|
+
lines.push(`**Expires:** ${result.expires_at}`);
|
|
1468
|
+
lines.push("");
|
|
1469
|
+
lines.push("**Step 1:** Upload the file:");
|
|
1470
|
+
lines.push("```");
|
|
1471
|
+
lines.push(`curl -X PUT -H "Content-Type: ${args.content_type}" --data-binary @${args.filename} "${result.upload_url}"`);
|
|
1472
|
+
lines.push("```");
|
|
1473
|
+
lines.push("");
|
|
1474
|
+
lines.push(`**Step 2:** Register the upload by calling this tool with action=confirm_upload, key="${result.key}", filename="${args.filename}", content_type="${args.content_type}"`);
|
|
1475
|
+
return {
|
|
1476
|
+
content: [{ type: "text", text: lines.join("\n") }]
|
|
1477
|
+
};
|
|
1478
|
+
}
|
|
1479
|
+
if (args.action === "confirm_upload") {
|
|
1480
|
+
if (!args.key) {
|
|
1481
|
+
return { content: [{ type: "text", text: "key is required for confirm_upload." }], isError: true };
|
|
1482
|
+
}
|
|
1483
|
+
if (!args.filename) {
|
|
1484
|
+
return { content: [{ type: "text", text: "filename is required for confirm_upload." }], isError: true };
|
|
1485
|
+
}
|
|
1486
|
+
if (!args.content_type) {
|
|
1487
|
+
return { content: [{ type: "text", text: "content_type is required for confirm_upload." }], isError: true };
|
|
1488
|
+
}
|
|
1489
|
+
const result = await client.confirmUpload(args.key, args.filename, args.content_type);
|
|
1490
|
+
const lines = [];
|
|
1491
|
+
lines.push("## Upload Confirmed");
|
|
1492
|
+
lines.push("");
|
|
1493
|
+
lines.push(`**URL:** ${result.url}`);
|
|
1494
|
+
lines.push(`**Filename:** ${result.filename}`);
|
|
1495
|
+
lines.push(`**Size:** ${formatSize(result.size)}`);
|
|
1496
|
+
lines.push(`**Type:** ${result.mimeType}`);
|
|
1497
|
+
return {
|
|
1498
|
+
content: [{ type: "text", text: lines.join("\n") }]
|
|
1499
|
+
};
|
|
1500
|
+
}
|
|
1339
1501
|
if (args.action === "list") {
|
|
1340
1502
|
const result = await client.listMedia();
|
|
1341
1503
|
const items = result?.media ?? [];
|