affine-mcp-server 1.11.0 → 1.11.2
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 +2 -2
- package/dist/tools/docs.js +57 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A Model Context Protocol (MCP) server that integrates with AFFiNE (self‑hosted or cloud). It exposes AFFiNE workspaces and documents to AI assistants over stdio (default) or HTTP (`/mcp`).
|
|
4
4
|
|
|
5
|
-
[](https://github.com/dawncr0w/affine-mcp-server/releases)
|
|
6
6
|
[](https://github.com/modelcontextprotocol/typescript-sdk)
|
|
7
7
|
[](https://github.com/dawncr0w/affine-mcp-server/actions/workflows/ci.yml)
|
|
8
8
|
[](LICENSE)
|
|
@@ -19,7 +19,7 @@ A Model Context Protocol (MCP) server that integrates with AFFiNE (self‑hosted
|
|
|
19
19
|
- Tools: 76 focused tools with WebSocket-based document editing
|
|
20
20
|
- Status: Active
|
|
21
21
|
|
|
22
|
-
> New in v1.11.
|
|
22
|
+
> New in v1.11.2: Corrected stale deleted-document visibility in `list_docs` after `delete_doc`, completing the `v1.11.1` delete-metadata fix.
|
|
23
23
|
|
|
24
24
|
## Features
|
|
25
25
|
|
package/dist/tools/docs.js
CHANGED
|
@@ -1985,6 +1985,9 @@ export function registerDocTools(server, gql, defaults) {
|
|
|
1985
1985
|
const docs = data.workspace.docs;
|
|
1986
1986
|
const tagsByDocId = new Map();
|
|
1987
1987
|
const titlesByDocId = new Map();
|
|
1988
|
+
let workspacePageCount = null;
|
|
1989
|
+
let workspacePageIds = null;
|
|
1990
|
+
const deletedDocIds = new Set();
|
|
1988
1991
|
try {
|
|
1989
1992
|
const { endpoint, cookie, bearer } = await getCookieAndEndpoint();
|
|
1990
1993
|
const wsUrl = wsUrlFromGraphQLEndpoint(endpoint);
|
|
@@ -1997,6 +2000,8 @@ export function registerDocTools(server, gql, defaults) {
|
|
|
1997
2000
|
Y.applyUpdate(wsDoc, Buffer.from(snapshot.missing, "base64"));
|
|
1998
2001
|
const meta = wsDoc.getMap("meta");
|
|
1999
2002
|
const pages = getWorkspacePageEntries(meta);
|
|
2003
|
+
workspacePageCount = pages.length;
|
|
2004
|
+
workspacePageIds = new Set(pages.map(page => page.id));
|
|
2000
2005
|
const { byId } = getWorkspaceTagOptionMaps(meta);
|
|
2001
2006
|
for (const page of pages) {
|
|
2002
2007
|
if (page.title) {
|
|
@@ -2006,6 +2011,20 @@ export function registerDocTools(server, gql, defaults) {
|
|
|
2006
2011
|
tagsByDocId.set(page.id, resolveTagLabels(tagEntries, byId));
|
|
2007
2012
|
}
|
|
2008
2013
|
}
|
|
2014
|
+
const graphEdges = Array.isArray(docs?.edges) ? docs.edges : [];
|
|
2015
|
+
if (workspacePageIds && graphEdges.length > workspacePageIds.size) {
|
|
2016
|
+
for (const edge of graphEdges) {
|
|
2017
|
+
const nodeId = edge?.node?.id;
|
|
2018
|
+
if (typeof nodeId !== "string" || workspacePageIds.has(nodeId)) {
|
|
2019
|
+
continue;
|
|
2020
|
+
}
|
|
2021
|
+
const edgeSnapshot = await loadDoc(socket, workspaceId, nodeId);
|
|
2022
|
+
const edgeExists = Boolean(edgeSnapshot.missing || edgeSnapshot.state || edgeSnapshot.timestamp);
|
|
2023
|
+
if (!edgeExists) {
|
|
2024
|
+
deletedDocIds.add(nodeId);
|
|
2025
|
+
}
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2009
2028
|
}
|
|
2010
2029
|
finally {
|
|
2011
2030
|
socket.disconnect();
|
|
@@ -2014,24 +2033,46 @@ export function registerDocTools(server, gql, defaults) {
|
|
|
2014
2033
|
catch {
|
|
2015
2034
|
// Keep list_docs available even when workspace snapshot fetch fails.
|
|
2016
2035
|
}
|
|
2036
|
+
const mergedEdges = Array.isArray(docs?.edges)
|
|
2037
|
+
? docs.edges.map((edge) => {
|
|
2038
|
+
const node = edge?.node;
|
|
2039
|
+
if (!node || typeof node.id !== "string") {
|
|
2040
|
+
return edge;
|
|
2041
|
+
}
|
|
2042
|
+
return {
|
|
2043
|
+
...edge,
|
|
2044
|
+
node: {
|
|
2045
|
+
...node,
|
|
2046
|
+
title: titlesByDocId.get(node.id) || node.title,
|
|
2047
|
+
tags: tagsByDocId.get(node.id) || [],
|
|
2048
|
+
},
|
|
2049
|
+
};
|
|
2050
|
+
})
|
|
2051
|
+
: [];
|
|
2052
|
+
const visibleEdges = deletedDocIds.size > 0
|
|
2053
|
+
? mergedEdges.filter((edge) => !deletedDocIds.has(edge?.node?.id))
|
|
2054
|
+
: mergedEdges;
|
|
2055
|
+
const correctedTotalCount = typeof docs?.totalCount === "number" &&
|
|
2056
|
+
typeof workspacePageCount === "number" &&
|
|
2057
|
+
(deletedDocIds.size > 0 ||
|
|
2058
|
+
visibleEdges.length === workspacePageCount) &&
|
|
2059
|
+
workspacePageCount < docs.totalCount
|
|
2060
|
+
? workspacePageCount
|
|
2061
|
+
: docs?.totalCount;
|
|
2062
|
+
const correctedPageInfo = docs?.pageInfo
|
|
2063
|
+
? {
|
|
2064
|
+
...docs.pageInfo,
|
|
2065
|
+
endCursor: visibleEdges.length > 0 ? visibleEdges[visibleEdges.length - 1]?.cursor ?? null : null,
|
|
2066
|
+
hasNextPage: typeof correctedTotalCount === "number" && !parsed.after
|
|
2067
|
+
? (parsed.offset ?? 0) + visibleEdges.length < correctedTotalCount
|
|
2068
|
+
: docs.pageInfo.hasNextPage,
|
|
2069
|
+
}
|
|
2070
|
+
: docs?.pageInfo;
|
|
2017
2071
|
const mergedDocs = {
|
|
2018
2072
|
...docs,
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
if (!node || typeof node.id !== "string") {
|
|
2023
|
-
return edge;
|
|
2024
|
-
}
|
|
2025
|
-
return {
|
|
2026
|
-
...edge,
|
|
2027
|
-
node: {
|
|
2028
|
-
...node,
|
|
2029
|
-
title: titlesByDocId.get(node.id) || node.title,
|
|
2030
|
-
tags: tagsByDocId.get(node.id) || [],
|
|
2031
|
-
},
|
|
2032
|
-
};
|
|
2033
|
-
})
|
|
2034
|
-
: [],
|
|
2073
|
+
totalCount: correctedTotalCount,
|
|
2074
|
+
pageInfo: correctedPageInfo,
|
|
2075
|
+
edges: visibleEdges,
|
|
2035
2076
|
};
|
|
2036
2077
|
return text(mergedDocs);
|
|
2037
2078
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "affine-mcp-server",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Model Context Protocol server for AFFiNE - enables AI assistants to interact with AFFiNE workspaces, documents, and collaboration features.",
|