nworks 0.4.0 → 0.5.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 +37 -2
- package/dist/index.js +412 -4
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +281 -0
- package/dist/mcp.js.map +1 -1
- package/package.json +1 -1
package/dist/mcp.js
CHANGED
|
@@ -14390,6 +14390,151 @@ async function readMail(mailId, userId = "me", profile = "default") {
|
|
|
14390
14390
|
return await res.json();
|
|
14391
14391
|
}
|
|
14392
14392
|
|
|
14393
|
+
// src/api/task.ts
|
|
14394
|
+
var BASE_URL5 = "https://www.worksapis.com/v1.0";
|
|
14395
|
+
async function authedFetch3(url2, init, profile) {
|
|
14396
|
+
const token = await getValidUserToken(profile);
|
|
14397
|
+
const headers = new Headers(init.headers);
|
|
14398
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
14399
|
+
return fetch(url2, { ...init, headers });
|
|
14400
|
+
}
|
|
14401
|
+
async function handleError3(res) {
|
|
14402
|
+
if (res.status === 401) {
|
|
14403
|
+
throw new AuthError("User token expired. Run `nworks login --user --scope task` again.");
|
|
14404
|
+
}
|
|
14405
|
+
let code = "UNKNOWN";
|
|
14406
|
+
let description = `HTTP ${res.status}`;
|
|
14407
|
+
try {
|
|
14408
|
+
const body = await res.json();
|
|
14409
|
+
code = body.code ?? code;
|
|
14410
|
+
description = body.description ?? description;
|
|
14411
|
+
} catch {
|
|
14412
|
+
}
|
|
14413
|
+
throw new ApiError(code, description, res.status);
|
|
14414
|
+
}
|
|
14415
|
+
async function resolveUserId(userId, profile) {
|
|
14416
|
+
if (userId !== "me") return userId;
|
|
14417
|
+
const url2 = `${BASE_URL5}/users/me`;
|
|
14418
|
+
const res = await authedFetch3(url2, { method: "GET" }, profile);
|
|
14419
|
+
if (!res.ok) return handleError3(res);
|
|
14420
|
+
const data = await res.json();
|
|
14421
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14422
|
+
console.error(`[nworks] Resolved "me" \u2192 ${data.userId}`);
|
|
14423
|
+
}
|
|
14424
|
+
return data.userId;
|
|
14425
|
+
}
|
|
14426
|
+
async function listTasks(categoryId = "default", userId = "me", count = 50, cursor, status = "ALL", profile = "default") {
|
|
14427
|
+
const params = new URLSearchParams();
|
|
14428
|
+
params.set("categoryId", categoryId);
|
|
14429
|
+
params.set("count", String(count));
|
|
14430
|
+
params.set("status", status);
|
|
14431
|
+
if (cursor) params.set("cursor", cursor);
|
|
14432
|
+
const url2 = `${BASE_URL5}/users/${userId}/tasks?${params.toString()}`;
|
|
14433
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14434
|
+
console.error(`[nworks] GET ${url2}`);
|
|
14435
|
+
}
|
|
14436
|
+
const res = await authedFetch3(url2, { method: "GET" }, profile);
|
|
14437
|
+
if (!res.ok) return handleError3(res);
|
|
14438
|
+
const data = await res.json();
|
|
14439
|
+
return { tasks: data.tasks ?? [], responseMetaData: data.responseMetaData };
|
|
14440
|
+
}
|
|
14441
|
+
async function createTask(opts) {
|
|
14442
|
+
const userId = opts.userId ?? "me";
|
|
14443
|
+
const profile = opts.profile ?? "default";
|
|
14444
|
+
const resolvedUserId = await resolveUserId(userId, profile);
|
|
14445
|
+
const assignorId = opts.assignorId ?? resolvedUserId;
|
|
14446
|
+
const assigneeIds = opts.assigneeIds ?? [resolvedUserId];
|
|
14447
|
+
const body = {
|
|
14448
|
+
assignorId,
|
|
14449
|
+
assignees: assigneeIds.map((id) => ({ assigneeId: id, status: "TODO" })),
|
|
14450
|
+
title: opts.title,
|
|
14451
|
+
content: opts.content ?? "",
|
|
14452
|
+
completionCondition: "ANY_ONE"
|
|
14453
|
+
};
|
|
14454
|
+
if (opts.dueDate) body.dueDate = opts.dueDate;
|
|
14455
|
+
if (opts.categoryId) body.categoryId = opts.categoryId;
|
|
14456
|
+
const url2 = `${BASE_URL5}/users/${userId}/tasks`;
|
|
14457
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14458
|
+
console.error(`[nworks] POST ${url2}`);
|
|
14459
|
+
console.error(`[nworks] Body: ${JSON.stringify(body, null, 2)}`);
|
|
14460
|
+
}
|
|
14461
|
+
const res = await authedFetch3(
|
|
14462
|
+
url2,
|
|
14463
|
+
{
|
|
14464
|
+
method: "POST",
|
|
14465
|
+
headers: { "Content-Type": "application/json" },
|
|
14466
|
+
body: JSON.stringify(body)
|
|
14467
|
+
},
|
|
14468
|
+
profile
|
|
14469
|
+
);
|
|
14470
|
+
if (res.status === 201) {
|
|
14471
|
+
return await res.json();
|
|
14472
|
+
}
|
|
14473
|
+
if (!res.ok) return handleError3(res);
|
|
14474
|
+
return await res.json();
|
|
14475
|
+
}
|
|
14476
|
+
async function updateTask(opts) {
|
|
14477
|
+
const profile = opts.profile ?? "default";
|
|
14478
|
+
const body = {};
|
|
14479
|
+
if (opts.title !== void 0) body.title = opts.title;
|
|
14480
|
+
if (opts.content !== void 0) body.content = opts.content;
|
|
14481
|
+
if (opts.dueDate !== void 0) body.dueDate = opts.dueDate;
|
|
14482
|
+
const url2 = `${BASE_URL5}/tasks/${opts.taskId}`;
|
|
14483
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14484
|
+
console.error(`[nworks] PATCH ${url2}`);
|
|
14485
|
+
}
|
|
14486
|
+
const res = await authedFetch3(
|
|
14487
|
+
url2,
|
|
14488
|
+
{
|
|
14489
|
+
method: "PATCH",
|
|
14490
|
+
headers: { "Content-Type": "application/json" },
|
|
14491
|
+
body: JSON.stringify(body)
|
|
14492
|
+
},
|
|
14493
|
+
profile
|
|
14494
|
+
);
|
|
14495
|
+
if (!res.ok) return handleError3(res);
|
|
14496
|
+
return await res.json();
|
|
14497
|
+
}
|
|
14498
|
+
async function completeTask(taskId, profile = "default") {
|
|
14499
|
+
const url2 = `${BASE_URL5}/tasks/${taskId}/complete`;
|
|
14500
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14501
|
+
console.error(`[nworks] POST ${url2}`);
|
|
14502
|
+
}
|
|
14503
|
+
const res = await authedFetch3(
|
|
14504
|
+
url2,
|
|
14505
|
+
{ method: "POST" },
|
|
14506
|
+
profile
|
|
14507
|
+
);
|
|
14508
|
+
if (res.status === 204) return;
|
|
14509
|
+
if (!res.ok) return handleError3(res);
|
|
14510
|
+
}
|
|
14511
|
+
async function incompleteTask(taskId, profile = "default") {
|
|
14512
|
+
const url2 = `${BASE_URL5}/tasks/${taskId}/incomplete`;
|
|
14513
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14514
|
+
console.error(`[nworks] POST ${url2}`);
|
|
14515
|
+
}
|
|
14516
|
+
const res = await authedFetch3(
|
|
14517
|
+
url2,
|
|
14518
|
+
{ method: "POST" },
|
|
14519
|
+
profile
|
|
14520
|
+
);
|
|
14521
|
+
if (res.status === 204) return;
|
|
14522
|
+
if (!res.ok) return handleError3(res);
|
|
14523
|
+
}
|
|
14524
|
+
async function deleteTask(taskId, profile = "default") {
|
|
14525
|
+
const url2 = `${BASE_URL5}/tasks/${taskId}`;
|
|
14526
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14527
|
+
console.error(`[nworks] DELETE ${url2}`);
|
|
14528
|
+
}
|
|
14529
|
+
const res = await authedFetch3(
|
|
14530
|
+
url2,
|
|
14531
|
+
{ method: "DELETE" },
|
|
14532
|
+
profile
|
|
14533
|
+
);
|
|
14534
|
+
if (res.status === 204) return;
|
|
14535
|
+
if (!res.ok) return handleError3(res);
|
|
14536
|
+
}
|
|
14537
|
+
|
|
14393
14538
|
// src/mcp/tools.ts
|
|
14394
14539
|
function registerTools(server) {
|
|
14395
14540
|
server.tool(
|
|
@@ -14752,6 +14897,142 @@ function registerTools(server) {
|
|
|
14752
14897
|
}
|
|
14753
14898
|
}
|
|
14754
14899
|
);
|
|
14900
|
+
server.tool(
|
|
14901
|
+
"nworks_task_list",
|
|
14902
|
+
"\uD560 \uC77C \uBAA9\uB85D\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4 (User OAuth task \uB610\uB294 task.read scope \uD544\uC694)",
|
|
14903
|
+
{
|
|
14904
|
+
categoryId: external_exports.string().optional().describe("\uCE74\uD14C\uACE0\uB9AC ID (\uAE30\uBCF8: default)"),
|
|
14905
|
+
status: external_exports.enum(["TODO", "ALL"]).optional().describe("\uD544\uD130: TODO \uB610\uB294 ALL (\uAE30\uBCF8: ALL)"),
|
|
14906
|
+
count: external_exports.number().optional().describe("\uD398\uC774\uC9C0\uB2F9 \uD56D\uBAA9 \uC218 (\uAE30\uBCF8: 50, \uCD5C\uB300: 100)"),
|
|
14907
|
+
cursor: external_exports.string().optional().describe("\uD398\uC774\uC9C0\uB124\uC774\uC158 \uCEE4\uC11C"),
|
|
14908
|
+
userId: external_exports.string().optional().describe("\uB300\uC0C1 \uC0AC\uC6A9\uC790 ID (\uBBF8\uC9C0\uC815 \uC2DC me)")
|
|
14909
|
+
},
|
|
14910
|
+
async ({ categoryId, status, count, cursor, userId }) => {
|
|
14911
|
+
try {
|
|
14912
|
+
const result = await listTasks(
|
|
14913
|
+
categoryId ?? "default",
|
|
14914
|
+
userId ?? "me",
|
|
14915
|
+
count ?? 50,
|
|
14916
|
+
cursor,
|
|
14917
|
+
status ?? "ALL"
|
|
14918
|
+
);
|
|
14919
|
+
const tasks = result.tasks.map((t) => ({
|
|
14920
|
+
taskId: t.taskId,
|
|
14921
|
+
title: t.title,
|
|
14922
|
+
status: t.status,
|
|
14923
|
+
dueDate: t.dueDate,
|
|
14924
|
+
assignor: t.assignorName ?? t.assignorId,
|
|
14925
|
+
created: t.createdTime
|
|
14926
|
+
}));
|
|
14927
|
+
return {
|
|
14928
|
+
content: [{ type: "text", text: JSON.stringify({ tasks, count: tasks.length, nextCursor: result.responseMetaData?.nextCursor ?? null }) }]
|
|
14929
|
+
};
|
|
14930
|
+
} catch (err) {
|
|
14931
|
+
const error48 = err;
|
|
14932
|
+
return {
|
|
14933
|
+
content: [{ type: "text", text: `Error: ${error48.message}` }],
|
|
14934
|
+
isError: true
|
|
14935
|
+
};
|
|
14936
|
+
}
|
|
14937
|
+
}
|
|
14938
|
+
);
|
|
14939
|
+
server.tool(
|
|
14940
|
+
"nworks_task_create",
|
|
14941
|
+
"\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.",
|
|
14942
|
+
{
|
|
14943
|
+
title: external_exports.string().describe("\uD560 \uC77C \uC81C\uBAA9"),
|
|
14944
|
+
content: external_exports.string().optional().describe("\uD560 \uC77C \uB0B4\uC6A9"),
|
|
14945
|
+
dueDate: external_exports.string().optional().describe("\uB9C8\uAC10\uC77C (YYYY-MM-DD)"),
|
|
14946
|
+
categoryId: external_exports.string().optional().describe("\uCE74\uD14C\uACE0\uB9AC ID"),
|
|
14947
|
+
assigneeIds: external_exports.array(external_exports.string()).optional().describe("\uB2F4\uB2F9\uC790 user ID \uBAA9\uB85D (\uBBF8\uC9C0\uC815 \uC2DC \uC790\uAE30 \uC790\uC2E0)"),
|
|
14948
|
+
userId: external_exports.string().optional().describe("\uC0DD\uC131\uC790 user ID (\uBBF8\uC9C0\uC815 \uC2DC me)")
|
|
14949
|
+
},
|
|
14950
|
+
async ({ title, content, dueDate, categoryId, assigneeIds, userId }) => {
|
|
14951
|
+
try {
|
|
14952
|
+
const result = await createTask({
|
|
14953
|
+
title,
|
|
14954
|
+
content,
|
|
14955
|
+
dueDate,
|
|
14956
|
+
categoryId,
|
|
14957
|
+
assigneeIds,
|
|
14958
|
+
userId: userId ?? "me"
|
|
14959
|
+
});
|
|
14960
|
+
return {
|
|
14961
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, taskId: result.taskId, title: result.title, status: result.status, dueDate: result.dueDate }) }]
|
|
14962
|
+
};
|
|
14963
|
+
} catch (err) {
|
|
14964
|
+
const error48 = err;
|
|
14965
|
+
return {
|
|
14966
|
+
content: [{ type: "text", text: `Error: ${error48.message}` }],
|
|
14967
|
+
isError: true
|
|
14968
|
+
};
|
|
14969
|
+
}
|
|
14970
|
+
}
|
|
14971
|
+
);
|
|
14972
|
+
server.tool(
|
|
14973
|
+
"nworks_task_update",
|
|
14974
|
+
"\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.",
|
|
14975
|
+
{
|
|
14976
|
+
taskId: external_exports.string().describe("\uD560 \uC77C ID"),
|
|
14977
|
+
status: external_exports.enum(["done", "todo"]).optional().describe("\uC0C1\uD0DC \uBCC0\uACBD: done \uB610\uB294 todo"),
|
|
14978
|
+
title: external_exports.string().optional().describe("\uC0C8 \uC81C\uBAA9"),
|
|
14979
|
+
content: external_exports.string().optional().describe("\uC0C8 \uB0B4\uC6A9"),
|
|
14980
|
+
dueDate: external_exports.string().optional().describe("\uC0C8 \uB9C8\uAC10\uC77C (YYYY-MM-DD)")
|
|
14981
|
+
},
|
|
14982
|
+
async ({ taskId, status, title, content, dueDate }) => {
|
|
14983
|
+
try {
|
|
14984
|
+
if (status) {
|
|
14985
|
+
if (status === "done") {
|
|
14986
|
+
await completeTask(taskId);
|
|
14987
|
+
} else {
|
|
14988
|
+
await incompleteTask(taskId);
|
|
14989
|
+
}
|
|
14990
|
+
}
|
|
14991
|
+
if (title !== void 0 || content !== void 0 || dueDate !== void 0) {
|
|
14992
|
+
const result = await updateTask({ taskId, title, content, dueDate });
|
|
14993
|
+
return {
|
|
14994
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, taskId: result.taskId, title: result.title, status: result.status, dueDate: result.dueDate }) }]
|
|
14995
|
+
};
|
|
14996
|
+
}
|
|
14997
|
+
if (status) {
|
|
14998
|
+
return {
|
|
14999
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, taskId, status: status === "done" ? "DONE" : "TODO" }) }]
|
|
15000
|
+
};
|
|
15001
|
+
}
|
|
15002
|
+
return {
|
|
15003
|
+
content: [{ type: "text", text: "Error: status, title, content, dueDate \uC911 \uD558\uB098 \uC774\uC0C1\uC744 \uC9C0\uC815\uD558\uC138\uC694." }],
|
|
15004
|
+
isError: true
|
|
15005
|
+
};
|
|
15006
|
+
} catch (err) {
|
|
15007
|
+
const error48 = err;
|
|
15008
|
+
return {
|
|
15009
|
+
content: [{ type: "text", text: `Error: ${error48.message}` }],
|
|
15010
|
+
isError: true
|
|
15011
|
+
};
|
|
15012
|
+
}
|
|
15013
|
+
}
|
|
15014
|
+
);
|
|
15015
|
+
server.tool(
|
|
15016
|
+
"nworks_task_delete",
|
|
15017
|
+
"\uD560 \uC77C\uC744 \uC0AD\uC81C\uD569\uB2C8\uB2E4 (User OAuth task scope \uD544\uC694)",
|
|
15018
|
+
{
|
|
15019
|
+
taskId: external_exports.string().describe("\uC0AD\uC81C\uD560 \uD560 \uC77C ID")
|
|
15020
|
+
},
|
|
15021
|
+
async ({ taskId }) => {
|
|
15022
|
+
try {
|
|
15023
|
+
await deleteTask(taskId);
|
|
15024
|
+
return {
|
|
15025
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, taskId, message: "Task deleted" }) }]
|
|
15026
|
+
};
|
|
15027
|
+
} catch (err) {
|
|
15028
|
+
const error48 = err;
|
|
15029
|
+
return {
|
|
15030
|
+
content: [{ type: "text", text: `Error: ${error48.message}` }],
|
|
15031
|
+
isError: true
|
|
15032
|
+
};
|
|
15033
|
+
}
|
|
15034
|
+
}
|
|
15035
|
+
);
|
|
14755
15036
|
server.tool(
|
|
14756
15037
|
"nworks_whoami",
|
|
14757
15038
|
"\uD604\uC7AC \uC778\uC99D\uB41C NAVER WORKS \uACC4\uC815 \uC815\uBCF4\uB97C \uD655\uC778\uD569\uB2C8\uB2E4",
|