nworks 0.4.0 → 0.6.1
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 +69 -7
- package/dist/index.js +774 -51
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +562 -45
- package/dist/mcp.js.map +1 -1
- package/package.json +1 -1
package/dist/mcp.js
CHANGED
|
@@ -14060,6 +14060,9 @@ async function listUsers(profile = "default") {
|
|
|
14060
14060
|
return { users: result.users ?? [], responseMetaData: result.responseMetaData };
|
|
14061
14061
|
}
|
|
14062
14062
|
|
|
14063
|
+
// src/api/calendar.ts
|
|
14064
|
+
import { randomUUID } from "crypto";
|
|
14065
|
+
|
|
14063
14066
|
// src/auth/oauth-user.ts
|
|
14064
14067
|
import { createServer } from "http";
|
|
14065
14068
|
import { URL as URL2 } from "url";
|
|
@@ -14110,50 +14113,177 @@ async function getValidUserToken(profile = "default") {
|
|
|
14110
14113
|
|
|
14111
14114
|
// src/api/calendar.ts
|
|
14112
14115
|
var BASE_URL2 = "https://www.worksapis.com/v1.0";
|
|
14113
|
-
async function
|
|
14116
|
+
async function authedFetch(url2, init, profile) {
|
|
14114
14117
|
const token = await getValidUserToken(profile);
|
|
14118
|
+
const headers = new Headers(init.headers);
|
|
14119
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
14120
|
+
return fetch(url2, { ...init, headers });
|
|
14121
|
+
}
|
|
14122
|
+
async function handleError(res) {
|
|
14123
|
+
if (res.status === 401) {
|
|
14124
|
+
throw new AuthError("User token expired. Run `nworks login --user --scope calendar` again.");
|
|
14125
|
+
}
|
|
14126
|
+
let code = "UNKNOWN";
|
|
14127
|
+
let description = `HTTP ${res.status}`;
|
|
14128
|
+
try {
|
|
14129
|
+
const body = await res.json();
|
|
14130
|
+
code = body.code ?? code;
|
|
14131
|
+
description = body.description ?? description;
|
|
14132
|
+
} catch {
|
|
14133
|
+
}
|
|
14134
|
+
throw new ApiError(code, description, res.status);
|
|
14135
|
+
}
|
|
14136
|
+
function generateEventId() {
|
|
14137
|
+
return `event-${randomUUID()}`;
|
|
14138
|
+
}
|
|
14139
|
+
function normalizeDateTime(dt) {
|
|
14140
|
+
const match = dt.match(/^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2})([+-]\d{2}:\d{2}|Z)?$/);
|
|
14141
|
+
if (match) {
|
|
14142
|
+
return `${match[1]}:00${match[2] ?? ""}`;
|
|
14143
|
+
}
|
|
14144
|
+
return dt;
|
|
14145
|
+
}
|
|
14146
|
+
async function listEvents(fromDateTime, untilDateTime, userId = "me", profile = "default") {
|
|
14115
14147
|
const from = encodeURIComponent(fromDateTime);
|
|
14116
14148
|
const until = encodeURIComponent(untilDateTime);
|
|
14117
14149
|
const url2 = `${BASE_URL2}/users/${userId}/calendar/events?fromDateTime=${from}&untilDateTime=${until}`;
|
|
14118
14150
|
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14119
14151
|
console.error(`[nworks] GET ${url2}`);
|
|
14120
14152
|
}
|
|
14121
|
-
const res = await
|
|
14122
|
-
|
|
14123
|
-
|
|
14124
|
-
|
|
14125
|
-
|
|
14126
|
-
|
|
14127
|
-
|
|
14128
|
-
|
|
14129
|
-
|
|
14153
|
+
const res = await authedFetch(url2, { method: "GET" }, profile);
|
|
14154
|
+
if (!res.ok) return handleError(res);
|
|
14155
|
+
const data = await res.json();
|
|
14156
|
+
return { events: data.events ?? [] };
|
|
14157
|
+
}
|
|
14158
|
+
async function createEvent(opts) {
|
|
14159
|
+
const userId = opts.userId ?? "me";
|
|
14160
|
+
const profile = opts.profile ?? "default";
|
|
14161
|
+
const timeZone = opts.timeZone ?? "Asia/Seoul";
|
|
14162
|
+
const eventId = generateEventId();
|
|
14163
|
+
const eventComponent = {
|
|
14164
|
+
eventId,
|
|
14165
|
+
summary: opts.summary,
|
|
14166
|
+
start: { dateTime: normalizeDateTime(opts.start), timeZone },
|
|
14167
|
+
end: { dateTime: normalizeDateTime(opts.end), timeZone }
|
|
14168
|
+
};
|
|
14169
|
+
if (opts.description) eventComponent.description = opts.description;
|
|
14170
|
+
if (opts.location) eventComponent.location = opts.location;
|
|
14171
|
+
if (opts.transparency) eventComponent.transparency = opts.transparency;
|
|
14172
|
+
if (opts.visibility) eventComponent.visibility = opts.visibility;
|
|
14173
|
+
if (opts.attendees) {
|
|
14174
|
+
eventComponent.attendees = opts.attendees.map((a) => ({
|
|
14175
|
+
email: a.email,
|
|
14176
|
+
displayName: a.displayName ?? "",
|
|
14177
|
+
partstat: "NEEDS-ACTION",
|
|
14178
|
+
isOptional: false,
|
|
14179
|
+
isResource: false
|
|
14180
|
+
}));
|
|
14130
14181
|
}
|
|
14131
|
-
|
|
14132
|
-
|
|
14133
|
-
|
|
14134
|
-
|
|
14135
|
-
|
|
14136
|
-
|
|
14137
|
-
|
|
14138
|
-
|
|
14139
|
-
|
|
14140
|
-
|
|
14182
|
+
const body = {
|
|
14183
|
+
eventComponents: [eventComponent],
|
|
14184
|
+
sendNotification: opts.sendNotification ?? false
|
|
14185
|
+
};
|
|
14186
|
+
const url2 = `${BASE_URL2}/users/${userId}/calendar/events`;
|
|
14187
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14188
|
+
console.error(`[nworks] POST ${url2}`);
|
|
14189
|
+
console.error(`[nworks] Body: ${JSON.stringify(body, null, 2)}`);
|
|
14190
|
+
}
|
|
14191
|
+
const res = await authedFetch(
|
|
14192
|
+
url2,
|
|
14193
|
+
{
|
|
14194
|
+
method: "POST",
|
|
14195
|
+
headers: { "Content-Type": "application/json" },
|
|
14196
|
+
body: JSON.stringify(body)
|
|
14197
|
+
},
|
|
14198
|
+
profile
|
|
14199
|
+
);
|
|
14200
|
+
if (res.status === 201) {
|
|
14201
|
+
return await res.json();
|
|
14202
|
+
}
|
|
14203
|
+
if (!res.ok) return handleError(res);
|
|
14204
|
+
return await res.json();
|
|
14205
|
+
}
|
|
14206
|
+
async function getEvent(eventId, userId = "me", profile = "default") {
|
|
14207
|
+
const url2 = `${BASE_URL2}/users/${userId}/calendar/events/${eventId}`;
|
|
14208
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14209
|
+
console.error(`[nworks] GET ${url2}`);
|
|
14141
14210
|
}
|
|
14211
|
+
const res = await authedFetch(url2, { method: "GET" }, profile);
|
|
14212
|
+
if (!res.ok) return handleError(res);
|
|
14142
14213
|
const data = await res.json();
|
|
14143
|
-
return
|
|
14214
|
+
return data.eventComponents[0];
|
|
14215
|
+
}
|
|
14216
|
+
async function updateEvent(opts) {
|
|
14217
|
+
const userId = opts.userId ?? "me";
|
|
14218
|
+
const profile = opts.profile ?? "default";
|
|
14219
|
+
const timeZone = opts.timeZone ?? "Asia/Seoul";
|
|
14220
|
+
const existing = await getEvent(opts.eventId, userId, profile);
|
|
14221
|
+
const eventComponent = {
|
|
14222
|
+
eventId: opts.eventId,
|
|
14223
|
+
summary: opts.summary ?? existing.summary,
|
|
14224
|
+
start: opts.start ? { dateTime: normalizeDateTime(opts.start), timeZone } : existing.start,
|
|
14225
|
+
end: opts.end ? { dateTime: normalizeDateTime(opts.end), timeZone } : existing.end
|
|
14226
|
+
};
|
|
14227
|
+
if (opts.description !== void 0) eventComponent.description = opts.description;
|
|
14228
|
+
else if (existing.description) eventComponent.description = existing.description;
|
|
14229
|
+
if (opts.location !== void 0) eventComponent.location = opts.location;
|
|
14230
|
+
else if (existing.location) eventComponent.location = existing.location;
|
|
14231
|
+
if (opts.transparency !== void 0) eventComponent.transparency = opts.transparency;
|
|
14232
|
+
if (opts.visibility !== void 0) eventComponent.visibility = opts.visibility;
|
|
14233
|
+
if (opts.attendees !== void 0) {
|
|
14234
|
+
eventComponent.attendees = opts.attendees.map((a) => ({
|
|
14235
|
+
email: a.email,
|
|
14236
|
+
displayName: a.displayName ?? "",
|
|
14237
|
+
partstat: "NEEDS-ACTION",
|
|
14238
|
+
isOptional: false,
|
|
14239
|
+
isResource: false
|
|
14240
|
+
}));
|
|
14241
|
+
} else if (existing.attendees) {
|
|
14242
|
+
eventComponent.attendees = existing.attendees;
|
|
14243
|
+
}
|
|
14244
|
+
const body = {
|
|
14245
|
+
eventComponents: [eventComponent],
|
|
14246
|
+
sendNotification: opts.sendNotification ?? false
|
|
14247
|
+
};
|
|
14248
|
+
const url2 = `${BASE_URL2}/users/${userId}/calendar/events/${opts.eventId}`;
|
|
14249
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14250
|
+
console.error(`[nworks] PUT ${url2}`);
|
|
14251
|
+
console.error(`[nworks] Body: ${JSON.stringify(body, null, 2)}`);
|
|
14252
|
+
}
|
|
14253
|
+
const res = await authedFetch(
|
|
14254
|
+
url2,
|
|
14255
|
+
{
|
|
14256
|
+
method: "PUT",
|
|
14257
|
+
headers: { "Content-Type": "application/json" },
|
|
14258
|
+
body: JSON.stringify(body)
|
|
14259
|
+
},
|
|
14260
|
+
profile
|
|
14261
|
+
);
|
|
14262
|
+
if (!res.ok) return handleError(res);
|
|
14263
|
+
}
|
|
14264
|
+
async function deleteEvent(eventId, userId = "me", sendNotification = false, profile = "default") {
|
|
14265
|
+
const params = new URLSearchParams();
|
|
14266
|
+
params.set("sendNotification", String(sendNotification));
|
|
14267
|
+
const url2 = `${BASE_URL2}/users/${userId}/calendar/events/${eventId}?${params.toString()}`;
|
|
14268
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14269
|
+
console.error(`[nworks] DELETE ${url2}`);
|
|
14270
|
+
}
|
|
14271
|
+
const res = await authedFetch(url2, { method: "DELETE" }, profile);
|
|
14272
|
+
if (res.status === 204) return;
|
|
14273
|
+
if (!res.ok) return handleError(res);
|
|
14144
14274
|
}
|
|
14145
14275
|
|
|
14146
14276
|
// src/api/drive.ts
|
|
14147
14277
|
import { readFile as readFile3, stat } from "fs/promises";
|
|
14148
14278
|
import { basename } from "path";
|
|
14149
14279
|
var BASE_URL3 = "https://www.worksapis.com/v1.0";
|
|
14150
|
-
async function
|
|
14280
|
+
async function authedFetch2(url2, init, profile) {
|
|
14151
14281
|
const token = await getValidUserToken(profile);
|
|
14152
14282
|
const headers = new Headers(init.headers);
|
|
14153
14283
|
headers.set("Authorization", `Bearer ${token}`);
|
|
14154
14284
|
return fetch(url2, { ...init, headers });
|
|
14155
14285
|
}
|
|
14156
|
-
async function
|
|
14286
|
+
async function handleError2(res) {
|
|
14157
14287
|
if (res.status === 401) {
|
|
14158
14288
|
throw new AuthError("User token expired. Run `nworks login --user --scope file` again.");
|
|
14159
14289
|
}
|
|
@@ -14177,8 +14307,8 @@ async function listFiles(userId = "me", folderId, count = 20, cursor, profile =
|
|
|
14177
14307
|
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14178
14308
|
console.error(`[nworks] GET ${url2}`);
|
|
14179
14309
|
}
|
|
14180
|
-
const res = await
|
|
14181
|
-
if (!res.ok) return
|
|
14310
|
+
const res = await authedFetch2(url2, { method: "GET" }, profile);
|
|
14311
|
+
if (!res.ok) return handleError2(res);
|
|
14182
14312
|
const data = await res.json();
|
|
14183
14313
|
return { files: data.files ?? [], responseMetaData: data.responseMetaData };
|
|
14184
14314
|
}
|
|
@@ -14191,7 +14321,7 @@ async function uploadFile(localPath, userId = "me", folderId, overwrite = false,
|
|
|
14191
14321
|
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14192
14322
|
console.error(`[nworks] POST ${createUrl} (create upload URL)`);
|
|
14193
14323
|
}
|
|
14194
|
-
const createRes = await
|
|
14324
|
+
const createRes = await authedFetch2(
|
|
14195
14325
|
createUrl,
|
|
14196
14326
|
{
|
|
14197
14327
|
method: "POST",
|
|
@@ -14200,7 +14330,7 @@ async function uploadFile(localPath, userId = "me", folderId, overwrite = false,
|
|
|
14200
14330
|
},
|
|
14201
14331
|
profile
|
|
14202
14332
|
);
|
|
14203
|
-
if (!createRes.ok) return
|
|
14333
|
+
if (!createRes.ok) return handleError2(createRes);
|
|
14204
14334
|
const { uploadUrl } = await createRes.json();
|
|
14205
14335
|
const fileBuffer = await readFile3(localPath);
|
|
14206
14336
|
const boundary = `----nworks${Date.now()}`;
|
|
@@ -14218,7 +14348,7 @@ Content-Type: application/octet-stream\r
|
|
|
14218
14348
|
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14219
14349
|
console.error(`[nworks] POST ${uploadUrl} (upload content, ${fileSize} bytes)`);
|
|
14220
14350
|
}
|
|
14221
|
-
const uploadRes = await
|
|
14351
|
+
const uploadRes = await authedFetch2(
|
|
14222
14352
|
uploadUrl,
|
|
14223
14353
|
{
|
|
14224
14354
|
method: "POST",
|
|
@@ -14227,7 +14357,7 @@ Content-Type: application/octet-stream\r
|
|
|
14227
14357
|
},
|
|
14228
14358
|
profile
|
|
14229
14359
|
);
|
|
14230
|
-
if (!uploadRes.ok) return
|
|
14360
|
+
if (!uploadRes.ok) return handleError2(uploadRes);
|
|
14231
14361
|
return await uploadRes.json();
|
|
14232
14362
|
}
|
|
14233
14363
|
async function uploadBuffer(fileBuffer, fileName, userId = "me", folderId, overwrite = false, profile = "default") {
|
|
@@ -14237,7 +14367,7 @@ async function uploadBuffer(fileBuffer, fileName, userId = "me", folderId, overw
|
|
|
14237
14367
|
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14238
14368
|
console.error(`[nworks] POST ${createUrl} (create upload URL for buffer)`);
|
|
14239
14369
|
}
|
|
14240
|
-
const createRes = await
|
|
14370
|
+
const createRes = await authedFetch2(
|
|
14241
14371
|
createUrl,
|
|
14242
14372
|
{
|
|
14243
14373
|
method: "POST",
|
|
@@ -14246,7 +14376,7 @@ async function uploadBuffer(fileBuffer, fileName, userId = "me", folderId, overw
|
|
|
14246
14376
|
},
|
|
14247
14377
|
profile
|
|
14248
14378
|
);
|
|
14249
|
-
if (!createRes.ok) return
|
|
14379
|
+
if (!createRes.ok) return handleError2(createRes);
|
|
14250
14380
|
const { uploadUrl } = await createRes.json();
|
|
14251
14381
|
const boundary = `----nworks${Date.now()}`;
|
|
14252
14382
|
const header = Buffer.from(
|
|
@@ -14263,7 +14393,7 @@ Content-Type: application/octet-stream\r
|
|
|
14263
14393
|
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14264
14394
|
console.error(`[nworks] POST ${uploadUrl} (upload buffer, ${fileSize} bytes)`);
|
|
14265
14395
|
}
|
|
14266
|
-
const uploadRes = await
|
|
14396
|
+
const uploadRes = await authedFetch2(
|
|
14267
14397
|
uploadUrl,
|
|
14268
14398
|
{
|
|
14269
14399
|
method: "POST",
|
|
@@ -14272,7 +14402,7 @@ Content-Type: application/octet-stream\r
|
|
|
14272
14402
|
},
|
|
14273
14403
|
profile
|
|
14274
14404
|
);
|
|
14275
|
-
if (!uploadRes.ok) return
|
|
14405
|
+
if (!uploadRes.ok) return handleError2(uploadRes);
|
|
14276
14406
|
return await uploadRes.json();
|
|
14277
14407
|
}
|
|
14278
14408
|
async function downloadFile(fileId, userId = "me", profile = "default") {
|
|
@@ -14280,7 +14410,7 @@ async function downloadFile(fileId, userId = "me", profile = "default") {
|
|
|
14280
14410
|
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14281
14411
|
console.error(`[nworks] GET ${url2} (get download URL)`);
|
|
14282
14412
|
}
|
|
14283
|
-
const redirectRes = await
|
|
14413
|
+
const redirectRes = await authedFetch2(
|
|
14284
14414
|
url2,
|
|
14285
14415
|
{ method: "GET", redirect: "manual" },
|
|
14286
14416
|
profile
|
|
@@ -14290,14 +14420,14 @@ async function downloadFile(fileId, userId = "me", profile = "default") {
|
|
|
14290
14420
|
}
|
|
14291
14421
|
const location = redirectRes.headers.get("location");
|
|
14292
14422
|
if (!location) {
|
|
14293
|
-
if (!redirectRes.ok) return
|
|
14423
|
+
if (!redirectRes.ok) return handleError2(redirectRes);
|
|
14294
14424
|
throw new ApiError("NO_REDIRECT", "No download URL returned", redirectRes.status);
|
|
14295
14425
|
}
|
|
14296
14426
|
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14297
14427
|
console.error(`[nworks] GET ${location} (download content)`);
|
|
14298
14428
|
}
|
|
14299
|
-
const downloadRes = await
|
|
14300
|
-
if (!downloadRes.ok) return
|
|
14429
|
+
const downloadRes = await authedFetch2(location, { method: "GET" }, profile);
|
|
14430
|
+
if (!downloadRes.ok) return handleError2(downloadRes);
|
|
14301
14431
|
const arrayBuffer = await downloadRes.arrayBuffer();
|
|
14302
14432
|
const buffer = Buffer.from(arrayBuffer);
|
|
14303
14433
|
const disposition = downloadRes.headers.get("content-disposition");
|
|
@@ -14313,13 +14443,13 @@ async function downloadFile(fileId, userId = "me", profile = "default") {
|
|
|
14313
14443
|
|
|
14314
14444
|
// src/api/mail.ts
|
|
14315
14445
|
var BASE_URL4 = "https://www.worksapis.com/v1.0";
|
|
14316
|
-
async function
|
|
14446
|
+
async function authedFetch3(url2, init, profile) {
|
|
14317
14447
|
const token = await getValidUserToken(profile);
|
|
14318
14448
|
const headers = new Headers(init.headers);
|
|
14319
14449
|
headers.set("Authorization", `Bearer ${token}`);
|
|
14320
14450
|
return fetch(url2, { ...init, headers });
|
|
14321
14451
|
}
|
|
14322
|
-
async function
|
|
14452
|
+
async function handleError3(res) {
|
|
14323
14453
|
if (res.status === 401) {
|
|
14324
14454
|
throw new AuthError("User token expired. Run `nworks login --user --scope mail` again.");
|
|
14325
14455
|
}
|
|
@@ -14348,7 +14478,7 @@ async function sendMail(opts) {
|
|
|
14348
14478
|
if (opts.cc) body.cc = opts.cc;
|
|
14349
14479
|
if (opts.bcc) body.bcc = opts.bcc;
|
|
14350
14480
|
if (opts.contentType) body.contentType = opts.contentType;
|
|
14351
|
-
const res = await
|
|
14481
|
+
const res = await authedFetch3(
|
|
14352
14482
|
url2,
|
|
14353
14483
|
{
|
|
14354
14484
|
method: "POST",
|
|
@@ -14358,7 +14488,7 @@ async function sendMail(opts) {
|
|
|
14358
14488
|
profile
|
|
14359
14489
|
);
|
|
14360
14490
|
if (res.status === 202) return;
|
|
14361
|
-
if (!res.ok) return
|
|
14491
|
+
if (!res.ok) return handleError3(res);
|
|
14362
14492
|
}
|
|
14363
14493
|
async function listMails(folderId = 0, userId = "me", count = 30, cursor, isUnread, profile = "default") {
|
|
14364
14494
|
const params = new URLSearchParams();
|
|
@@ -14369,8 +14499,8 @@ async function listMails(folderId = 0, userId = "me", count = 30, cursor, isUnre
|
|
|
14369
14499
|
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14370
14500
|
console.error(`[nworks] GET ${url2}`);
|
|
14371
14501
|
}
|
|
14372
|
-
const res = await
|
|
14373
|
-
if (!res.ok) return
|
|
14502
|
+
const res = await authedFetch3(url2, { method: "GET" }, profile);
|
|
14503
|
+
if (!res.ok) return handleError3(res);
|
|
14374
14504
|
const data = await res.json();
|
|
14375
14505
|
return {
|
|
14376
14506
|
mails: data.mails ?? [],
|
|
@@ -14385,11 +14515,156 @@ async function readMail(mailId, userId = "me", profile = "default") {
|
|
|
14385
14515
|
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14386
14516
|
console.error(`[nworks] GET ${url2}`);
|
|
14387
14517
|
}
|
|
14388
|
-
const res = await
|
|
14389
|
-
if (!res.ok) return
|
|
14518
|
+
const res = await authedFetch3(url2, { method: "GET" }, profile);
|
|
14519
|
+
if (!res.ok) return handleError3(res);
|
|
14390
14520
|
return await res.json();
|
|
14391
14521
|
}
|
|
14392
14522
|
|
|
14523
|
+
// src/api/task.ts
|
|
14524
|
+
var BASE_URL5 = "https://www.worksapis.com/v1.0";
|
|
14525
|
+
async function authedFetch4(url2, init, profile) {
|
|
14526
|
+
const token = await getValidUserToken(profile);
|
|
14527
|
+
const headers = new Headers(init.headers);
|
|
14528
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
14529
|
+
return fetch(url2, { ...init, headers });
|
|
14530
|
+
}
|
|
14531
|
+
async function handleError4(res) {
|
|
14532
|
+
if (res.status === 401) {
|
|
14533
|
+
throw new AuthError("User token expired. Run `nworks login --user --scope task` again.");
|
|
14534
|
+
}
|
|
14535
|
+
let code = "UNKNOWN";
|
|
14536
|
+
let description = `HTTP ${res.status}`;
|
|
14537
|
+
try {
|
|
14538
|
+
const body = await res.json();
|
|
14539
|
+
code = body.code ?? code;
|
|
14540
|
+
description = body.description ?? description;
|
|
14541
|
+
} catch {
|
|
14542
|
+
}
|
|
14543
|
+
throw new ApiError(code, description, res.status);
|
|
14544
|
+
}
|
|
14545
|
+
async function resolveUserId(userId, profile) {
|
|
14546
|
+
if (userId !== "me") return userId;
|
|
14547
|
+
const url2 = `${BASE_URL5}/users/me`;
|
|
14548
|
+
const res = await authedFetch4(url2, { method: "GET" }, profile);
|
|
14549
|
+
if (!res.ok) return handleError4(res);
|
|
14550
|
+
const data = await res.json();
|
|
14551
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14552
|
+
console.error(`[nworks] Resolved "me" \u2192 ${data.userId}`);
|
|
14553
|
+
}
|
|
14554
|
+
return data.userId;
|
|
14555
|
+
}
|
|
14556
|
+
async function listTasks(categoryId = "default", userId = "me", count = 50, cursor, status = "ALL", profile = "default") {
|
|
14557
|
+
const params = new URLSearchParams();
|
|
14558
|
+
params.set("categoryId", categoryId);
|
|
14559
|
+
params.set("count", String(count));
|
|
14560
|
+
params.set("status", status);
|
|
14561
|
+
if (cursor) params.set("cursor", cursor);
|
|
14562
|
+
const url2 = `${BASE_URL5}/users/${userId}/tasks?${params.toString()}`;
|
|
14563
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14564
|
+
console.error(`[nworks] GET ${url2}`);
|
|
14565
|
+
}
|
|
14566
|
+
const res = await authedFetch4(url2, { method: "GET" }, profile);
|
|
14567
|
+
if (!res.ok) return handleError4(res);
|
|
14568
|
+
const data = await res.json();
|
|
14569
|
+
return { tasks: data.tasks ?? [], responseMetaData: data.responseMetaData };
|
|
14570
|
+
}
|
|
14571
|
+
async function createTask(opts) {
|
|
14572
|
+
const userId = opts.userId ?? "me";
|
|
14573
|
+
const profile = opts.profile ?? "default";
|
|
14574
|
+
const resolvedUserId = await resolveUserId(userId, profile);
|
|
14575
|
+
const assignorId = opts.assignorId ?? resolvedUserId;
|
|
14576
|
+
const assigneeIds = opts.assigneeIds ?? [resolvedUserId];
|
|
14577
|
+
const body = {
|
|
14578
|
+
assignorId,
|
|
14579
|
+
assignees: assigneeIds.map((id) => ({ assigneeId: id, status: "TODO" })),
|
|
14580
|
+
title: opts.title,
|
|
14581
|
+
content: opts.content ?? "",
|
|
14582
|
+
completionCondition: "ANY_ONE"
|
|
14583
|
+
};
|
|
14584
|
+
if (opts.dueDate) body.dueDate = opts.dueDate;
|
|
14585
|
+
if (opts.categoryId) body.categoryId = opts.categoryId;
|
|
14586
|
+
const url2 = `${BASE_URL5}/users/${userId}/tasks`;
|
|
14587
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14588
|
+
console.error(`[nworks] POST ${url2}`);
|
|
14589
|
+
console.error(`[nworks] Body: ${JSON.stringify(body, null, 2)}`);
|
|
14590
|
+
}
|
|
14591
|
+
const res = await authedFetch4(
|
|
14592
|
+
url2,
|
|
14593
|
+
{
|
|
14594
|
+
method: "POST",
|
|
14595
|
+
headers: { "Content-Type": "application/json" },
|
|
14596
|
+
body: JSON.stringify(body)
|
|
14597
|
+
},
|
|
14598
|
+
profile
|
|
14599
|
+
);
|
|
14600
|
+
if (res.status === 201) {
|
|
14601
|
+
return await res.json();
|
|
14602
|
+
}
|
|
14603
|
+
if (!res.ok) return handleError4(res);
|
|
14604
|
+
return await res.json();
|
|
14605
|
+
}
|
|
14606
|
+
async function updateTask(opts) {
|
|
14607
|
+
const profile = opts.profile ?? "default";
|
|
14608
|
+
const body = {};
|
|
14609
|
+
if (opts.title !== void 0) body.title = opts.title;
|
|
14610
|
+
if (opts.content !== void 0) body.content = opts.content;
|
|
14611
|
+
if (opts.dueDate !== void 0) body.dueDate = opts.dueDate;
|
|
14612
|
+
const url2 = `${BASE_URL5}/tasks/${opts.taskId}`;
|
|
14613
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14614
|
+
console.error(`[nworks] PATCH ${url2}`);
|
|
14615
|
+
}
|
|
14616
|
+
const res = await authedFetch4(
|
|
14617
|
+
url2,
|
|
14618
|
+
{
|
|
14619
|
+
method: "PATCH",
|
|
14620
|
+
headers: { "Content-Type": "application/json" },
|
|
14621
|
+
body: JSON.stringify(body)
|
|
14622
|
+
},
|
|
14623
|
+
profile
|
|
14624
|
+
);
|
|
14625
|
+
if (!res.ok) return handleError4(res);
|
|
14626
|
+
return await res.json();
|
|
14627
|
+
}
|
|
14628
|
+
async function completeTask(taskId, profile = "default") {
|
|
14629
|
+
const url2 = `${BASE_URL5}/tasks/${taskId}/complete`;
|
|
14630
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14631
|
+
console.error(`[nworks] POST ${url2}`);
|
|
14632
|
+
}
|
|
14633
|
+
const res = await authedFetch4(
|
|
14634
|
+
url2,
|
|
14635
|
+
{ method: "POST" },
|
|
14636
|
+
profile
|
|
14637
|
+
);
|
|
14638
|
+
if (res.status === 204) return;
|
|
14639
|
+
if (!res.ok) return handleError4(res);
|
|
14640
|
+
}
|
|
14641
|
+
async function incompleteTask(taskId, profile = "default") {
|
|
14642
|
+
const url2 = `${BASE_URL5}/tasks/${taskId}/incomplete`;
|
|
14643
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14644
|
+
console.error(`[nworks] POST ${url2}`);
|
|
14645
|
+
}
|
|
14646
|
+
const res = await authedFetch4(
|
|
14647
|
+
url2,
|
|
14648
|
+
{ method: "POST" },
|
|
14649
|
+
profile
|
|
14650
|
+
);
|
|
14651
|
+
if (res.status === 204) return;
|
|
14652
|
+
if (!res.ok) return handleError4(res);
|
|
14653
|
+
}
|
|
14654
|
+
async function deleteTask(taskId, profile = "default") {
|
|
14655
|
+
const url2 = `${BASE_URL5}/tasks/${taskId}`;
|
|
14656
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14657
|
+
console.error(`[nworks] DELETE ${url2}`);
|
|
14658
|
+
}
|
|
14659
|
+
const res = await authedFetch4(
|
|
14660
|
+
url2,
|
|
14661
|
+
{ method: "DELETE" },
|
|
14662
|
+
profile
|
|
14663
|
+
);
|
|
14664
|
+
if (res.status === 204) return;
|
|
14665
|
+
if (!res.ok) return handleError4(res);
|
|
14666
|
+
}
|
|
14667
|
+
|
|
14393
14668
|
// src/mcp/tools.ts
|
|
14394
14669
|
function registerTools(server) {
|
|
14395
14670
|
server.tool(
|
|
@@ -14500,6 +14775,112 @@ function registerTools(server) {
|
|
|
14500
14775
|
}
|
|
14501
14776
|
}
|
|
14502
14777
|
);
|
|
14778
|
+
server.tool(
|
|
14779
|
+
"nworks_calendar_create",
|
|
14780
|
+
"\uCE98\uB9B0\uB354 \uC77C\uC815\uC744 \uC0DD\uC131\uD569\uB2C8\uB2E4 (User OAuth calendar scope \uD544\uC694)",
|
|
14781
|
+
{
|
|
14782
|
+
summary: external_exports.string().describe("\uC77C\uC815 \uC81C\uBAA9"),
|
|
14783
|
+
start: external_exports.string().describe("\uC2DC\uC791 \uC77C\uC2DC (YYYY-MM-DDThh:mm:ss)"),
|
|
14784
|
+
end: external_exports.string().describe("\uC885\uB8CC \uC77C\uC2DC (YYYY-MM-DDThh:mm:ss)"),
|
|
14785
|
+
timeZone: external_exports.string().optional().describe("\uD0C0\uC784\uC874 (\uAE30\uBCF8: Asia/Seoul)"),
|
|
14786
|
+
description: external_exports.string().optional().describe("\uC77C\uC815 \uC124\uBA85"),
|
|
14787
|
+
location: external_exports.string().optional().describe("\uC7A5\uC18C"),
|
|
14788
|
+
attendees: external_exports.array(external_exports.object({ email: external_exports.string(), displayName: external_exports.string().optional() })).optional().describe("\uCC38\uC11D\uC790 \uBAA9\uB85D"),
|
|
14789
|
+
sendNotification: external_exports.boolean().optional().describe("\uCC38\uC11D\uC790\uC5D0\uAC8C \uC54C\uB9BC \uBC1C\uC1A1 (\uAE30\uBCF8: false)"),
|
|
14790
|
+
userId: external_exports.string().optional().describe("\uB300\uC0C1 \uC0AC\uC6A9\uC790 ID (\uBBF8\uC9C0\uC815 \uC2DC me)")
|
|
14791
|
+
},
|
|
14792
|
+
async ({ summary, start, end, timeZone, description, location, attendees, sendNotification, userId }) => {
|
|
14793
|
+
try {
|
|
14794
|
+
const result = await createEvent({
|
|
14795
|
+
summary,
|
|
14796
|
+
start,
|
|
14797
|
+
end,
|
|
14798
|
+
timeZone,
|
|
14799
|
+
description,
|
|
14800
|
+
location,
|
|
14801
|
+
attendees,
|
|
14802
|
+
sendNotification,
|
|
14803
|
+
userId: userId ?? "me"
|
|
14804
|
+
});
|
|
14805
|
+
const event = result.eventComponents?.[0];
|
|
14806
|
+
return {
|
|
14807
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, eventId: event?.eventId, summary: event?.summary, start: event?.start, end: event?.end }) }]
|
|
14808
|
+
};
|
|
14809
|
+
} catch (err) {
|
|
14810
|
+
const error48 = err;
|
|
14811
|
+
return {
|
|
14812
|
+
content: [{ type: "text", text: `Error: ${error48.message}` }],
|
|
14813
|
+
isError: true
|
|
14814
|
+
};
|
|
14815
|
+
}
|
|
14816
|
+
}
|
|
14817
|
+
);
|
|
14818
|
+
server.tool(
|
|
14819
|
+
"nworks_calendar_update",
|
|
14820
|
+
"\uCE98\uB9B0\uB354 \uC77C\uC815\uC744 \uC218\uC815\uD569\uB2C8\uB2E4 (User OAuth calendar scope \uD544\uC694)",
|
|
14821
|
+
{
|
|
14822
|
+
eventId: external_exports.string().describe("\uC77C\uC815 ID"),
|
|
14823
|
+
summary: external_exports.string().optional().describe("\uC0C8 \uC81C\uBAA9"),
|
|
14824
|
+
start: external_exports.string().optional().describe("\uC0C8 \uC2DC\uC791 \uC77C\uC2DC (YYYY-MM-DDThh:mm:ss)"),
|
|
14825
|
+
end: external_exports.string().optional().describe("\uC0C8 \uC885\uB8CC \uC77C\uC2DC (YYYY-MM-DDThh:mm:ss)"),
|
|
14826
|
+
timeZone: external_exports.string().optional().describe("\uD0C0\uC784\uC874 (\uAE30\uBCF8: Asia/Seoul)"),
|
|
14827
|
+
description: external_exports.string().optional().describe("\uC0C8 \uC124\uBA85"),
|
|
14828
|
+
location: external_exports.string().optional().describe("\uC0C8 \uC7A5\uC18C"),
|
|
14829
|
+
sendNotification: external_exports.boolean().optional().describe("\uCC38\uC11D\uC790\uC5D0\uAC8C \uC54C\uB9BC \uBC1C\uC1A1 (\uAE30\uBCF8: false)"),
|
|
14830
|
+
userId: external_exports.string().optional().describe("\uB300\uC0C1 \uC0AC\uC6A9\uC790 ID (\uBBF8\uC9C0\uC815 \uC2DC me)")
|
|
14831
|
+
},
|
|
14832
|
+
async ({ eventId, summary, start, end, timeZone, description, location, sendNotification, userId }) => {
|
|
14833
|
+
try {
|
|
14834
|
+
await updateEvent({
|
|
14835
|
+
eventId,
|
|
14836
|
+
summary,
|
|
14837
|
+
start,
|
|
14838
|
+
end,
|
|
14839
|
+
timeZone,
|
|
14840
|
+
description,
|
|
14841
|
+
location,
|
|
14842
|
+
sendNotification,
|
|
14843
|
+
userId: userId ?? "me"
|
|
14844
|
+
});
|
|
14845
|
+
return {
|
|
14846
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, eventId, message: "Event updated" }) }]
|
|
14847
|
+
};
|
|
14848
|
+
} catch (err) {
|
|
14849
|
+
const error48 = err;
|
|
14850
|
+
return {
|
|
14851
|
+
content: [{ type: "text", text: `Error: ${error48.message}` }],
|
|
14852
|
+
isError: true
|
|
14853
|
+
};
|
|
14854
|
+
}
|
|
14855
|
+
}
|
|
14856
|
+
);
|
|
14857
|
+
server.tool(
|
|
14858
|
+
"nworks_calendar_delete",
|
|
14859
|
+
"\uCE98\uB9B0\uB354 \uC77C\uC815\uC744 \uC0AD\uC81C\uD569\uB2C8\uB2E4 (User OAuth calendar scope \uD544\uC694)",
|
|
14860
|
+
{
|
|
14861
|
+
eventId: external_exports.string().describe("\uC0AD\uC81C\uD560 \uC77C\uC815 ID"),
|
|
14862
|
+
sendNotification: external_exports.boolean().optional().describe("\uCC38\uC11D\uC790\uC5D0\uAC8C \uC54C\uB9BC \uBC1C\uC1A1 (\uAE30\uBCF8: false)"),
|
|
14863
|
+
userId: external_exports.string().optional().describe("\uB300\uC0C1 \uC0AC\uC6A9\uC790 ID (\uBBF8\uC9C0\uC815 \uC2DC me)")
|
|
14864
|
+
},
|
|
14865
|
+
async ({ eventId, sendNotification, userId }) => {
|
|
14866
|
+
try {
|
|
14867
|
+
await deleteEvent(
|
|
14868
|
+
eventId,
|
|
14869
|
+
userId ?? "me",
|
|
14870
|
+
sendNotification ?? false
|
|
14871
|
+
);
|
|
14872
|
+
return {
|
|
14873
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, eventId, message: "Event deleted" }) }]
|
|
14874
|
+
};
|
|
14875
|
+
} catch (err) {
|
|
14876
|
+
const error48 = err;
|
|
14877
|
+
return {
|
|
14878
|
+
content: [{ type: "text", text: `Error: ${error48.message}` }],
|
|
14879
|
+
isError: true
|
|
14880
|
+
};
|
|
14881
|
+
}
|
|
14882
|
+
}
|
|
14883
|
+
);
|
|
14503
14884
|
server.tool(
|
|
14504
14885
|
"nworks_drive_list",
|
|
14505
14886
|
"\uB4DC\uB77C\uC774\uBE0C \uD30C\uC77C/\uD3F4\uB354 \uBAA9\uB85D\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4 (User OAuth file \uB610\uB294 file.read scope \uD544\uC694)",
|
|
@@ -14752,6 +15133,142 @@ function registerTools(server) {
|
|
|
14752
15133
|
}
|
|
14753
15134
|
}
|
|
14754
15135
|
);
|
|
15136
|
+
server.tool(
|
|
15137
|
+
"nworks_task_list",
|
|
15138
|
+
"\uD560 \uC77C \uBAA9\uB85D\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4 (User OAuth task \uB610\uB294 task.read scope \uD544\uC694)",
|
|
15139
|
+
{
|
|
15140
|
+
categoryId: external_exports.string().optional().describe("\uCE74\uD14C\uACE0\uB9AC ID (\uAE30\uBCF8: default)"),
|
|
15141
|
+
status: external_exports.enum(["TODO", "ALL"]).optional().describe("\uD544\uD130: TODO \uB610\uB294 ALL (\uAE30\uBCF8: ALL)"),
|
|
15142
|
+
count: external_exports.number().optional().describe("\uD398\uC774\uC9C0\uB2F9 \uD56D\uBAA9 \uC218 (\uAE30\uBCF8: 50, \uCD5C\uB300: 100)"),
|
|
15143
|
+
cursor: external_exports.string().optional().describe("\uD398\uC774\uC9C0\uB124\uC774\uC158 \uCEE4\uC11C"),
|
|
15144
|
+
userId: external_exports.string().optional().describe("\uB300\uC0C1 \uC0AC\uC6A9\uC790 ID (\uBBF8\uC9C0\uC815 \uC2DC me)")
|
|
15145
|
+
},
|
|
15146
|
+
async ({ categoryId, status, count, cursor, userId }) => {
|
|
15147
|
+
try {
|
|
15148
|
+
const result = await listTasks(
|
|
15149
|
+
categoryId ?? "default",
|
|
15150
|
+
userId ?? "me",
|
|
15151
|
+
count ?? 50,
|
|
15152
|
+
cursor,
|
|
15153
|
+
status ?? "ALL"
|
|
15154
|
+
);
|
|
15155
|
+
const tasks = result.tasks.map((t) => ({
|
|
15156
|
+
taskId: t.taskId,
|
|
15157
|
+
title: t.title,
|
|
15158
|
+
status: t.status,
|
|
15159
|
+
dueDate: t.dueDate,
|
|
15160
|
+
assignor: t.assignorName ?? t.assignorId,
|
|
15161
|
+
created: t.createdTime
|
|
15162
|
+
}));
|
|
15163
|
+
return {
|
|
15164
|
+
content: [{ type: "text", text: JSON.stringify({ tasks, count: tasks.length, nextCursor: result.responseMetaData?.nextCursor ?? null }) }]
|
|
15165
|
+
};
|
|
15166
|
+
} catch (err) {
|
|
15167
|
+
const error48 = err;
|
|
15168
|
+
return {
|
|
15169
|
+
content: [{ type: "text", text: `Error: ${error48.message}` }],
|
|
15170
|
+
isError: true
|
|
15171
|
+
};
|
|
15172
|
+
}
|
|
15173
|
+
}
|
|
15174
|
+
);
|
|
15175
|
+
server.tool(
|
|
15176
|
+
"nworks_task_create",
|
|
15177
|
+
"\uD560 \uC77C\uC744 \uC0DD\uC131\uD569\uB2C8\uB2E4 (User OAuth task scope \uD544\uC694). \uAE30\uBCF8\uC801\uC73C\uB85C \uC790\uAE30 \uC790\uC2E0\uC5D0\uAC8C \uD560\uB2F9\uB429\uB2C8\uB2E4.",
|
|
15178
|
+
{
|
|
15179
|
+
title: external_exports.string().describe("\uD560 \uC77C \uC81C\uBAA9"),
|
|
15180
|
+
content: external_exports.string().optional().describe("\uD560 \uC77C \uB0B4\uC6A9"),
|
|
15181
|
+
dueDate: external_exports.string().optional().describe("\uB9C8\uAC10\uC77C (YYYY-MM-DD)"),
|
|
15182
|
+
categoryId: external_exports.string().optional().describe("\uCE74\uD14C\uACE0\uB9AC ID"),
|
|
15183
|
+
assigneeIds: external_exports.array(external_exports.string()).optional().describe("\uB2F4\uB2F9\uC790 user ID \uBAA9\uB85D (\uBBF8\uC9C0\uC815 \uC2DC \uC790\uAE30 \uC790\uC2E0)"),
|
|
15184
|
+
userId: external_exports.string().optional().describe("\uC0DD\uC131\uC790 user ID (\uBBF8\uC9C0\uC815 \uC2DC me)")
|
|
15185
|
+
},
|
|
15186
|
+
async ({ title, content, dueDate, categoryId, assigneeIds, userId }) => {
|
|
15187
|
+
try {
|
|
15188
|
+
const result = await createTask({
|
|
15189
|
+
title,
|
|
15190
|
+
content,
|
|
15191
|
+
dueDate,
|
|
15192
|
+
categoryId,
|
|
15193
|
+
assigneeIds,
|
|
15194
|
+
userId: userId ?? "me"
|
|
15195
|
+
});
|
|
15196
|
+
return {
|
|
15197
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, taskId: result.taskId, title: result.title, status: result.status, dueDate: result.dueDate }) }]
|
|
15198
|
+
};
|
|
15199
|
+
} catch (err) {
|
|
15200
|
+
const error48 = err;
|
|
15201
|
+
return {
|
|
15202
|
+
content: [{ type: "text", text: `Error: ${error48.message}` }],
|
|
15203
|
+
isError: true
|
|
15204
|
+
};
|
|
15205
|
+
}
|
|
15206
|
+
}
|
|
15207
|
+
);
|
|
15208
|
+
server.tool(
|
|
15209
|
+
"nworks_task_update",
|
|
15210
|
+
"\uD560 \uC77C\uC744 \uC218\uC815\uD569\uB2C8\uB2E4 (User OAuth task scope \uD544\uC694). \uC0C1\uD0DC \uBCC0\uACBD(done/todo)\uACFC \uD544\uB4DC \uC218\uC815\uC744 \uBAA8\uB450 \uC9C0\uC6D0\uD569\uB2C8\uB2E4.",
|
|
15211
|
+
{
|
|
15212
|
+
taskId: external_exports.string().describe("\uD560 \uC77C ID"),
|
|
15213
|
+
status: external_exports.enum(["done", "todo"]).optional().describe("\uC0C1\uD0DC \uBCC0\uACBD: done \uB610\uB294 todo"),
|
|
15214
|
+
title: external_exports.string().optional().describe("\uC0C8 \uC81C\uBAA9"),
|
|
15215
|
+
content: external_exports.string().optional().describe("\uC0C8 \uB0B4\uC6A9"),
|
|
15216
|
+
dueDate: external_exports.string().optional().describe("\uC0C8 \uB9C8\uAC10\uC77C (YYYY-MM-DD)")
|
|
15217
|
+
},
|
|
15218
|
+
async ({ taskId, status, title, content, dueDate }) => {
|
|
15219
|
+
try {
|
|
15220
|
+
if (status) {
|
|
15221
|
+
if (status === "done") {
|
|
15222
|
+
await completeTask(taskId);
|
|
15223
|
+
} else {
|
|
15224
|
+
await incompleteTask(taskId);
|
|
15225
|
+
}
|
|
15226
|
+
}
|
|
15227
|
+
if (title !== void 0 || content !== void 0 || dueDate !== void 0) {
|
|
15228
|
+
const result = await updateTask({ taskId, title, content, dueDate });
|
|
15229
|
+
return {
|
|
15230
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, taskId: result.taskId, title: result.title, status: result.status, dueDate: result.dueDate }) }]
|
|
15231
|
+
};
|
|
15232
|
+
}
|
|
15233
|
+
if (status) {
|
|
15234
|
+
return {
|
|
15235
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, taskId, status: status === "done" ? "DONE" : "TODO" }) }]
|
|
15236
|
+
};
|
|
15237
|
+
}
|
|
15238
|
+
return {
|
|
15239
|
+
content: [{ type: "text", text: "Error: status, title, content, dueDate \uC911 \uD558\uB098 \uC774\uC0C1\uC744 \uC9C0\uC815\uD558\uC138\uC694." }],
|
|
15240
|
+
isError: true
|
|
15241
|
+
};
|
|
15242
|
+
} catch (err) {
|
|
15243
|
+
const error48 = err;
|
|
15244
|
+
return {
|
|
15245
|
+
content: [{ type: "text", text: `Error: ${error48.message}` }],
|
|
15246
|
+
isError: true
|
|
15247
|
+
};
|
|
15248
|
+
}
|
|
15249
|
+
}
|
|
15250
|
+
);
|
|
15251
|
+
server.tool(
|
|
15252
|
+
"nworks_task_delete",
|
|
15253
|
+
"\uD560 \uC77C\uC744 \uC0AD\uC81C\uD569\uB2C8\uB2E4 (User OAuth task scope \uD544\uC694)",
|
|
15254
|
+
{
|
|
15255
|
+
taskId: external_exports.string().describe("\uC0AD\uC81C\uD560 \uD560 \uC77C ID")
|
|
15256
|
+
},
|
|
15257
|
+
async ({ taskId }) => {
|
|
15258
|
+
try {
|
|
15259
|
+
await deleteTask(taskId);
|
|
15260
|
+
return {
|
|
15261
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, taskId, message: "Task deleted" }) }]
|
|
15262
|
+
};
|
|
15263
|
+
} catch (err) {
|
|
15264
|
+
const error48 = err;
|
|
15265
|
+
return {
|
|
15266
|
+
content: [{ type: "text", text: `Error: ${error48.message}` }],
|
|
15267
|
+
isError: true
|
|
15268
|
+
};
|
|
15269
|
+
}
|
|
15270
|
+
}
|
|
15271
|
+
);
|
|
14755
15272
|
server.tool(
|
|
14756
15273
|
"nworks_whoami",
|
|
14757
15274
|
"\uD604\uC7AC \uC778\uC99D\uB41C NAVER WORKS \uACC4\uC815 \uC815\uBCF4\uB97C \uD655\uC778\uD569\uB2C8\uB2E4",
|