nworks 0.6.2 → 0.7.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 +31 -2
- package/dist/index.js +340 -4
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +229 -0
- package/dist/mcp.js.map +1 -1
- package/package.json +1 -1
package/dist/mcp.js
CHANGED
|
@@ -14665,6 +14665,114 @@ async function deleteTask(taskId, profile = "default") {
|
|
|
14665
14665
|
if (!res.ok) return handleError4(res);
|
|
14666
14666
|
}
|
|
14667
14667
|
|
|
14668
|
+
// src/api/board.ts
|
|
14669
|
+
var BASE_URL6 = "https://www.worksapis.com/v1.0";
|
|
14670
|
+
async function authedFetch5(url2, init, profile) {
|
|
14671
|
+
const token = await getValidUserToken(profile);
|
|
14672
|
+
const headers = new Headers(init.headers);
|
|
14673
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
14674
|
+
return fetch(url2, { ...init, headers });
|
|
14675
|
+
}
|
|
14676
|
+
async function handleError5(res) {
|
|
14677
|
+
if (res.status === 401) {
|
|
14678
|
+
throw new AuthError("User token expired. Run `nworks login --user --scope board` again.");
|
|
14679
|
+
}
|
|
14680
|
+
let code = "UNKNOWN";
|
|
14681
|
+
let description = `HTTP ${res.status}`;
|
|
14682
|
+
try {
|
|
14683
|
+
const body = await res.json();
|
|
14684
|
+
code = body.code ?? code;
|
|
14685
|
+
description = body.description ?? description;
|
|
14686
|
+
} catch {
|
|
14687
|
+
}
|
|
14688
|
+
throw new ApiError(code, description, res.status);
|
|
14689
|
+
}
|
|
14690
|
+
function safeParseJson(text) {
|
|
14691
|
+
const safe = text.replace(
|
|
14692
|
+
/"((?:board|post|domain|user)Id)"\s*:\s*(\d{16,})/g,
|
|
14693
|
+
'"$1":"$2"'
|
|
14694
|
+
);
|
|
14695
|
+
return JSON.parse(safe);
|
|
14696
|
+
}
|
|
14697
|
+
async function listBoards(count = 20, cursor, profile = "default") {
|
|
14698
|
+
const params = new URLSearchParams();
|
|
14699
|
+
params.set("count", String(count));
|
|
14700
|
+
if (cursor) params.set("cursor", cursor);
|
|
14701
|
+
const url2 = `${BASE_URL6}/boards?${params.toString()}`;
|
|
14702
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14703
|
+
console.error(`[nworks] GET ${url2}`);
|
|
14704
|
+
}
|
|
14705
|
+
const res = await authedFetch5(url2, { method: "GET" }, profile);
|
|
14706
|
+
if (!res.ok) return handleError5(res);
|
|
14707
|
+
const text = await res.text();
|
|
14708
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14709
|
+
console.error(`[nworks] Response: ${text}`);
|
|
14710
|
+
}
|
|
14711
|
+
const data = safeParseJson(text);
|
|
14712
|
+
return { boards: data.boards ?? [], responseMetaData: data.responseMetaData };
|
|
14713
|
+
}
|
|
14714
|
+
async function listPosts(boardId, count = 20, cursor, profile = "default") {
|
|
14715
|
+
const params = new URLSearchParams();
|
|
14716
|
+
params.set("count", String(count));
|
|
14717
|
+
if (cursor) params.set("cursor", cursor);
|
|
14718
|
+
const url2 = `${BASE_URL6}/boards/${boardId}/posts?${params.toString()}`;
|
|
14719
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14720
|
+
console.error(`[nworks] GET ${url2}`);
|
|
14721
|
+
}
|
|
14722
|
+
const res = await authedFetch5(url2, { method: "GET" }, profile);
|
|
14723
|
+
if (!res.ok) return handleError5(res);
|
|
14724
|
+
const text = await res.text();
|
|
14725
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14726
|
+
console.error(`[nworks] Response: ${text}`);
|
|
14727
|
+
}
|
|
14728
|
+
const data = safeParseJson(text);
|
|
14729
|
+
return { posts: data.posts ?? [], responseMetaData: data.responseMetaData };
|
|
14730
|
+
}
|
|
14731
|
+
async function readPost(boardId, postId, profile = "default") {
|
|
14732
|
+
const url2 = `${BASE_URL6}/boards/${boardId}/posts/${postId}`;
|
|
14733
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14734
|
+
console.error(`[nworks] GET ${url2}`);
|
|
14735
|
+
}
|
|
14736
|
+
const res = await authedFetch5(url2, { method: "GET" }, profile);
|
|
14737
|
+
if (!res.ok) return handleError5(res);
|
|
14738
|
+
const text = await res.text();
|
|
14739
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14740
|
+
console.error(`[nworks] Response: ${text}`);
|
|
14741
|
+
}
|
|
14742
|
+
return safeParseJson(text);
|
|
14743
|
+
}
|
|
14744
|
+
async function createPost(opts) {
|
|
14745
|
+
const profile = opts.profile ?? "default";
|
|
14746
|
+
const body = {
|
|
14747
|
+
title: opts.title,
|
|
14748
|
+
body: opts.body ?? ""
|
|
14749
|
+
};
|
|
14750
|
+
if (opts.enableComment !== void 0) body.enableComment = opts.enableComment;
|
|
14751
|
+
if (opts.sendNotifications !== void 0) body.sendNotifications = opts.sendNotifications;
|
|
14752
|
+
const url2 = `${BASE_URL6}/boards/${opts.boardId}/posts`;
|
|
14753
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14754
|
+
console.error(`[nworks] POST ${url2}`);
|
|
14755
|
+
console.error(`[nworks] Body: ${JSON.stringify(body, null, 2)}`);
|
|
14756
|
+
}
|
|
14757
|
+
const res = await authedFetch5(
|
|
14758
|
+
url2,
|
|
14759
|
+
{
|
|
14760
|
+
method: "POST",
|
|
14761
|
+
headers: { "Content-Type": "application/json" },
|
|
14762
|
+
body: JSON.stringify(body)
|
|
14763
|
+
},
|
|
14764
|
+
profile
|
|
14765
|
+
);
|
|
14766
|
+
if (res.status === 201 || res.ok) {
|
|
14767
|
+
const text = await res.text();
|
|
14768
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
14769
|
+
console.error(`[nworks] Response: ${text}`);
|
|
14770
|
+
}
|
|
14771
|
+
return safeParseJson(text);
|
|
14772
|
+
}
|
|
14773
|
+
return handleError5(res);
|
|
14774
|
+
}
|
|
14775
|
+
|
|
14668
14776
|
// src/mcp/tools.ts
|
|
14669
14777
|
function registerTools(server) {
|
|
14670
14778
|
server.tool(
|
|
@@ -15270,6 +15378,127 @@ function registerTools(server) {
|
|
|
15270
15378
|
}
|
|
15271
15379
|
}
|
|
15272
15380
|
);
|
|
15381
|
+
server.tool(
|
|
15382
|
+
"nworks_board_list",
|
|
15383
|
+
"\uAC8C\uC2DC\uD310 \uBAA9\uB85D\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4 (User OAuth board \uB610\uB294 board.read scope \uD544\uC694)",
|
|
15384
|
+
{
|
|
15385
|
+
count: external_exports.number().optional().describe("\uD398\uC774\uC9C0\uB2F9 \uD56D\uBAA9 \uC218 (\uAE30\uBCF8: 20)"),
|
|
15386
|
+
cursor: external_exports.string().optional().describe("\uD398\uC774\uC9C0\uB124\uC774\uC158 \uCEE4\uC11C")
|
|
15387
|
+
},
|
|
15388
|
+
async ({ count, cursor }) => {
|
|
15389
|
+
try {
|
|
15390
|
+
const result = await listBoards(count ?? 20, cursor);
|
|
15391
|
+
const boards = result.boards.map((b) => ({
|
|
15392
|
+
boardId: b.boardId,
|
|
15393
|
+
boardName: b.boardName,
|
|
15394
|
+
description: b.description ?? ""
|
|
15395
|
+
}));
|
|
15396
|
+
return {
|
|
15397
|
+
content: [{ type: "text", text: JSON.stringify({ boards, count: boards.length, nextCursor: result.responseMetaData?.nextCursor ?? null }) }]
|
|
15398
|
+
};
|
|
15399
|
+
} catch (err) {
|
|
15400
|
+
const error48 = err;
|
|
15401
|
+
return {
|
|
15402
|
+
content: [{ type: "text", text: `Error: ${error48.message}` }],
|
|
15403
|
+
isError: true
|
|
15404
|
+
};
|
|
15405
|
+
}
|
|
15406
|
+
}
|
|
15407
|
+
);
|
|
15408
|
+
server.tool(
|
|
15409
|
+
"nworks_board_posts",
|
|
15410
|
+
"\uAC8C\uC2DC\uD310\uC758 \uAE00 \uBAA9\uB85D\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4 (User OAuth board \uB610\uB294 board.read scope \uD544\uC694)",
|
|
15411
|
+
{
|
|
15412
|
+
boardId: external_exports.string().describe("\uAC8C\uC2DC\uD310 ID"),
|
|
15413
|
+
count: external_exports.number().optional().describe("\uD398\uC774\uC9C0\uB2F9 \uD56D\uBAA9 \uC218 (\uAE30\uBCF8: 20, \uCD5C\uB300: 40)"),
|
|
15414
|
+
cursor: external_exports.string().optional().describe("\uD398\uC774\uC9C0\uB124\uC774\uC158 \uCEE4\uC11C")
|
|
15415
|
+
},
|
|
15416
|
+
async ({ boardId, count, cursor }) => {
|
|
15417
|
+
try {
|
|
15418
|
+
const result = await listPosts(boardId, count ?? 20, cursor);
|
|
15419
|
+
const posts = result.posts.map((p) => ({
|
|
15420
|
+
postId: p.postId,
|
|
15421
|
+
title: p.title,
|
|
15422
|
+
userName: p.userName ?? "",
|
|
15423
|
+
readCount: p.readCount ?? 0,
|
|
15424
|
+
commentCount: p.commentCount ?? 0,
|
|
15425
|
+
createdTime: p.createdTime ?? ""
|
|
15426
|
+
}));
|
|
15427
|
+
return {
|
|
15428
|
+
content: [{ type: "text", text: JSON.stringify({ posts, count: posts.length, nextCursor: result.responseMetaData?.nextCursor ?? null }) }]
|
|
15429
|
+
};
|
|
15430
|
+
} catch (err) {
|
|
15431
|
+
const error48 = err;
|
|
15432
|
+
return {
|
|
15433
|
+
content: [{ type: "text", text: `Error: ${error48.message}` }],
|
|
15434
|
+
isError: true
|
|
15435
|
+
};
|
|
15436
|
+
}
|
|
15437
|
+
}
|
|
15438
|
+
);
|
|
15439
|
+
server.tool(
|
|
15440
|
+
"nworks_board_read",
|
|
15441
|
+
"\uAC8C\uC2DC\uD310 \uAE00\uC758 \uC0C1\uC138 \uB0B4\uC6A9\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4 (User OAuth board \uB610\uB294 board.read scope \uD544\uC694)",
|
|
15442
|
+
{
|
|
15443
|
+
boardId: external_exports.string().describe("\uAC8C\uC2DC\uD310 ID"),
|
|
15444
|
+
postId: external_exports.string().describe("\uAE00 ID")
|
|
15445
|
+
},
|
|
15446
|
+
async ({ boardId, postId }) => {
|
|
15447
|
+
try {
|
|
15448
|
+
const post = await readPost(boardId, postId);
|
|
15449
|
+
return {
|
|
15450
|
+
content: [{ type: "text", text: JSON.stringify({
|
|
15451
|
+
postId: post.postId,
|
|
15452
|
+
boardId: post.boardId,
|
|
15453
|
+
title: post.title,
|
|
15454
|
+
body: post.body ?? "",
|
|
15455
|
+
userName: post.userName ?? "",
|
|
15456
|
+
readCount: post.readCount ?? 0,
|
|
15457
|
+
commentCount: post.commentCount ?? 0,
|
|
15458
|
+
createdTime: post.createdTime ?? "",
|
|
15459
|
+
updatedTime: post.updatedTime ?? ""
|
|
15460
|
+
}) }]
|
|
15461
|
+
};
|
|
15462
|
+
} catch (err) {
|
|
15463
|
+
const error48 = err;
|
|
15464
|
+
return {
|
|
15465
|
+
content: [{ type: "text", text: `Error: ${error48.message}` }],
|
|
15466
|
+
isError: true
|
|
15467
|
+
};
|
|
15468
|
+
}
|
|
15469
|
+
}
|
|
15470
|
+
);
|
|
15471
|
+
server.tool(
|
|
15472
|
+
"nworks_board_create",
|
|
15473
|
+
"\uAC8C\uC2DC\uD310\uC5D0 \uAE00\uC744 \uC791\uC131\uD569\uB2C8\uB2E4 (User OAuth board scope \uD544\uC694)",
|
|
15474
|
+
{
|
|
15475
|
+
boardId: external_exports.string().describe("\uAC8C\uC2DC\uD310 ID"),
|
|
15476
|
+
title: external_exports.string().describe("\uAE00 \uC81C\uBAA9"),
|
|
15477
|
+
body: external_exports.string().optional().describe("\uAE00 \uBCF8\uBB38"),
|
|
15478
|
+
enableComment: external_exports.boolean().optional().describe("\uB313\uAE00 \uD5C8\uC6A9 (\uAE30\uBCF8: true)"),
|
|
15479
|
+
sendNotifications: external_exports.boolean().optional().describe("\uC54C\uB9BC \uBC1C\uC1A1 (\uAE30\uBCF8: false)")
|
|
15480
|
+
},
|
|
15481
|
+
async ({ boardId, title, body, enableComment, sendNotifications }) => {
|
|
15482
|
+
try {
|
|
15483
|
+
const post = await createPost({
|
|
15484
|
+
boardId,
|
|
15485
|
+
title,
|
|
15486
|
+
body,
|
|
15487
|
+
enableComment,
|
|
15488
|
+
sendNotifications
|
|
15489
|
+
});
|
|
15490
|
+
return {
|
|
15491
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, postId: post.postId, boardId: post.boardId, title: post.title }) }]
|
|
15492
|
+
};
|
|
15493
|
+
} catch (err) {
|
|
15494
|
+
const error48 = err;
|
|
15495
|
+
return {
|
|
15496
|
+
content: [{ type: "text", text: `Error: ${error48.message}` }],
|
|
15497
|
+
isError: true
|
|
15498
|
+
};
|
|
15499
|
+
}
|
|
15500
|
+
}
|
|
15501
|
+
);
|
|
15273
15502
|
server.tool(
|
|
15274
15503
|
"nworks_whoami",
|
|
15275
15504
|
"\uD604\uC7AC \uC778\uC99D\uB41C NAVER WORKS \uACC4\uC815 \uC815\uBCF4\uB97C \uD655\uC778\uD569\uB2C8\uB2E4",
|