dingtalk-wiki 1.2.17 → 1.2.19
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/index.js +24 -14
- package/package.json +2 -2
package/index.js
CHANGED
|
@@ -871,17 +871,17 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
871
871
|
},
|
|
872
872
|
{
|
|
873
873
|
name: 'get_wiki_doc_content',
|
|
874
|
-
description: '
|
|
874
|
+
description: '读取文档内容。对 .adoc 在线文档使用 blocks API;对上传的 .md 等文件使用存储下载 API(需 Storage.DownloadInfo.Read 权限)。',
|
|
875
875
|
inputSchema: {
|
|
876
876
|
type: 'object',
|
|
877
877
|
properties: {
|
|
878
878
|
doc_key: {
|
|
879
879
|
type: 'string',
|
|
880
|
-
description: '文档标识。支持
|
|
880
|
+
description: '文档标识。支持 nodeId(dentryUuid)、docKey,或文档 URL。'
|
|
881
881
|
},
|
|
882
882
|
workspace_id: {
|
|
883
883
|
type: 'string',
|
|
884
|
-
description: '知识库 ID
|
|
884
|
+
description: '知识库 ID(可选)。自动通过 wiki/nodes API 解析。'
|
|
885
885
|
},
|
|
886
886
|
operator_id: {
|
|
887
887
|
type: 'string',
|
|
@@ -893,13 +893,13 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
893
893
|
},
|
|
894
894
|
{
|
|
895
895
|
name: 'update_wiki_doc_content',
|
|
896
|
-
description: '
|
|
896
|
+
description: '覆写 .adoc 在线文档正文内容(⚠️ 全量覆盖,不可撤销)。对上传的 .md 等文件不支持修改。',
|
|
897
897
|
inputSchema: {
|
|
898
898
|
type: 'object',
|
|
899
899
|
properties: {
|
|
900
900
|
doc_key: {
|
|
901
901
|
type: 'string',
|
|
902
|
-
description: '文档标识。支持
|
|
902
|
+
description: '文档标识。支持 nodeId(dentryUuid)、docKey,或文档 URL。仅 .adoc 在线文档支持写入。'
|
|
903
903
|
},
|
|
904
904
|
content: {
|
|
905
905
|
type: 'string',
|
|
@@ -1192,6 +1192,11 @@ async function resolveDocKey(docKey, operatorId, dingtalkInstance) {
|
|
|
1192
1192
|
const node = nodeInfo.node || nodeInfo;
|
|
1193
1193
|
console.error(`[DEBUG] resolveDocKey: wiki/nodes response keys=${Object.keys(node).join(',')}`);
|
|
1194
1194
|
|
|
1195
|
+
// 缓存 workspaceId,供后续 fallback 使用
|
|
1196
|
+
if (node.workspaceId) {
|
|
1197
|
+
dingtalkInstance._resolvedWorkspaceId = node.workspaceId;
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1195
1200
|
// wiki/nodes 的 nodeId = dentryUuid,直接可用
|
|
1196
1201
|
// 但 node.document.docKey 可能是不同的值,优先使用
|
|
1197
1202
|
if (node.document?.docKey) {
|
|
@@ -1345,6 +1350,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1345
1350
|
});
|
|
1346
1351
|
|
|
1347
1352
|
const doc = response.data;
|
|
1353
|
+
const nodeId = doc.nodeId || doc.id;
|
|
1348
1354
|
const typeLabels = {
|
|
1349
1355
|
DOC: '文档',
|
|
1350
1356
|
WORKBOOK: '表格',
|
|
@@ -1364,7 +1370,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1364
1370
|
'',
|
|
1365
1371
|
`${typeIcon} ${name}`,
|
|
1366
1372
|
`🗂️ 类型: ${doc_type}`,
|
|
1367
|
-
`🆔 Node ID: ${
|
|
1373
|
+
`🆔 Node ID: ${nodeId}`,
|
|
1368
1374
|
];
|
|
1369
1375
|
|
|
1370
1376
|
if (doc.docKey) {
|
|
@@ -1381,7 +1387,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1381
1387
|
}
|
|
1382
1388
|
|
|
1383
1389
|
setImmediate(() => {
|
|
1384
|
-
wikiIndex.add(
|
|
1390
|
+
wikiIndex.add(nodeId || doc.docKey, {
|
|
1385
1391
|
title: name,
|
|
1386
1392
|
content: args.content || '',
|
|
1387
1393
|
workspaceId: workspace_id || doc.workspaceId,
|
|
@@ -1389,7 +1395,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1389
1395
|
url: doc.url || '',
|
|
1390
1396
|
type: doc_type,
|
|
1391
1397
|
});
|
|
1392
|
-
const contentId = doc.docKey || doc.dentryUuid ||
|
|
1398
|
+
const contentId = doc.docKey || doc.dentryUuid || nodeId;
|
|
1393
1399
|
if (args.content && contentId) {
|
|
1394
1400
|
dingtalk.docRequest('POST', `/v1.0/doc/suites/documents/${contentId}/overwriteContent`, {
|
|
1395
1401
|
operatorId: opId,
|
|
@@ -1444,7 +1450,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1444
1450
|
const result = await dingtalk.docRequest('GET', `/v2.0/wiki/nodes/${node_id}`, {
|
|
1445
1451
|
operatorId: operator_id || null
|
|
1446
1452
|
});
|
|
1447
|
-
const node = result;
|
|
1453
|
+
const node = result.node || result;
|
|
1448
1454
|
let output = `📄 节点详情\n\n`;
|
|
1449
1455
|
output += `名称: ${node.name || '-'}\n`;
|
|
1450
1456
|
output += `ID: ${node.id || node.nodeId || '-'}\n`;
|
|
@@ -1506,7 +1512,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1506
1512
|
for (const child of children) {
|
|
1507
1513
|
const name = child.name || '';
|
|
1508
1514
|
if (name.includes(keyword)) {
|
|
1509
|
-
matchedNodes.push({ name, nodeId: child.dentryId || child.nodeId || child.id, workspaceId: ws.workspaceId, workspaceName: ws.name, type: child.contentType === 'folder' ? '文件夹' : '文档', url: child.url || '' });
|
|
1515
|
+
matchedNodes.push({ name, nodeId: child.dentryUuid || child.dentryId || child.nodeId || child.id, workspaceId: ws.workspaceId, workspaceName: ws.name, type: child.contentType === 'folder' ? '文件夹' : '文档', url: child.url || '' });
|
|
1510
1516
|
}
|
|
1511
1517
|
const childId = child.dentryId || child.nodeId || child.id;
|
|
1512
1518
|
if (child.hasChildren && childId && !visited.has(childId)) queue.push(childId);
|
|
@@ -1562,6 +1568,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1562
1568
|
const icon = item.type === 'FOLDER' || item.type === 'folder' ? '📁' : '📄';
|
|
1563
1569
|
output += `${i + 1}. ${icon} ${item.title}\n`;
|
|
1564
1570
|
output += ` 知识库: ${item.workspaceName} (${item.workspaceId})\n`;
|
|
1571
|
+
output += ` Node ID: ${item.id}\n`;
|
|
1565
1572
|
output += ` 匹配度: ${(item.score * 100).toFixed(0)}%\n`;
|
|
1566
1573
|
if (item.url) output += ` 链接: ${item.url}\n`;
|
|
1567
1574
|
if (item.content) {
|
|
@@ -1633,10 +1640,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1633
1640
|
if (operator_id) {
|
|
1634
1641
|
dingtalk.setOperatorId(operator_id);
|
|
1635
1642
|
}
|
|
1643
|
+
dingtalk._resolvedWorkspaceId = null;
|
|
1636
1644
|
|
|
1637
1645
|
let realDocKey = await resolveDocKey(docKey, operator_id || null, dingtalk);
|
|
1638
1646
|
console.error(`[DEBUG] get_wiki_doc_content: input=${docKey}, resolved=${realDocKey}`);
|
|
1639
1647
|
|
|
1648
|
+
const effectiveWsId = workspaceId || dingtalk._resolvedWorkspaceId;
|
|
1649
|
+
|
|
1640
1650
|
// 尝试 blocks API 读取 .adoc 在线文档内容
|
|
1641
1651
|
try {
|
|
1642
1652
|
const result = await dingtalk.docRequest('GET', `/v1.0/doc/suites/documents/${realDocKey}/blocks`, { operatorId: operator_id || null });
|
|
@@ -1659,7 +1669,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1659
1669
|
const isDocKeyIllegal = blocksErr.message.includes('doc key is illegal');
|
|
1660
1670
|
|
|
1661
1671
|
// Fallback: 尝试存储 v1.0 下载 API(对上传的 .md 等文件有效)
|
|
1662
|
-
if (isDocKeyIllegal &&
|
|
1672
|
+
if (isDocKeyIllegal && effectiveWsId) {
|
|
1663
1673
|
try {
|
|
1664
1674
|
const token = await dingtalk.getAccessToken();
|
|
1665
1675
|
const opId = await dingtalk.resolveOperatorId(operator_id || null);
|
|
@@ -1678,7 +1688,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1678
1688
|
if (parentId) dirParams.dentryId = parentId;
|
|
1679
1689
|
const dirRes = await axios({
|
|
1680
1690
|
method: 'GET',
|
|
1681
|
-
url: `${DINGTALK_API_V2}/v2.0/doc/spaces/${
|
|
1691
|
+
url: `${DINGTALK_API_V2}/v2.0/doc/spaces/${effectiveWsId}/directories`,
|
|
1682
1692
|
headers: { 'x-acs-dingtalk-access-token': token },
|
|
1683
1693
|
params: dirParams
|
|
1684
1694
|
});
|
|
@@ -1722,7 +1732,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1722
1732
|
let hint = '';
|
|
1723
1733
|
if (isDocKeyIllegal) {
|
|
1724
1734
|
hint = `\n\n原因: 此文档不是 .adoc 在线文档,blocks API 无法读取。`;
|
|
1725
|
-
if (
|
|
1735
|
+
if (effectiveWsId) {
|
|
1726
1736
|
hint += `\n已尝试存储 v1.0 下载 API 但仍失败(需开通 Storage.DownloadInfo.Read 权限)。`;
|
|
1727
1737
|
} else {
|
|
1728
1738
|
hint += `\n请提供 workspace_id 以尝试存储 v1.0 下载 API。`;
|
|
@@ -1731,7 +1741,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1731
1741
|
return {
|
|
1732
1742
|
content: [{
|
|
1733
1743
|
type: 'text',
|
|
1734
|
-
text: `❌ 读取文档内容失败\n错误: ${blocksErr.message}${hint}\n\n调试信息:\n- 输入 doc_key: ${docKey}\n- 解析后 realDocKey: ${realDocKey}\n- workspaceId: ${
|
|
1744
|
+
text: `❌ 读取文档内容失败\n错误: ${blocksErr.message}${hint}\n\n调试信息:\n- 输入 doc_key: ${docKey}\n- 解析后 realDocKey: ${realDocKey}\n- workspaceId: ${effectiveWsId || '未提供'}\n- operator_id: ${operator_id || '未提供(将自动解析)'}`
|
|
1735
1745
|
}],
|
|
1736
1746
|
isError: true
|
|
1737
1747
|
};
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dingtalk-wiki",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.19",
|
|
4
4
|
"description": "DingTalk Wiki / Docs read-write MCP server that fills the gap left by DingTalk official MCP.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"dingtalk-wiki": "
|
|
7
|
+
"dingtalk-wiki": "index.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"start": "node index.js",
|